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
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div macro='annotations'></div>
<div class='editor' macro='edit text'></div>
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser excludeLists'></span></div>
<!--}}}-->
To get started with this blank [[TiddlyWiki]], you'll need to modify the following tiddlers:
* [[SiteTitle]] & [[SiteSubtitle]]: The title and subtitle of the site, as shown above (after saving, they will also appear in the browser title bar)
* [[MainMenu]]: The menu (usually on the left)
* [[DefaultTiddlers]]: Contains the names of the tiddlers that you want to appear when the TiddlyWiki is opened
You'll also need to enter your username for signing your edits: <<option txtUserName>>
<<importTiddlers>>
<!--{{{-->
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml' />
<!--}}}-->
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]]
<!--{{{-->
<div class='header' role='banner' 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' role='navigation' refresh='content' tiddler='MainMenu'></div>
<div id='sidebar'>
<div id='sidebarOptions' role='navigation' refresh='content' tiddler='SideBarOptions'></div>
<div id='sidebarTabs' role='complementary' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
<div id='displayArea' role='main'>
<div id='messageArea'></div>
<div id='tiddlerDisplay'></div>
</div>
<!--}}}-->
/*{{{*/
body {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

hr {height:1px;}

a {text-decoration:none;}

dt {font-weight:bold;}

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

.txtOptionInput {width:11em;}

#contentWrapper .chkOptionInput {border:0;}

.externalLink {text-decoration:underline;}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

.whenBackstage {display:none;}
.backstageVisible .whenBackstage {display:block;}
/*}}}*/
/***
StyleSheet for use when a translation requires any css style changes.
This StyleSheet can be used directly by languages such as Chinese, Japanese and Korean which need larger font sizes.
***/
/*{{{*/
body {font-size:0.8em;}
#sidebarOptions {font-size:1.05em;}
#sidebarOptions a {font-style:normal;}
#sidebarOptions .sliderPanel {font-size:0.95em;}
.subtitle {font-size:0.8em;}
.viewer table.listView {font-size:0.95em;}
/*}}}*/
/*{{{*/
@media print {
#mainMenu, #sidebar, #messageArea, .toolbar, #backstageButton, #backstageArea {display: none !important;}
#displayArea {margin: 1em 1em 0em;}
noscript {display:none;} /* Fixes a feature in Firefox 1.5.0.2 where print preview displays the noscript content */
}
/*}}}*/
<!--{{{-->
<div class='toolbar' role='navigation' 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>
<!--}}}-->
/***
|''Name''|RefreshTiddlerCommand|
|''Version''|0.3.0|
***/
//{{{
(function($) {

var cmd = config.commands.refreshTiddler = {
	text: "refresh",
	locale: {
		refreshing: "Refreshing tiddler..."
	},
	tooltip: "refresh this tiddler to be the one on the server",
	handler: function(ev, src, title) {
		var tiddler = store.getTiddler(title);
		if(!tiddler) {
			tiddler = new Tiddler(title);
			merge(tiddler.fields, config.defaultCustomFields);
		}
		$(story.getTiddler(title)).find(".viewer").
			empty().text(cmd.locale.refreshing);
		var dirtyStatus = store.isDirty();
		story.loadMissingTiddler(title, {
			"server.workspace": tiddler.fields["server.recipe"]  ? "recipes/" + tiddler.fields["server.recipe"] :
				tiddler.fields["server.workspace"] || "bags/"+tiddler.fields["server.bag"],
			"server.host": tiddler.fields["server.host"],
			"server.type": tiddler.fields["server.type"]
		}, function() {
			store.setDirty(dirtyStatus);
		});
	}
};

})(jQuery);
//}}}
/***
|Name|[[SwitchThemePlugin]]|
|Source|http://www.TiddlyTools.com/#SwitchThemePlugin|
|Documentation|http://www.TiddlyTools.com/#SwitchThemePluginInfo|
|Version|5.3.0|
|Author|Eric Shulman - [[ELSDesignStudios]]|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.3|
|Type|plugin|
|Description|Select alternative TiddlyWiki template/stylesheet 'themes' from a droplist|
!!!!!Documentation
>see [[SwitchThemePluginInfo]] for details
!!!!!Configuration
<<<
Current theme:<<switchTheme width:auto>>
<<option chkRandomTheme>> select a random theme at startup
//Note: to prevent a given theme from being chosen at random, tag it with <<tag noRandom>>//
<<<
!!!!!Installation Note
>As of 4/13/2008, a "core patch" function that provides backward-compatibility with TW2.3.x has been split into a separate [[SwitchThemePluginPatch]] tiddler to reduce installation overhead for //this// plugin.  You only need to install the additional plugin tiddler when using SwitchThemePlugin in documents based on TW2.3.x or a pre-release (beta) version of TW2.4.0
!!!!!Revisions
<<<
2008.04.23 [5.3.0] added option for chkRandomTheme (select random theme at startup)
2008.04.13 [5.2.0] moved TW2.3.x fixup for core's switchTheme() function to [[SwitchThemePluginPatch]] and simplified random theme handling.  Also, changed "Web*" prefix to "*ReadOnly" suffix for compatibility with TW240 core convention.
| Please see [[SwitchThemePluginInfo]] for previous revision details |
2008.01.22 [5.0.0] Completely re-written and renamed from [[SelectStylesheetPlugin]] (now retired)
>//history for retired [[SelectStylesheetPlugin]] omitted//
2005.07.20 [1.0.0] Initial Release
<<<
!!!!!Code
***/
//{{{
version.extensions.switchTheme = {major: 5, minor: 3, revision: 0, date: new Date(2008,4,23)};

config.macros.switchTheme = {
	handler: function(place,macroName,params) {
		setStylesheet(".switchTheme {width:100%;font-size:8pt;margin:0em}","switchThemePlugin");
		if (params[0] && (params[0].substr(0,6)=="width:"))	var width=(params.shift()).substr(6);
		if (params[0] && (params[0].substr(0,6)=="label:"))	var label=(params.shift()).substr(6);
		if (params[0] && (params[0].substr(0,7)=="prompt:"))	var prompt=(params.shift()).substr(7);
		if (params[0] && params[0].trim().length) // create a link that sets a specific theme
			createTiddlyButton(place,label?label:params[0],prompt?prompt:params[0],
				function(){ config.macros.switchTheme.set(params[0]); return false;});
		else { // create a select list of available themes
			var theList=createTiddlyElement(place,"select",null,"switchTheme",null);
			theList.size=1;
			if (width) theList.style.width=width;
			theList.onchange=function() { config.macros.switchTheme.set(this.value); return true; };
			this.refresh(theList);
		}
	},
	refresh: function(list) {
		var indent = String.fromCharCode(160)+String.fromCharCode(160);
		while(list.length > 0){list.options[0]=null;} // clear list
		list.options[list.length] = new Option("select a theme:","",true,true);
		list.options[list.length] = new Option(indent+"[default]","StyleSheet");
		list.options[list.length] = new Option(indent+"[random]","*");
		var themes=store.getTaggedTiddlers("systemTheme");
		for (var i=0; i<themes.length; i++) if (themes[i].title!="StyleSheet")
			list.options[list.length]=new Option(indent+themes[i].title,themes[i].title);
		// show current selection
		for (var t=0; t<list.options.length; t++)
			if (list.options[t].value==config.options.txtTheme)
				{ list.selectedIndex=t; break; }
	},
	set: function(theme) {
		if (!theme||!theme.trim().length) return;
		if (theme=="*") { // select a random theme (excluding themes tagged with "noRandom")
			var themes=store.getTaggedTiddlers("systemTheme"); if (!themes.length) return false;
			var which=Math.floor(Math.random()*themes.length);
			while (themes[which].title==config.options.txtTheme||themes[which].isTagged("noRandom"))
				which=Math.floor(Math.random()*themes.length);
			theme=themes[which].title;
		}
		// apply and remember selected theme
		story.switchTheme(theme);
		config.options.txtTheme=theme;
		saveOptionCookie("txtTheme");
		// sync theme droplists
		var elems=document.getElementsByTagName("select");
		var lists=[]; for (var i=0; i<elems.length; i++)
			if (hasClass(elems[i],"switchTheme")) lists.push(elems[i]);
		for (var k=0; k<lists.length; k++)
			for (var t=0; t<lists[k].options.length; t++)
				if (lists[k].options[t].value==config.options.txtTheme)
					{ lists[k].selectedIndex=t; break; }
		return;
	}
}
//}}}

// // select a random theme at startup (if enabled)
//{{{
if (config.options.chkRandomTheme===undefined)
	config.options.chkRandomTheme=false;
if (config.options.chkRandomTheme)
	config.macros.switchTheme.set("*");
//}}}
! AlbumID, authKey
@@IMPORTANT: Change this tiddler to be private. Otherwise your pictures will be publicly available!@@

!! Format
SLICE_NAME: ALBUM_ID, ALBUM_AUTH_KEY

Note, the comma after ALBUM_ID above! It needs to be there!

!! Album list

album1: 5734759251355149249, Gv1sRgCK_CgaL7ueetswE
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink" version="1.1" viewBox="72 648 70 70" 
width="30" height="30">
<g stroke="none" stroke-opacity="1" stroke-dasharray="none" fill="none" fill-opacity="1">
	<g>
		<path d="M 77.59005 669.34003 C 71.532745 681.90424 73.714462 697.4441 84.135193 707.86475 
		C 97.315445 721.0451 118.684715 721.0451 131.8649 707.86475 
		C 145.04515 694.68457 145.04515 673.31537 131.8649 660.13513 
		C 121.4441 649.7141 105.90419 647.53253 93.339905 653.5899 L 102.047455 662.2976 
		C 109.58637 660.2373 117.987976 662.16803 123.90997 668.08997 
		C 132.69673 676.8767 132.69673 691.12317 123.90997 699.90985 
		C 115.12313 708.6966 100.87699 708.6966 92.09012 699.90985 
		C 86.168266 693.98804 84.23744 685.58643 86.297653 678.04755 Z M 72 648 L 72 668.25 L 78.75 661.49957 
		L 99.00019 681.7502 L 105.750175 675.00006 L 85.50013 654.75012 L 92.249985 648 Z" fill="black"
		class="glyph"/>
	</g>
</g>
</svg>
A [[SiteIcon|SiteIcon tiddler]]@glossary helps provide some identity to your space.  Ideally it'd be a square and a minimum of 48*48 pixels size.  You can upload your site icon using the uploader below.

<<binaryUploadPublic title:SiteIcon>>
/***
***/
/*{{{*/
/**
 * SyntaxHighlighter
 * http://alexgorbatchev.com/SyntaxHighlighter
 *
 * SyntaxHighlighter is donationware. If you are using it, please donate.
 * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
 *
 * @version
 * 3.0.83 (July 02 2010)
 * 
 * @copyright
 * Copyright (C) 2004-2010 Alex Gorbatchev.
 *
 * @license
 * Dual licensed under the MIT and GPL licenses.
 */
;(function()
{
	// CommonJS
	typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null;

	function Brush()
	{
		var keywords =	'break case catch continue ' +
						'default delete do else false  ' +
						'for function if in instanceof ' +
						'new null return super switch ' +
						'this throw true try typeof var while with'
						;

		var r = SyntaxHighlighter.regexLib;
		
		this.regexList = [
			{ regex: r.multiLineDoubleQuotedString,					css: 'string' },			// double quoted strings
			{ regex: r.multiLineSingleQuotedString,					css: 'string' },			// single quoted strings
			{ regex: r.singleLineCComments,							css: 'comments' },			// one line comments
			{ regex: r.multiLineCComments,							css: 'comments' },			// multiline comments
			{ regex: /\s*#.*/gm,									css: 'preprocessor' },		// preprocessor tags like #region and #endregion
			{ regex: new RegExp(this.getKeywords(keywords), 'gm'),	css: 'keyword' }			// keywords
			];
	
		this.forHtmlScript(r.scriptScriptTags);
	};

	Brush.prototype	= new SyntaxHighlighter.Highlighter();
	Brush.aliases	= ['js', 'jscript', 'javascript'];

	SyntaxHighlighter.brushes.JScript = Brush;

	// CommonJS
	typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
})();
/*}}}*/
The scope of this site[[*|SiteImprovements]][[*|ThemeTiddlers]] is to __share things I learn and do__[[*|ToBeDone]] about my main interest. Therefore, here you can find information about different areas but related to Robotics.

It is possible that some notes are written in languages as Spanish and Italian, I think that sharing knowledge is most important than the language is used. However, I try to use English as main language.

Please, click [[here|http://dgerod.xyz-lab.org.es]] if you want to go to my personal web. And if you have any comment about this site please feel free to [[contact me|http://dgerod.xyz-lab.org.es/contact-info.html]]
!!!!Definitions
{{{
\def\modulus#1{{\left\lvert {#1} \right\rvert}}
\def\norm#1{{\left\Vert {#1} \right\Vert}}
\def\equivalent{\sim}
\def\quotient{\solidus}
}}}

!!!!Notes
{{{\equivalent}}} is for equivalence relations.

!!!!Examples
{{{
\modulus{x - y}
\norm{\bold{x} - \bold{y}}
a \equivalent b
\quotient{\reals}/{\rationals}
}}}
\[
\modulus{x - y}\qquad
\norm{\bold{x} - \bold{y}}\qquad
a \equivalent b\qquad
\quotient{\reals}/{\rationals}
\]
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
/***
|Name|TagCloudPlugin|
|Source|http://www.TiddlyTools.com/#TagCloudPlugin|
|Version|1.7.0|
|Author|Eric Shulman|
|Original Author|Clint Checketts|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|present a 'cloud' of tags (or links) using proportional font display|
!Usage
<<<
{{{
<<cloud type action:... limit:... tag tag tag ...>>
<<cloud type action:... limit:... +TiddlerName>>
<<cloud type action:... limit:... -TiddlerName>>
<<cloud type action:... limit:... =tagvalue>>
}}}
where:
* //type// is a keyword, one of:
** ''tags'' (default) - displays a cloud of tags, based on frequency of use
** ''links'' - displays a cloud of tiddlers, based on number of links //from// each tiddler
** ''references'' - displays a cloud of tiddlers, based on number of links //to// each tiddler
* ''action:popup'' (default) - clicking a cloud item shows a popup with links to related tiddlers<br>//or//<br> ''action:goto'' - clicking a cloud item immediately opens the tiddler corresponding to that item
* ''limit:N'' (optional) - restricts the cloud display to only show the N most popular tags/links
* ''tag tag tag...'' (or ''title title title'' if ''links''/''references'' is used)<br>shows all tags/links in the document //except// for those listed as macro parameters
* ''+TiddlerName''<br>show only tags/links read from a space-separated, bracketed list stored in a separate tiddler.
* ''-TiddlerName''<br>show all tags/links //except// those read from a space-separated, bracketed list stored in a separate tiddler.
* ''=tagvalue'' (//only if type=''tags''//)<br>shows only tags that are themselves tagged with the indicated tag value (i.e., ~TagglyTagging usage)
//note: for backward-compatibility, you can also use the macro {{{<<tagCloud ...>>}}} in place of {{{<<cloud ...>>}}}//
<<<
!Examples
<<<
//all tags excluding<<tag systemConfig>>, <<tag excludeMissing>> and <<tag script>>//
{{{<<cloud systemConfig excludeMissing script>>}}}
{{groupbox{<<cloud systemConfig excludeMissing script>>}}}
//top 10 tags excluding<<tag systemConfig>>, <<tag excludeMissing>> and <<tag script>>//
{{{<<cloud limit:10 systemConfig excludeMissing script>>}}}
{{groupbox{<<cloud limit:10 systemConfig excludeMissing script>>}}}
//tags listed in// [[FavoriteTags]]
{{{<<cloud +FavoriteTags>>}}}
{{groupbox{<<cloud +FavoriteTags>>}}}
//tags NOT listed in// [[FavoriteTags]]
{{{<<cloud -FavoriteTags>>}}}
{{groupbox{<<cloud -FavoriteTags>>}}}
//links to tiddlers tagged with 'package'//
{{{<<cloud action:goto =package>>}}}
{{groupbox{<<cloud action:goto =package>>}}}
//top 20 most referenced tiddlers//
{{{<<cloud references limit:20>>}}}
{{groupbox{<<cloud references limit:20>>}}}
//top 20 tiddlers that contain the most links//
{{{<<cloud links limit:20>>}}}
{{groupbox{<<cloud links limit:20>>}}}
<<<
!Revisions
<<<
2009.07.17 [1.7.0] added {{{-TiddlerName}}} parameter to exclude tags that are listed in the indicated tiddler
2009.02.26 [1.6.0] added {{{action:...}}} parameter to apply popup vs. goto action when clicking cloud items
2009.02.05 [1.5.0] added ability to show links or back-links (references) instead of tags and renamed macro to {{{<<cloud>>}}} to reflect more generalized usage.
2008.12.16 [1.4.2] corrected group calculation to prevent 'group=0' error
2008.12.16 [1.4.1] revised tag filtering so excluded tags don't affect calculations
2008.12.15 [1.4.0] added {{{limit:...}}} parameter to restrict the number of tags displayed to the top N most popular
2008.11.15 [1.3.0] added {{{+TiddlerName}}} parameter to include only tags that are listed in the indicated tiddler
2008.09.05 [1.2.0] added '=tagname' parameter to include only tags that are themselves tagged with the specified value (i.e., ~TagglyTagging usage)
2008.07.03 [1.1.0] added 'segments' property to macro object.  Extensive code cleanup
<<<
!Code
***/
//{{{
version.extensions.TagCloudPlugin= {major: 1, minor: 7 , revision: 0, date: new Date(2009,7,17)};
//Originally created by Clint Checketts, contributions by Jonny Leroy and Eric Shulman
//Currently maintained and enhanced by Eric Shulman
//}}}
//{{{
config.macros.cloud = {
	tagstip: "%1 tiddlers tagged with '%0'",
	refslabel: " (%0 references)",
	refstip: "%1 tiddlers have links to '%0'",
	linkslabel: " (%0 links)",
	linkstip: "'%0' has links to %1 other tiddlers",
	groups: 9,
	init: function() {
		config.macros.tagCloud=config.macros.cloud; // for backward-compatibility
		config.shadowTiddlers.TagCloud='<<cloud>>';
		config.shadowTiddlers.StyleSheetTagCloud=
			'/*{{{*/\n'
			+'.tagCloud span {line-height: 3.5em; margin:3px;}\n'
			+'.tagCloud1{font-size: 80%;}\n'
			+'.tagCloud2{font-size: 100%;}\n'
			+'.tagCloud3{font-size: 120%;}\n'
			+'.tagCloud4{font-size: 140%;}\n'
			+'.tagCloud5{font-size: 160%;}\n'
			+'.tagCloud6{font-size: 180%;}\n'
			+'.tagCloud7{font-size: 200%;}\n'
			+'.tagCloud8{font-size: 220%;}\n'
			+'.tagCloud9{font-size: 240%;}\n'
			+'/*}}}*/\n';
		setStylesheet(store.getTiddlerText('StyleSheetTagCloud'),'tagCloudsStyles');
	},
	getLinks: function(tiddler) { // get list of links to existing tiddlers and shadows
		if (!tiddler.linksUpdated) tiddler.changed();
		var list=[]; for (var i=0; i<tiddler.links.length; i++) {
			var title=tiddler.links[i];
			if (store.isShadowTiddler(title)||store.tiddlerExists(title))
				list.push(title);
		}
		return list;
	},
	handler: function(place,macroName,params) {
		// unpack params
		var inc=[]; var ex=[]; var limit=0; var action='popup';
		var links=(params[0]&&params[0].toLowerCase()=='links'); if (links) params.shift();
		var refs=(params[0]&&params[0].toLowerCase()=='references'); if (refs) params.shift();
		if (params[0]&&params[0].substr(0,7).toLowerCase()=='action:')
			action=params.shift().substr(7).toLowerCase();
		if (params[0]&&params[0].substr(0,6).toLowerCase()=='limit:')
			limit=parseInt(params.shift().substr(6));
		while (params.length) {
			if (params[0].substr(0,1)=='+') { // read taglist from tiddler
				inc=inc.concat(store.getTiddlerText(params[0].substr(1),'').readBracketedList());
			} else if (params[0].substr(0,1)=='-') { // exclude taglist from tiddler
				ex=ex.concat(store.getTiddlerText(params[0].substr(1),'').readBracketedList());
			} else if (params[0].substr(0,1)=='=') { // get tag list using tagged tags
				var tagged=store.getTaggedTiddlers(params[0].substr(1));
				for (var t=0; t<tagged.length; t++) inc.push(tagged[t].title);
			} else ex.push(params[0]); // exclude params
			params.shift();
		}
		// get all items, include/exclude specific items
		var items=[];
		var list=(links||refs)?store.getTiddlers('title','excludeLists'):store.getTags();
		for (var t=0; t<list.length; t++) {
			var title=(links||refs)?list[t].title:list[t][0];
			if (links)	var count=this.getLinks(list[t]).length;
			else if (refs)	var count=store.getReferringTiddlers(title).length;
			else 		var count=list[t][1];
			if ((!inc.length||inc.contains(title))&&(!ex.length||!ex.contains(title)))
				items.push({ title:title, count:count });
		}
		if(!items.length) return;
		// sort by decending count, limit results (optional)
		items=items.sort(function(a,b){return(a.count==b.count)?0:(a.count>b.count?-1:1);});
		while (limit && items.length>limit) items.pop();
		// find min/max and group size
		var most=items[0].count;
		var least=items[items.length-1].count;
		var groupSize=(most-least+1)/this.groups;
		// sort by title and draw the cloud of items
		items=items.sort(function(a,b){return(a.title==b.title)?0:(a.title>b.title?1:-1);});
		var cloudWrapper = createTiddlyElement(place,'div',null,'tagCloud',null);
		for (var t=0; t<items.length; t++) {
			cloudWrapper.appendChild(document.createTextNode(' '));
			var group=Math.ceil((items[t].count-least)/groupSize)||1;
			var className='tagCloudtag tagCloud'+group;
			var tip=refs?this.refstip:links?this.linkstip:this.tagstip;
			tip=tip.format([items[t].title,items[t].count]);
			if (action=='goto') { // TAG/LINK/REFERENCES GOTO
				var btn=createTiddlyLink(cloudWrapper,items[t].title,true,className);
				btn.title=tip;
				btn.style.fontWeight='normal';
			} else if (!links&&!refs) { // TAG POPUP
				var btn=createTiddlyButton(cloudWrapper,items[t].title,tip,onClickTag,className);
				btn.setAttribute('tag',items[t].title);
			} else { // LINK/REFERENCES POPUP
				var btn=createTiddlyButton(cloudWrapper,items[t].title,tip,
					function(ev) { var e=ev||window.event; var cmt=config.macros.cloud;
						var popup = Popup.create(this);
						var title = this.getAttribute('tiddler');
						var count = this.getAttribute('count');
						var refs  = this.getAttribute('refs')=='T';
						var links = this.getAttribute('links')=='T';
						var label = (refs?cmt.refslabel:cmt.linkslabel).format([count]);
						createTiddlyLink(popup,title,true);
						createTiddlyText(popup,label);
						createTiddlyElement(popup,'hr');
						if (refs) {
							popup.setAttribute('tiddler',title);
							config.commands.references.handlePopup(popup,title);
						}
						if (links) {
							var tiddler = store.fetchTiddler(title);
							var links=config.macros.cloud.getLinks(tiddler);
							for(var i=0;i<links.length;i++)
								createTiddlyLink(createTiddlyElement(popup,'li'),
									links[i],true);
						}
						Popup.show();
						e.cancelBubble=true; if(e.stopPropagation) e.stopPropagation();
						return false;
					}, className);
				btn.setAttribute('tiddler',items[t].title);
				btn.setAttribute('count',items[t].count);
				btn.setAttribute('refs',refs?'T':'F');
				btn.setAttribute('links',links?'T':'F');
				btn.title=tip;
			}
		}
	}
};
//}}}
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div>Written: <span macro="edit written"></span></div>
<div macro='annotations'></div>
<div class='editor' macro='edit text'></div>
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser excludeLists'></span></div>
<!--}}}-->
Parallel manipulators are robotic devices that differ from the more traditional serial robotic manipulators by virtue of their kinematics structure. Parallel manipulators are composed of multiple closed kinematics loops.

The delta-3 robot is a three degree of freedom parallel manipulator. It was designed by Clavel (1988) et al. at the [[Swiss Federal Institute of Technology|http://www.ethz.ch]]. This manipulator robot has only translational degrees of freedom.

It is interesting to have a [[model of the robot|Build a cardboard prototype of a delta-3 robot]] for doing this study .

!Analysis of the Robot

The DELTA-3 Robot (DR-3) is composed by two parallel platforms named as End-Effector and Fixed-Framed; and three symmetric legs (see figure below). 

The Fixed-Frame (FF) is usually attached to a fixed surface and the tool of the robot is mounted in the TCP-0 which is placed on the center of the End-Effector. The End-Effector (EE) could also be named as travel plate because it is the mobile base of the robot.

{{center{[img[https://lh3.googleusercontent.com/-kSNb-hYhdwA/T7jVDvR0j4I/AAAAAAAAAsI/mzAQj_WVHqU/s288/img46.png]]}}}{{center{  {{small{Scheme of the DELTA-3 Robot}}} }}} 

Each leg is composed by two links and three joints (RUU); the actuated joint is rotational (R) and the two passive joints are universal (U). And their position in the robot is named as Fi, Gi and Ei (see previous figure), respectively; where the index i is the number of the leg (1, 2 or 3).

{{center{[img[https://lh6.googleusercontent.com/-B8pItrmG2xE/T7jVC4U6xtI/AAAAAAAAAsI/FdbDzPXdFrA/s144/img0.png]][img[https://lh3.googleusercontent.com/-upeqFSDjit0/T7jVDKkCpqI/AAAAAAAAAsI/zrCMOTEVAFM/s144/img1.png]]}}}{{center{  {{small{Spheres defined by the passive joints (placed in G and E) and Link 2}}} }}} 
{{center{[img[https://lh5.googleusercontent.com/-hMwQ5pKUh2w/T7jVFYkPJgI/AAAAAAAAAsI/p7qBAPRXoPo/s144/img2.png]]}}}{{center{  {{small{Circle defined by the actuated joint placed in F and Link1}}} }}} 

F1, F2 and F3 are the positions in the Fixed-Frame of the actuated joints, J1, J2 and J3 respectively. 

!Kinematics

The configuration parameters of a robot are the parameters which define a specific model of a robot type. For a DELTA-3 robot the geometry of its mechanical structure is directly used as configuration parameters:
* Side length of end-effector (EE)
* Length of link 2, from knee(E) to ankle(C)
* Length of link 1, from hip(D) to knee(E)
* Side length of fixed-frame (FF)

The [[algorithms|https://code.google.com/p/robotics-utils]] for solving the Kinematics Problem of the delta-3 robot was developed using [[Scilab|http://www.scilab.org]].

/***
|''Name''|TiddlyFileImporter|
|''Version''|0.3.8|
|''Author''|Ben Gillies|
|''Type''|plugin|
|''Description''|Upload a TiddlyWiki file to TiddlyWeb, and import the tiddlers.|
!Usage
Upload a TiddlyWiki file to TiddlyWeb, and import the tiddlers.
!Requires
tiddlyweb
tiddlywebplugins.reflector
!Code
***/
//{{{
(function($){
if(!version.extensions.TiddlyFileImporter)
{ //# ensure that the plugin is only installed once
	version.extensions.TiddlyFileImporter = { installed: true };
}

config.macros.fileImport = {
	reflectorURI: '/reflector?csrf_token=%0',
	incorrectTypeError: 'Incorrect File Type. You must upload a TiddlyWiki',
	uploadLabel: 'Upload',
	uploadLabelPrompt: 'Import tiddlers from this TiddlyWiki',
	step1FileText: 'File:',
	step1PostText: 'In the next screen you will select the tiddlers to import.',
	step1Title: 'Step 1: Pick a TiddlyWiki to import',
	step1TypeChooser: 'Import From:',
	step3Html: ['<input type="hidden" name="markList" />',
		'<input type="hidden" checked="true" name="chkSync" />',
		'<input type="hidden" name="chkSave" />',
		'<input type="hidden" name="txtSaveTiddler" />'].join(),

	handler: function(place, macroName, params, wikifier, paramString) {
		var wizard = new Wizard();
		wizard.createWizard(place, 'Import a TiddlyWiki');
		this.restart(wizard);
	},

	restart: function(wizard) {
		var me = config.macros.fileImport;
		wizard.addStep(me.step1Title, ['<input type="hidden" ',
			'name="markList" />'].join(""));
		var markList = wizard.getElement('markList');
		var uploadWrapper = document.createElement('div');
		markList.parentNode.insertBefore(uploadWrapper, markList);
		uploadWrapper.setAttribute('refresh', 'macro');
		uploadWrapper.getAttribute('macroName', 'fileImport');
		var iframeName = 'reflectorImporter' + Math.random().toString();
		me.createForm(uploadWrapper, wizard, iframeName);
		$(uploadWrapper).append('<p>' + me.step1PostText + '</p>');
		wizard.setValue('serverType', 'tiddlyweb');
		wizard.setValue('adaptor', new config.adaptors.file());
		wizard.setValue('host', config.defaultCustomFields['server.host']);
		wizard.setValue('context', {});
		var iframe = $(['<iframe name="' + iframeName + '" ',
			'style="display: none" />'].join("")).appendTo(uploadWrapper);
		var onSubmit = function(ev) {
			var uploadType = $('select[name=uploadtype]', wizard.formElem).val();
			if (uploadType == "file") {
				// set an onload ready to hijack the form
				me.setOnLoad(uploadWrapper, wizard, iframe[0]);
				wizard.importType = 'file';
				wizard.formElem.submit();
			} else {
				var csrf_token = config.extensions.tiddlyspace.getCSRFToken();
				$.ajax({
					url: "%0/reflector?csrf_token=%1".format(
						config.defaultCustomFields["server.host"], csrf_token),
					type: "POST",
					dataType: "text",
					data: {
						uri: $("input", ".importFrom", wizard.formElem).val()
					},
					success: function(data, txtStatus, xhr) {
						wizard.POSTResponse = data;
						me.importTiddlers(uploadWrapper, wizard);
					},
					error: function(xhr, txtStatus, error) {
						displayMessage(["There was an error fetching the ",
							'url: ', txtStatus].join(""));
						me.restart(wizard);
					}
				});
				return false;
			}
		};
		wizard.setButtons([{
			caption: me.uploadLabel,
			tooltip: me.uploadLabelPrompt,
			onClick: onSubmit
		}]);
		$(wizard.formElem).submit(function(ev) {
			onSubmit(ev);
			ev.preventDefault();
		});
	},

	createForm: function(place, wizard, iframeName) {
		var form = wizard.formElem;
		var me = config.macros.fileImport;
		form.action = me.reflectorURI.format(
			config.extensions.tiddlyspace.getCSRFToken());
		form.enctype = 'multipart/form-data';
		form.encoding = 'multipart/form-data';
		form.method = 'POST';
		form.target = iframeName;
		onSelectChange = function(e) {
			var changeTo = $(this).val();
			if (changeTo == "file") {
				$(".importFrom").html('%0 <input type="file" name="file" />'.
					format(me.step1FileText));
			} else {
				$(".importFrom").html('URL: <input type="text" name="uri" />'
					+ ' Do you want <a target="_blank" href="http://faq.tiddlyspace.com/How%20do%20I%20include%2Fexclude%20spaces%3F">inclusion</a> instead?');
			}
		};
		$(place).append('<span>%0</span>'.format(me.step1TypeChooser)).
			append($(['<select name="uploadtype"><option value="file" selected="selected">file',
				'<option value="uri">url</select>'].join("")).change(onSelectChange)).
			append('<div class="importFrom">%0<input type="file" name="file" /></div>'.
					format(me.step1FileText));
	},

	setOnLoad: function(place, wizard, iframe) {
		var me = config.macros.fileImport;
		var loadHandler = function() {
			me.importTiddlers.apply(this, [place, wizard, iframe]);
		};
		iframe.onload = loadHandler;
		completeReadyStateChanges = 0;
		iframe.onreadystatechange = function() {
			if (++(completeReadyStateChanges) == 5) {
				loadHandler();
			}
		};
	},

	importTiddlers: function(place, wizard, iframe) {
		var tmpStore = new TiddlyWiki();
		var POSTedWiki = "";
		if (wizard.importType == "file") {
			try {
				POSTedWiki= iframe.contentWindow
					.document.documentElement.innerHTML;
			} catch(e) {
				displayMessage(config.macros.fileImport.incorrectTypeError);
				config.macros.fileImport.restart(wizard);
				return;
			}
			// now we are done, so remove the iframe
			$(iframe).remove();
		} else {
			POSTedWiki = wizard.POSTResponse;
		}

		tmpStore.importTiddlyWiki(POSTedWiki);
		var newTiddlers = tmpStore.getTiddlers();
		var workspace = config.defaultCustomFields['server.workspace'];
		var context = {
			status: true,
			statusText: 'OK',
			httpStatus: 200,
			adaptor: wizard.getValue('adaptor'),
			tiddlers: newTiddlers
		};
		context.adaptor.store = tmpStore;
		wizard.setValue('context', context);
		wizard.setValue('workspace', workspace);
		wizard.setValue('inFileImport', true);
		config.macros.importTiddlers.onGetTiddlerList(context, wizard);
	}
};

var _onGetTiddler = config.macros.importTiddlers.onGetTiddler;
config.macros.importTiddlers.onGetTiddler = function(context, wizard) {
	if (wizard.getValue('inFileImport')) {
		var me = config.macros.importTiddlers;
		if(!context.status)
			displayMessage("Error in importTiddlers.onGetTiddler: " + context.statusText);
		var tiddler = context.tiddler;
		var fields = tiddler.fields;
		merge(fields, config.defaultCustomFields);
		fields["server.workspace"] = wizard.getValue('workspace');
		delete fields['server.permissions'];
		delete fields['server.bag'];
		fields['server.page.revision'] = 'false';
		delete fields['server.recipe'];
		fields.changecount = 1;
		store.suspendNotifications();
		store.saveTiddler(tiddler.title, tiddler.title, tiddler.text,
			tiddler.modifier, tiddler.modified, tiddler.tags, tiddler.fields,
			false, tiddler.created);
		store.resumeNotifications();
		var remainingImports = wizard.getValue("remainingImports")-1;
		wizard.setValue("remainingImports",remainingImports);
		if(remainingImports === 0) {
			if(context.isSynchronous) {
				store.notifyAll();
				refreshDisplay();
			}
			wizard.setButtons([
					{caption: me.doneLabel, tooltip: me.donePrompt, onClick: me.onClose}
				],me.statusDoneImport);
			autoSaveChanges();
		}
	} else {
		_onGetTiddler.apply(this, arguments);
	}
};

var _onCancel = config.macros.importTiddlers.onCancel;
config.macros.importTiddlers.onCancel = function(e)
{
	var wizard = new Wizard(this);
	if (!wizard.getValue('inFileImport')) {
		return _onCancel.apply(this, arguments);
	}
	var place = wizard.clear();
	config.macros.fileImport.restart(wizard);
	return false;
};

var _step3Html = config.macros.importTiddlers.step3Html;
var _onGetTiddlerList = config.macros.importTiddlers.onGetTiddlerList;
config.macros.importTiddlers.onGetTiddlerList = function(context, wizard) {
	var fileImport = config.macros.fileImport;
	var importTiddlers = config.macros.importTiddlers;
	if (wizard.getValue('inFileImport')) {
		importTiddlers.step3Html = fileImport.step3Html;
	} else {
		importTiddlers.step3Html = _step3Html;
	}
	_onGetTiddlerList.apply(this, arguments);
};
})(jQuery);
//}}}
To upload a private binary tiddler use the following form:
If you do not enter a title, the filename will be used for the title of the tiddler.
<<binaryUpload edit:title>>
/***
|Name|ShCore.js|
***/
/**
 * SyntaxHighlighter
 * http://alexgorbatchev.com/SyntaxHighlighter
 *
 * SyntaxHighlighter is donationware. If you are using it, please donate.
 * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
 *
 * @version
 * 3.0.83 (July 02 2010)
 * 
 * @copyright
 * Copyright (C) 2004-2010 Alex Gorbatchev.
 *
 * @license
 * Dual licensed under the MIT and GPL licenses.
 */
//{{{
eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('K M;I(M)1S 2U("2a\'t 4k M 4K 2g 3l 4G 4H");(6(){6 r(f,e){I(!M.1R(f))1S 3m("3s 15 4R");K a=f.1w;f=M(f.1m,t(f)+(e||""));I(a)f.1w={1m:a.1m,19:a.19?a.19.1a(0):N};H f}6 t(f){H(f.1J?"g":"")+(f.4s?"i":"")+(f.4p?"m":"")+(f.4v?"x":"")+(f.3n?"y":"")}6 B(f,e,a,b){K c=u.L,d,h,g;v=R;5K{O(;c--;){g=u[c];I(a&g.3r&&(!g.2p||g.2p.W(b))){g.2q.12=e;I((h=g.2q.X(f))&&h.P===e){d={3k:g.2b.W(b,h,a),1C:h};1N}}}}5v(i){1S i}5q{v=11}H d}6 p(f,e,a){I(3b.Z.1i)H f.1i(e,a);O(a=a||0;a<f.L;a++)I(f[a]===e)H a;H-1}M=6(f,e){K a=[],b=M.1B,c=0,d,h;I(M.1R(f)){I(e!==1d)1S 3m("2a\'t 5r 5I 5F 5B 5C 15 5E 5p");H r(f)}I(v)1S 2U("2a\'t W 3l M 59 5m 5g 5x 5i");e=e||"";O(d={2N:11,19:[],2K:6(g){H e.1i(g)>-1},3d:6(g){e+=g}};c<f.L;)I(h=B(f,c,b,d)){a.U(h.3k);c+=h.1C[0].L||1}Y I(h=n.X.W(z[b],f.1a(c))){a.U(h[0]);c+=h[0].L}Y{h=f.3a(c);I(h==="[")b=M.2I;Y I(h==="]")b=M.1B;a.U(h);c++}a=15(a.1K(""),n.Q.W(e,w,""));a.1w={1m:f,19:d.2N?d.19:N};H a};M.3v="1.5.0";M.2I=1;M.1B=2;K C=/\\$(?:(\\d\\d?|[$&`\'])|{([$\\w]+)})/g,w=/[^5h]+|([\\s\\S])(?=[\\s\\S]*\\1)/g,A=/^(?:[?*+]|{\\d+(?:,\\d*)?})\\??/,v=11,u=[],n={X:15.Z.X,1A:15.Z.1A,1C:1r.Z.1C,Q:1r.Z.Q,1e:1r.Z.1e},x=n.X.W(/()??/,"")[1]===1d,D=6(){K f=/^/g;n.1A.W(f,"");H!f.12}(),y=6(){K f=/x/g;n.Q.W("x",f,"");H!f.12}(),E=15.Z.3n!==1d,z={};z[M.2I]=/^(?:\\\\(?:[0-3][0-7]{0,2}|[4-7][0-7]?|x[\\29-26-f]{2}|u[\\29-26-f]{4}|c[A-3o-z]|[\\s\\S]))/;z[M.1B]=/^(?:\\\\(?:0(?:[0-3][0-7]{0,2}|[4-7][0-7]?)?|[1-9]\\d*|x[\\29-26-f]{2}|u[\\29-26-f]{4}|c[A-3o-z]|[\\s\\S])|\\(\\?[:=!]|[?*+]\\?|{\\d+(?:,\\d*)?}\\??)/;M.1h=6(f,e,a,b){u.U({2q:r(f,"g"+(E?"y":"")),2b:e,3r:a||M.1B,2p:b||N})};M.2n=6(f,e){K a=f+"/"+(e||"");H M.2n[a]||(M.2n[a]=M(f,e))};M.3c=6(f){H r(f,"g")};M.5l=6(f){H f.Q(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g,"\\\\$&")};M.5e=6(f,e,a,b){e=r(e,"g"+(b&&E?"y":""));e.12=a=a||0;f=e.X(f);H b?f&&f.P===a?f:N:f};M.3q=6(){M.1h=6(){1S 2U("2a\'t 55 1h 54 3q")}};M.1R=6(f){H 53.Z.1q.W(f)==="[2m 15]"};M.3p=6(f,e,a,b){O(K c=r(e,"g"),d=-1,h;h=c.X(f);){a.W(b,h,++d,f,c);c.12===h.P&&c.12++}I(e.1J)e.12=0};M.57=6(f,e){H 6 a(b,c){K d=e[c].1I?e[c]:{1I:e[c]},h=r(d.1I,"g"),g=[],i;O(i=0;i<b.L;i++)M.3p(b[i],h,6(k){g.U(d.3j?k[d.3j]||"":k[0])});H c===e.L-1||!g.L?g:a(g,c+1)}([f],0)};15.Z.1p=6(f,e){H J.X(e[0])};15.Z.W=6(f,e){H J.X(e)};15.Z.X=6(f){K e=n.X.1p(J,14),a;I(e){I(!x&&e.L>1&&p(e,"")>-1){a=15(J.1m,n.Q.W(t(J),"g",""));n.Q.W(f.1a(e.P),a,6(){O(K c=1;c<14.L-2;c++)I(14[c]===1d)e[c]=1d})}I(J.1w&&J.1w.19)O(K b=1;b<e.L;b++)I(a=J.1w.19[b-1])e[a]=e[b];!D&&J.1J&&!e[0].L&&J.12>e.P&&J.12--}H e};I(!D)15.Z.1A=6(f){(f=n.X.W(J,f))&&J.1J&&!f[0].L&&J.12>f.P&&J.12--;H!!f};1r.Z.1C=6(f){M.1R(f)||(f=15(f));I(f.1J){K e=n.1C.1p(J,14);f.12=0;H e}H f.X(J)};1r.Z.Q=6(f,e){K a=M.1R(f),b,c;I(a&&1j e.58()==="3f"&&e.1i("${")===-1&&y)H n.Q.1p(J,14);I(a){I(f.1w)b=f.1w.19}Y f+="";I(1j e==="6")c=n.Q.W(J,f,6(){I(b){14[0]=1f 1r(14[0]);O(K d=0;d<b.L;d++)I(b[d])14[0][b[d]]=14[d+1]}I(a&&f.1J)f.12=14[14.L-2]+14[0].L;H e.1p(N,14)});Y{c=J+"";c=n.Q.W(c,f,6(){K d=14;H n.Q.W(e,C,6(h,g,i){I(g)5b(g){24"$":H"$";24"&":H d[0];24"`":H d[d.L-1].1a(0,d[d.L-2]);24"\'":H d[d.L-1].1a(d[d.L-2]+d[0].L);5a:i="";g=+g;I(!g)H h;O(;g>d.L-3;){i=1r.Z.1a.W(g,-1)+i;g=1Q.3i(g/10)}H(g?d[g]||"":"$")+i}Y{g=+i;I(g<=d.L-3)H d[g];g=b?p(b,i):-1;H g>-1?d[g+1]:h}})})}I(a&&f.1J)f.12=0;H c};1r.Z.1e=6(f,e){I(!M.1R(f))H n.1e.1p(J,14);K a=J+"",b=[],c=0,d,h;I(e===1d||+e<0)e=5D;Y{e=1Q.3i(+e);I(!e)H[]}O(f=M.3c(f);d=f.X(a);){I(f.12>c){b.U(a.1a(c,d.P));d.L>1&&d.P<a.L&&3b.Z.U.1p(b,d.1a(1));h=d[0].L;c=f.12;I(b.L>=e)1N}f.12===d.P&&f.12++}I(c===a.L){I(!n.1A.W(f,"")||h)b.U("")}Y b.U(a.1a(c));H b.L>e?b.1a(0,e):b};M.1h(/\\(\\?#[^)]*\\)/,6(f){H n.1A.W(A,f.2S.1a(f.P+f[0].L))?"":"(?:)"});M.1h(/\\((?!\\?)/,6(){J.19.U(N);H"("});M.1h(/\\(\\?<([$\\w]+)>/,6(f){J.19.U(f[1]);J.2N=R;H"("});M.1h(/\\\\k<([\\w$]+)>/,6(f){K e=p(J.19,f[1]);H e>-1?"\\\\"+(e+1)+(3R(f.2S.3a(f.P+f[0].L))?"":"(?:)"):f[0]});M.1h(/\\[\\^?]/,6(f){H f[0]==="[]"?"\\\\b\\\\B":"[\\\\s\\\\S]"});M.1h(/^\\(\\?([5A]+)\\)/,6(f){J.3d(f[1]);H""});M.1h(/(?:\\s+|#.*)+/,6(f){H n.1A.W(A,f.2S.1a(f.P+f[0].L))?"":"(?:)"},M.1B,6(){H J.2K("x")});M.1h(/\\./,6(){H"[\\\\s\\\\S]"},M.1B,6(){H J.2K("s")})})();1j 2e!="1d"&&(2e.M=M);K 1v=6(){6 r(a,b){a.1l.1i(b)!=-1||(a.1l+=" "+b)}6 t(a){H a.1i("3e")==0?a:"3e"+a}6 B(a){H e.1Y.2A[t(a)]}6 p(a,b,c){I(a==N)H N;K d=c!=R?a.3G:[a.2G],h={"#":"1c",".":"1l"}[b.1o(0,1)]||"3h",g,i;g=h!="3h"?b.1o(1):b.5u();I((a[h]||"").1i(g)!=-1)H a;O(a=0;d&&a<d.L&&i==N;a++)i=p(d[a],b,c);H i}6 C(a,b){K c={},d;O(d 2g a)c[d]=a[d];O(d 2g b)c[d]=b[d];H c}6 w(a,b,c,d){6 h(g){g=g||1P.5y;I(!g.1F){g.1F=g.52;g.3N=6(){J.5w=11}}c.W(d||1P,g)}a.3g?a.3g("4U"+b,h):a.4y(b,h,11)}6 A(a,b){K c=e.1Y.2j,d=N;I(c==N){c={};O(K h 2g e.1U){K g=e.1U[h];d=g.4x;I(d!=N){g.1V=h.4w();O(g=0;g<d.L;g++)c[d[g]]=h}}e.1Y.2j=c}d=e.1U[c[a]];d==N&&b!=11&&1P.1X(e.13.1x.1X+(e.13.1x.3E+a));H d}6 v(a,b){O(K c=a.1e("\\n"),d=0;d<c.L;d++)c[d]=b(c[d],d);H c.1K("\\n")}6 u(a,b){I(a==N||a.L==0||a=="\\n")H a;a=a.Q(/</g,"&1y;");a=a.Q(/ {2,}/g,6(c){O(K d="",h=0;h<c.L-1;h++)d+=e.13.1W;H d+" "});I(b!=N)a=v(a,6(c){I(c.L==0)H"";K d="";c=c.Q(/^(&2s;| )+/,6(h){d=h;H""});I(c.L==0)H d;H d+\'<17 1g="\'+b+\'">\'+c+"</17>"});H a}6 n(a,b){a.1e("\\n");O(K c="",d=0;d<50;d++)c+="                    ";H a=v(a,6(h){I(h.1i("\\t")==-1)H h;O(K g=0;(g=h.1i("\\t"))!=-1;)h=h.1o(0,g)+c.1o(0,b-g%b)+h.1o(g+1,h.L);H h})}6 x(a){H a.Q(/^\\s+|\\s+$/g,"")}6 D(a,b){I(a.P<b.P)H-1;Y I(a.P>b.P)H 1;Y I(a.L<b.L)H-1;Y I(a.L>b.L)H 1;H 0}6 y(a,b){6 c(k){H k[0]}O(K d=N,h=[],g=b.2D?b.2D:c;(d=b.1I.X(a))!=N;){K i=g(d,b);I(1j i=="3f")i=[1f e.2L(i,d.P,b.23)];h=h.1O(i)}H h}6 E(a){K b=/(.*)((&1G;|&1y;).*)/;H a.Q(e.3A.3M,6(c){K d="",h=N;I(h=b.X(c)){c=h[1];d=h[2]}H\'<a 2h="\'+c+\'">\'+c+"</a>"+d})}6 z(){O(K a=1E.36("1k"),b=[],c=0;c<a.L;c++)a[c].3s=="20"&&b.U(a[c]);H b}6 f(a){a=a.1F;K b=p(a,".20",R);a=p(a,".3O",R);K c=1E.4i("3t");I(!(!a||!b||p(a,"3t"))){B(b.1c);r(b,"1m");O(K d=a.3G,h=[],g=0;g<d.L;g++)h.U(d[g].4z||d[g].4A);h=h.1K("\\r");c.39(1E.4D(h));a.39(c);c.2C();c.4C();w(c,"4u",6(){c.2G.4E(c);b.1l=b.1l.Q("1m","")})}}I(1j 3F!="1d"&&1j M=="1d")M=3F("M").M;K e={2v:{"1g-27":"","2i-1s":1,"2z-1s-2t":11,1M:N,1t:N,"42-45":R,"43-22":4,1u:R,16:R,"3V-17":R,2l:11,"41-40":R,2k:11,"1z-1k":11},13:{1W:"&2s;",2M:R,46:11,44:11,34:"4n",1x:{21:"4o 1m",2P:"?",1X:"1v\\n\\n",3E:"4r\'t 4t 1D O: ",4g:"4m 4B\'t 51 O 1z-1k 4F: ",37:\'<!4T 1z 4S "-//4V//3H 4W 1.0 4Z//4Y" "1Z://2y.3L.3K/4X/3I/3H/3I-4P.4J"><1z 4I="1Z://2y.3L.3K/4L/5L"><3J><4N 1Z-4M="5G-5M" 6K="2O/1z; 6J=6I-8" /><1t>6L 1v</1t></3J><3B 1L="25-6M:6Q,6P,6O,6N-6F;6y-2f:#6x;2f:#6w;25-22:6v;2O-3D:3C;"><T 1L="2O-3D:3C;3w-32:1.6z;"><T 1L="25-22:6A-6E;">1v</T><T 1L="25-22:.6C;3w-6B:6R;"><T>3v 3.0.76 (72 73 3x)</T><T><a 2h="1Z://3u.2w/1v" 1F="38" 1L="2f:#3y">1Z://3u.2w/1v</a></T><T>70 17 6U 71.</T><T>6T 6X-3x 6Y 6D.</T></T><T>6t 61 60 J 1k, 5Z <a 2h="6u://2y.62.2w/63-66/65?64=5X-5W&5P=5O" 1L="2f:#3y">5R</a> 5V <2R/>5U 5T 5S!</T></T></3B></1z>\'}},1Y:{2j:N,2A:{}},1U:{},3A:{6n:/\\/\\*[\\s\\S]*?\\*\\//2c,6m:/\\/\\/.*$/2c,6l:/#.*$/2c,6k:/"([^\\\\"\\n]|\\\\.)*"/g,6o:/\'([^\\\\\'\\n]|\\\\.)*\'/g,6p:1f M(\'"([^\\\\\\\\"]|\\\\\\\\.)*"\',"3z"),6s:1f M("\'([^\\\\\\\\\']|\\\\\\\\.)*\'","3z"),6q:/(&1y;|<)!--[\\s\\S]*?--(&1G;|>)/2c,3M:/\\w+:\\/\\/[\\w-.\\/?%&=:@;]*/g,6a:{18:/(&1y;|<)\\?=?/g,1b:/\\?(&1G;|>)/g},69:{18:/(&1y;|<)%=?/g,1b:/%(&1G;|>)/g},6d:{18:/(&1y;|<)\\s*1k.*?(&1G;|>)/2T,1b:/(&1y;|<)\\/\\s*1k\\s*(&1G;|>)/2T}},16:{1H:6(a){6 b(i,k){H e.16.2o(i,k,e.13.1x[k])}O(K c=\'<T 1g="16">\',d=e.16.2x,h=d.2X,g=0;g<h.L;g++)c+=(d[h[g]].1H||b)(a,h[g]);c+="</T>";H c},2o:6(a,b,c){H\'<2W><a 2h="#" 1g="6e 6h\'+b+" "+b+\'">\'+c+"</a></2W>"},2b:6(a){K b=a.1F,c=b.1l||"";b=B(p(b,".20",R).1c);K d=6(h){H(h=15(h+"6f(\\\\w+)").X(c))?h[1]:N}("6g");b&&d&&e.16.2x[d].2B(b);a.3N()},2x:{2X:["21","2P"],21:{1H:6(a){I(a.V("2l")!=R)H"";K b=a.V("1t");H e.16.2o(a,"21",b?b:e.13.1x.21)},2B:6(a){a=1E.6j(t(a.1c));a.1l=a.1l.Q("47","")}},2P:{2B:6(){K a="68=0";a+=", 18="+(31.30-33)/2+", 32="+(31.2Z-2Y)/2+", 30=33, 2Z=2Y";a=a.Q(/^,/,"");a=1P.6Z("","38",a);a.2C();K b=a.1E;b.6W(e.13.1x.37);b.6V();a.2C()}}}},35:6(a,b){K c;I(b)c=[b];Y{c=1E.36(e.13.34);O(K d=[],h=0;h<c.L;h++)d.U(c[h]);c=d}c=c;d=[];I(e.13.2M)c=c.1O(z());I(c.L===0)H d;O(h=0;h<c.L;h++){O(K g=c[h],i=a,k=c[h].1l,j=3W 0,l={},m=1f M("^\\\\[(?<2V>(.*?))\\\\]$"),s=1f M("(?<27>[\\\\w-]+)\\\\s*:\\\\s*(?<1T>[\\\\w-%#]+|\\\\[.*?\\\\]|\\".*?\\"|\'.*?\')\\\\s*;?","g");(j=s.X(k))!=N;){K o=j.1T.Q(/^[\'"]|[\'"]$/g,"");I(o!=N&&m.1A(o)){o=m.X(o);o=o.2V.L>0?o.2V.1e(/\\s*,\\s*/):[]}l[j.27]=o}g={1F:g,1n:C(i,l)};g.1n.1D!=N&&d.U(g)}H d},1M:6(a,b){K c=J.35(a,b),d=N,h=e.13;I(c.L!==0)O(K g=0;g<c.L;g++){b=c[g];K i=b.1F,k=b.1n,j=k.1D,l;I(j!=N){I(k["1z-1k"]=="R"||e.2v["1z-1k"]==R){d=1f e.4l(j);j="4O"}Y I(d=A(j))d=1f d;Y 6H;l=i.3X;I(h.2M){l=l;K m=x(l),s=11;I(m.1i("<![6G[")==0){m=m.4h(9);s=R}K o=m.L;I(m.1i("]]\\>")==o-3){m=m.4h(0,o-3);s=R}l=s?m:l}I((i.1t||"")!="")k.1t=i.1t;k.1D=j;d.2Q(k);b=d.2F(l);I((i.1c||"")!="")b.1c=i.1c;i.2G.74(b,i)}}},2E:6(a){w(1P,"4k",6(){e.1M(a)})}};e.2E=e.2E;e.1M=e.1M;e.2L=6(a,b,c){J.1T=a;J.P=b;J.L=a.L;J.23=c;J.1V=N};e.2L.Z.1q=6(){H J.1T};e.4l=6(a){6 b(j,l){O(K m=0;m<j.L;m++)j[m].P+=l}K c=A(a),d,h=1f e.1U.5Y,g=J,i="2F 1H 2Q".1e(" ");I(c!=N){d=1f c;O(K k=0;k<i.L;k++)(6(){K j=i[k];g[j]=6(){H h[j].1p(h,14)}})();d.28==N?1P.1X(e.13.1x.1X+(e.13.1x.4g+a)):h.2J.U({1I:d.28.17,2D:6(j){O(K l=j.17,m=[],s=d.2J,o=j.P+j.18.L,F=d.28,q,G=0;G<s.L;G++){q=y(l,s[G]);b(q,o);m=m.1O(q)}I(F.18!=N&&j.18!=N){q=y(j.18,F.18);b(q,j.P);m=m.1O(q)}I(F.1b!=N&&j.1b!=N){q=y(j.1b,F.1b);b(q,j.P+j[0].5Q(j.1b));m=m.1O(q)}O(j=0;j<m.L;j++)m[j].1V=c.1V;H m}})}};e.4j=6(){};e.4j.Z={V:6(a,b){K c=J.1n[a];c=c==N?b:c;K d={"R":R,"11":11}[c];H d==N?c:d},3Y:6(a){H 1E.4i(a)},4c:6(a,b){K c=[];I(a!=N)O(K d=0;d<a.L;d++)I(1j a[d]=="2m")c=c.1O(y(b,a[d]));H J.4e(c.6b(D))},4e:6(a){O(K b=0;b<a.L;b++)I(a[b]!==N)O(K c=a[b],d=c.P+c.L,h=b+1;h<a.L&&a[b]!==N;h++){K g=a[h];I(g!==N)I(g.P>d)1N;Y I(g.P==c.P&&g.L>c.L)a[b]=N;Y I(g.P>=c.P&&g.P<d)a[h]=N}H a},4d:6(a){K b=[],c=2u(J.V("2i-1s"));v(a,6(d,h){b.U(h+c)});H b},3U:6(a){K b=J.V("1M",[]);I(1j b!="2m"&&b.U==N)b=[b];a:{a=a.1q();K c=3W 0;O(c=c=1Q.6c(c||0,0);c<b.L;c++)I(b[c]==a){b=c;1N a}b=-1}H b!=-1},2r:6(a,b,c){a=["1s","6i"+b,"P"+a,"6r"+(b%2==0?1:2).1q()];J.3U(b)&&a.U("67");b==0&&a.U("1N");H\'<T 1g="\'+a.1K(" ")+\'">\'+c+"</T>"},3Q:6(a,b){K c="",d=a.1e("\\n").L,h=2u(J.V("2i-1s")),g=J.V("2z-1s-2t");I(g==R)g=(h+d-1).1q().L;Y I(3R(g)==R)g=0;O(K i=0;i<d;i++){K k=b?b[i]:h+i,j;I(k==0)j=e.13.1W;Y{j=g;O(K l=k.1q();l.L<j;)l="0"+l;j=l}a=j;c+=J.2r(i,k,a)}H c},49:6(a,b){a=x(a);K c=a.1e("\\n");J.V("2z-1s-2t");K d=2u(J.V("2i-1s"));a="";O(K h=J.V("1D"),g=0;g<c.L;g++){K i=c[g],k=/^(&2s;|\\s)+/.X(i),j=N,l=b?b[g]:d+g;I(k!=N){j=k[0].1q();i=i.1o(j.L);j=j.Q(" ",e.13.1W)}i=x(i);I(i.L==0)i=e.13.1W;a+=J.2r(g,l,(j!=N?\'<17 1g="\'+h+\' 5N">\'+j+"</17>":"")+i)}H a},4f:6(a){H a?"<4a>"+a+"</4a>":""},4b:6(a,b){6 c(l){H(l=l?l.1V||g:g)?l+" ":""}O(K d=0,h="",g=J.V("1D",""),i=0;i<b.L;i++){K k=b[i],j;I(!(k===N||k.L===0)){j=c(k);h+=u(a.1o(d,k.P-d),j+"48")+u(k.1T,j+k.23);d=k.P+k.L+(k.75||0)}}h+=u(a.1o(d),c()+"48");H h},1H:6(a){K b="",c=["20"],d;I(J.V("2k")==R)J.1n.16=J.1n.1u=11;1l="20";J.V("2l")==R&&c.U("47");I((1u=J.V("1u"))==11)c.U("6S");c.U(J.V("1g-27"));c.U(J.V("1D"));a=a.Q(/^[ ]*[\\n]+|[\\n]*[ ]*$/g,"").Q(/\\r/g," ");b=J.V("43-22");I(J.V("42-45")==R)a=n(a,b);Y{O(K h="",g=0;g<b;g++)h+=" ";a=a.Q(/\\t/g,h)}a=a;a:{b=a=a;h=/<2R\\s*\\/?>|&1y;2R\\s*\\/?&1G;/2T;I(e.13.46==R)b=b.Q(h,"\\n");I(e.13.44==R)b=b.Q(h,"");b=b.1e("\\n");h=/^\\s*/;g=4Q;O(K i=0;i<b.L&&g>0;i++){K k=b[i];I(x(k).L!=0){k=h.X(k);I(k==N){a=a;1N a}g=1Q.4q(k[0].L,g)}}I(g>0)O(i=0;i<b.L;i++)b[i]=b[i].1o(g);a=b.1K("\\n")}I(1u)d=J.4d(a);b=J.4c(J.2J,a);b=J.4b(a,b);b=J.49(b,d);I(J.V("41-40"))b=E(b);1j 2H!="1d"&&2H.3S&&2H.3S.1C(/5s/)&&c.U("5t");H b=\'<T 1c="\'+t(J.1c)+\'" 1g="\'+c.1K(" ")+\'">\'+(J.V("16")?e.16.1H(J):"")+\'<3Z 5z="0" 5H="0" 5J="0">\'+J.4f(J.V("1t"))+"<3T><3P>"+(1u?\'<2d 1g="1u">\'+J.3Q(a)+"</2d>":"")+\'<2d 1g="17"><T 1g="3O">\'+b+"</T></2d></3P></3T></3Z></T>"},2F:6(a){I(a===N)a="";J.17=a;K b=J.3Y("T");b.3X=J.1H(a);J.V("16")&&w(p(b,".16"),"5c",e.16.2b);J.V("3V-17")&&w(p(b,".17"),"56",f);H b},2Q:6(a){J.1c=""+1Q.5d(1Q.5n()*5k).1q();e.1Y.2A[t(J.1c)]=J;J.1n=C(e.2v,a||{});I(J.V("2k")==R)J.1n.16=J.1n.1u=11},5j:6(a){a=a.Q(/^\\s+|\\s+$/g,"").Q(/\\s+/g,"|");H"\\\\b(?:"+a+")\\\\b"},5f:6(a){J.28={18:{1I:a.18,23:"1k"},1b:{1I:a.1b,23:"1k"},17:1f M("(?<18>"+a.18.1m+")(?<17>.*?)(?<1b>"+a.1b.1m+")","5o")}}};H e}();1j 2e!="1d"&&(2e.1v=1v);',62,441,'||||||function|||||||||||||||||||||||||||||||||||||return|if|this|var|length|XRegExp|null|for|index|replace|true||div|push|getParam|call|exec|else|prototype||false|lastIndex|config|arguments|RegExp|toolbar|code|left|captureNames|slice|right|id|undefined|split|new|class|addToken|indexOf|typeof|script|className|source|params|substr|apply|toString|String|line|title|gutter|SyntaxHighlighter|_xregexp|strings|lt|html|test|OUTSIDE_CLASS|match|brush|document|target|gt|getHtml|regex|global|join|style|highlight|break|concat|window|Math|isRegExp|throw|value|brushes|brushName|space|alert|vars|http|syntaxhighlighter|expandSource|size|css|case|font|Fa|name|htmlScript|dA|can|handler|gm|td|exports|color|in|href|first|discoveredBrushes|light|collapse|object|cache|getButtonHtml|trigger|pattern|getLineHtml|nbsp|numbers|parseInt|defaults|com|items|www|pad|highlighters|execute|focus|func|all|getDiv|parentNode|navigator|INSIDE_CLASS|regexList|hasFlag|Match|useScriptTags|hasNamedCapture|text|help|init|br|input|gi|Error|values|span|list|250|height|width|screen|top|500|tagName|findElements|getElementsByTagName|aboutDialog|_blank|appendChild|charAt|Array|copyAsGlobal|setFlag|highlighter_|string|attachEvent|nodeName|floor|backref|output|the|TypeError|sticky|Za|iterate|freezeTokens|scope|type|textarea|alexgorbatchev|version|margin|2010|005896|gs|regexLib|body|center|align|noBrush|require|childNodes|DTD|xhtml1|head|org|w3|url|preventDefault|container|tr|getLineNumbersHtml|isNaN|userAgent|tbody|isLineHighlighted|quick|void|innerHTML|create|table|links|auto|smart|tab|stripBrs|tabs|bloggerMode|collapsed|plain|getCodeLinesHtml|caption|getMatchesHtml|findMatches|figureOutLineNumbers|removeNestedMatches|getTitleHtml|brushNotHtmlScript|substring|createElement|Highlighter|load|HtmlScript|Brush|pre|expand|multiline|min|Can|ignoreCase|find|blur|extended|toLowerCase|aliases|addEventListener|innerText|textContent|wasn|select|createTextNode|removeChild|option|same|frame|xmlns|dtd|twice|1999|equiv|meta|htmlscript|transitional|1E3|expected|PUBLIC|DOCTYPE|on|W3C|XHTML|TR|EN|Transitional||configured|srcElement|Object|after|run|dblclick|matchChain|valueOf|constructor|default|switch|click|round|execAt|forHtmlScript|token|gimy|functions|getKeywords|1E6|escape|within|random|sgi|another|finally|supply|MSIE|ie|toUpperCase|catch|returnValue|definition|event|border|imsx|constructing|one|Infinity|from|when|Content|cellpadding|flags|cellspacing|try|xhtml|Type|spaces|2930402|hosted_button_id|lastIndexOf|donate|active|development|keep|to|xclick|_s|Xml|please|like|you|paypal|cgi|cmd|webscr|bin|highlighted|scrollbars|aspScriptTags|phpScriptTags|sort|max|scriptScriptTags|toolbar_item|_|command|command_|number|getElementById|doubleQuotedString|singleLinePerlComments|singleLineCComments|multiLineCComments|singleQuotedString|multiLineDoubleQuotedString|xmlComments|alt|multiLineSingleQuotedString|If|https|1em|000|fff|background|5em|xx|bottom|75em|Gorbatchev|large|serif|CDATA|continue|utf|charset|content|About|family|sans|Helvetica|Arial|Geneva|3em|nogutter|Copyright|syntax|close|write|2004|Alex|open|JavaScript|highlighter|July|02|replaceChild|offset|83'.split('|'),0,{}))
//}}}
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
	<title>Reply</title>
	<link rel="stylesheet" href="//tiddlyspace.com/bags/benspa_public/tiddlers/bootvelcro.css">
	<style>
		html,
		body {
			overflow: hidden;
			background-color: transparent;
		}

		#container {
			/* prevent a fouc if no images present */
			display: none;
		}

		.modal-header {
			border-bottom: none;
			padding: 5px 0 0;
			position: absolute;
			width: 100%;
			background-color: #e0e0e0;
			-webkit-border-radius: 6px 6px 0 0;
			-moz-border-radius: 6px 6px 0 0;
			border-radius: 6px 6px 0 0;
			cursor: move;
		}

		.form-actions {
			position: absolute;
			bottom: 0;
			box-sizing: border-box;
			-moz-box-sizing: border-box;
			width: 100%;
			margin: 0;
			border-radius: 0 0 6px 6px;
			background-color: #e0e0e0;
			border-top: 1px solid gray;
		}

		.form-actions input.btn {
			width: auto;
			float: right;
			margin: 0 0.2em;
		}

		.closeBtn {
			background-color: #DCE7F1 !important;
		}

		.primary {
			background-color: #09F !important;
		}

		h1 {
			margin-bottom: 9px;
			margin-top: 9px;
		}

		body {
			width: 100%;
			height: 100%;
			position: absolute;
		}

		.modal {
			margin: 10px;
			top: 0;
			left: 0;
			bottom: 0;
			width: 510px;
			position: absolute;
			box-shadow: #444 0px 0px 10px 2px;
			border-radius: 6px;
			background-color: white;
			border: 1px solid gray;
			background-color: #F0F4F8;
		}

		label em {
			cursor: pointer;
		}

		.modal-body {
			overflow: auto;
			position: absolute;
			top: 0;
			bottom: 0;
			left: 0;
			right: 0;
			margin: 65px 20px 67px;
			background-color: transparent;
		}

		.nav-tabs {
			padding-left: 1%;
			margin: 0;
			width: 99%;
			border-color: gray;
		}

		.nav-tabs > li {
			cursor: pointer;
		}

		.nav-tabs > li > a {
			line-height: 2.4em;
			font-weight: bold;
			font-size: 100%;
		}

		.nav-tabs > li.active > a{
			background-color: #F0F4F8;
			border-color: gray;
			border-bottom-color: #F0F4F8;
		}

		.active {
			display: block;
		}

		input,
		textarea,
		select,
		.uneditable-input {
			color: #606060;
		}

		.imagePicker {
			-moz-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
			-webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
			box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
			border: 1px solid #CCC;
			height: 110px;
			overflow: auto;
			-webkit-border-radius: 3px;
			-moz-border-radius: 3px;
			border-radius: 3px;
			margin-left: 0;
		}

		.imagePicker img {
			margin: 5px;
			border: 2px solid transparent;
		}

		.imagePicker .current {
			border: 2px dotted #555;
		}

		label {
			font-weight: bold;
		}

		.form-actions label {
			float: left;
			margin-top: 0.75em;
		}

		fieldset input,
		fieldset textarea {
			width: 90%;
			border-color: gray;
		}

		@media all and (max-width: 550px) {
			.modal {
				width: 95%;
			}
		}

		#help {
			position: absolute;
			border: 0;
			right: 4px;
			top: 5px;
			text-indent: -9999px;
			color: transparent;
			height: 16px;
			width: 16px;
			background: none;
			background-image: url(/bags/common/tiddlers/help.png);
			background-repeat: no-repeat;
			background-color: white;
			z-index: 2;
			border-radius: 10px;
		}

		#help-info {
			padding: 0;
			border: 1px solid gray;
			width: 60%;
			height: 50px;
			color: #404040;
			background-color: white;
			position: absolute;
			top: 5px;
			right: 5px;
			z-index: 1;
			cursor: auto;
			border-radius: 5px;

		}

		#help-info p {
			padding: 10px 25px;
			margin-bottom: 0;
		}
	</style>
</head>
<body>
	<div id="container">
		<form action="#" class="modal">
			<div class="modal-header">
				<button id="help">help</button>
				<div id="help-info" style="display:none;"><p>
				Found something interesting? Write about it in your own space. <a href="//docs.tiddlyspace.com/Reply to this Tiddler" target="_blank">Find out more</a>
				</p></div>
				<ul class="nav nav-tabs" data-tabs="tabs">
					<li class="active" data-tab-name="post"><a href="#postForm">Reply</a></li>
				</ul>
			</div>


			<fieldset id="postForm" class="modal-body">
				<label>Title
					<input type="text" name="title">
				</label>
				<input type="hidden" name="url">
				<label>Post
					<textarea name="text" rows="8"></textarea>
				</label>
				<label>Tags
					<input type="text" name="tags" value="">
				</label>
			</fieldset>


			<div class="form-actions">
				<label class="checkbox">
					<input type="checkbox" name="private" val="private">
					keep private
				</label>
				<input type="submit" class="btn primary btn-large" value="Done">
				<input type="button" class="btn btn-large closeBtn" value="Cancel">
			</div>
		</form>
	</div>

	<script type="text/javascript"
            src="/bags/common/tiddlers/jquery.js"></script>
	<script type="text/javascript" src="/bags/tiddlyspace/tiddlers/chrjs"></script>
	<script type="text/javascript" src="/bags/common/tiddlers/_reply.js"></script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
	<title>Account</title>
	<link href="/bags/common/tiddlers/profile.css" type='text/css' rel='stylesheet' >
	<link href="/bags/common/tiddlers/admin.css" type='text/css' rel='stylesheet' >
	<link href="/bags/common/tiddlers/jquery-ui.custom.css" type='text/css' rel='stylesheet' >
</head>
<body>

<div id="container">
	<div class="main section">
		<a class="app" href="/">home</a>
		<div class="left">
		<div id="siteiconArea">
		<h2>User Icon</h2>
		<div>
			<img id="siteicon" class="siteicon">
			<form id="upload" method="POST" enctype="multipart/form-data">
				<input type="hidden" name="title" value="SiteIcon" />
				<input type="hidden" name="tags" value="excludeLists">
				<input type="hidden" name="csrf_token" class="csrf" />
				<input type="file" name="file" accept="image/*" />
				<input type="submit" value="upload" />
			</form>
			<div id="dropzone">Drop file here
				<img class="notloading" src="/bags/common/tiddlers/ajax-loader.gif" alt="submitting SiteIcon" />
			</div>
		</div>
		</div>
		<h2>Find Space</h2>
		<form class="spaceSearch">
			<input class="inputBox" type="text" placeholder="find space" />
			<a href="http://docs.tiddlyspace.com/What%20is%20a%20Space%3F" class="help"
				title="What is a space?">What is a space?</a>
			<button>view all</button>
		</form>
		<div class='list-container'>
			You are a member of the following spaces:
			<ul class='ts-space-search'>
			</ul>
		</div>
		<h2>Create New Space</h2>
		<form class="ts-spaces">
			<input class="inputBox" type="text" name="spacename" placeholder="space name"><span class="hostSuffix">.tiddlyspace.com</span>
			<input type="submit" value="Create Space" />
		</form>
		</div>
		<div class="right">
		<h2>Change Password</h2>
		<form class="ts-password">
			<input class="inputBox" placeholder="existing password" type="password" name="password">
			<input class="inputBox" placeholder="new password" type="password" name="new_password">
			<input class="inputBox" placeholder="new password"	type="password" name="new_password_confirm">
			<input type="submit" value="Change password">
		</form>
		<h2>OpenID</h2>
		<h3>Why OpenID?</h3>
		<a href="http://openid.net/"><img src="/bags/common/tiddlers/openid.png" alt="openid" ></a><br />
		Use just one username and password across hundreds of OpenID-enabled sites.<br />
		It's an open standard.<br />
		<a href="http://openid.net/what/">learn more</a>
		<ul class="ts-identities"></ul>
		<form class="ts-openid" target="_top">
			<div>
				Add an openid:
			</div>
			<input class="inputBox" type="text" name="openid" placeholder="your openid" />
			<input type="submit" value="Register" />
			<a href="http://openid.net/get-an-openid/" class="help"
			title="What is an open id?">What is an open id?</a>
		</form>
		</div>
		<div class="clear"></div>
	</div>
</div>
<script src="/bags/common/tiddlers/backstage.js"></script>
<script src='/bags/common/tiddlers/jquery.js'></script>
<script src='/bags/tiddlyspace/tiddlers/chrjs'></script>
<script src='/bags/common/tiddlers/chrjs.space'></script>
<script src='/bags/common/tiddlers/chrjs.users'></script>
<script src='/bags/common/tiddlers/chrjs.identities'></script>
<script src="/bags/common/tiddlers/jquery-ui.custom.js"></script>
<script src='/bags/common/tiddlers/jquery-form.js'></script>
<script src="/bags/common/tiddlers/siteiconupload.js"></script>
<script src='/bags/common/tiddlers/ts.js'></script>
<script src="/status.js"></script>
<script type="text/javascript">
/*
 * jQuery UI Autocomplete HTML Extension
 *
 * Copyright 2010, Scott González (http://scottgonzalez.com)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 *
 * http://github.com/scottgonzalez/jquery-ui-extensions
 */
(function( $ ) {

var proto = $.ui.autocomplete.prototype,
	initSource = proto._initSource;

function filter( array, term ) {
	var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
	return $.grep( array, function(value) {
		return matcher.test( $( "<div>" ).html( value.label || value.value || value ).text() );
	});
}

$.extend( proto, {
	_initSource: function() {
		if ( this.options.html && $.isArray(this.options.source) ) {
			this.source = function( request, response ) {
				response( filter( this.options.source, request.term ) );
			};
		} else {
			initSource.call( this );
		}
	},

	_renderItem: function( ul, item) {
		return $( "<li></li>" )
			.data( "item.autocomplete", item )
			.append( $( "<a></a>" )[ this.options.html ? "html" : "text" ]( item.label ) )
			.appendTo( ul );
	}
});

})( jQuery );

/***
_accounts application specific javascript
***/
var link;
ts.init(function(ts) {
	if(ts.user.anon) { // redirect to homepage when user not logged in
		window.location = ts.getHost();
	} else if(ts.user.name === ts.currentSpace){
		initSiteIconUpload(ts.user.name);
	} else {
		link = $("<a />").attr("href", ts.getHost(ts.user.name) + "/_account").text("Change User Icon");
		$("#siteiconArea div").empty().append(link);
	}
	$(".hostSuffix").text("." + ts.getHost("").split("//")[1]);
	ts.getSpaces(function(spaces) {
		$("<div class='info' />").text("You have " + spaces.length + " spaces.").insertBefore($(".spaceSearch")[0]);
		$("form.spaceSearch input").autocomplete({
			html: true,
			source: function(req, response) {
				ts.getSpaces(function(spaces) {
					var selected = [];
					for(var i = 0; i < spaces.length; i++) {
						var space = spaces[i];
						if(space.name.indexOf(req.term) > -1) {
							var host = ts.getHost(space.name) ;
							var img = host + "/SiteIcon";
							selected.push({
								value: space.name,
								label: '<a href="' + host + '" target="_parent" class="autocompleteLink"><img src="' + img + '" style="height:24px;width:auto;max-height:24px;max-width:24px;"/>' + space.name + '</a>'
							});
						}
					}
					response(selected);
				});
			},
			select: function(event, ui) {
				window.top.location = ts.getHost(ui.item.value);
			}
		});

		var $ul = $('.ts-space-search');
		$.each(spaces, function(i, space) {
			$ul.append($('<li/>').html($('<a/>').attr('href', space.uri)
				.text(space.name)));
		});

		$('form.spaceSearch button').click(function(ev) {
			$('.list-container').slideToggle('fast');
			ev.preventDefault();
			return false;
		});
	});
});

if(window != window.top) {
	$("html").addClass("iframeMode");
	$("a").live("click",function(ev) {
		$(ev.target).attr("target", "_parent");
	});
}
</script>
<!--[if lt IE 8]>
<script type="text/javascript" src="/bags/common/tiddlers/json2.js"></script>
<![endif]-->
</body>
</html>
!Upload an icon
<<tiddler spaceIcon>>
!Describe your space
If you haven't already done so, you should provide a brief decscription of yourself and what you're using this space for. To do this, just edit the [[SiteInfo]] tiddler (keeping the title the same of course).

!Change the title
<<tiddler spaceTitle>>
!Change the theme
<<tiddler colorScheme>>
!Change the menu
If you'd like to change the menu items along the top, you can edit the [[MainMenu]] tiddler.

!Change the default tiddlers
<<tiddler setDefaultTiddlers>>
!More Advanced customisations
If you know HTML and CSS, you can edit some or all of the following tiddlers to customise your space further:
* PageTemplate
* EditTemplate
* ViewTemplate
* StyleSheet
!Summary
Here we initialise the ~MathJax environment.

The Init section of this tiddler is rendered automatically when the site is loaded.  This effect was achieved by adding the line
{{{
<div style='display:none' macro='tiddler LatexNucleus##Init'></div>
}}}
to [[PageTemplate]].  It is important to add this line before the <div id='displayArea'> tag so that mathematics which appears in a default tiddle is rendered correctly.  The goal of Init is to initialise the ~MathJax environment and then call \SaveGlobals so that this freshly initialised state can be returned to at any time by use of the command \Clean.

!Init
$
%We hook the usual macro-creating Latex commands up to Richard's javascript routines.
\def\newcommand{\MetaNewCom}
\def\renewcommand{\MetaNewCom}
\def\def{\MetaDef}

%Here we make copies of the standard Latex commands which we may displace.
\let\LaTeXepsilon\epsilon
\let\LaTeXsubset\subset
\let\LaTeXrestriction\restriction

%We transclude all of the macroset tiddlers so that the macroset macros are always available.  If you create a new macroset then you'll need to add the appropriate line here so that it is detected when the site loads.
$<<tiddler BasicMacros##Code>>$
$<<tiddler KunenMacros##Code>>$
$<<tiddler GarethMacros##Code>>$

%We also include a dummy macroset, \LocalMacros, which can be used for the main extra macros of a particular tiddler.  This can be useful, for example, if you want to comment on someones work using some of your personal macros but don't want to replace any of the local definitions.
\def\LocalMacros{}

%We preload the macrosets which are considered global.
\BasicMacros
\BasicMacroAbbreviations
\BasicMacrosSupplement

%And finally we save the current state of the ~MathJax definition tables.  This is the state we return to whenever \Clean is called.  We also call \Clean here to keep the ~MathJax environment in good condition when this tiddler is viewed.  This is put in a separate mathematics block because \SaveGlobals will throw an error on every call other than the first and this error will prevent \Clean from being called if \Clean is later on in the same block.
\SaveGlobals
$$
\Clean
$
//{{{
/**
 * SyntaxHighlighter
 * http://alexgorbatchev.com/SyntaxHighlighter
 *
 * SyntaxHighlighter is donationware. If you are using it, please donate.
 * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
 *
 * @version
 * 3.0.83 (July 02 2010)
 * 
 * @copyright
 * Copyright (C) 2004-2010 Alex Gorbatchev.
 *
 * @license
 * Dual licensed under the MIT and GPL licenses.
 */
;(function()
{
	// CommonJS
	typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null;

	function Brush()
	{
		function process(match, regexInfo)
		{
			var constructor = SyntaxHighlighter.Match,
				code = match[0],
				tag = new XRegExp('(&lt;|<)[\\s\\/\\?]*(?<name>[:\\w-\\.]+)', 'xg').exec(code),
				result = []
				;
		
			if (match.attributes != null) 
			{
				var attributes,
					regex = new XRegExp('(?<name> [\\w:\\-\\.]+)' +
										'\\s*=\\s*' +
										'(?<value> ".*?"|\'.*?\'|\\w+)',
										'xg');

				while ((attributes = regex.exec(code)) != null) 
				{
					result.push(new constructor(attributes.name, match.index + attributes.index, 'color1'));
					result.push(new constructor(attributes.value, match.index + attributes.index + attributes[0].indexOf(attributes.value), 'string'));
				}
			}

			if (tag != null)
				result.push(
					new constructor(tag.name, match.index + tag[0].indexOf(tag.name), 'keyword')
				);

			return result;
		}
	
		this.regexList = [
			{ regex: new XRegExp('(\\&lt;|<)\\!\\[[\\w\\s]*?\\[(.|\\s)*?\\]\\](\\&gt;|>)', 'gm'),			css: 'color2' },	// <![ ... [ ... ]]>
			{ regex: SyntaxHighlighter.regexLib.xmlComments,												css: 'comments' },	// <!-- ... -->
			{ regex: new XRegExp('(&lt;|<)[\\s\\/\\?]*(\\w+)(?<attributes>.*?)[\\s\\/\\?]*(&gt;|>)', 'sg'), func: process }
		];
	};

	Brush.prototype	= new SyntaxHighlighter.Highlighter();
	Brush.aliases	= ['xml', 'xhtml', 'xslt', 'html'];

	SyntaxHighlighter.brushes.Xml = Brush;

	// CommonJS
	typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
})();
//}}}
Sometimes it is useful to create a simple prototype when you are studying a complex robot as parallel ones are. A prototype can help you to understand how its structure reacts when one or more actuated joints are modified.

A prototype was built during the [[study of the delta-3 robot|Kinematics study of a delta-3 robot]] and it was done using cardboard, you can see some photos below or in my [[Picasa site|https://picasaweb.google.com/101542046887408327725/Delta3Robot1stPrototypeCardboardModel?authuser=0&feat=directlink]].

<<tiddler "Picasa##album" with: d9er0d 5744574092705046017 144>>
Before building it the model was designed using the Community Edition of [[QCAD|http://www.qcad.org]]; you can find a version for Windows OS [[here|http://qcadbin-win.sourceforge.net]].
The model can be downloaded as [[PDF|https://docs.google.com/open?id=0ByovaZlEMcTJRlZwNl9zb2RhdUE]] to print and cut or you can get the original [[DXF|https://docs.google.com/open?id=0ByovaZlEMcTJVlozM2lpNkdXLUE]] file. 

/***
|''Name''|TiddlySpaceConfig|
|''Version''|0.7.7|
|''Description''|TiddlySpace configuration|
|''Status''|stable|
|''Source''|http://github.com/TiddlySpace/tiddlyspace/raw/master/src/plugins/TiddlySpaceConfig.js|
|''CoreVersion''|2.6.1|
|''Requires''|TiddlyWebConfig ServerSideSavingPlugin TiddlyFileImporter|
!Code
***/
//{{{
(function($) {

var tweb = config.extensions.tiddlyweb;

var recipe = config.defaultCustomFields["server.workspace"].split("recipes/")[1];
var currentSpace; // assigned later

var disabledTabs = [];

var coreBags = ["system", "tiddlyspace"];
var systemSpaces = ["plugins", "info", "images", "theme"];
systemSpaces = $.map(systemSpaces, function(item, i) {
	return "system-%0_public".format(item);
});

// hijack search macro to add custom attributes for mobile devices
var _search = config.macros.search.handler;
config.macros.search.handler = function(place, macroName, params) {
	_search.apply(this, arguments);
	$(".searchField:input", place).
		attr({ autocapitalize: "off", autocorrect: "off" });
};

// arg is either a container name or a tiddler object
// if fuzzy is truthy, space may be inferred from workspace (for new tiddlers)
// returns space object or false
var determineSpace = function(arg, fuzzy) {
	if(typeof arg == "string") { // container name
		var space = split(arg, "_", "r");
		return ["public", "private"].contains(space.type) ? space : false;
	} else if(arg) { // tiddler
		var container = determineContainer(arg, fuzzy);
		return container ? determineSpace(container.name, fuzzy) : false;
	} else {
		return false;
	}
};

// if fuzzy is truthy, container may be inferred from workspace for new tiddlers
// returns container object or false
var determineContainer = function(tiddler, fuzzy) { // TODO: expose?
	var bag = tiddler.fields["server.bag"];
	var recipe = tiddler.fields["server.recipe"]; // XXX: unused/irrelevant/redundant!?
	if(bag) {
		return { type: "bag", name: bag };
	} else if(recipe) {
		return { type: "recipe", name: recipe };
	} else if(fuzzy) { // new tiddler
		var workspace = tiddler.fields["server.workspace"];
		if(workspace) {
			var container = split(workspace, "/", "l");
			return ["bags", "recipes"].contains(container.type) ? container : false;
		} else {
			return false;
		}
	} else {
		return false;
	}
};

// hijack removeTiddlerCallback to restore tiddler from recipe cascade -- TODO: move into TiddlyWebWiki?
var sssp = config.extensions.ServerSideSavingPlugin;
var _removeTiddlerCallback = sssp.removeTiddlerCallback;
sssp.removeTiddlerCallback = function(context, userParams) {
	var title = context.tiddler.title;
	var recipe = context.tiddler.fields["server.recipe"];
	_removeTiddlerCallback.apply(this, arguments);
	if(recipe) {
		context.workspace = "recipes/" + recipe;
		var callback = function(context, userParams) {
			if(context.status) {
				var dirty = store.isDirty();
				store.saveTiddler(context.tiddler).clearChangeCount();
				store.setDirty(dirty);
			} else {
				store.notify(title, true);
			}
		};
		context.adaptor.getTiddler(title, context, null, callback);
	}
};

// splits a string once using delimiter
// mode "l" splits at the first, "r" at the last occurrence
// returns an object with members type and name
var split = function(str, sep, mode) {
	mode = mode == "r" ? "pop" : "shift"; // TODO: use +/-1 instead of "l"/"r"?
	var arr = str.split(sep);
	var type = arr.length > 1 ? arr[mode]() : null;
	return { type: type, name: arr.join(sep) };
};

var plugin = config.extensions.tiddlyspace = {
	currentSpace: determineSpace(recipe),
	coreBags: coreBags.concat(systemSpaces),

	determineSpace: determineSpace,
	isValidSpaceName: function(name) {
		return name.match(/^[a-z][0-9a-z\-]*[0-9a-z]$/) ? true : false;
	},
	getCurrentBag: function(type) {
		return "%0_%1".format(currentSpace, type);
	},
	getCurrentWorkspace: function(type) {
		return "bags/" + this.getCurrentBag(type);
	},
	// returns the URL for a space's avatar (SiteIcon) based on a server_host
	// object and an optional space name
	// optional nocors argument prevents cross-domain URLs from being generated
	getAvatar: function(host, space, nocors) {
		if(space && typeof space != "string") { // backwards compatibility -- XXX: deprecated
			space = space.name;
		}
		var subdomain = nocors ? currentSpace : space;
		host = host ? this.getHost(host, subdomain) : "";
		var bag = space ? "%0_public".format(space) : "tiddlyspace";
		return "%0/bags/%1/tiddlers/SiteIcon".format(host, bag);
	},
	// returns the URL based on a server_host object (scheme, host, port) and an
	// optional subdomain
	getHost: function(host, subdomain) {
		if(host === undefined) { // offline
			tweb.status.server_host = {}; // prevents exceptions further down the stack -- XXX: hacky workaround, breaks encapsulation
			return null;
		}
		subdomain = subdomain ? subdomain + "." : "";
		var url = "%0://%1%2".format(host.scheme, subdomain, host.host);
		var port = host.port;
		if(port && !["80", "443"].contains(port)) {
			url += ":" + port;
		}
		return url;
	},
	disableTab: function(tabTiddler) {
		if(typeof(tabTiddler) == "string") {
			disabledTabs.push(tabTiddler);
		} else {
			for(var i = 0; i < tabTiddler.length; i++) {
				plugin.disableTab(tabTiddler[i]);
			}
		}
	},
    checkSyncStatus: function(tiddler) {
		if(tiddler) {
			var title = typeof(tiddler) === "string" ? tiddler : tiddler.title;
			var el = story.getTiddler(title) || false;
			if(el) {
				refreshElements(el);
			}
		}
	},
	isDisabledTab: function(tabTitle) {
		var match = new RegExp("(?:\\[\\[([^\\]]+)\\]\\])", "mg").exec(tabTitle);
		var tabIdentifier = match ? match[1] : tabTitle;
		return disabledTabs.contains(tabIdentifier);
	},
	getCSRFToken: window.getCSRFToken || null // this may not have been processed yet
};

currentSpace = plugin.currentSpace.name;

tweb.serverPrefix = tweb.host.split("/")[3] || ""; // XXX: assumes root handler
tweb.getStatus(function(status) {
	var url = plugin.getHost(status.server_host);
	tweb.status.server_host.url = url;
	config.messages.tsVersion = status.version;
});

if(window.location.protocol == "file:") {
	// enable AutoSave by default
	config.options.chkAutoSave = config.options.chkAutoSave === undefined ?
		true : config.options.chkAutoSave;
} else {
	// set global read-only mode based on membership heuristics
	var indicator = store.getTiddler("SiteTitle") || tiddler;
	readOnly = !(recipe.split("_").pop() == "private" ||
		tweb.hasPermission("write", indicator));
	// replace TiddlyWiki's ImportTiddlers due to cross-domain restrictions
	if(config.macros.fileImport) {
		$.extend(config.macros.importTiddlers, config.macros.fileImport);
	}
}

// hijack saveChanges to ensure SystemSettings is private by default
var _saveChanges = saveChanges;
saveChanges = function(onlyIfDirty, tiddlers) {
	if(tiddlers && tiddlers.length == 1 &&
			tiddlers[0] && tiddlers[0].title == "SystemSettings") {
		var fields = tiddlers[0].fields;
		delete fields["server.recipe"];
		fields["server.bag"] = plugin.getCurrentBag("private");
		fields["server.workspace"] = plugin.getCurrentWorkspace("private");
	}
	return _saveChanges.apply(this, arguments);
};

// ensure backstage is always initialized
// required to circumvent TiddlyWiki's read-only based handling
config.macros.backstageInit = {
	init: function() {
		showBackstage = true;
	}
};

// disable evaluated macro parameters for security reasons
config.evaluateMacroParameters = "none";
var _parseParams = String.prototype.parseParams;
String.prototype.parseParams = function(defaultName, defaultValue, allowEval,
		noNames, cascadeDefaults) {
	if(config.evaluateMacroParameters == "none") {
		arguments[2] = false;
	}
	return _parseParams.apply(this, arguments);
};

var _tabsMacro = config.macros.tabs.handler;
config.macros.tabs.handler = function(place, macroName, params) {
	var newParams = [params[0]]; // keep cookie name
	for(var i = 1; i < params.length; i += 3) {
		var tabTitle = params[i + 2];
		if(!plugin.isDisabledTab(tabTitle)){
			newParams = newParams.concat(params[i], params[i + 1], tabTitle);
		}
	}
	_tabsMacro.apply(this, [place, macroName, newParams]);
};

// disable ControlView for XHRs by default
$.ajaxSetup({
	beforeSend: function(xhr) {
		xhr.setRequestHeader("X-ControlView", "false");
	}
});
// TiddlyWeb adaptor currently still uses httpReq, which needs extra magic -- XXX: obsolete this!
var _httpReq = httpReq;
httpReq = function(type, url, callback, params, headers, data, contentType,
		username, password, allowCache) {
	headers = headers || {};
	headers["X-ControlView"] = "false";
	_httpReq.apply(this, arguments);
};

// register style sheet for backstage separately (important)
store.addNotification("StyleSheetBackstage", refreshStyles);

// option for default privacy setting
config.optionsDesc.chkPrivateMode = "Set your default privacy mode to private";
config.optionsSource.chkPrivateMode = "setting";
config.options.chkPrivateMode = config.options.chkPrivateMode || false;
saveSystemSetting("chkPrivateMode", true);
config.defaultCustomFields["server.workspace"] = plugin.
	getCurrentWorkspace(config.options.chkPrivateMode ? "private" : "public");

config.paramifiers.follow = {
	onstart: function(v) {
		if(!readOnly) {
			var bag = "%0_public".format(currentSpace);
			story.displayTiddler(null, v, DEFAULT_EDIT_TEMPLATE, null, null,
				"server.bag:%0 server.workspace:bags/%0".format(bag));
			story.setTiddlerTag(v, "follow", 1);
			story.focusTiddler(v, "text");
		}
	}
};

var fImport = config.macros.fileImport;
if(fImport) {
	fImport.uploadTo = "Upload to: ";
	var _createForm = config.macros.fileImport.createForm;
	config.macros.fileImport.createForm = function(place, wizard, iframeName) {
		var container = $("<div />").text(fImport.uploadTo).appendTo(place);
		var select = $('<select name="mode" />').appendTo(container)[0];
		$('<option value="private" selected>private</a>').appendTo(select);
		$('<option value="public">public</a>').appendTo(select);
		wizard.setValue("importmode", select);
		_createForm.apply(this, [place, wizard, iframeName]);
	};

	var _onGet = config.macros.importTiddlers.onGetTiddler;
	config.macros.importTiddlers.onGetTiddler = function(context, wizard) {
		var type = $(wizard.getValue("importmode")).val();
		var ws =  plugin.getCurrentWorkspace(type);
		wizard.setValue("workspace", ws);
		_onGet.apply(this, [context, wizard]);
	};
}

config.extensions.ServerSideSavingPlugin.reportSuccess = function(msg, tiddler) {
	plugin.checkSyncStatus(tiddler);
	msg = config.extensions.ServerSideSavingPlugin.locale[msg];
	var link = "/" + encodeURIComponent(tiddler.title);
	displayMessage(msg.format([tiddler.title]), link);
};


})(jQuery);
//}}}
/*{{{*/
txtUserName = "d9er0d";
txtUploadUserName = "d9er0d";
config.options.chkBackstage = false;
config.options.chkAnimate = false;
config.options.chkDisableWikiLinks = true;
config.options.chkGenerateAnRssFeed = true;
config.options.txtRssTag = "%toRSS";
config.options.txtTheme = "MochaTheme";
/*}}}*/
/***
|''Name''|TiddlyWebAdaptor|
|''Description''|adaptor for interacting with TiddlyWeb|
|''Author:''|FND|
|''Contributors''|Chris Dent, Martin Budden|
|''Version''|1.4.10|
|''Status''|stable|
|''Source''|http://svn.tiddlywiki.org/Trunk/association/adaptors/TiddlyWebAdaptor.js|
|''CodeRepository''|http://svn.tiddlywiki.org/Trunk/association/|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''CoreVersion''|2.5|
|''Keywords''|serverSide TiddlyWeb|
!Notes
This plugin includes [[jQuery JSON|http://code.google.com/p/jquery-json/]].
!To Do
* createWorkspace
* document custom/optional context attributes (e.g. filters, query, revision) and tiddler fields (e.g. server.title, origin)
!Code
***/
//{{{
(function($) {

var adaptor = config.adaptors.tiddlyweb = function() {};

adaptor.prototype = new AdaptorBase();
adaptor.serverType = "tiddlyweb";
adaptor.serverLabel = "TiddlyWeb";
adaptor.mimeType = "application/json";

adaptor.parsingErrorMessage = "Error parsing result from server";
adaptor.noBagErrorMessage = "no bag specified for tiddler";
adaptor.locationIDErrorMessage = "no bag or recipe specified for tiddler"; // TODO: rename

// retrieve current status (requires TiddlyWeb status plugin)
adaptor.prototype.getStatus = function(context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	var uriTemplate = "%0/status";
	var uri = uriTemplate.format([context.host]);
	var req = httpReq("GET", uri, adaptor.getStatusCallback, context,
		null, null, null, null, null, true);
	return typeof req == "string" ? req : true;
};

adaptor.getStatusCallback = function(status, context, responseText, uri, xhr) {
	context.status = responseText ? status : false;
	try {
		context.statusText = xhr.statusText;
	} catch(exc) { // offline (Firefox)
		context.status = false;
		context.statusText = null;
	}
	context.httpStatus = xhr.status;
	if(context.status) {
		context.serverStatus = $.evalJSON(responseText); // XXX: error handling!?
	}
	if(context.callback) {
		context.callback(context, context.userParams);
	}
};

// retrieve a list of workspaces
adaptor.prototype.getWorkspaceList = function(context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	context.workspaces = [];
	var uriTemplate = "%0/recipes"; // XXX: bags?
	var uri = uriTemplate.format([context.host]);
	var req = httpReq("GET", uri, adaptor.getWorkspaceListCallback,
		context, { accept: adaptor.mimeType }, null, null, null, null, true);
	return typeof req == "string" ? req : true;
};

adaptor.getWorkspaceListCallback = function(status, context, responseText, uri, xhr) {
	context.status = status;
	context.statusText = xhr.statusText;
	context.httpStatus = xhr.status;
	if(status) {
		try {
			var workspaces = $.evalJSON(responseText);
		} catch(ex) {
			context.status = false; // XXX: correct?
			context.statusText = exceptionText(ex, adaptor.parsingErrorMessage);
			if(context.callback) {
				context.callback(context, context.userParams);
			}
			return;
		}
		context.workspaces = workspaces.map(function(itm) { return { title: itm }; });
	}
	if(context.callback) {
		context.callback(context, context.userParams);
	}
};

// retrieve a list of tiddlers
adaptor.prototype.getTiddlerList = function(context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	var uriTemplate = "%0/%1/%2/tiddlers%3";
	var params = context.filters ? "?" + context.filters : "";
	if(context.format) {
		params = context.format + params;
	}
	var workspace = adaptor.resolveWorkspace(context.workspace);
	var uri = uriTemplate.format([context.host, workspace.type + "s",
		adaptor.normalizeTitle(workspace.name), params]);
	var req = httpReq("GET", uri, adaptor.getTiddlerListCallback,
		context, merge({ accept: adaptor.mimeType }, context.headers), null, null, null, null, true);
	return typeof req == "string" ? req : true;
};

adaptor.getTiddlerListCallback = function(status, context, responseText, uri, xhr) {
	context.status = status;
	context.statusText = xhr.statusText;
	context.httpStatus = xhr.status;
	if(status) {
		context.tiddlers = [];
		try {
			var tiddlers = $.evalJSON(responseText); //# NB: not actual tiddler instances
		} catch(ex) {
			context.status = false; // XXX: correct?
			context.statusText = exceptionText(ex, adaptor.parsingErrorMessage);
			if(context.callback) {
				context.callback(context, context.userParams);
			}
			return;
		}
		for(var i = 0; i < tiddlers.length; i++) {
			var tiddler = adaptor.toTiddler(tiddlers[i], context.host);
			context.tiddlers.push(tiddler);
		}
	}
	if(context.callback) {
		context.callback(context, context.userParams);
	}
};

// perform global search
adaptor.prototype.getSearchResults = function(context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	var uriTemplate = "%0/search?q=%1%2";
	var filterString = context.filters ? ";" + context.filters : "";
	var uri = uriTemplate.format([context.host, context.query, filterString]); // XXX: parameters need escaping?
	var req = httpReq("GET", uri, adaptor.getSearchResultsCallback,
		context, { accept: adaptor.mimeType }, null, null, null, null, true);
	return typeof req == "string" ? req : true;
};

adaptor.getSearchResultsCallback = function(status, context, responseText, uri, xhr) {
	adaptor.getTiddlerListCallback(status, context, responseText, uri, xhr); // XXX: use apply?
};

// retrieve a particular tiddler's revisions
adaptor.prototype.getTiddlerRevisionList = function(title, limit, context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	var uriTemplate = "%0/%1/%2/tiddlers/%3/revisions";
	var workspace = adaptor.resolveWorkspace(context.workspace);
	var uri = uriTemplate.format([context.host, workspace.type + "s",
		adaptor.normalizeTitle(workspace.name), adaptor.normalizeTitle(title)]);
	var req = httpReq("GET", uri, adaptor.getTiddlerRevisionListCallback,
		context, merge({ accept: adaptor.mimeType }, context.headers), null, null, null, null, true);
	return typeof req == "string" ? req : true;
};

adaptor.getTiddlerRevisionListCallback = function(status, context, responseText, uri, xhr) {
	context.status = status;
	context.statusText = xhr.statusText;
	context.httpStatus = xhr.status;
	if(status) {
		context.revisions = [];
		try {
			var tiddlers = $.evalJSON(responseText); //# NB: not actual tiddler instances
		} catch(ex) {
			context.status = false; // XXX: correct?
			context.statusText = exceptionText(ex, adaptor.parsingErrorMessage);
			if(context.callback) {
				context.callback(context, context.userParams);
			}
			return;
		}
		for(var i = 0; i < tiddlers.length; i++) {
			var tiddler = adaptor.toTiddler(tiddlers[i], context.host);
			context.revisions.push(tiddler);
		}
		var sortField = "server.page.revision";
		context.revisions.sort(function(a, b) {
			return a.fields[sortField] < b.fields[sortField] ? 1 :
				(a.fields[sortField] == b.fields[sortField] ? 0 : -1);
		});
	}
	if(context.callback) {
		context.callback(context, context.userParams);
	}
};

// retrieve an individual tiddler revision -- XXX: breaks with standard arguments list -- XXX: convenience function; simply use getTiddler?
adaptor.prototype.getTiddlerRevision = function(title, revision, context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	context.revision = revision;
	return this.getTiddler(title, context, userParams, callback);
};

// retrieve an individual tiddler
//# context is an object with members host and workspace
//# callback is passed the new context and userParams
adaptor.prototype.getTiddler = function(title, context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	context.title = title;
	if(context.revision) {
		var uriTemplate = "%0/%1/%2/tiddlers/%3/revisions/%4";
	} else {
		uriTemplate = "%0/%1/%2/tiddlers/%3";
	}
	if(!context.tiddler) {
		context.tiddler = new Tiddler(title);
	}
	context.tiddler.fields["server.type"] = adaptor.serverType;
	context.tiddler.fields["server.host"] = AdaptorBase.minHostName(context.host);
	context.tiddler.fields["server.workspace"] = context.workspace;
	var workspace = adaptor.resolveWorkspace(context.workspace);
	var uri = uriTemplate.format([context.host, workspace.type + "s",
		adaptor.normalizeTitle(workspace.name), adaptor.normalizeTitle(title),
		context.revision]);
	var req = httpReq("GET", uri, adaptor.getTiddlerCallback, context,
		merge({ accept: adaptor.mimeType }, context.headers), null, null, null, null, true);
	return typeof req == "string" ? req : true;
};

adaptor.getTiddlerCallback = function(status, context, responseText, uri, xhr) {
	context.status = status;
	context.statusText = xhr.statusText;
	context.httpStatus = xhr.status;
	if(status) {
		try {
			var tid = $.evalJSON(responseText);
		} catch(ex) {
			context.status = false;
			context.statusText = exceptionText(ex, adaptor.parsingErrorMessage);
			if(context.callback) {
				context.callback(context, context.userParams);
			}
			return;
		}
		var tiddler = adaptor.toTiddler(tid, context.host);
		tiddler.title = context.tiddler.title;
		tiddler.fields["server.etag"] = xhr.getResponseHeader("Etag");
		// normally we'd assign context.tiddler = tiddler here - but we can't do
		// that because of IE, which triggers getTiddler in putTiddlerCallback,
		// and since ServerSideSavingPlugin foolishly relies on persistent
		// object references, we need to merge the data into the existing object
		$.extend(context.tiddler, tiddler);
	}
	if(context.callback) {
		context.callback(context, context.userParams);
	}
};

// retrieve tiddler chronicle (all revisions)
adaptor.prototype.getTiddlerChronicle = function(title, context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	context.title = title;
	var uriTemplate = "%0/%1/%2/tiddlers/%3/revisions?fat=1";
	var workspace = adaptor.resolveWorkspace(context.workspace);
	var uri = uriTemplate.format([context.host, workspace.type + "s",
		adaptor.normalizeTitle(workspace.name), adaptor.normalizeTitle(title)]);
	var req = httpReq("GET", uri, adaptor.getTiddlerChronicleCallback,
		context, { accept: adaptor.mimeType }, null, null, null, null, true);
	return typeof req == "string" ? req : true;
};

adaptor.getTiddlerChronicleCallback = function(status, context, responseText, uri, xhr) {
	context.status = status;
	context.statusText = xhr.statusText;
	context.httpStatus = xhr.status;
	if(status) {
		context.responseText = responseText;
	}
	if(context.callback) {
		context.callback(context, context.userParams);
	}
};

// store an individual tiddler
adaptor.prototype.putTiddler = function(tiddler, context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	context.title = tiddler.title;
	context.tiddler = tiddler;
	context.host = context.host || this.fullHostName(tiddler.fields["server.host"]);
	var uriTemplate = "%0/%1/%2/tiddlers/%3";
	try {
		context.workspace = context.workspace || tiddler.fields["server.workspace"];
		var workspace = adaptor.resolveWorkspace(context.workspace);
	} catch(ex) {
		return adaptor.locationIDErrorMessage;
	}
	var uri = uriTemplate.format([context.host, workspace.type + "s",
		adaptor.normalizeTitle(workspace.name),
		adaptor.normalizeTitle(tiddler.title)]);
	var etag = adaptor.generateETag(workspace, tiddler);
	var headers = etag ? { "If-Match": etag } : null;
	var payload = {
		type: tiddler.fields["server.content-type"] || null,
		text: tiddler.text,
		tags: tiddler.tags,
		fields: $.extend({}, tiddler.fields)
	};
	delete payload.fields.changecount;
	$.each(payload.fields, function(key, value) {
		if(key.indexOf("server.") == 0) {
			delete payload.fields[key];
		}
	});
	payload = $.toJSON(payload);
	var req = httpReq("PUT", uri, adaptor.putTiddlerCallback,
		context, headers, payload, adaptor.mimeType, null, null, true);
	return typeof req == "string" ? req : true;
};

adaptor.putTiddlerCallback = function(status, context, responseText, uri, xhr) {
	context.status = [204, 1223].contains(xhr.status);
	context.statusText = xhr.statusText;
	context.httpStatus = xhr.status;
	if(context.status) {
		var loc = xhr.getResponseHeader("Location");
		var etag = xhr.getResponseHeader("Etag");
		if(loc && etag) {
			var bag = loc.split("/bags/").pop().split("/")[0];
			context.tiddler.fields["server.bag"] = bag;
			context.tiddler.fields["server.workspace"] = "bags/" + bag;
			var rev = etag.split("/").pop().split(/;|:/)[0];
			context.tiddler.fields["server.page.revision"] = rev;
			context.tiddler.fields["server.etag"] = etag;
			if(context.callback) {
				context.callback(context, context.userParams);
			}
		} else { // IE
			context.adaptor.getTiddler(context.tiddler.title, context,
				context.userParams, context.callback);
		}
	} else if(context.callback) {
		context.callback(context, context.userParams);
	}
};

// store a tiddler chronicle
adaptor.prototype.putTiddlerChronicle = function(revisions, context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	context.title = revisions[0].title;
	var headers = null;
	var uriTemplate = "%0/%1/%2/tiddlers/%3/revisions";
	var host = context.host || this.fullHostName(tiddler.fields["server.host"]);
	var workspace = adaptor.resolveWorkspace(context.workspace);
	var uri = uriTemplate.format([host, workspace.type + "s",
		adaptor.normalizeTitle(workspace.name),
		adaptor.normalizeTitle(context.title)]);
	if(workspace.type == "bag") { // generate ETag
		var etag = [adaptor.normalizeTitle(workspace.name),
			adaptor.normalizeTitle(context.title), 0].join("/"); //# zero-revision prevents overwriting existing contents
		headers = { "If-Match": '"' + etag + '"' };
	}
	var payload = $.toJSON(revisions);
	var req = httpReq("POST", uri, adaptor.putTiddlerChronicleCallback,
		context, headers, payload, adaptor.mimeType, null, null, true);
	return typeof req == "string" ? req : true;
};

adaptor.putTiddlerChronicleCallback = function(status, context, responseText, uri, xhr) {
	context.status = [204, 1223].contains(xhr.status);
	context.statusText = xhr.statusText;
	context.httpStatus = xhr.status;
	if(context.callback) {
		context.callback(context, context.userParams);
	}
};

// store a collection of tiddlers (import TiddlyWiki HTML store)
adaptor.prototype.putTiddlerStore = function(store, context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	var uriTemplate = "%0/%1/%2/tiddlers";
	var host = context.host;
	var workspace = adaptor.resolveWorkspace(context.workspace);
	var uri = uriTemplate.format([host, workspace.type + "s",
		adaptor.normalizeTitle(workspace.name)]);
	var req = httpReq("POST", uri, adaptor.putTiddlerStoreCallback,
		context, null, store, "text/x-tiddlywiki", null, null, true);
	return typeof req == "string" ? req : true;
};

adaptor.putTiddlerStoreCallback = function(status, context, responseText, uri, xhr) {
	context.status = [204, 1223].contains(xhr.status);
	context.statusText = xhr.statusText;
	context.httpStatus = xhr.status;
	if(context.callback) {
		context.callback(context, context.userParams);
	}
};

// rename an individual tiddler or move it to a different workspace -- TODO: make {from|to}.title optional
//# from and to are objects with members title and workspace (bag; optional),
//# representing source and target tiddler, respectively
adaptor.prototype.moveTiddler = function(from, to, context, userParams, callback) { // XXX: rename parameters (old/new)?
	var self = this;
	var newTiddler = store.getTiddler(from.title) || store.getTiddler(to.title); //# local rename might already have occurred
	var oldTiddler = $.extend(true, {}, newTiddler); //# required for eventual deletion
	oldTiddler.title = from.title; //# required for original tiddler's ETag
	var _getTiddlerChronicle = function(title, context, userParams, callback) {
		return self.getTiddlerChronicle(title, context, userParams, callback);
	};
	var _putTiddlerChronicle = function(context, userParams) {
		if(!context.status) {
			return callback(context, userParams);
		}
		var revisions = $.evalJSON(context.responseText); // XXX: error handling?
		// change current title while retaining previous location
		for(var i = 0; i < revisions.length; i++) {
			delete revisions[i].revision;
			if(!revisions[i].fields.origin) { // NB: origin = "<workspace>/<title>"
				revisions[i].fields.origin = ["bags", revisions[i].bag, revisions[i].title].join("/");
			}
			revisions[i].title = to.title;
		}
		// add new revision
		var rev = $.extend({}, revisions[0]);
		$.each(newTiddler, function(i, item) {
			if(!$.isFunction(item)) {
				rev[i] = item;
			}
		});
		rev.title = to.title;
		rev.created = rev.created.convertToYYYYMMDDHHMM();
		rev.modified = new Date().convertToYYYYMMDDHHMM();
		delete rev.fields.changecount;
		revisions.unshift(rev);
		if(to.workspace) {
			context.workspace = to.workspace;
		} else if(context.workspace.substring(0, 4) != "bags") { // NB: target workspace must be a bag
			context.workspace = "bags/" + rev.bag;
		}
		var subCallback = function(context, userParams) {
			if(!context.status) {
				return callback(context, userParams);
			}
			context.adaptor.getTiddler(newTiddler.title, context, userParams, _deleteTiddler);
		};
		return self.putTiddlerChronicle(revisions, context, context.userParams, subCallback);
	};
	var _deleteTiddler = function(context, userParams) {
		if(!context.status) {
			return callback(context, userParams);
		}
		$.extend(true, newTiddler, context.tiddler);
		context.callback = null;
		return self.deleteTiddler(oldTiddler, context, context.userParams, callback);
	};
	callback = callback || function() {};
	context = this.setContext(context, userParams);
	context.host = context.host || oldTiddler.fields["server.host"];
	context.workspace = from.workspace || oldTiddler.fields["server.workspace"];
	return _getTiddlerChronicle(from.title, context, userParams, _putTiddlerChronicle);
};

// delete an individual tiddler
adaptor.prototype.deleteTiddler = function(tiddler, context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	context.title = tiddler.title; // XXX: not required!?
	var uriTemplate = "%0/bags/%1/tiddlers/%2";
	var host = context.host || this.fullHostName(tiddler.fields["server.host"]);
	var bag = tiddler.fields["server.bag"];
	if(!bag) {
		return adaptor.noBagErrorMessage;
	}
	var uri = uriTemplate.format([host, adaptor.normalizeTitle(bag),
		adaptor.normalizeTitle(tiddler.title)]);
	var etag = adaptor.generateETag({ type: "bag", name: bag }, tiddler);
	var headers = etag ? { "If-Match": etag } : null;
	var req = httpReq("DELETE", uri, adaptor.deleteTiddlerCallback, context, headers,
		null, null, null, null, true);
	return typeof req == "string" ? req : true;
};

adaptor.deleteTiddlerCallback = function(status, context, responseText, uri, xhr) {
	context.status = [204, 1223].contains(xhr.status);
	context.statusText = xhr.statusText;
	context.httpStatus = xhr.status;
	if(context.callback) {
		context.callback(context, context.userParams);
	}
};

// compare two revisions of a tiddler (requires TiddlyWeb differ plugin)
//# if context.rev1 is not specified, the latest revision will be used for comparison
//# if context.rev2 is not specified, the local revision will be sent for comparison
//# context.format is a string as determined by the TiddlyWeb differ plugin
adaptor.prototype.getTiddlerDiff = function(title, context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	context.title = title;

	var tiddler = store.getTiddler(title);
	try {
		var workspace = adaptor.resolveWorkspace(tiddler.fields["server.workspace"]);
	} catch(ex) {
		return adaptor.locationIDErrorMessage;
	}
	var tiddlerRef = [workspace.type + "s", workspace.name, tiddler.title].join("/");

	var rev1 = context.rev1 ? [tiddlerRef, context.rev1].join("/") : tiddlerRef;
	var rev2 = context.rev2 ? [tiddlerRef, context.rev2].join("/") : null;

	var uriTemplate = "%0/diff?rev1=%1";
	if(rev2) {
		uriTemplate += "&rev2=%2";
	}
	if(context.format) {
		uriTemplate += "&format=%3";
	}
	var host = context.host || this.fullHostName(tiddler.fields["server.host"]);
	var uri = uriTemplate.format([host, adaptor.normalizeTitle(rev1),
		adaptor.normalizeTitle(rev2), context.format]);

	if(rev2) {
		var req = httpReq("GET", uri, adaptor.getTiddlerDiffCallback, context, null,
			null, null, null, null, true);
	} else {
		var payload = {
			title: tiddler.title,
			text: tiddler.text,
			modifier: tiddler.modifier,
			tags: tiddler.tags,
			fields: $.extend({}, tiddler.fields)
		}; // XXX: missing attributes!?
		payload = $.toJSON(payload);
		req = httpReq("POST", uri, adaptor.getTiddlerDiffCallback, context,
			null, payload, adaptor.mimeType, null, null, true);
	}
	return typeof req == "string" ? req : true;
};

adaptor.getTiddlerDiffCallback = function(status, context, responseText, uri, xhr) {
	context.status = status;
	context.statusText = xhr.statusText;
	context.httpStatus = xhr.status;
	context.uri = uri;
	if(status) {
		context.diff = responseText;
	}
	if(context.callback) {
		context.callback(context, context.userParams);
	}
};

// generate tiddler information
adaptor.prototype.generateTiddlerInfo = function(tiddler) {
	var info = {};
	var uriTemplate = "%0/%1/%2/tiddlers/%3";
	var host = this.host || tiddler.fields["server.host"]; // XXX: this.host obsolete?
	host = this.fullHostName(host);
	var workspace = adaptor.resolveWorkspace(tiddler.fields["server.workspace"]);
	info.uri = uriTemplate.format([host, workspace.type + "s",
		adaptor.normalizeTitle(workspace.name),
		adaptor.normalizeTitle(tiddler.title)]);
	return info;
};

// create Tiddler instance from TiddlyWeb tiddler JSON
adaptor.toTiddler = function(json, host) {
	var created = Date.convertFromYYYYMMDDHHMM(json.created);
	var modified = Date.convertFromYYYYMMDDHHMM(json.modified);
	var fields = json.fields;
	fields["server.type"] = adaptor.serverType;
	fields["server.host"] = AdaptorBase.minHostName(host);
	fields["server.bag"] = json.bag;
	fields["server.title"] = json.title;
	if(json.recipe) {
		fields["server.recipe"] = json.recipe;
	}
	if(json.type && json.type != "None") {
		fields["server.content-type"] = json.type;
	}
	fields["server.permissions"] = json.permissions.join(", ");
	fields["server.page.revision"] = json.revision;
	fields["server.workspace"] = "bags/" + json.bag;
	var tiddler = new Tiddler(json.title);
	tiddler.assign(tiddler.title, json.text, json.modifier, modified, json.tags,
		created, json.fields, json.creator);
	return tiddler;
};

adaptor.resolveWorkspace = function(workspace) {
	var components = workspace.split("/");
	return {
		type: components[0] == "bags" ? "bag" : "recipe",
		name: components[1] || components[0]
	};
};

adaptor.generateETag = function(workspace, tiddler) {
	var revision = tiddler.fields["server.page.revision"];
	var etag = revision == "false" ? null : tiddler.fields["server.etag"];
	if(!etag && workspace.type == "bag") {
		if(typeof revision == "undefined") {
			revision = "0";
		} else if(revision == "false") {
			return null;
		}
		etag = [adaptor.normalizeTitle(workspace.name),
			adaptor.normalizeTitle(tiddler.title), revision].join("/");
		etag = '"' + etag + '"';
	}
	return etag;
};

adaptor.normalizeTitle = function(title) {
	return encodeURIComponent(title);
};

})(jQuery);


/*
 * jQuery JSON Plugin
 * version: 1.3
 * source: http://code.google.com/p/jquery-json/
 * license: MIT (http://www.opensource.org/licenses/mit-license.php)
 */
(function($){function toIntegersAtLease(n)
{return n<10?'0'+n:n;}
Date.prototype.toJSON=function(date)
{return this.getUTCFullYear()+'-'+
toIntegersAtLease(this.getUTCMonth())+'-'+
toIntegersAtLease(this.getUTCDate());};var escapeable=/["\\\x00-\x1f\x7f-\x9f]/g;var meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'};$.quoteString=function(string)
{if(escapeable.test(string))
{return'"'+string.replace(escapeable,function(a)
{var c=meta[a];if(typeof c==='string'){return c;}
c=a.charCodeAt();return'\\u00'+Math.floor(c/16).toString(16)+(c%16).toString(16);})+'"';}
return'"'+string+'"';};$.toJSON=function(o,compact)
{var type=typeof(o);if(type=="undefined")
return"undefined";else if(type=="number"||type=="boolean")
return o+"";else if(o===null)
return"null";if(type=="string")
{return $.quoteString(o);}
if(type=="object"&&typeof o.toJSON=="function")
return o.toJSON(compact);if(type!="function"&&typeof(o.length)=="number")
{var ret=[];for(var i=0;i<o.length;i++){ret.push($.toJSON(o[i],compact));}
if(compact)
return"["+ret.join(",")+"]";else
return"["+ret.join(", ")+"]";}
if(type=="function"){throw new TypeError("Unable to convert object of type 'function' to json.");}
var ret=[];for(var k in o){var name;type=typeof(k);if(type=="number")
name='"'+k+'"';else if(type=="string")
name=$.quoteString(k);else
continue;var val=$.toJSON(o[k],compact);if(typeof(val)!="string"){continue;}
if(compact)
ret.push(name+":"+val);else
ret.push(name+": "+val);}
return"{"+ret.join(", ")+"}";};$.compactJSON=function(o)
{return $.toJSON(o,true);};$.evalJSON=function(src)
{return eval("("+src+")");};$.secureEvalJSON=function(src)
{var filtered=src;filtered=filtered.replace(/\\["\\\/bfnrtu]/g,'@');filtered=filtered.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']');filtered=filtered.replace(/(?:^|:|,)(?:\s*\[)+/g,'');if(/^[\],:{}\s]*$/.test(filtered))
return eval("("+src+")");else
throw new SyntaxError("Error parsing JSON, source is not valid.");};})(jQuery);
//}}}
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
/***
|''Name''|SyntaxHighlighterPlugin3|
|''Description''|Enables syntax highlighting|
|''Author''|PMario|
|''Version''|0.3.0|
|''Status''|''beta''|
|''Source''|http://syntaxhighlighter.tiddlyspace.com/#SyntaxHighlighterPlugin3|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''CoreVersion''|2.5.0|
|''Requires''|ShCore.js|
|''Keywords''|syntax highlighting color code|
!Documentation
*see: [[SyntaxHighlighterPlugin3Info]]
!Description
Enables syntax highlighting for <pre> and <code> blocks. Adds a new formatter for {{{<code class='brush:???'>}}} 
!Usage
!!!!StyleSheet
<<<
*add this to your StyleSheet
{{{
[[ShCore.css]]
[[ShThemeDefault.css]]
}}}
<<<
!!!! Macro highlightTiddlerText
<<<
highlightTiddlerText macro is needed, if you have tiddlers, that contain plain source text and you want to transclude them into other tiddlers. Or if you have brushes, that can't use curly braces. 
{{{
<<highlightTiddlerText tiddlerName params>>
eg
<<highlightTiddlerText "##myCode" "js tab-size:4 highlight[2,5]">>
}}}
see: [[SyntaxHighlighterPlugin3Info]] for more
<<<
!!!! Macro highlightSyntax
<<<
*The highlightSyntax macro is only needed if you have inline html blocks. see: [[SyntaxHighlighterPlugin3Info]]
!!!!! ViewTemplate
>*Same as macro, but will be executed automatically for every tiddler. see: [[SyntaxHighlighterPlugin3Info]]
!!!!! Parameters
{{{<<highlightSyntax [tagName]>> }}}
*will render all blocks, with any defined tag name. eg: tagName = code.
*[tagName] is optional. Default is "pre".
<<<
!!!!Configuration options
<<<
Guess syntax: <<option chkGuessSyntax>> .. If activated, ~TiddlyWiky <pre> blocks will be rendered according to there block braces. see [[SyntaxHighlighterPlugin3Info]]
Expert mode: <<option chkExpertSyntax>> .. If activated, additional values below will be used. see [[SyntaxHighlighterPlugin3Info]]

{{{ {{{ }}} txtShText: <<option txtShText>> eg: 'brush:text tab-size:4 + options'
{{{ /*{{{* / }}} txtShCss: <<option txtShCss>> eg: 'brush:css  + options'
{{{ //{{{ }}} txtShPlugin: <<option txtShPlugin>> 'brush:js  + options'
{{{ <!--{{{-->> }}} txtShXml: <<option txtShXml>> 'brush:xml  + options'

Additional options can be found at: [[SyntaxHighlighter homepage|http://alexgorbatchev.com/SyntaxHighlighter/manual/configuration/]]
<<<
!!!!Revision History
<<<
*V 0.3.0 2012-05-07
** highlightTiddlerText macro added
<<<
!!!Code
***/

//{{{
version.extensions.SyntaxHighlighterPlugin3 = {major: 0, minor: 2, revision: 1, date: new Date(2011,8,1)};

(function($) {

if(!window.SyntaxHighlighter) {
	throw "Missing dependency: ShCore.js (check brushes too)";
}

config.macros.highlightSyntax = {
	getElementsByClass: function (searchClass,node,tag) {
		var classElements = [];
        if ( node == null ) node = document;
        if ( tag == null )  tag = '*';
		
		var els = node.getElementsByTagName(tag);
		var elsLen = els.length;
		var pattern = new RegExp("(^|\\s)"+searchClass+"(:|\\s|$)");
		for (i = 0, j = 0; i < elsLen; i++) {
			if ( pattern.test(els[i].className) ) {
				classElements[j] = els[i];
				j++;
			}
		}
		return classElements;
	},
	
	handler: function(place, macroName, params, wikifier, paramString, tiddler) {
		// the configured tagName can be temporarily overwritten by the macro.
		var tagName = params[0] || SyntaxHighlighter.config.tagName;
		var arr = this.getElementsByClass('brush', story.findContainingTiddler(place), tagName);
		for (i=0; i<arr.length; i++) {
			SyntaxHighlighter.highlight(null, arr[i]);
		}			
	} // handler
};

config.macros.highlightTiddlerText = {
	handler: function(place, macroName, params, wikifier, paramString, tiddler) {
		// tiddler, slice or sction name
		var param = params[0];
		var pos = param.indexOf(config.textPrimitives.sliceSeparator);
		if (pos === 0) { param = tiddler.title + param}

		pos = param.indexOf(config.textPrimitives.sectionSeparator)
		if (pos === 0) { param = tiddler.title + param}

		// wikify =(function (source,output,highlightRegExp,tiddler)
		var content = "<code class='brush:%0'>\n%1\n</code>".format(params[1] || "text", store.getTiddlerText(param));
		wikify(content, place);
	} // handler
};
})(jQuery);
//}}}
/***
!!!!!New formatter for {{{<code class='brush:??'>}}}
***/
//{{{
config.formatters.push({
	name: "highlightSyntax",
	match: "^<code[\\s]+[^>]+>\\n",
	element: "pre",
	handler: function(w)
	{
        this.lookaheadRegExp = /<code[\s]+class.*=.*["'](.*)["'].*>\n((?:^[^\n]*\n)+?)(^<\/code>$\n?)/img;
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
            var options = lookaheadMatch[1];
			var text = lookaheadMatch[2];
			if(config.browser.isIE)
				text = text.replace(/\n/g,"\r");
			var element = createTiddlyElement(w.output,this.element,null,options,text);
            SyntaxHighlighter.highlight(null, element);
			w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
		}
	}
});
//}}}
/***
!!!!!Add class attribute to pre, if defined
***/
//{{{
(function(formatters) { //# set up alias
	var helper = {};	
	helper.enclosedTextHelper = function(w){
		var attr;
		var co = config.options;
		var expert = (co.chkExpertSyntax != undefined)? co.chkExpertSyntax : false;
		var guess  = (co.chkGuessSyntax != undefined)? co.chkGuessSyntax : true;
		
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
			var text = lookaheadMatch[1];
			if(config.browser.isIE)
				text = text.replace(/\n/g,"\r");

			switch(w.matchText) {
			case "{{{\n": // text
				attr = (expert) ? (co.txtShText) ? (co.txtShText) : 'brush:text' : 'brush:text' ;
				break;
			case "/*{{{*/\n": // CSS
				attr = (expert) ? (co.txtShCss) ? (co.txtShCss) : 'brush:css' : 'brush:css';
				break;
			case "//{{{\n": // plugin
				attr = (expert) ? (co.txtShPlugin) ? (co.txtShPlugin) : 'brush:js' : 'brush:js';
				break;
			case "<!--{{{-->\n": //template
				attr =  (expert) ? (co.txtShXml) ? (co.txtShXml) : 'brush:xml' : 'brush:xml';
				break;
			}
			var element = createTiddlyElement(w.output,this.element,null,attr,text);		
	        if (guess || expert) SyntaxHighlighter.highlight(null, element);

			w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
		}
	};
	// merge the new helper function into formatterHelpers. 
	merge(config.formatterHelpers, helper);

})(config.formatters); //# end of alias
//}}}
/*{{{*/
.tiddler .originButton div {
	display: inline-block;
}

.tiddler .spaceSiteIcon .siteIcon {
	_display: inline; /* IE doesn't like inline-block */
}

.tiddler .originButton {
	display: block;
}

.selected .tagging,
.selected .tagging:hover {
	border: none;
	background: none;
}

.tagging {
	float: none;
	background: none;
	border: none;
}

.tagging li.listTitle {
	margin-left: 0px;
}
.tagging li {
	margin: 0 8px;
}

.tagging .tiddlyLink {
	-webkit-border-radius: 3px;
	-moz-border-radius: 3px;
	-o-border-radius: 3px;
	border-radius: 3px;
	padding: 1px 2px;
	line-height: 1.2em;
}

/* for following */
#popup .siteIcon {
	float: left;
	height: 25px;
}

.content {
	width: 100%; /* IE */
	font-size: 0.9em;
}

.editorHeading {
	height: 48px;
}

.heading {
	left: 0;
	margin-bottom: 40px;
	position: relative;
	top: 32px;
}

.followButton a {
	display: block;
	margin-top: -20px;
}

.tiddler .followPlaceHolder {
	display: block;
	position: absolute;
	top: 16px;
	right: 64px;
	_right: 138px; // add width of modifierIcon
}

.tiddler .followButton {
	position: relative;
	height: 24px;
	text-align: left;
	color: #fff;
	background: [[ColorPalette::PrimaryMid]];
	padding: 10px 0px 0px 10px;
	width: 38px;
	margin: -16px -8px 24px 0;
}

/* creates the larger triangle */
.followButton:before {
	content: "\00a0";
	display: block; /* reduce the damage in FF3.0 */
	position: relative;
	bottom: -20px;
	right: 0;
	width: 0;
	height: 0;
	border-width: 0 0 20px 20px;
	border-style: solid;
	border-color: transparent [[ColorPalette::PrimaryMid]];
}

.toolbar svg {
	height: 16px;
	width: 16px;
}

.toolbar svg .glyph {
	fill: #ccc;
}

.toolbar a:hover .glyph {
	fill: black;
}

.toolbar a:active .glyph {
	fill: [[ColorPalette::Background]];
}

.originButton,
.followPlaceHolder,
.tiddler .subtitle {
	cursor: pointer;
}

.editSpaceSiteIcon .originButton {
	cursor: auto;
}

.tiddler .subtitle:hover {
	font-weight: bold;
	background: none;
}

.originButton img,
.originButton svg {
	margin-left: 0px;
}

.modifierIcon {
	position: absolute;
	width: 74px;
	top: 0px;
	right: 0px;
	_right: 74px; /* in IE6 positioning works incorrectly so use -width instead */
	text-align: right;
}

.modifierIcon img,
.modifierIcon svg {
	margin-right: 8px;
}

.tiddler .viewer {
	padding-bottom: 16px;
	margin: 0 0 0 56px;
	line-height: 1.4em;
}

.viewer pre {
	margin-left: 0;
}

.siteIcon .label {
	color: [[ColorPalette::TertiaryDark]];
}

.tiddler .spaceSiteIcon {
	float: left;
	margin-right: 0;
	margin-top: 0;
	position: relative;
	display: block;
}

.tiddler .titleBar {
	display: block;
	margin-right: 136px;
	margin-left: 56px;
}

.followButton a {
	color: [[ColorPalette::Background]];
}

.tiddler {
	position: relative;
	padding: 0;
	margin-bottom: 3em;
	border-top: 3px solid [[ColorPalette::PrimaryMid]];
	background: #fff;
}

.tiddler .editor {
	padding: 0px 8px;
}

.tiddler .heading .title {
	position: relative;
	display: block;
	word-wrap: break-word;
	font-size: 32px;
	line-height: 32px;
}
.tiddler .heading .editor.title {
	font-size: 1.7em;
	line-height: normal;
}

.tiddler .headingClear {
	clear: both;
}

.tiddler .subtitle {
	font-style: italic;
	font-size: 0.9em;
	color: #a6a59e;
	margin-top: 0;
}

.toolbar {
	position: absolute;
	padding: 0;
	top: 8px;
	right: -8px;
}

.toolbar .moreCommand.highlight {
	background: none;
}

.tiddler .toolbar .button {
	border: none;
	display: inline;
	padding: 0px;
	margin-right: 16px;
}

.tiddler .toolbar a:hover {
	background: none;
}

.tiddler .tagged .listTitle {
	display: none;
}

.revButton {
	float: right;
}

/*! EditTemplate specific*/
.tiddler .privacySettings {
	text-align: center;
}
.tiddler .privacySettings .originButton {
	display: inline;
}

.editSpaceSiteIcon, .privacyEdit {
	float: left;
}

.editSpaceSiteIcon svg,
.editSpaceSiteIcon img,
.editSpaceSiteIcon .roundelLabel {
	float: left;
}

.tagTitle {
	position: absolute;
	text-align: center;
	width: 48px;
	top: 0px;
	left: -56px;
}

.editSpaceSiteIcon .originButton img,
.editSpaceSiteIcon .originButton svg {
	height: 16px;
	margin-left: 24px;
	margin-right: 32px;
	width: 16px;
}

.tagAnnotation {
	margin-top: 8px;
	padding-bottom: 8px;
}
.annotationsBox {
	margin-top: 8px;
}

.editorFooter {
	position: relative;
	padding: 0;
	margin-top: 16px;
	margin-left: 64px;
}

.tiddler .editorFooter .editor {
	padding-left: 0px;
}

.heading .editor input {
	width: 100%;
	font-size: 1.5em;
}

.spaceSiteIcon .externalImage .image a:hover,
.modifierIcon .externalImage .image a:hover {
	background: none;
}

div.toolbar {
	visibility:hidden;
	right:-16px;
}

.selected div.toolbar {
	visibility: visible;
}

.followButton a:hover {
	background: [[ColorPalette::PrimaryMid]];
	text-decoration: underline;
}

a.image:hover {
	background: transparent;
}

@media all and (max-device-width: 480px) {
	div.toolbar {
		visibility:visible;
	}
}
@media only screen and (device-width: 768px) {
	div.toolbar {
		visibility:visible;
	}
}
@media all and (max-width: 960px) {
	.tiddler .titleBar {
		margin-left: 36px;
		margin-right: 80px;
	}

	.tiddler .heading {
		margin-bottom: 48px;
	}

	.tiddler .heading .title {
		font-size: 32px;
		line-height: 32px;
	}

	.tiddler .modifierIcon img,
	.tiddler .modifierIcon svg,
	.tiddler .spaceSiteIcon .originButton img,
	.originButton svg {
		width: 32px;
		height: 32px;
		margin-left: 0px;
		margin-right: 0px;
	}

	.tiddler .followPlaceHolder {
		right: 48px;
	}

	.tiddler .followButton {
		width: 24px;
	}

	.tiddler .viewer {
		margin: 0px 0px 0px 36px;
		padding-top: 0;
	}

	br {
		line-height: 0.5em;
	}
}
/*}}}*/
ColorPalette
StyleSheet
SiteSubtitle
GettingStarted
SiteTitle
MainMenu
SiteIcon
DefaultTiddlers
ViewTemplate
PageTemplate
SideBarOptions
EditTemplate
SiteInfo
SideBarTabs
ToolbarCommands
A hybrid control architecture has been developed for controlling a differential robot. The task of our robot was to follow another mobile robot (named as leader). 

Our robot (named as persecutor, too) had four sensors of distance and an omni-directional camera. 

{{center{[img[https://lh3.googleusercontent.com/-9BY5I37Yjoo/UM3gjy3SymI/AAAAAAAAAro/tvfsbDF-hRY/s288/hybrid_control_env.png]]  [img[https://lh6.googleusercontent.com/-nI6qrWDUaPo/UM3gj2YtoaI/AAAAAAAAArk/f0Nf6dxIL3Y/s288/hybrid_control_camera.png]]}}}

The 'follow-the-leader' task can be divided into several sub-tasks: exploring the environment, locating the leader, locating obstacles, and moving to the leader.

A low-level and high priority task was added: avoiding collisions. Due to its critical priority, the avoiding collision task was defined as a reactive behaviour, while the other sub-tasks are sequential and non-critical and they are managed by the architecture scheduler. Therefore the control architecture is divided into: reactive behaviours and scheduled sub-tasks.

For avoiding collision the sensor system is used, while for the non-critical sub-tasks such as exploring the environment, locating the leader and locating obstacles, the camera is used as input.

This hybrid architecture control has been developed in C/C++, and tested using [[Virtual Robot Simulator|http://robotica.isa.upv.es/virtualrobot]]
/***
|Name|InlineJavascriptPlugin|
|Source|http://www.TiddlyTools.com/#InlineJavascriptPlugin|
|Documentation|http://www.TiddlyTools.com/#InlineJavascriptPluginInfo|
|Version|1.9.6|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|Insert Javascript executable code directly into your tiddler content.|
''Call directly into TW core utility routines, define new functions, calculate values, add dynamically-generated TiddlyWiki-formatted output'' into tiddler content, or perform any other programmatic actions each time the tiddler is rendered.
!!!!!Documentation
>see [[InlineJavascriptPluginInfo]]
!!!!!Revisions
<<<
2010.12.15 1.9.6 allow (but ignore) type="..." syntax
|please see [[InlineJavascriptPluginInfo]] for additional revision details|
2005.11.08 1.0.0 initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.InlineJavascriptPlugin= {major: 1, minor: 9, revision: 6, date: new Date(2010,12,15)};

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

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

// // GLOBAL FUNCTION: $(...) -- 'shorthand' convenience syntax for document.getElementById()
//{{{
if (typeof($)=='undefined') { function $(id) { return document.getElementById(id.replace(/^#/,'')); } }
//}}}
/***
|''Name''|RenderBufferPlugin|
|''Description''|Transcludes text from a tiddler, specified by line number and number of lines. |
|''Author''|PMario|
|''Version''|0.1.0|
|''Status''|''beta''|
|''Source''|http://codemirror-plugins.tiddlyspace.com/#RenderBuffer.js|
|''License''|[[CC by-nc-sa 3.0|http://creativecommons.org/licenses/by-nc-sa/3.0/]]|
|''CoreVersion''|2.5.0|
|''Keywords''|render wikify buffer tiddler transclusion|

! Documentation
<<<
This plugin, was developed to render parts of a tiddler, for documentation purpose. You can use it to render eg: 10 lines of a tiddler. Or you can search for a special string at the beginning of the line, plus 10 lines from there ... 
<<<

!! Macro Parameters
<<<
{{{
<<renderBuffer 
	text: "multi line plain text"
	tiddler: "tiddlerName"
	start: lineNumber 
	lines: numberOfLines 
	find: "regexp start text"
	next: "regexp stop text" 

	element: "htmlELement"
	class: "className"
	id: "idName"
>>
}}}
* The first 6 parameters are used to define the start end the end of the text to be transcluded.
* The last 4 parameters are optional, to specify special rendering options. 
** eg: syntax highlighting 
** or add special CSS classes
<<<
!!! Definitions
<<<
; text
: If the text parameter is defined, none of the others is needed. See: Usage section
; tiddler
: Name of the tiddler, where the text comes from. If you use {{{ {{tiddler.title}} }}} it is possible to create a "too much recursion" error. So take care!
; start
: Line Number .. if you exactly know the line number. The first line number is 1. Most of the times "find" will be the better option, if "source" tiddlers are modified.
; lines
: Number of lines, that should be transcluded.
; find
: A "search text" can be used as a start parameter. 
: If find is used, "start" line number is not needed.
: ''important:'' the "search text" is ''not case sensitive'' and ''is hardcoded to start at the beginning of the line''. 
; next
: The next parameter is a "search string" or a header definition. If used, "lines" is not needed. The "start" and "next" parameters are regExp's. So the function is very powerfull but it can be tricky to define them. See: Usage section for "simple" examples. One of the best sites about regular expressions, I know is: http://www.regular-expressions.info (All my regexp knowledge comes from there :)
; element
: The HTML element, that should be created. Default is a {{{<span>}}}. {{{code}}} needs to be used, if you need syntax highlighting. 
; class
: Can be used to specify a special CSS class, or a definition for the syntax highlighter.
; id
: HTML ID property. No needed at the moment. 
<<<
!!! Usage
<<<
''Just render the text''
{{{
<<renderBuffer text:'!!!! heading
Some multi line text'>>
}}}
renders as:
><<renderBuffer text:'!!!! heading
Some multi line text'>>
----
''The first section of this tiddler''
{{{
<<renderBuffer tiddler:RenderBufferPlugin find:'!' next:'!+'>>
}}}
renders as: 
><<renderBuffer tiddler:RenderBufferPlugin find:'!' next:'!+'>>
----
''The Usage section of this tiddler, limited to 7 lines''
{{{
<<renderBuffer tiddler:RenderBufferPlugin find:'!+ usage' lines:7>>
}}}
renders as: 
><<renderBuffer tiddler:RenderBufferPlugin find:'!+ usage' lines:7>>
----
A naive approach can be seen in the first example below. The problem there is, it is more likely to break. Since it uses the exact text. So if the text is changed, it may break. The search text is //not// case sensitive.
{{{
<<renderBuffer tiddler:RenderBufferPlugin find:'! doc' next:'!! all'>>
}}}
''better version''
{{{
<<renderBuffer tiddler:RenderBufferPlugin find:'! doc' next:'!+'>>
}}}
renders as: 
><<renderBuffer tiddler:RenderBufferPlugin find:'! doc' next:'!+'>>
----
''4 lines of the code from this tiddler''
{{{
<<renderBuffer tiddler:RenderBufferPlugin find:"version" lines:4 element:code class:"javascript">>
}}}
renders as:
><<renderBuffer tiddler:RenderBufferPlugin find:"version" lines:4 element:code class:"javascript">>
----
''or'' if we want to search for the "header" function we need to specify white space in front, since it doesn't start at the beginning of the line. 
{{{
<<renderBuffer tiddler:RenderBufferPlugin find:"[\t]+handler" lines:4 element:code class:"javascript">>
}}}
renders as:
><<renderBuffer tiddler:RenderBufferPlugin find:"[ \t]+handler" lines:4 element:code class:"javascript">>
----
''or'' more advanced. We want to see the "defaults" object.
{{{
<<<renderBuffer tiddler:RenderBufferPlugin find:"[ \t]+defaults" next:"[ \t]+handler" element:code class:"javascript">>
}}}
renders as:
><<renderBuffer tiddler:RenderBufferPlugin find:"[ \t]+defaults" next:"[ \t]+handler" element:code class:"javascript">>
----
If this gets to complicated, you can use some "comment markers" for start and next. As you can see, the "start" marker will be rendered, but the "end" marker will be skipped. This is by intention! See the "real" code below.
{{{
<<renderBuffer tiddler:RenderBufferPlugin find:"//start" next:"//end" element:code class:"javascript">>
}}}
renders as:
><<renderBuffer tiddler:RenderBufferPlugin find:"//start" next:"//end" element:code class:"javascript">>

<<<
!!! History
<<<
* V 0.1.0 - 2014.03.12
** beta release
** much more docs and examples.
** add possibility to specify a "code" element for syntax highlighting.

* V 0.0.1 - 2012.02.14
** alpha release
<<<
!!! Code
***/
//{{{

version.extensions.RenderBufferPlugin = {
	major: 0,
	minor: 1,
	revision: 0,
	date: new Date(2012, 2, 14)
};

(function ($) {
	var me;

	config.macros.renderBuffer = me = {
		// should be done for easy localisation
		locale: {
			txtBtnTooltip: "Just for testing at the moment!"
		},
		
		// converts the named params into keys of an object. 
		// Be aware, that parmName:true will be a text "true" variable, not a boolean !!
		// See: https://developer.mozilla.org/en/JavaScript/Guide/Working_with_Objects
		paramsToObject: function (conf, names, params, initValue) {			
			var tmp; 
			for (var i=0, im = names.length; i<im; i += 1) {
				tmp = getParam( params, names[i], initValue);
				
				// the conf.xx variable will only be set if a parameter or "initValue" is defined;
				// For my examples. I don t use initValue!!
				if (tmp) {
					conf[names[i]] = tmp;
				} 
			} // for
		},

		// Set some default values
		defaults: {
			start: 0,
			lines: 5,
			element: 'span',
			class: 'cmBuffer',
			id: ''
		},

		handler: function (place, macroName, params, wikifier, paramString, tiddler) {
			params = paramString.parseParams(null, null, true);
			// console.log('params', params);
			var btn;				// will be the button element.
			var txtTooltip;			// button tooltip is a helper variable to make the code more readable
			var conf = {};			// contains the named params, to work with.

			// these are optional params which are used by your plugin.
			// no 'place' param is allowed, it will be overwritten.
			var names = ['text', 'tiddler', 'start', 'lines', 'find', 'next', 'element', 'class', 'id'];

			// define the default values, if needed. See: http://api.jquery.com/jQuery.extend/
			$.extend(conf, me.defaults);
	
			// next function converts names into object keys.
			// can be: me.paramsToObject(conf, names, params, initValue); 
			// BUT initValue will overwrite me.defaults! code line above
			me.paramsToObject(conf, names, params);

			conf.place = place;        // place will be needed to find the containing element.
			
			// ============================================================================
			// from here on, you can work with your "conf" object, that contains the params.
	 		// console.log('conf: ', conf);

			// start default line = 1 ==> index 0
			conf.start = (conf.start > 0) ? parseInt(conf.start,10)-1 : 0; 
			conf.lines = parseInt(conf.lines,10);
			conf.tiddler = (conf.tiddler) ? conf.tiddler : null;
			
			// Special handling for code elements used with syntax highlighting.
			if (conf.element == "code") {
				conf.output = createTiddlyElement(place, "span");
			} else {
				conf.output = createTiddlyElement(place, conf.element, conf.id, conf.class);
			}

			$(conf.output).data('conf', conf).attr({"refresh":'macro', "macroname": macroName});

			if (!conf.button) me.refresh(conf.output);
		}, // handler

		refresh: function (el) {
			var tmp
				, iMax
				, regStart, regNext
				, conf = $(el).data('conf');
						
			// if tiddler is specified, text will not be used
			conf.text = (conf.tiddler) ? store.getTiddlerText(conf.tiddler) : conf.text;

			tmp = conf.text.split('\n');
			iMax = (tmp.length >= conf.lines) ? conf.lines : tmp.length;
			// console.log('tmp: ', tmp, conf.text);
			
			if (conf.find) {
				// TODO may be remove special handling and move this to documentation
				// <<renderBuffer find:"!(?=[^!])" should do it as well. Is difficult for users :(
				if (conf.find      === '!')      regStart = new RegExp('^!(?=[^!])', 'im')
				else if (conf.find === '!!')     regStart = new RegExp('^!!(?=[^!])', 'im')
				else if (conf.find === '!!!')    regStart = new RegExp('^!!!(?=[^!])', 'im')
				else if (conf.find === '!!!!')   regStart = new RegExp('^!!!!(?=[^!])', 'im')
				else if (conf.find === '!!!!!')  regStart = new RegExp('^!!!!!(?=[^!])', 'im')
				else if (conf.find === '!!!!!!') regStart = new RegExp('^!!!!!!', 'im')
				else regStart = new RegExp('^' + conf.find, 'im'); 

				if (conf.next      === '!')      regNext = new RegExp('^!(?=[^!])', 'im')
				else if (conf.next === '!!')     regNext = new RegExp('^!!(?=[^!])', 'im')
				else if (conf.next === '!!!')    regNext = new RegExp('^!!!(?=[^!])', 'im')
				else if (conf.next === '!!!!')   regNext = new RegExp('^!!!!(?=[^!])', 'im')
				else if (conf.next === '!!!!!')  regNext = new RegExp('^!!!!!(?=[^!])', 'im')
				else if (conf.next === '!!!!!!') regNext = new RegExp('^!!!!!!', 'im')
				else regNext  = new RegExp('^' + conf.next, 'im');

				iMax = tmp.length;
				for (i=0, iMax=tmp.length; i < iMax; i++ ) {
					match = tmp[i].match(regStart);
					if (match != null) {
						conf.start = i;
						// set iMax to conf.lines. It will be recalculated if conf.next exists
						iMax = conf.lines;// iMax - i;
						i += 1;
						break;
					}
				} // for

//start ... don't remove these comments. They are needed for the docs :)
				if (conf.next) {
					for (iMax=tmp.length; i < iMax; i++ ) {
						match = tmp[i].match(regNext);
						if (match != null) {
							iMax = i-conf.start;
							break;
						}
					}
				} // if 
//end ... don't remove
			} // if (conf.find)

			conf.text = tmp.slice(conf.start, conf.start+iMax).join('\n');

			if (conf.element == "code") {
				conf.text = "<code class='brush:%0'>\n%1\n</code>".format(conf.class || "text", conf.text);
			}
			
			$(conf.output).empty();
			wikify(conf.text, conf.output);
		}
	}; // end plugin
})(jQuery);

//}}}
These are projects, professional and personal, in which I has been involved:
<<forEachTiddler
      where 'tiddler.tags.contains("%project") && 
                  ! tiddler.tags.contains("#todo")'
      sortBy 'tiddler.title'
      write "'* [['+tiddler.title+'|'+tiddler.title+']]\n'">>
The title and subtitle of your space are visible to visitors and are also displayed in your browser's tabs. Click on the SiteTitle and SiteSubtitle tiddler links below to make changes.
* [[SiteTitle]]
* [[SiteSubtitle]]
The cell of production is composed by an arm-robot, a camera placed in the arm of the robot, two conveyor belts and a computer. The computer manages all the processes in the cell and it orders the robot to take tiles that are coming on one of the conveyor belts. To be able to take them, they must have been located previously and this is the first task of the vision system.

{{center {[img[https://lh5.googleusercontent.com/-RCPmBYRVuAA/T7jVTx9NH5I/AAAAAAAAApY/89VxNimpUzk/s800/Trencadis_RoboticCell.png]][img[https://lh6.googleusercontent.com/-iUfnC_hu6RY/T7jVTvoDAeI/AAAAAAAAApc/BecUwchfcZk/s800/Trencadis_Mosaic.png]]}}}

When the tiles are located and taken by the robot the vision system has to recognize the shape of the tiles, and finally the robot puts the recognized tiles on the other conveyor belt.

This project was developed by the [[Robotics Group|http://robotica.ai2.upv.es]] of the Polytechnic University of Valencia (Spain) for [[Trencadis Innovación SL|http://www.trencadis.es/]].

{{center{<<player id=1 flash https://www.youtube.com/v/TgJDt92qamk 400 300>>}}}

dgerod's notes about Robotics and more
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div>Written: <span macro="edit written"></span></div>
<div macro='annotations'></div>
<div class='editor' macro='edit text'></div>
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser excludeLists'></span></div>
<!--}}}-->
[[Welcome]]
<!--{{{-->
<div macro='slideRevision'></div>
<div class='heading'>
	<span class="titleBar">
		<div class='title' macro='view title text'></div>
	</span>
	<span class='modifierIcon'
		macro='view modifier SiteIcon label:no height:48 width:48 preserveAspectRatio:yes'>
	</span>
	<div class='toolbar'
		macro='toolbar [[ToolbarCommands::RevisionToolbar]] icons:yes height:48 width:48 more:popup'>
	</div>
	<div class='tagClear'></div>
</div>
<div class='content'>
	<div class='viewer' macro='view text wikified'></div>
</div>
<div class='tagInfo'>
	<div class='tidTags' macro='tags'></div>
	<div class='tagging' macro='tagging'></div>
</div>
<!--}}}-->
[[MochaStyleSheetMain]]
[[MochaStyleSheetColors]]
[[MochaStyleSheetTiddlerText]]
<<tiddler Documentation>>
//{{{
/**
 * SyntaxHighlighter
 * http://alexgorbatchev.com/SyntaxHighlighter
 *
 * SyntaxHighlighter is donationware. If you are using it, please donate.
 * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
 *
 * @version
 * 3.0.83 (July 02 2010)
 * 
 * @copyright
 * Copyright (C) 2004-2010 Alex Gorbatchev.
 *
 * @license
 * Dual licensed under the MIT and GPL licenses.
 */
;(function()
{
	// CommonJS
	typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null;

	function Brush()
	{
	};

	Brush.prototype	= new SyntaxHighlighter.Highlighter();
	Brush.aliases	= ['text', 'plain'];

	SyntaxHighlighter.brushes.Plain = Brush;

	// CommonJS
	typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
})();
//}}}
! Software
!!!Scientific Applications 
* [[Maxima CAS|http://maxima.sourceforge.net]], a computer algebra system.
* [[Scilab|http://www.scilab.org]], a scientific software package for numerical computations providing a powerful open computing environment for engineering and scientific applications.
!!!CAD 
* [[QCAD|http://www.qcad.org/]] is an application for computer aided drafting in 2D, you can create technical drawings such as plans for buildings, interiors, mechanical parts or schemas and diagrams. There is a free version named as Community Edition and you can find it compiled for Windows OS [[here|http://qcadbin-win.sourceforge.net]].
!!!Utilities
* [[Console Calculator|http://ccalc.shanebweb.com]], a fast and powerful command-line calculator for Windows/Mac OS X.
* [[Embedded TEX|http://www.sunlightd.com/EmbeddedTeX]], adds LaTeX and more to Microsoft Word and other Office programs.
/***
|''Name''|TiddlySpacePublishingCommands|
|''Version''|0.8.5|
|''Status''|@@beta@@|
|''Description''|toolbar commands for drafting and publishing|
|''Author''|Jon Robson|
|''Source''|http://github.com/TiddlySpace/tiddlyspace/raw/master/src/plugins/TiddlySpacePublishingCommands.js|
|''CoreVersion''|2.6.1|
|''Requires''|TiddlySpaceConfig TiddlySpaceFilters|
!Usage
Provides changeToPrivate, changeToPublic and saveDraft commands
Provides TiddlySpacePublisher macro.
{{{<<TiddlySpacePublisher type:private>>}}} make lots of private tiddlers public.
{{{<<TiddlySpacePublisher type:public>>}}} make lots of public tiddlers public.
!TODO
* add public argument?
!Code
***/
//{{{
(function($) {

var tiddlyspace = config.extensions.tiddlyspace;
var originMacro = config.macros.tiddlerOrigin;

tiddlyspace.getTiddlerStatusType = function(tiddler) {
	var isShadow = store.isShadowTiddler(tiddler.title);
	var exists = store.tiddlerExists(tiddler.title);
	if(isShadow && !exists) {
		return "shadow";
	} else if(!exists) {
		return "missing";
	} else {
		var types = ["private", "public"];
		var type = "external";
		for(var i = 0; i < types.length; i++) {
			var t = types[i];
			type = config.filterHelpers.is[t](tiddler) ? t : type;
		}
		if(config.filterHelpers.is.unsynced(tiddler)) {
			type = type == "private" ? "unsyncedPrivate" : "unsyncedPublic";
		}
		return type;
	}
};

var cmd = config.commands.publishTiddler = {
	text: "make public",
	tooltip: "Change this private tiddler into a public tiddler",
	errorMsg: "Error publishing %0: %1",

	isEnabled: function(tiddler) {
		return !readOnly && config.filterHelpers.is["private"](tiddler);
	},
	handler: function(ev, src, title) {
		var tiddler = store.getTiddler(title);
		if(tiddler) {
			var newBag = cmd.toggleBag(tiddler.fields["server.bag"]);
			this.moveTiddler(tiddler, {
				title: tiddler.fields["publish.name"] || tiddler.title,
				fields: { "server.bag": newBag }
			});
		}
	},
	toggleBag: function(bag, to) {
		var newBag;
		if(typeof bag != typeof "") {
			var tiddler = bag;
			bag = tiddler.fields["server.bag"];
		}
		if(bag.indexOf("_private") > -1) { // should make use of endsWith
			to = to ? to : "public";
			newBag = bag.replace("_private", "_" + to);
		} else {
			to = to ? to : "private";
			newBag = bag.replace("_public", "_" + to);
		}
		return newBag;
	},
	copyTiddler: function(title, newTitle, newBag, callback) {
		var original = store.getTiddler(title);
		newTitle = newTitle ? newTitle : title;
		var adaptor = original.getAdaptor();
		var publish = function(original, callback) {
			var tiddler = $.extend(new Tiddler(newTitle), original);
			tiddler.fields = $.extend({}, original.fields, {
				"server.bag": newBag,
				"server.workspace": "bags/%0".format(newBag),
				"server.page.revision": "false"
			});
			delete tiddler.fields["server.title"];
			tiddler.title = newTitle;
			adaptor.putTiddler(tiddler, null, null, callback);
		};
		publish(original, callback);
	},
	moveTiddler: function(tiddler, newTiddler, callback) {
			var info = {
			copyContext: {},
			deleteContext: {}
		};
		var _dirty = store.isDirty();
		var adaptor = tiddler.getAdaptor();
		var newTitle = newTiddler.title;
		var oldTitle = tiddler.title;
		delete tiddler.fields["server.workspace"];
		var oldBag = tiddler.fields["server.bag"];
		var newBag = newTiddler.fields["server.bag"];
		var newWorkspace = "bags/%0".format(newBag);
		cmd.copyTiddler(oldTitle, newTitle, newBag, function(ctx) {
				info.copyContext = ctx;
				var context = {
					tiddler: tiddler,
					workspace: newWorkspace
				};
				store.addTiddler(ctx.tiddler);
				tiddler.title = oldTitle; // for cases where a rename occurs
				if(ctx.status) { // only do if a success
					if(oldBag != newBag) {
						adaptor.deleteTiddler(tiddler, context, {}, function(ctx) {
							info.deleteContext = ctx;
							var el;
							if(tiddler) {
								tiddler.fields["server.workspace"] = newWorkspace;
								tiddler.fields["server.bag"] = newBag;
							}
							el = el ? el : story.refreshTiddler(oldTitle, null, true);
							if(oldTitle != newTitle) {
								store.deleteTiddler(oldTitle);
								store.notify(oldTitle, true);
							}
							if(el) {
								story.displayTiddler(el, newTitle);
							}
							if(oldTitle != newTitle) {
								story.closeTiddler(oldTitle);
							}
							if(callback) {
								callback(info);
							}
							store.setDirty(_dirty);
						});
					} else {
						if(callback) {
							callback(info);
						}
					}
					refreshDisplay();
				}
		});
	}
};

var changeToPrivate = config.commands.changeToPrivate = {
	text: "make private",
	tooltip: "turn this public tiddler into a private tiddler",
	isEnabled: function(tiddler) {
		return !readOnly && config.filterHelpers.is["public"](tiddler);
	},
	handler: function(event, src, title) {
		var tiddler = store.getTiddler(title);
		var newBag = cmd.toggleBag(tiddler, "private");
		var newTiddler = { title: title, fields: { "server.bag": newBag }};
		cmd.moveTiddler(tiddler, newTiddler);
	}
};
config.commands.changeToPublic = cmd;

/* Save as draft command */
var saveDraftCmd = config.commands.saveDraft = {
	text: "save draft",
	tooltip: "Save as a private draft",
	isEnabled: function(tiddler) {
		return changeToPrivate.isEnabled(tiddler);
	},
	getDraftTitle: function(title) {
		var draftTitle;
		var draftNum = "";
		while(!draftTitle) {
			var suggestedTitle = "%0 [draft%1]".format(title, draftNum);
			if(store.getTiddler(suggestedTitle)) {
				draftNum = !draftNum ? 2 : draftNum + 1;
			} else {
				draftTitle = suggestedTitle;
			}
		}
		return draftTitle;
	},
	createDraftTiddler: function(title, gatheredFields) {
		var tiddler = store.getTiddler(title);
		var draftTitle = saveDraftCmd.getDraftTitle(title);
		var draftTiddler = new Tiddler(draftTitle);
		if(tiddler) {
			$.extend(true, draftTiddler, tiddler);
		} else {
			$.extend(draftTiddler.fields, config.defaultCustomFields);
		}
		for(var fieldName in gatheredFields) {
			if(TiddlyWiki.isStandardField(fieldName)) {
				draftTiddler[fieldName] = gatheredFields[fieldName];
			} else {
				draftTiddler.fields[fieldName] = gatheredFields[fieldName];
			}
		}
		var privateBag = tiddlyspace.getCurrentBag("private");
		var privateWorkspace = tiddlyspace.getCurrentWorkspace("private");
		draftTiddler.title = draftTitle;
		draftTiddler.fields["publish.name"] = title;
		draftTiddler.fields["server.workspace"] = privateWorkspace;
		draftTiddler.fields["server.bag"] = privateBag;
		draftTiddler.fields["server.title"] = draftTitle;
		draftTiddler.fields["server.page.revision"] = "false";
		delete draftTiddler.fields["server.etag"];
		return draftTiddler;
	},
	handler: function(ev, src, title) {
		var tiddler = store.getTiddler(title); // original tiddler
		var tidEl = story.getTiddler(title);
		var uiFields = {};
		story.gatherSaveFields(tidEl, uiFields);
		var tid = saveDraftCmd.createDraftTiddler(title, uiFields);
		tid = store.saveTiddler(tid.title, tid.title, tid.text, tid.modifier,
			new Date(), tid.tags, tid.fields);
		autoSaveChanges(null, [tid]);
		story.closeTiddler(title);
		story.displayTiddler(src, title);
		story.displayTiddler(src, tid.title);
	}
};

var macro = config.macros.TiddlySpacePublisher = {
	locale: {
		title: "Batch Publisher",
		changeStatusLabel: "Make %0",
		noTiddlersText: "No tiddlers to publish",
		changeStatusPrompt: "Make all the selected tiddlers %0.",
		description: "Change tiddlers from %0 to %1 in this space"
	},

	listViewTemplate: {
		columns: [
			{ name: "Selected", field: "Selected", rowName: "title", type: "Selector" },
			{ name: "Tiddler", field: "tiddler", title: "Tiddler", type: "Tiddler" },
			{ name: "Status", field: "status", title: "Status", type: "WikiText" }
		],
		rowClasses: []
	},

	changeStatus: function(tiddlers, status, callback) { // this is what is called when you click the publish button
		var publicBag;
		for(var i = 0; i < tiddlers.length; i++) {
			var tiddler = tiddlers[i];
			var newTiddler = {
				title: tiddler.title,
				fields: { "server.bag": cmd.toggleBag(tiddler, status) }
			};
			cmd.moveTiddler(tiddler, newTiddler, callback);
		}
	},
	getMode: function(paramString) {
		var params = paramString.parseParams("anon")[0];
		var status = params.type ?
			(["public", "private"].contains(params.type[0]) ? params.type[0] : "private") :
			"private";
		var newStatus = status == "public" ? "private" : "public";
		return [status, newStatus];
	},
	handler: function(place, macroName, params, wikifier, paramString, tiddler) {
		var wizard = new Wizard();
		var locale = macro.locale;
		var status = macro.getMode(paramString);
		wizard.createWizard(place, locale.title);
		wizard.addStep(macro.locale.description.format(status[0], status[1]),
			'<input type="hidden" name="markList" />');
		var markList = wizard.getElement("markList");
		var listWrapper = $("<div />").addClass("batchPublisher").
			attr("refresh", "macro").attr("macroName", macroName).
			attr("params", paramString)[0];
		markList.parentNode.insertBefore(listWrapper, markList);
		$.data(listWrapper, "wizard", wizard);
		macro.refresh(listWrapper);
	},
	getCheckedTiddlers: function(listWrapper, titlesOnly) {
		var tiddlers = [];
		$(".chkOptionInput[rowName]:checked", listWrapper).each(function(i, el) {
			var title = $(el).attr("rowName");
			if(titlesOnly) {
				tiddlers.push(title);
			} else {
				tiddlers.push(store.getTiddler(title));
			}
		});
		return tiddlers;
	},
	refresh: function(listWrapper) {
		var checked = macro.getCheckedTiddlers(listWrapper, true);
		var paramString = $(listWrapper).empty().attr("params");
		var wizard = $.data(listWrapper, "wizard");
		var locale = macro.locale;
		var params = paramString.parseParams("anon")[0];
		var publishCandidates = [];
		var status = macro.getMode(paramString);
		var pubType = status[0];
		var newPubType = status[1];
		var tiddlers = params.filter ? store.filterTiddlers(params.filter[0]) :
			store.filterTiddlers("[is[%0]]".format(pubType));
		var enabled = [];
		for(var i = 0; i < tiddlers.length; i++) {
			var tiddler = tiddlers[i];
			var title = tiddler.title;
			if(!tiddler.tags.contains("excludePublisher") && title !== "SystemSettings") {
				publishCandidates.push({ title: title, tiddler: tiddler, status: pubType});
			}
			if(checked.contains(title)) {
				enabled.push("[rowname=%0]".format(title));
			}
		}

		if(publishCandidates.length === 0) {
			createTiddlyElement(listWrapper, "em", null, null, locale.noTiddlersText);
		} else {
			var listView = ListView.create(listWrapper, publishCandidates, macro.listViewTemplate);
			wizard.setValue("listView", listView);
			var btnHandler = function(ev) {
				var tiddlers = macro.getCheckedTiddlers(listWrapper);
				var callback = function(status) {
					$(".batchPublisher").each(function(i, el) {
						macro.refresh(el);
					});
				};
				macro.changeStatus(tiddlers, newPubType, callback);
			};
			wizard.setButtons([{
				caption: locale.changeStatusLabel.format(newPubType),
				tooltip: locale.changeStatusPrompt.format(newPubType),
				onClick: btnHandler
			}]);
			$(enabled.join(",")).attr("checked", true); // retain what was checked before
		}
	}
};

})(jQuery);
//}}}
<!--{{{-->
<div class='title' macro='view title'></div>
<div class='toolbar' macro='toolbar -closeTiddler closeOthers +editTiddler permalink references jump'></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>
<!--}}}-->
/***
|''Name''|PluginMathJax|
|''Description''|Displays TeX math using MathJax|
|''Author''|[[Canada East|http://tiddlywiki.canada-east.ca/]]|
|''Version''|1.3|
|''Date''|2010-10-07|
|''CodeRepository''|[[PluginMathJax|http://tiddlywiki.canada-east.ca/#PluginMathJax]]|
|''CoreVersion''|[[2.6.1|http://www.tiddlywiki.com]]|
|''Requires''|[[MathJax v1.01|http://www.mathjax.org/]]|
|''Feedback''|[[Contact|https://spreadsheets.google.com/viewform?formkey=dGg2RkpxZW5zWTh6QjZxOXgzZUlfakE6MQ]]|
|''Tweaks''|~MathJax location and default HTML-CSS scale changed by Gareth Davies.  I've also added a hook to a ~MathJax extension for managing local definitions written by Richard Lupton and I've set the newcommand extension to load on start-up.|
!Description
This plugin uses [[MathJax|http://www.mathjax.org/]] to typeset ([[AMS|http://www.ams.org/publications/authors/tex/amslatex]]) [[LaTeX|http://www.latex-project.org/]]  math. It can also be configured to use additional MathJax functionality.
>"MathJax is an open source JavaScript display engine for mathematics that works in all modern browsers."
!Notes
Right click any math display for a MathJax menu. The user can select the renderer and zoom settings. It performs best in [[Webkit|http://en.wikipedia.org/wiki/List_of_web_browsers#WebKit-based_browsers]] based browsers. Larger math displays such as the additional examples tiddler below can put quite a load on IE. PluginMathJax is based on: [[Plugin: jsMath|http://bob.mcelrath.org/tiddlyjsmath.html]]
!Installation
#''Backup'' your TiddlyWiki!
#It is required that the MathJax directory is installed in '''js/MathJax/''' in the same location as the TiddlyWiki html file.<br>(Or edit the script source where commented in the plugin code below after installation to match the location of your MathJax install.)
#Install this plugin (and examples tiddler linked below if desired).
!Usage
|!Source|!Output|h
|{{{The variable $x$ is real.}}}|The variable $x$ is real.|
|{{{The variable \(y\) is complex.}}}|The variable \(y\) is complex.|
|{{{This \[\int_a^b x = \frac{1}{2}(b^2-a^2)\] is an easy integral.}}}|This \[\int_a^b x = \frac{1}{2}(b^2-a^2)\] is an easy integral.|
|{{{This $$\int_a^b \sin x = -(\cos b - \cos a)$$ is another easy integral.}}}|This $$\int_a^b \sin x = -(\cos b - \cos a)$$ is another easy integral.|
|{{{Block formatted equations may also use the 'equation' environment \begin{equation}  \int \tan x = -\ln \cos x \end{equation} }}}|Block formatted equations may also use the 'equation' environment \begin{equation}  \int \tan x = -\ln \cos x \end{equation}|
|{{{Equation arrays are also supported \begin{eqnarray} a &=& b \\ c &=& d \end{eqnarray} }}}|Equation arrays are also supported \begin{eqnarray} a &=& b \\ c &=& d \end{eqnarray} |
|{{{I spent \$7.38 on lunch.}}}|I spent \$7.38 on lunch.|
|{{{I had to insert a backslash (\\) into my document}}}|I had to insert a backslash (\\) into my document|
| <br>[[Complete list of supported LaTeX commands|http://www.mathjax.org/resources/docs/?tex.html#supported-latex-commands]] |>|
!Examples
[[Additional MathJax Examples|MathJax Examples]]
!Configuration
MathJax can be manually configured if desired by editing the code below (advanced). See the [[MathJax documentation|http://www.mathjax.org/resources/docs/?configuration.html#configuration-options-by-component]] for details.
!Revision History
*v1.3, 2010-10-07, returned to original formatters design, kept modified wikify and recommended way of loading MathJax dynamically, removed the tex2jax extension and corrected several browser compatibility issues (InnerHTML for Opera and IE9).
*v1.2, 2010-10-05, removed some redundant MathJax config entries, moved modified wikify and MathJax.Hub.Queue call.
*v1.1, 2010-10-03, autoLinkWikiWords disabled in absence of DisableWikiLinksPlugin, modifed wikify.
*v1.0, 2010-09-26, Initial Release
!Code
***/
//{{{

if(!version.extensions.PluginMathJax) { 
    version.extensions.PluginMathJax = { installed: true };

    config.extensions.PluginMathJax = {

        install: function() {

            var script = document.createElement("script");
            script.type = "text/javascript";

            // *** Use the location of your MathJax! *** :
            /*
             * Gareth: The following line assumes you have
             * MathJax installed on your server in a sensible
             * location.  I've commented this out.
             */
            //script.src = "js/MathJax/MathJax.js";

            /*
             * Because this tiddlywiki is currently hosted on
             * tiddlyspace.com I've had to point to the 'MathJax
             * Content Delivery Network' instead.
             */
            script.src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"
            // EndGareth

            /*
             * Gareth: Richard's local definition ~MathJax
             * extension (implementation of TeXs \let command)
             * has been added to the list of extensions along
             * with the newcommand extension upon which it
             * depends.  Also, the scale option for HTML-CSS was
             * changed from 115 to 100.
             */
            var mjconfig = 'MathJax.Hub.Config({' +
            'jax: ["input/TeX","output/HTML-CSS"],' +
            'extensions: ["TeX/AMSmath.js", "TeX/AMSsymbols.js", "TeX/newcommand.js", "http://oxkunengroup.tiddlyspace.com/localTeX.js"],' +
            '"HTML-CSS": {' +
                'scale: 100' +
                '}' +
            '});' +

            'MathJax.Hub.Startup.onload();';

            var ie9RegExp = /^9\./;
            var UseInnerHTML = (config.browser.isOpera || config.browser.isIE && ie9RegExp.test(config.browser.ieVersion[1]));

            if (UseInnerHTML) {script.innerHTML = mjconfig;}
                else {script.text = mjconfig;}

            script.text = mjconfig;

            document.getElementsByTagName("head")[0].appendChild(script);

            // Define wikifers for latex
            config.formatterHelpers.mathFormatHelper = function(w) {
                var e = document.createElement(this.element);
                e.type = this.type;
                var endRegExp = new RegExp(this.terminator, "mg");
                endRegExp.lastIndex = w.matchStart+w.matchLength;
                var matched = endRegExp.exec(w.source);
                if(matched) {
                    var txt = w.source.substr(w.matchStart+w.matchLength,
                        matched.index-w.matchStart-w.matchLength);
                    if(this.keepdelim) {
                      txt = w.source.substr(w.matchStart, matched.index+matched[0].length-w.matchStart);
                    }
                    if (UseInnerHTML) {
                        e.innerHTML = txt;
                    } else {
                        e.text = txt;
                    }
                    w.output.appendChild(e);
                    w.nextMatch = endRegExp.lastIndex;
                }
            }

            config.formatters.push({
              name: "displayMath1",
              match: "\\\$\\\$",
              terminator: "\\\$\\\$\\n?",
              termRegExp: "\\\$\\\$\\n?",
              element: "script",
              type: "math/tex; mode=display",
              handler: config.formatterHelpers.mathFormatHelper
            });

            config.formatters.push({
              name: "inlineMath1",
              match: "\\\$", 
              terminator: "\\\$",
              termRegExp: "\\\$",
              element: "script",
              type: "math/tex",
              handler: config.formatterHelpers.mathFormatHelper
            });

            var backslashformatters = new Array(0);

            backslashformatters.push({
              name: "inlineMath2",
              match: "\\\\\\\(",
              terminator: "\\\\\\\)",
              termRegExp: "\\\\\\\)",
              element: "script",
              type: "math/tex",
              handler: config.formatterHelpers.mathFormatHelper
            });

            backslashformatters.push({
              name: "displayMath2",
              match: "\\\\\\\[",
              terminator: "\\\\\\\]\\n?",
              termRegExp: "\\\\\\\]\\n?",
              element: "script",
              type: "math/tex; mode=display",
              handler: config.formatterHelpers.mathFormatHelper
            });

            backslashformatters.push({
              name: "displayMath3",
              match: "\\\\begin\\{equation\\}",
              terminator: "\\\\end\\{equation\\}\\n?",
              termRegExp: "\\\\end\\{equation\\}\\n?",
              element: "script",
              type: "math/tex; mode=display",
              handler: config.formatterHelpers.mathFormatHelper
            });

            // These can be nested.  e.g. \begin{equation} \begin{array}{ccc} \begin{array}{ccc} ...
            backslashformatters.push({
              name: "displayMath4",
              match: "\\\\begin\\{eqnarray\\}",
              terminator: "\\\\end\\{eqnarray\\}\\n?",
              termRegExp: "\\\\end\\{eqnarray\\}\\n?",
              element: "script",
              type: "math/tex; mode=display",
              keepdelim: true,
              handler: config.formatterHelpers.mathFormatHelper
            });

            // The escape must come between backslash formatters and regular ones.
            // So any latex-like \commands must be added to the beginning of
            // backslashformatters here.
            backslashformatters.push({
                name: "escape",
                match: "\\\\.",
                handler: function(w) {
                    w.output.appendChild(document.createTextNode(w.source.substr(w.matchStart+1,1)));
                    w.nextMatch = w.matchStart+2;
                }
            });

          config.formatters=backslashformatters.concat(config.formatters);

          old_wikify = wikify;
          wikify = function(source,output,highlightRegExp,tiddler)
          {
              old_wikify.apply(this,arguments);
              if (window.MathJax) {MathJax.Hub.Queue(["Typeset",MathJax.Hub,output])}
          };

        }
    };

  config.extensions.PluginMathJax.install();

}

//}}}
!Spaces
<<groupBy server.bag>>

!Private
<<list filter [is[private]]>>

!Public
<<list filter [is[public]]>>

!Drafts
<<list filter [is[draft]]>>
/*{{{*/
/**
 * SyntaxHighlighter
 * http://alexgorbatchev.com/SyntaxHighlighter
 *
 * SyntaxHighlighter is donationware. If you are using it, please donate.
 * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
 *
 * @version
 * 3.0.83 (July 02 2010)
 * 
 * @copyright
 * Copyright (C) 2004-2010 Alex Gorbatchev.
 *
 * @license
 * Dual licensed under the MIT and GPL licenses.
 */
.syntaxhighlighter {
  background-color: white !important;
}
.syntaxhighlighter .line.alt1 {
  background-color: white !important;
}
.syntaxhighlighter .line.alt2 {
  background-color: white !important;
}
.syntaxhighlighter .line.highlighted.alt1, .syntaxhighlighter .line.highlighted.alt2 {
  background-color: #e0e0e0 !important;
}
.syntaxhighlighter .line.highlighted.number {
  color: black !important;
}
.syntaxhighlighter table caption {
  color: black !important;
}
.syntaxhighlighter .gutter {
  color: #afafaf !important;
}
.syntaxhighlighter .gutter .line {
  border-right: 3px solid #6ce26c !important;
}
.syntaxhighlighter .gutter .line.highlighted {
  background-color: #6ce26c !important;
  color: white !important;
}
.syntaxhighlighter.printing .line .content {
  border: none !important;
}
.syntaxhighlighter.collapsed {
  overflow: visible !important;
}
.syntaxhighlighter.collapsed .toolbar {
  color: blue !important;
  background: white !important;
  border: 1px solid #6ce26c !important;
}
.syntaxhighlighter.collapsed .toolbar a {
  color: blue !important;
}
.syntaxhighlighter.collapsed .toolbar a:hover {
  color: red !important;
}
.syntaxhighlighter .toolbar {
  color: white !important;
  background: #6ce26c !important;
  border: none !important;
}
.syntaxhighlighter .toolbar a {
  color: white !important;
}
.syntaxhighlighter .toolbar a:hover {
  color: black !important;
}
.syntaxhighlighter .plain, .syntaxhighlighter .plain a {
  color: black !important;
}
.syntaxhighlighter .comments, .syntaxhighlighter .comments a {
  color: #008200 !important;
}
.syntaxhighlighter .string, .syntaxhighlighter .string a {
  color: blue !important;
}
.syntaxhighlighter .keyword {
  color: #006699 !important;
}
.syntaxhighlighter .preprocessor {
  color: gray !important;
}
.syntaxhighlighter .variable {
  color: #aa7700 !important;
}
.syntaxhighlighter .value {
  color: #009900 !important;
}
.syntaxhighlighter .functions {
  color: #ff1493 !important;
}
.syntaxhighlighter .constants {
  color: #0066cc !important;
}
.syntaxhighlighter .script {
  font-weight: bold !important;
  color: #006699 !important;
  background-color: none !important;
}
.syntaxhighlighter .color1, .syntaxhighlighter .color1 a {
  color: gray !important;
}
.syntaxhighlighter .color2, .syntaxhighlighter .color2 a {
  color: #ff1493 !important;
}
.syntaxhighlighter .color3, .syntaxhighlighter .color3 a {
  color: red !important;
}

.syntaxhighlighter .keyword {
  font-weight: bold !important;
}
/*}}}*/
/***
<<highlightSyntax>>
***/
/***
|''Name''|TiddlySpaceBackstage|
|''Version''|0.8.0|
|''Description''|Provides a TiddlySpace version of the backstage and a homeLink macro|
|''Status''|@@beta@@|
|''Contributors''|Jon Lister, Jon Robson, Colm Britton|
|''Source''|http://github.com/TiddlySpace/tiddlyspace/raw/master/src/plugins/TiddlySpaceBackstage.js|
|''Requires''|TiddlySpaceConfig ImageMacroPlugin TiddlySpaceViewTypes|
!StyleSheet
.tiddler .error.annotation .button{
	display: inline-block;
}

#backstageArea {
	z-index: 49;
	color: white;
	background-color: black;
	background: -webkit-gradient(linear,left bottom,left top,color-stop(0, #222),color-stop(0.5, #333),color-stop(1, #555));
	background: -moz-linear-gradient(center bottom,#222 0%, #333 50%, #555 100%);
	filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#ff555555, endColorstr=#ff222222);
	-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#ff555555, endColorstr=#ff222222)";
	height: 25px;
	padding: 0;
}

#backstageButton {
	overflow: hidden;
}

#backstageButton #backstageShow,
#backstageButton #backstageHide {
	margin: 0px;
	padding: 0px;
}

#backstageButton #backstageShow:hover,
#backstageButton #backstageHide:hover {
	background: none;
	color: none;
}

#backstageButton img,
#backstageButton svg {
	width: 24px;
	height: 24px;
}

#messageArea {
	top: 50px;
}

#backstageToolbar {
	position: relative;
}

#backstageArea a {
	padding: 0px;
	margin-left: 0px;
	color: white;
	background: none;
}

#backstageArea a:hover {
	background-color: white;
}

#backstage ol,
#backstage ul {
	padding: auto;
}

#backstageButton a {
	margin: 0;
}

.backstagePanelBody ul {
	padding: 5px;
	margin: 5px;
}

#backstage #backstagePanel {
	margin-left: 5%;
	padding: 0em;
	margin-right: 5%;
}

#backstageToolbar a {
	position: relative;
}

#backstageArea a.backstageSelTab,
#backstageToolbar .backstageTask {
	line-height: 25px;
	color: #767676;
}

.backstageTask .externalImage,
.backstageTask .image {
	display: inline;
}

#backstageToolbar a span {
	z-index: 2;
}

a.backstageTask {
	display: inline;
        margin-left: 1em !important;
}

.backstagePanelBody .button {
	display: inline-block;
	margin-right: 10px;
}

.backstagePanelBody {
	margin: 0 0 0 0.6em;
	padding: 0.4em 0.5em 1px 0.5em;
}

#backstage table {
	margin: auto;
}

#backstage .wizard table {
	border: 0px;
	margin: 0;
}

#backstage div  li.listLink {
	border: 0px;
	width: 78%;
	font-size: 0.7em;
}

#backstage div li.listTitle {
	font-weight: bold;
	text-decoration: underline;
	font-size: 1em;
	background: #ccc;
	width: 100%;
}

#backstage fieldset {
	border: solid 1px [[ColorPalette::Background]];
}

#backstage .viewer table,#backstage table.twtable {
	border: 0px;
}

#backstageToolbar img {
	padding: 0;
}

#backstage .wizard,
#backstage .wizardFooter {
	background: none;
}

.viewer td, .viewer tr, .twtable td, .twtable tr {
	border: 1px solid #eee;
}

#backstage .inlineList ul li {
	background-color: [[ColorPalette::Background]];
	border: solid 1px [[ColorPalette::TertiaryMid]];
	display: block;
	float: left;
	list-style: none;
	margin-right: 1em;
	padding: 0.5em;
}

.backstageClear, .inlineList form {
	clear: both;
	display: block;
	margin-top: 3em;
}

.tiddlyspaceMenu {
	text-align: center;
}

span.chunkyButton {
	display: inline-block;
	padding: 0;
	margin: 0;
	border: solid 2px #000;
	background-color: #04b;
}

span.chunkyButton a.button, span.chunkyButton a:active.button {
	white-space: nowrap;
	font-weight: bold;
	font-size: 1.8em;
	color: #fff;
	text-align: center;
	padding: 0.5em 0.5em;
	margin: 0;
	border-style: none;
	display: block;
}

span.chunkyButton:hover {
	background-color: #014;
}

span.chunkyButton a.button:hover {
	border-style: none;
	background: none;
	color: #fff;
}

#backstage .unpluggedSpaceTab .wizard,
.unpluggedSpaceTab .wizard {
	background: white;
	border: 2px solid #CCC;
	padding: 5px;
}

.syncKey .keyItem {
	border: 1px solid black;
	display: inline-block;
	margin: 0.2em;
	padding: 0.1em 0.1em 0.1em 0.1em;
}

.keyHeading {
	font-size: 2em;
	font-weight: bold;
	margin: 0.4em 0em -0.2em;
}

.unpluggedSpaceTab .putToServer,
.unpluggedSpaceTab .notChanged {
	display: none;
}

.tiddlyspaceMenu ul {
	margin: 0;
	padding: 0;
}

.tiddlyspaceMenu ul li {
	list-style: none;
}

.unsyncedChanges .unsyncedList {
	display: block;
}

.unsyncedList {
	display: none;
}
!Code
***/
//{{{
(function ($) {
    var name = "StyleSheet" + tiddler.title;
    config.shadowTiddlers[name] = "/*{{{*/\n%0\n/*}}}*/".
        format(store.getTiddlerText(tiddler.title + "##StyleSheet")); // this accesses the StyleSheet section of the current tiddler (the plugin that contains it)
    store.addNotification(name, refreshStyles);

    if (!config.extensions.tiddlyweb.status.tiddlyspace_version) { // unplugged
        config.extensions.tiddlyweb.status.tiddlyspace_version = "<unknown>";
        config.extensions.tiddlyweb.status.server_host = {
            url:config.extensions.tiddlyweb.host }; // TiddlySpaceLinkPlugin expects this
    }
    var disabled_tasks_for_nonmembers = ["tiddlers", "plugins", "batch", "sync"];

    var tweb = config.extensions.tiddlyweb;
    var tiddlyspace = config.extensions.tiddlyspace;
    var currentSpace = tiddlyspace.currentSpace.name;
    var imageMacro = config.macros.image;

    if (config.options.chkBackstage === undefined) {
        config.options.chkBackstage = false;
    }

// Set up Backstage
    config.tasks = {};
    config.tasks.status = {
        text:"status",
        tooltip:"TiddlySpace Info",
        content:"<<tiddler Backstage##Menu>>"
    };
    config.tasks.tiddlers = {
        text:"tiddlers",
        tooltip:"tiddlers control panel",
        content:"<<tiddler Backstage##BackstageTiddlers>>"
    };
    config.tasks.plugins = {
        text:"plugins",
        tooltip:"Manage installed plugins",
        content:"<<tiddler Backstage##Plugins>>"
    };
    config.tasks.batch = {
        text:"batch",
        tooltip:"Batch manage public/private tiddlers",
        content:"<<tiddler Backstage##BatchOps>>"
    };
    config.tasks.tweaks = {
        text:"tweaks",
        tooltip:"Tweak TiddlyWiki behaviors",
        content:"<<tiddler Backstage##Tweaks>>"
    };
    config.tasks.exportTiddlers = {
        text:"import/export",
        tooltip:"Import/export tiddlers from/to a TiddlyWiki",
        content:"<<tiddler Backstage##ImportExport>>"
    };
    config.tasks.sync = {
        text:"sync",
        tooltip:"Check Sync status",
        content:"<<tiddler Backstage##SpaceUnplugged>>"
    };

    if (window.location.protocol === "file:") {
        config.unplugged = true;
    }

    config.backstageTasks = ["status", "tiddlers", "plugins",
        "batch", "tweaks", "exportTiddlers", "sync"];

    config.messages.backstage.prompt = "";
// initialize state
    var _show = backstage.show;
    backstage.show = function () {
        // selectively hide backstage tasks and tabs based on user status
        var tasks = $("#backstageToolbar .backstageTask").show();
        var bs = backstage.tiddlyspace;
        if (!config.unplugged) {
            tweb.getUserInfo(function (user) {
                if (user.anon) {
                    jQuery.each(disabled_tasks_for_nonmembers, function (i, task) {
                        var taskIndex = config.backstageTasks.indexOf(task);
                        if (taskIndex !== -1) {
                            config.backstageTasks.splice(taskIndex, 1);
                        }
                    });
                    config.messages.memberStatus = bs.locale.loggedout;
                } else {
                    config.messages.memberStatus = readOnly ?
                        bs.locale.nonmember : bs.locale.member;
                }
            });
        } else {
            config.messages.memberStatus = bs.locale.unplugged;
        }

        // display backstage
        return _show.apply(this, arguments);
    };
    if (readOnly) {
        jQuery.each(disabled_tasks_for_nonmembers, function (i, task) {
            var taskIndex = config.backstageTasks.indexOf(task);
            if (taskIndex !== -1) {
                config.backstageTasks.splice(taskIndex, 1);
            }
        });
    }

    var tasks = config.tasks;
    var commonUrl = "/bags/common/tiddlers/%0";

    backstage.tiddlyspace = {
        locale:{
            member:"You are a member of this space.",
            nonmember:"You are not a member of this space.",
            loggedout:"You are currently logged out of TiddlySpace.",
            unplugged:"You are unplugged."
        },
        showButton:function () {
            var showBtn = $("#backstageShow")[0];
            var altText = $(showBtn).text();
            $(showBtn).empty();
            imageMacro.renderImage(showBtn, "backstage.svg",
                { altImage:commonUrl.format("backstage.png"), alt:altText});
        },
        hideButton:function () {
            var hideBtn = $("#backstageHide")[0];
            var altText = $(hideBtn).text();
            $(hideBtn).empty();
            imageMacro.renderImage(hideBtn, "close.svg",
                { altImage:commonUrl.format("close.png"), alt:altText, width:24, height:24 });
        }
    };

    var _init = backstage.init;
    backstage.init = function () {
        _init.apply(this, arguments);
        var init = function (user) {
            var bs = backstage.tiddlyspace;
            bs.showButton();
            bs.hideButton();
        };
        tweb.getUserInfo(init);
    };

    var home = config.macros.homeLink = {
        locale:{
            linkText:"your home space"
        },
        handler:function (place) {
            var container = $("<span />").appendTo(place)[0];
            tweb.getUserInfo(function (user) {
                if (!user.anon && user.name !== currentSpace) {
                    createSpaceLink(container, user.name, null, home.locale.linkText);
                }
            });
        }
    };

    config.macros.exportSpace = {
        handler:function (place, macroName, params) {
            var filename = params[0] ||
                "/tiddlers.wiki?download=%0.html".format(currentSpace);
            $('<a class="button">download</a>').// XXX: i18n
                attr("href", filename).appendTo(place);
        }
    };

}(jQuery));
//}}}
/***
|''Name''|RevisionsCommandPlugin|
|''Description''|provides access to tiddler revisions|
|''Author''|FND|
|''Contributors''|Martin Budden|
|''Version''|0.3.3|
|''Status''|@@beta@@|
|''Source''|http://svn.tiddlywiki.org/Trunk/association/plugins/RevisionsCommandPlugin.js|
|''CodeRepository''|http://svn.tiddlywiki.org/Trunk/association/plugins/|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''CoreVersion''|2.6.0|
|''Keywords''|serverSide|
!Usage
Extend [[ToolbarCommands]] with {{{revisions}}}.
!Revision History
!!v0.1 (2009-07-23)
* initial release (renamed from experimental ServerCommandsPlugin)
!!v0.2 (2010-03-04)
* suppressed wikification in diff view
!!v0.3 (2010-04-07)
* restored wikification in diff view
* added link to side-by-side diff view
!To Do
* strip server.* fields from revision tiddlers
* resolve naming conflicts
* i18n, l10n
* code sanitizing
* documentation
!Code
***/
//{{{
(function($) {

jQuery.twStylesheet(".diff { white-space: pre, font-family: monospace }",
	{ id: "diff" });

var cmd = config.commands.revisions = {
	type: "popup",
	hideShadow: true,
	text: "revisions",
	tooltip: "display tiddler revisions",
	revTooltip: "", // TODO: populate dynamically?
	loadLabel: "loading...",
	loadTooltip: "loading revision list",
	selectLabel: "select",
	selectTooltip: "select revision for comparison",
	selectedLabel: "selected",
	compareLabel: "compare",
	linkLabel: "side-by-side view",
	revSuffix: " [rev. #%0]",
	diffSuffix: " [diff: #%0 #%1]",
	dateFormat: "YYYY-0MM-0DD 0hh:0mm",
	listError: "revisions could not be retrieved",

	handlePopup: function(popup, title) {
		title = this.stripSuffix("rev", title);
		title = this.stripSuffix("diff", title);
		var tiddler = store.getTiddler(title);
		var type = _getField("server.type", tiddler);
		var adaptor = new config.adaptors[type]();
		var limit = null; // TODO: customizable
		var context = {
			host: _getField("server.host", tiddler),
			workspace: _getField("server.workspace", tiddler)
		};
		var loading = createTiddlyButton(popup, cmd.loadLabel, cmd.loadTooltip);
		var params = { popup: popup, loading: loading, origin: title };
		adaptor.getTiddlerRevisionList(title, limit, context, params, this.displayRevisions);
	},

	displayRevisions: function(context, userParams) {
		removeNode(userParams.loading);
		if(context.status) {
			var callback = function(ev) {
				var e = ev || window.event;
				var revision = resolveTarget(e).getAttribute("revision");
				context.adaptor.getTiddlerRevision(tiddler.title, revision, context,
					userParams, cmd.displayTiddlerRevision);
			};
			var table = createTiddlyElement(userParams.popup, "table");
			for(var i = 0; i < context.revisions.length; i++) {
				var tiddler = context.revisions[i];
				var row = createTiddlyElement(table, "tr");
				var timestamp = tiddler.modified.formatString(cmd.dateFormat);
				var revision = tiddler.fields["server.page.revision"];
				var cell = createTiddlyElement(row, "td");
				createTiddlyButton(cell, timestamp, cmd.revTooltip, callback, null,
					null, null, { revision: revision });
				cell = createTiddlyElement(row, "td", null, null, tiddler.modifier);
				cell = createTiddlyElement(row, "td");
				createTiddlyButton(cell, cmd.selectLabel, cmd.selectTooltip,
					cmd.revisionSelected, null, null, null,
					{ index:i, revision: revision, col: 2 });
				cmd.context = context; // XXX: unsafe (singleton)!?
			}
		} else {
			$("<li />").text(cmd.listError).appendTo(userParams.popup);
		}
	},

	revisionSelected: function(ev) {
		var e = ev || window.event;
		e.cancelBubble = true;
		if(e.stopPropagation) {
			e.stopPropagation();
		}
		var n = resolveTarget(e);
		var index = n.getAttribute("index");
		var col = n.getAttribute("col");
		while(!index || !col) {
			n = n.parentNode;
			index = n.getAttribute("index");
			col = n.getAttribute("col");
		}
		cmd.revision = n.getAttribute("revision");
		var table = n.parentNode.parentNode.parentNode;
		var rows = table.childNodes;
		for(var i = 0; i < rows.length; i++) {
			var c = rows[i].childNodes[col].firstChild;
			if(i == index) {
				if(c.textContent) {
					c.textContent = cmd.selectedLabel;
				} else {
					c.text = cmd.selectedLabel;
				}
			} else {
				if(c.textContent) {
					c.textContent = cmd.compareLabel;
				} else {
					c.text = cmd.compareLabel;
				}
				c.onclick = cmd.compareSelected;
			}
		}
	},

	compareSelected: function(ev) {
		var e = ev || window.event;
		var n = resolveTarget(e);
		var context = cmd.context;
		context.rev1 = n.getAttribute("revision");
		context.rev2 = cmd.revision;
		context.tiddler = context.revisions[n.getAttribute("index")];
		context.format = "unified";
		context.adaptor.getTiddlerDiff(context.tiddler.title, context,
			context.userParams, cmd.displayTiddlerDiffs);
	},

	displayTiddlerDiffs: function(context, userParams) {
		var tiddler = context.tiddler;
		tiddler.title += cmd.diffSuffix.format([context.rev1, context.rev2]);
		tiddler.text = "{{diff{\n" + context.diff + "\n}}}";
		tiddler.tags = ["diff"];
		tiddler.fields.doNotSave = "true"; // XXX: correct?
		if(!store.getTiddler(tiddler.title)) {
			store.addTiddler(tiddler);
		}
		var src = story.getTiddler(userParams.origin);
		var tiddlerEl = story.displayTiddler(src, tiddler);
		var uri = context.uri.replace("format=unified", "format=horizontal");
		var link = $('<a target="_blank" />').attr("href", uri).text(cmd.linkLabel);
		$(".viewer", tiddlerEl).prepend(link);
	},

	displayTiddlerRevision: function(context, userParams) {
		var tiddler = context.tiddler;
		tiddler.title += cmd.revSuffix.format([tiddler.fields["server.page.revision"]]);
		tiddler.fields.doNotSave = "true"; // XXX: correct?
		if(!store.getTiddler(tiddler.title)) {
			store.addTiddler(tiddler);
		}
		var src = story.getTiddler(userParams.origin);
		story.displayTiddler(src, tiddler);
	},

	stripSuffix: function(type, title) {
		var str = cmd[type + "Suffix"];
		var i = str.indexOf("%0");
		i = title.indexOf(str.substr(0, i));
		if(i != -1) {
			title = title.substr(0, i);
		}
		return title;
	}
};

var _getField = function(name, tiddler) {
	return tiddler.fields[name] || config.defaultCustomFields[name];
};

})(jQuery);
//}}}
/***
|''Description''|Sanitisation for dynamically pulling tiddlers into your space and displaying them|
!Notes
Works both inside and outside TiddlyWiki. Uses the HTML Sanitizer provided by the Google Caja project
(see http://code.google.com/p/google-caja/wiki/JsHtmlSanitizer for more on this), which is licensed under
an Apache License (see http://www.apache.org/licenses/LICENSE-2.0).
!Code
***/
//{{{
(function($) {

var cleanURL = function(url) {
	var regexp = /^(?:http|https|mailto|ftp|irc|news):\/\//;
	return (regexp.test(url)) ? url : null;
};

$.sanitize = function(html) {
	return html_sanitize(html, cleanURL);
};

/*
 * HTML Sanitizer, provided by Google Caja
 */

/* Copyright Google Inc.
 * Licensed under the Apache Licence Version 2.0
 * Autogenerated at Tue May 17 17:39:24 BST 2011
 * @provides html4
 */var html4={};html4.atype={NONE:0,URI:1,URI_FRAGMENT:11,SCRIPT:2,STYLE:3,ID:4,IDREF:5,IDREFS:6,GLOBAL_NAME:7,LOCAL_NAME:8,CLASSES:9,FRAME_TARGET:10},html4.ATTRIBS={"*::class":9,"*::dir":0,"*::id":4,"*::lang":0,"*::onclick":2,"*::ondblclick":2,"*::onkeydown":2,"*::onkeypress":2,"*::onkeyup":2,"*::onload":2,"*::onmousedown":2,"*::onmousemove":2,"*::onmouseout":2,"*::onmouseover":2,"*::onmouseup":2,"*::style":3,"*::title":0,"a::accesskey":0,"a::coords":0,"a::href":1,"a::hreflang":0,"a::name":7,"a::onblur":2,"a::onfocus":2,"a::rel":0,"a::rev":0,"a::shape":0,"a::tabindex":0,"a::target":10,"a::type":0,"area::accesskey":0,"area::alt":0,"area::coords":0,"area::href":1,"area::nohref":0,"area::onblur":2,"area::onfocus":2,"area::shape":0,"area::tabindex":0,"area::target":10,"bdo::dir":0,"blockquote::cite":1,"br::clear":0,"button::accesskey":0,"button::disabled":0,"button::name":8,"button::onblur":2,"button::onfocus":2,"button::tabindex":0,"button::type":0,"button::value":0,"canvas::height":0,"canvas::width":0,"caption::align":0,"col::align":0,"col::char":0,"col::charoff":0,"col::span":0,"col::valign":0,"col::width":0,"colgroup::align":0,"colgroup::char":0,"colgroup::charoff":0,"colgroup::span":0,"colgroup::valign":0,"colgroup::width":0,"del::cite":1,"del::datetime":0,"dir::compact":0,"div::align":0,"dl::compact":0,"font::color":0,"font::face":0,"font::size":0,"form::accept":0,"form::action":1,"form::autocomplete":0,"form::enctype":0,"form::method":0,"form::name":7,"form::onreset":2,"form::onsubmit":2,"form::target":10,"h1::align":0,"h2::align":0,"h3::align":0,"h4::align":0,"h5::align":0,"h6::align":0,"hr::align":0,"hr::noshade":0,"hr::size":0,"hr::width":0,"iframe::align":0,"iframe::frameborder":0,"iframe::height":0,"iframe::marginheight":0,"iframe::marginwidth":0,"iframe::width":0,"img::align":0,"img::alt":0,"img::border":0,"img::height":0,"img::hspace":0,"img::ismap":0,"img::name":7,"img::src":1,"img::usemap":11,"img::vspace":0,"img::width":0,"input::accept":0,"input::accesskey":0,"input::align":0,"input::alt":0,"input::autocomplete":0,"input::checked":0,"input::disabled":0,"input::ismap":0,"input::maxlength":0,"input::name":8,"input::onblur":2,"input::onchange":2,"input::onfocus":2,"input::onselect":2,"input::readonly":0,"input::size":0,"input::src":1,"input::tabindex":0,"input::type":0,"input::usemap":11,"input::value":0,"ins::cite":1,"ins::datetime":0,"label::accesskey":0,"label::for":5,"label::onblur":2,"label::onfocus":2,"legend::accesskey":0,"legend::align":0,"li::type":0,"li::value":0,"map::name":7,"menu::compact":0,"ol::compact":0,"ol::start":0,"ol::type":0,"optgroup::disabled":0,"optgroup::label":0,"option::disabled":0,"option::label":0,"option::selected":0,"option::value":0,"p::align":0,"pre::width":0,"q::cite":1,"select::disabled":0,"select::multiple":0,"select::name":8,"select::onblur":2,"select::onchange":2,"select::onfocus":2,"select::size":0,"select::tabindex":0,"table::align":0,"table::bgcolor":0,"table::border":0,"table::cellpadding":0,"table::cellspacing":0,"table::frame":0,"table::rules":0,"table::summary":0,"table::width":0,"tbody::align":0,"tbody::char":0,"tbody::charoff":0,"tbody::valign":0,"td::abbr":0,"td::align":0,"td::axis":0,"td::bgcolor":0,"td::char":0,"td::charoff":0,"td::colspan":0,"td::headers":6,"td::height":0,"td::nowrap":0,"td::rowspan":0,"td::scope":0,"td::valign":0,"td::width":0,"textarea::accesskey":0,"textarea::cols":0,"textarea::disabled":0,"textarea::name":8,"textarea::onblur":2,"textarea::onchange":2,"textarea::onfocus":2,"textarea::onselect":2,"textarea::readonly":0,"textarea::rows":0,"textarea::tabindex":0,"tfoot::align":0,"tfoot::char":0,"tfoot::charoff":0,"tfoot::valign":0,"th::abbr":0,"th::align":0,"th::axis":0,"th::bgcolor":0,"th::char":0,"th::charoff":0,"th::colspan":0,"th::headers":6,"th::height":0,"th::nowrap":0,"th::rowspan":0,"th::scope":0,"th::valign":0,"th::width":0,"thead::align":0,"thead::char":0,"thead::charoff":0,"thead::valign":0,"tr::align":0,"tr::bgcolor":0,"tr::char":0,"tr::charoff":0,"tr::valign":0,"ul::compact":0,"ul::type":0},html4.eflags={OPTIONAL_ENDTAG:1,EMPTY:2,CDATA:4,RCDATA:8,UNSAFE:16,FOLDABLE:32,SCRIPT:64,STYLE:128},html4.ELEMENTS={a:0,abbr:0,acronym:0,address:0,applet:16,area:2,b:0,base:18,basefont:18,bdo:0,big:0,blockquote:0,body:49,br:2,button:0,canvas:0,caption:0,center:0,cite:0,code:0,col:2,colgroup:1,dd:1,del:0,dfn:0,dir:0,div:0,dl:0,dt:1,em:0,fieldset:0,font:0,form:0,frame:18,frameset:16,h1:0,h2:0,h3:0,h4:0,h5:0,h6:0,head:49,hr:2,html:49,i:0,iframe:4,img:2,input:2,ins:0,isindex:18,kbd:0,label:0,legend:0,li:1,link:18,map:0,menu:0,meta:18,nobr:0,noframes:20,noscript:20,object:16,ol:0,optgroup:0,option:1,p:1,param:18,pre:0,q:0,s:0,samp:0,script:84,select:0,small:0,span:0,strike:0,strong:0,style:148,sub:0,sup:0,table:0,tbody:1,td:1,textarea:8,tfoot:1,th:1,thead:1,title:24,tr:1,tt:0,u:0,ul:0,"var":0},html4.ueffects={NOT_LOADED:0,SAME_DOCUMENT:1,NEW_DOCUMENT:2},html4.URIEFFECTS={"a::href":2,"area::href":2,"blockquote::cite":0,"body::background":1,"del::cite":0,"form::action":2,"img::src":1,"input::src":1,"ins::cite":0,"q::cite":0},html4.ltypes={UNSANDBOXED:2,SANDBOXED:1,DATA:0},html4.LOADERTYPES={"a::href":2,"area::href":2,"blockquote::cite":2,"body::background":1,"del::cite":2,"form::action":2,"img::src":1,"input::src":1,"ins::cite":2,"q::cite":2};var html=function(a){function x(b,c,d){var e=[];w(function(b,e){for(var f=0;f<e.length;f+=2){var g=e[f],h=e[f+1],i=null,j;if((j=b+"::"+g,a.ATTRIBS.hasOwnProperty(j))||(j="*::"+g,a.ATTRIBS.hasOwnProperty(j)))i=a.ATTRIBS[j];if(i!==null)switch(i){case a.atype.NONE:break;case a.atype.SCRIPT:case a.atype.STYLE:h=null;break;case a.atype.ID:case a.atype.IDREF:case a.atype.IDREFS:case a.atype.GLOBAL_NAME:case a.atype.LOCAL_NAME:case a.atype.CLASSES:h=d?d(h):h;break;case a.atype.URI:h=c&&c(h);break;case a.atype.URI_FRAGMENT:h&&"#"===h.charAt(0)?(h=d?d(h):h,h&&(h="#"+h)):h=null;break;default:h=null}else h=null;e[f+1]=h}return e})(b,e);return e.join("")}function w(b){var c,d;return v({startDoc:function(a){c=[],d=!1},startTag:function(e,f,g){if(!d){if(!a.ELEMENTS.hasOwnProperty(e))return;var h=a.ELEMENTS[e];if(h&a.eflags.FOLDABLE)return;if(h&a.eflags.UNSAFE){d=!(h&a.eflags.EMPTY);return}f=b(e,f);if(f){h&a.eflags.EMPTY||c.push(e),g.push("<",e);for(var i=0,j=f.length;i<j;i+=2){var k=f[i],l=f[i+1];l!==null&&l!==void 0&&g.push(" ",k,'="',r(l),'"')}g.push(">")}}},endTag:function(b,e){if(d)d=!1;else{if(!a.ELEMENTS.hasOwnProperty(b))return;var f=a.ELEMENTS[b];if(!(f&(a.eflags.UNSAFE|a.eflags.EMPTY|a.eflags.FOLDABLE))){var g;if(f&a.eflags.OPTIONAL_ENDTAG)for(g=c.length;--g>=0;){var h=c[g];if(h===b)break;if(!(a.ELEMENTS[h]&a.eflags.OPTIONAL_ENDTAG))return}else for(g=c.length;--g>=0;)if(c[g]===b)break;if(g<0)return;for(var i=c.length;--i>g;){var h=c[i];a.ELEMENTS[h]&a.eflags.OPTIONAL_ENDTAG||e.push("</",h,">")}c.length=g,e.push("</",b,">")}}},pcdata:function(a,b){d||b.push(a)},rcdata:function(a,b){d||b.push(a)},cdata:function(a,b){d||b.push(a)},endDoc:function(a){for(var b=c.length;--b>=0;)a.push("</",c[b],">");c.length=0}})}function v(c){return function(d,e){d=String(d);var f=null,g=!1,h=[],j=void 0,l=void 0,m=void 0;c.startDoc&&c.startDoc(e);while(d){var n=d.match(g?t:u);d=d.substring(n[0].length);if(g){if(n[1]){var o=b(n[1]),p;if(n[2]){var q=n[3];switch(q.charCodeAt(0)){case 34:case 39:q=q.substring(1,q.length-1)}p=k(i(q))}else p=o;h.push(o,p)}else if(n[4]){l!==void 0&&(m?c.startTag&&c.startTag(j,h,e):c.endTag&&c.endTag(j,e));if(m&&l&(a.eflags.CDATA|a.eflags.RCDATA)){f===null?f=b(d):f=f.substring(f.length-d.length);var r=f.indexOf("</"+j);r<0&&(r=d.length),l&a.eflags.CDATA?c.cdata&&c.cdata(d.substring(0,r),e):c.rcdata&&c.rcdata(s(d.substring(0,r)),e),d=d.substring(r)}j=l=m=void 0,h.length=0,g=!1}}else if(n[1])c.pcdata&&c.pcdata(n[0],e);else if(n[3])m=!n[2],g=!0,j=b(n[3]),l=a.ELEMENTS.hasOwnProperty(j)?a.ELEMENTS[j]:void 0;else if(n[4])c.pcdata&&c.pcdata(n[4],e);else if(n[5]&&c.pcdata)switch(n[5]){case"<":c.pcdata("&lt;",e);break;case">":c.pcdata("&gt;",e);break;default:c.pcdata("&amp;",e)}}c.endDoc&&c.endDoc(e)}}function s(a){return a.replace(m,"&amp;$1").replace(n,"&lt;").replace(o,"&gt;")}function r(a){return a.replace(l,"&amp;").replace(n,"&lt;").replace(o,"&gt;").replace(p,"&#34;").replace(q,"&#61;")}function k(a){return a.replace(j,g)}function i(a){return a.replace(h,"")}function g(a,b){return f(b)}function f(a){a=b(a);if(c.hasOwnProperty(a))return c[a];var f=a.match(d);if(f)return String.fromCharCode(parseInt(f[1],10));if(!!(f=a.match(e)))return String.fromCharCode(parseInt(f[1],16));return""}var b;"script"==="SCRIPT".toLowerCase()?b=function(a){return a.toLowerCase()}:b=function(a){return a.replace(/[A-Z]/g,function(a){return String.fromCharCode(a.charCodeAt(0)|32)})};var c={lt:"<",gt:">",amp:"&",nbsp:"240",quot:'"',apos:"'"},d=/^#(\d+)$/,e=/^#x([0-9A-Fa-f]+)$/,h=/\0/g,j=/&(#\d+|#x[0-9A-Fa-f]+|\w+);/g,l=/&/g,m=/&([^a-z#]|#(?:[^0-9x]|x(?:[^0-9a-f]|$)|$)|$)/gi,n=/</g,o=/>/g,p=/\"/g,q=/\=/g,t=new RegExp("^\\s*(?:(?:([a-z][a-z-]*)(\\s*=\\s*(\"[^\"]*\"|'[^']*'|(?=[a-z][a-z-]*\\s*=)|[^>\"'\\s]*))?)|(/?>)|[\\s\\S][^a-z\\s>]*)","i"),u=new RegExp("^(?:&(\\#[0-9]+|\\#[x][0-9a-f]+|\\w+);|<!--[\\s\\S]*?-->|<!\\w[^>]*>|<\\?[^>*]*>|<(/)?([a-z][a-z0-9]*)|([^<&>]+)|([<&>]))","i");return{escapeAttrib:r,makeHtmlSanitizer:w,makeSaxParser:v,normalizeRCData:s,sanitize:x,unescapeEntities:k}}(html4),html_sanitize=html.sanitize

// stop here if we're not in TiddlyWiki
// XXX: is this the correct way of checking for TiddlyWiki?
if (!window.TiddlyWiki || !window.store || !store instanceof TiddlyWiki) {
	return;
}

var tiddlyspace = config.extensions.tiddlyspace;

var _subWikify = Wikifier.prototype.subWikify;

var cleanedTitle = 'This section has been cleaned of any potentially harmful code';

var replaceFunctions = {
	html: function(w) {
		var sanitizedHTML, spanEl;
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
			sanitizedHTML = $.sanitize(lookaheadMatch[1]);
			spanEl = createTiddlyElement(w.output, 'span', null, 'sanitized');
			spanEl.innerHTML = sanitizedHTML;
			spanEl.setAttribute('title', cleanedTitle);
			w.nextMatch = this.lookaheadRegExp.lastIndex;
		}
	},
	customFormat: function(w) {
		switch(w.matchText) {
			case '@@':
				var e = createTiddlyElement(w.output, 'span');
				var styles = config.formatterHelpers.inlineCssHelper(w);
				if (styles.length === 0) {
					e.className = 'marked';
				}
				w.subWikifyTerm(e, /(@@)/mg);
				break;
			case '{{':
				var lookaheadRegExp = /\{\{[\s]*([\w]+[\s\w]*)[\s]*\{(\n?)/mg;
				lookaheadRegExp.lastIndex = w.matchStart;
				var lookaheadMatch = lookaheadRegExp.exec(w.source);
				if(lookaheadMatch) {
					w.nextMatch = lookaheadRegExp.lastIndex;
					e = createTiddlyElement(w.output,lookaheadMatch[2] == "\n" ? "div" : "span",null,lookaheadMatch[1]);
					w.subWikifyTerm(e,/(\}\}\})/mg);
				}
				break;
		}
	}
};

Wikifier.prototype.subWikify = function(output, terminator) {
	var tid = this.tiddler,
		spaceName = tiddlyspace.currentSpace.name,
		tidSpace, recipeName, stripped;
	try {
		recipeName = tid.fields['server.recipe'] ||
			tid.fields['server.workspace'];
		tidSpace = tiddlyspace.resolveSpaceName(recipeName);
		if (tidSpace !== spaceName) {
			// external tiddler, so replace dangerous formatters
			stripped = stripHTML(tid, this.formatter);
		}
	} catch(e) {
		// do nothing. There's no tiddler, so assume it's safe (?!?!?)
	}

	_subWikify.apply(this, arguments);

	if (stripped) {
		// change back to the original function
		unstripHTML(stripped, this.formatter);
	}
};

// replace potentially unsafe formatters with versions that strip bad HTML/CSS
var stripHTML = function(tid, formatter) {
	var popped = {}, _handler;
	for (var i = 0; i < formatter.formatters.length; i++) {
		var f = formatter.formatters[i];
		if (replaceFunctions[f.name]) {
			_handler = f.handler;
			popped[f.name] = _handler;
			f.handler = replaceFunctions[f.name];
		}
	};

	return popped;
};

// put the original formatters back where they belong
var unstripHTML = function(stripped, formatter) {
	for (var i = 0; i < formatter.formatters.length; i++) {
		var f = formatter.formatters[i];
		if (stripped[f.name]) {
			f.handler = stripped[f.name];
		}
	};
};

})(jQuery);
//}}}
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
<!--{{{-->
<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 written date'></span> (edited <span 
macro='view modified 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>
<!--}}}-->
<!--{{{-->
<link rel="shortcut icon" href="/recipes/dgerod_public/tiddlers/favicon.ico" />
<link href="/bags/dgerod_public/tiddlers.atom" rel="alternate"
	type="application/atom+xml" title="dgerod's public feed" />
<link rel="canonical" href="http://dgerod.tiddlyspace.com/" />
<!--}}}-->
/***
|Name|TaggedTemplateTweak|
|Source|http://www.TiddlyTools.com/#TaggedTemplateTweak|
|Documentation|http://www.TiddlyTools.com/#TaggedTemplateTweakInfo|
|Version|1.6.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|use alternative ViewTemplate/EditTemplate for specific tiddlers|
This plugin extends the core function, story.chooseTemplateForTiddler(), so that any given tiddler can be viewed and/or edited using alternatives to the standard tiddler templates.
!!!!!Documentation
>see [[TaggedTemplateTweakInfo]]
!!!!!Revisions
<<<
2009.09.02 [1.6.1] apply field-based template (if any) *before* tag-based template
| please see [[TaggedTemplateTweakInfo]] for previous revision details |
2007.06.11 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.TaggedTemplateTweak= {major: 1, minor: 6, revision: 1, date: new Date(2009,9,2)};

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

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

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

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

	// look for template using tags as prefix
	var tiddler=store.getTiddler(title);
	if (!tiddler) return coreTemplate; // tiddler doesn't exist... use core result
	for (i=0; i<tiddler.tags.length; i++) {
		var t=tiddler.tags[i]+template; // add tag prefix to template
		var c=t.substr(0,1).toUpperCase()+t.substr(1); // capitalized for WikiWord title
		if (store.getTiddlerText(theme+t))	{ return theme+t; } // theme##tagTemplate
		if (store.getTiddlerText(theme+c))	{ return theme+c; } // theme##TagTemplate
		if (store.getTiddlerText(t)) 		{ return t; }	    // tagTemplate
		if (store.getTiddlerText(c))		{ return c; }	    // TagTemplate
	}
	
	// no match... use core result
	return coreTemplate;
}
//}}}
I have an Asus Eee PC 900A since September 2008, it was a present from some friends. I like it a lot, it was one of the best present I have ever received because it is something that I am using every day for Internet surfing.

It was getting old so at the end of 2012 I decided to improve it adding some extra memory and a touchscreen. As I said previously I like a lot the computer but I always missed that it was not touchable.   

After buying the touchscreen kit on eBay for less than 50 USD, it was the time to start work. 
I did this work together with my friend AMV who has more experience than me in soldering electronic components, and he likes to mount and unmount electronic devices.

<<tiddler "Picasa##album" with: d9er0d 5809652901045244353 144>>
I must say that having a touchscreen on the Eee PC is better than I was expecting. Laying on the sofa while I watch TV and surf on my new touchable Eee PC is a very cool experience.

{{center{<<player id=1 flash https://www.youtube.com/v/jWWZtiM083c 400 300>>}}}
You can find more information about how to mount the touchscreen surfing Internet. Some good links I found are:
* http://www.sampletheweb.com/2008/01/21/asus-eee-pc-touchscreen-installation/
* http://www.youtube.com/watch?v=yPIlOuxAWRE
* http://www.youtube.com/watch?v=xgVXNoWf-DA
* http://forum.eeeuser.com/index.php?/topic/56675-asus-eee-900ha-touchscreen-tutorial/
* http://www.thefanclub.co.za/how-to/how-ubuntu-1204-touchscreen-calibration
iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAYAAAA6GuKaAAAABGdBTUEAALGPC/xhBQAACkNpQ0NQSUNDIFByb2ZpbGUAAHgBnZZ3VFNZE8Dvey+90BJCkRJ6DU1KAJESepFeRSUkAUIJGBKwV0QFVxQVaYoiiyIuuLoUWSuiWFgUFLAvyCKgrIuriIplX/QcZf/Y/b6z88ec35s7c+/cmbnnPAAovoFCUSasAECGSCIO8/FgxsTGMfHdAAZEgAPWAHB52VlB4d4RABU/Lw4zG3WSsUygz/p1/xe4xfINYTI/m/5/pcjLEkvQnULQkLl8QTYP5TyU03MlWTL7JMr0xDQZwxgZi9EEUVaVcfIXNv/s84XdZMzPEPFRH1nOWfwMvow7UN6SIxWgjASinJ8jFOSifBtl/XRphhDlNyjTMwTcbAAwFJldIuCloGyFMkUcEcZBeR4ABEryLE6cxRLBMjRPADiZWcvFwuQUCdOYZ8K0dnRkM30FuekCiYQVwuWlccV8JiczI4srWg7AlzvLooCSrLZMtMj21o729iwbC7T8X+VfF796/TvIevvF42Xo555BjK5vtm+x32yZ1QCwp9Da7PhmSywDoGUTAKr3vtn0DwAgnwdA841Z92HI5iVFIslysrTMzc21EAp4FrKCfpX/6fDV859h1nkWsvO+1o7pKUjiStMlTFlReZnpmVIxMzuLyxMwWX8bYnTr/xw4K61ZeZiHCZIEYoEIPSoKnTKhKBltt4gvlAgzRUyh6J86/B/DZuUgwy9zjQKt5iOgL7EACjfoAPm9C2BoZIDE70dXoK99CyRGAdnLi9Ye/TL3KKPrn/XfFFyEfsLZwmSmzMwJi2DypOIcGaNvQqawgATkAR2oAS2gB4wBC9gAB+AM3IAX8AfBIALEgsWAB1JABhCDXLAKrAf5oBDsAHtAOagCNaAONIAToAWcBhfAZXAd3AR94D4YBCPgGZgEr8EMBEF4iArRIDVIGzKAzCAbiA3Nh7ygQCgMioUSoGRIBEmhVdBGqBAqhsqhg1Ad9CN0CroAXYV6oLvQEDQO/Qm9gxGYAtNhTdgQtoTZsDscAEfAi+BkeCm8As6Dt8OlcDV8DG6GL8DX4T54EH4GTyEAISMMRAdhIWyEgwQjcUgSIkbWIAVICVKNNCBtSCdyCxlEJpC3GByGhmFiWBhnjC8mEsPDLMWswWzDlGOOYJoxHZhbmCHMJOYjlorVwJphnbB+2BhsMjYXm48twdZim7CXsH3YEexrHA7HwBnhHHC+uFhcKm4lbhtuH64Rdx7XgxvGTeHxeDW8Gd4FH4zn4iX4fHwZ/hj+HL4XP4J/QyATtAk2BG9CHEFE2EAoIRwlnCX0EkYJM0QFogHRiRhM5BOXE4uINcQ24g3iCHGGpEgyIrmQIkippPWkUlID6RLpAeklmUzWJTuSQ8lC8jpyKfk4+Qp5iPyWokQxpXAo8RQpZTvlMOU85S7lJZVKNaS6UeOoEup2ah31IvUR9Y0cTc5Czk+OL7dWrkKuWa5X7rk8Ud5A3l1+sfwK+RL5k/I35CcUiAqGChwFrsIahQqFUwoDClOKNEVrxWDFDMVtikcVryqOKeGVDJW8lPhKeUqHlC4qDdMQmh6NQ+PRNtJqaJdoI3Qc3YjuR0+lF9J/oHfTJ5WVlG2Vo5SXKVcon1EeZCAMQ4YfI51RxDjB6Ge8U9FUcVcRqGxVaVDpVZlWnaPqpipQLVBtVO1TfafGVPNSS1Pbqdai9lAdo26qHqqeq75f/ZL6xBz6HOc5vDkFc07MuacBa5hqhGms1Dik0aUxpaml6aOZpVmmeVFzQouh5aaVqrVb66zWuDZNe762UHu39jntp0xlpjsznVnK7GBO6mjo+OpIdQ7qdOvM6BrpRupu0G3UfahH0mPrJent1mvXm9TX1g/SX6Vfr3/PgGjANkgx2GvQaTBtaGQYbbjZsMVwzEjVyM9ohVG90QNjqrGr8VLjauPbJjgTtkmayT6Tm6awqZ1pimmF6Q0z2MzeTGi2z6zHHGvuaC4yrzYfYFFY7qwcVj1ryIJhEWixwaLF4rmlvmWc5U7LTsuPVnZW6VY1Vvetlaz9rTdYt1n/aWNqw7OpsLk9lzrXe+7aua1zX9ia2Qps99vesaPZBdlttmu3+2DvYC+2b7Afd9B3SHCodBhg09kh7G3sK45YRw/HtY6nHd862TtJnE44/eHMck5zPuo8Ns9onmBezbxhF10XrstBl8H5zPkJ8w/MH3TVceW6Vrs+dtNz47vVuo26m7inuh9zf+5h5SH2aPKY5jhxVnPOeyKePp4Fnt1eSl6RXuVej7x1vZO9670nfex8Vvqc98X6Bvju9B3w0/Tj+dX5Tfo7+K/27wigBIQHlAc8DjQNFAe2BcFB/kG7gh4sMFggWtASDIL9gncFPwwxClka8nMoLjQktCL0SZh12KqwznBa+JLwo+GvIzwiiiLuRxpHSiPbo+Sj4qPqoqajPaOLowdjLGNWx1yPVY8VxrbG4eOi4mrjphZ6LdyzcCTeLj4/vn+R0aJli64uVl+cvvjMEvkl3CUnE7AJ0QlHE95zg7nV3KlEv8TKxEkeh7eX94zvxt/NHxe4CIoFo0kuScVJY8kuybuSx1NcU0pSJoQcYbnwRapvalXqdFpw2uG0T+nR6Y0ZhIyEjFMiJVGaqCNTK3NZZk+WWVZ+1uBSp6V7lk6KA8S12VD2ouxWCR39meqSGks3SYdy5udU5LzJjco9uUxxmWhZ13LT5VuXj67wXvH9SsxK3sr2VTqr1q8aWu2++uAaaE3imva1emvz1o6s81l3ZD1pfdr6XzZYbSje8Gpj9Ma2PM28dXnDm3w21efL5YvzBzY7b67agtki3NK9de7Wsq0fC/gF1wqtCksK32/jbbv2nfV3pd992p60vbvIvmj/DtwO0Y7+na47jxQrFq8oHt4VtKt5N3N3we5Xe5bsuVpiW1K1l7RXunewNLC0tUy/bEfZ+/KU8r4Kj4rGSo3KrZXT+/j7eve77W+o0qwqrHp3QHjgzkGfg83VhtUlh3CHcg49qYmq6fye/X1drXptYe2Hw6LDg0fCjnTUOdTVHdU4WlQP10vrx4/FH7v5g+cPrQ2shoONjMbC4+C49PjTHxN+7D8RcKL9JPtkw08GP1U20ZoKmqHm5c2TLSktg62xrT2n/E+1tzm3Nf1s8fPh0zqnK84onyk6Szqbd/bTuRXnps5nnZ+4kHxhuH1J+/2LMRdvd4R2dF8KuHTlsvfli53uneeuuFw5fdXp6qlr7Gst1+2vN3fZdTX9YvdLU7d9d/MNhxutNx1vtvXM6znb69p74Zbnrcu3/W5f71vQ19Mf2X9nIH5g8A7/ztjd9Lsv7uXcm7m/7gH2QcFDhYcljzQeVf9q8mvjoP3gmSHPoa7H4Y/vD/OGn/2W/dv7kbwn1Cclo9qjdWM2Y6fHvcdvPl34dORZ1rOZifzfFX+vfG78/Kc/3P7omoyZHHkhfvHpz20v1V4efmX7qn0qZOrR64zXM9MFb9TeHHnLftv5Lvrd6Ezue/z70g8mH9o+Bnx88Cnj06e/AAOb8/zszueKAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAIeUlEQVRYCe1Zb2xb1RU/9/k9O26TJqVpSByn+UNC3JZuQMukaWirBR9BGtJAIAqlEkgg+ABCsLVFWhAU0DRp8IlNYkIskSYhPvKBDxRvKIwVSin9Q9MmTRziJG7aQtrYcWw/v7tzrn1v3nOe/eIC+cKOZN97zz3n3J/vO+/cc48B/k9rswPs+y5z8B+xXZxZd6GdfuDsZmDQhf06m91L2E9wYMMA1iQ3tfde2xeN2+Zr7l4T6IG3Y01Z3XqUAduLK0bwo9e48jD+wL/7O2BoIBo1a9TFfamBBt6N1edz8HvO+dOoVu9QZYw3bWiAYF2A+f0B0A0f5HJ5sKwCLKQWIZ1ehEKh4FQBSALnLxod2lu1gF816BcGY7stxt8GLh6/WFzXdau1pVlrb2uFhoZ68Pl8DlD2Af5QmJ+/ComZGZi9cBGxcjWNID7IM/bYn/ZEE4pZpbMq0PuHDv+BcfYS2hFuQGB7ezq1jvYQaJpWxbz7VDabg6npGRiPf6PAI5Aks9hDL++Nfuiutcz1BH1gKPYmWn5cqoTbQ1akr0ertqtS1qtdSKXg5Omz6D4pJcoZu/fVPdH3FMOlUxW0HTDTNL5jW4S1Xb/Zxcy1s8hNRs9PwMTklDRiIvB7EPj7klHeVgR9YPDwAAD7IymQO+z8+U1aU1Njuf4PNp6cSsDIufPSXgqjyy9feTh6SjLsrSvoYuzln6Kg7tN81q5bdvyogCWgsfE4nJ+YLA45jPjr2G0D90WXfackuOItorDGgQ8SYJLZvq1/TQDTWr09XaDcj0Ekm4VXiV9OK0Bnc9ZTGL3pwICOcGjZSLnmjzTe2t8HgYBfWGfAn6KnXr6U4ySjXc5l+ZMk5DN03t/b4+o+5UbEuGCBPpkEfWoOtMtXgeHBAj4NrOs2gBneDGZPCLjhWM7VjGEYELmxD746ebo0b9F7dbdd2AHq4NDhpzlnfyGBvt5u6OncYpet2DfOTELgszNFoBWkuN+A7G0RyG/rqiDhZB/54jgeRleIidvBIq89FB2TEg73QMAP0gQGYd4ZbpcylVuLQ/DwF1A3fMIBWNN9YAT9QK0k2vm6T06i/FEBQ/IrtX3dXXLKpzF4Vg6oVTv9/FAsrHM+gTw9HGqF7Vv77XKufQKsj8+IOcYYNIY2QRO6grG+DmhMlF/Mwvz0JZhHt5FHt9nTBpnoTtwdtbyQLf/65MhRSKXSxL7sD7AuGUnUThvc+i1OCqcLtbaW668Yk0vYAYdv6YWWyBbw1wcVYFIy1gVgc187hHfeCKyUm+jjs2CMTK6wWc5obVEH2SY8+XfLeQXa4toNxKTjubGxQc67t+hl5MNEtKPhW/sguLG6TrBxPdAP00q7G/h8xOFSbguFWq9XbI3Db+RAgcbM8nZirgsGPZMgfWJGLdjY3gzBJmeWKo2XtwS8Mdwi2OTj+sRsuYhjHAzW0WkseBZwFfoUaJzpotmG+nXUVCUdfVRSE4KuhezyeuKip2pDw3ohg94flsJ20GL1QCAg5yq2FIeJRJTAl64WIh+XUUX7tminmv463O0SdciOHbTgaXggeJE4OFDIh7cTGSW8dOzzpCcI3w0v8hvF0xHl1G6uQGitwhAdFESFfEGFMcFY5RfpCVrFBrltoh30EhnKYpbiRdamDULEMguQTws1LxU1T3Gb9IjoiPcit01cBs0hTgbSGW8Qpu3lo4OjFrLLU07iRTm8SZdoXnYUaAy3cWIuLKTwBl3d18xuTH5KLnIFQWfmU9Je1TZzJQ1XEnNChvTN7raq8jRJN/kSxWVHgcY3CpMCfGQIOL2oBKWcs0VfzP5iq+DR0Zw4NuoJnAAnvhxD+1zoUfIkf7jT+PKIbFPpgahY7CnOKdCsAP8usgAuzHk/8vzWTpFuCoMl4HNnpyCXdr4T+UwOLo5Ow/Sxc8BLdQ/KPfKRTrlcxfbq1QVbrcRS575KcHULhvMaJHEfWmeTc+IWUdFaaSITvRWCuAeUS9CuzONhQR+KwxTWKErIl07aIsBLv77ZM1ki+SmskUjCi7UqLaidHtgXXeKMf0BCi5kMXLr8nZSv3GIekbljFyz9aofjUYuogjtsB0yuQHKU3a3mMmCaJj7xy3Lt4688GD0uB2qnBYNpb+CWPUL9sYk4NG/aKNheX5TY5/u3YC4xA8bURWDfLRRzE3lzCTWDecPyy+tlj+anZ5NAwIkwL3pHdEpfeKQ7af/gRzFk7ibuz27atuZ3RFqXwH78n88gn8crG8C832Td6AkrQx7NEmmcPYeN+Ilnzo7iYaPipJhfi6/R83EJGLAc91c7YFpf+bQEc+jh6FEs4b5OY/qlI+dG5dSatHOXvhV1vtJiY0YdHCpfeAVoEjDCsB+bU9RPYvijIspaENX0Tpz6WuUzuMv75BXLvr4raFEr5uwBFBQBm6o+tlqbXf8H69PN+/NjJ1RcxuzxZXzqw24LuIImQaqjaZYALs7oc2PjQB95OXUzdq08qlcfPX5S+TGef0NGO7xYyd6K6FEuuH8o9jvG+T+RL8JjQ3097Njejzec+nLRmsf0z8DpM2dFkX1Zmb/lD2tPVPtnwBM0GXvhndidlob/ApSuPJT4d20JAxXV6R5XK9HTmp69gO/KhCM6YTx+5tCeO0QQqGZzVaDJANVFDMt6E2vHdymDuEpbSzMLtbXBdRsbPS/EVMNIzCTx5Z5zghX/vbB7K/mwWq/UWTVoqXhgMPYoBs+D9v9eaI6qUuuDQUYXY7pn0o2DEnjKh9OLS0DJj0vKa2KE+DOFNbcoIdcsb2sGTQYGYjE9Nw33Y0l4L+NwZ7lRrzEumsTDeQjvL3+z1+i89OT8NYGWytQKt8HqFBV70FtuR1YXfsTNHluiJXwqcbpk4I88ooH2L92E/1KCVpz+iXz/D36BLy8VVzwEAAAAAElFTkSuQmCC
[[ShCore.css]]
[[ShThemeDefault.css]]
/***
|''Name''|BinaryTiddlersPlugin|
|''Description''|renders base64-encoded binary tiddlers as images or links|
|''Author''|FND|
|''Version''|0.3.2|
|''Status''|@@beta@@|
|''Source''|http://svn.tiddlywiki.org/Trunk/association/plugins/BinaryTiddlersPlugin.js|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''CoreVersion''|2.5|
!Code
***/
//{{{
(function($) {

"use strict";

var ctfield = "server.content-type";

var plugin = config.extensions.BinaryTiddlersPlugin = {
	isWikiText: function(tiddler) {
		var ctype = tiddler.fields[ctfield];
		if(ctype) {
			if (ctype === 'text/x-tiddlywiki') {
				return true;
			}
			return !this.isBinary(tiddler) && !this.isTextual(ctype);
		} else {
			return true;
		}
	},
	// NB: pseudo-binaries are considered non-binary here
	isBinary: function(tiddler) {
		var ctype = tiddler.fields[ctfield];
		return ctype ? !this.isTextual(ctype) : false;
	},
	isTextual: function(ctype) {
		return ctype.indexOf("text/") === 0
			|| this.endsWith(ctype, "+xml")
			|| ctype === 'application/json'
			|| ctype === 'application/javascript';
	},
	endsWith: function(str, suffix) {
		return str.length >= suffix.length &&
			str.substr(str.length - suffix.length) === suffix;
	},
	isLink: function(tiddler) {
		return this.isBinary(tiddler) && tiddler.text.indexOf("<html>") !== -1;
	}
};

// Disable edit for linked tiddlers (for now)
// This will be changed to a GET then PUT
config.commands.editTiddler.isEnabled = function(tiddler) {
    var existingTest = config.commands.editTiddler.isEnabled;
    if (existingTest) {
        return existingTest && !plugin.isLink(tiddler);
    } else {
        return !plugin.isLink(tiddler);
    }
};

// hijack text viewer to add special handling for binary tiddlers
var _view = config.macros.view.views.wikified;
config.macros.view.views.wikified = function(value, place, params, wikifier,
		paramString, tiddler) {
	var ctype = tiddler.fields["server.content-type"];
	if(params[0] === "text" && ctype && ctype !== 'text/x-tiddlywiki' &&
			!tiddler.tags.contains("systemConfig") && !plugin.isLink(tiddler)) {
		var el;
		if(plugin.isBinary(tiddler)) {
			var uri = "data:%0;base64,%1".format([ctype, tiddler.text]); // TODO: fallback for legacy browsers
			if(ctype.indexOf("image/") === 0) {
				el = $("<img />").attr("alt", tiddler.title).attr("src", uri);
			} else {
				el = $("<a />").attr("href", uri).text(tiddler.title);
			}
		} else {
			el = $("<pre />").text(tiddler.text);
		}
		el.appendTo(place);
	} else {
		_view.apply(this, arguments);
	}
};

// hijack edit macro to disable editing of binary tiddlers' body
var _editHandler = config.macros.edit.handler;
config.macros.edit.handler = function(place, macroName, params, wikifier,
		paramString, tiddler) {
	if(params[0] === "text" && plugin.isBinary(tiddler)) {
		return false;
	} else {
		_editHandler.apply(this, arguments);
	}
};

// hijack autoLinkWikiWords to ignore binary tiddlers
var _autoLink = Tiddler.prototype.autoLinkWikiWords;
Tiddler.prototype.autoLinkWikiWords = function() {
	return plugin.isWikiText(this) ? _autoLink.apply(this, arguments) : false;
};

}(jQuery));
//}}}
/***
|''Name''|ImageMacroPlugin|
|''Version''|0.9.4|
|''Description''|Allows the rendering of svg images in a TiddlyWiki|
|''Author''|Osmosoft|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''Notes''|Currently only works in modern browsers (not IE)|
|''Requires''|BinaryTiddlersPlugin|
!Usage
{{{<<image SVG>>}}} will render the text of the tiddler with title SVG as an SVG image (but not in ie where it will fail silently)
!!Parameters
width/height: specify width/height parameters
link: make the image link to a given location
tiddlyLink: link to a tiddler

!Notes
Binary tiddlers in TiddlyWeb when passed through the wikifier will be shown as images.
eg. {{{<<view text wikified>>}}} on a binary tiddler will show the image.
{{{<<view fieldname image>>}}}
will render the value of the tiddler field 'fieldname' as an image. This field can contain a tid
{{{<<image SiteIcon>>}}}
will create an image tag where the tiddler has content type beginning image and not ending +xml
will attempt to create svg object in other scenarios
{{{<<image /photos/x.jpg>>}}}
will create an image tag with src /photos/x.jpg as long as there is not a tiddler called /photos/x.jpg in 
which case it will render that tiddler as an image. Note for the case of svg files it will attempt to render as an svg if possible via the image
tag. It doesn't embed the svg in the dom for security reasons as svg code can contain javascript.
!Code
***/
//{{{
(function($) {

var macro = config.macros.image = {
	shim: "/bags/common/tiddlers/shim",
	ieVersion: config.browser.isIE ? parseInt(config.browser.ieVersion[1], 10) : false,
	svgns: "http://www.w3.org/2000/svg",
	xlinkns: "http://www.w3.org/1999/xlink", 
	svgAvailable: document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"),
	_fixPrefix: 1,
	_external_cache: {},
	_image_tag_cache: {},
	_image_dimensions: {},
	locale: {
		badImage: "This image cannot be displayed."
	},
	handler: function(place, macroName, params, wikifier, paramString, tiddler){
		var imageSource = params[0];
		// collect named arguments
		var args = macro.getArguments(paramString, params);
		this.renderImage(place, imageSource, args);
	},
	init: function() {
		var startupImages = store.getTaggedTiddlers("systemImage");
		var place = $("<div />").attr("id", "systemImageArea").appendTo("body").hide()[0];
		for(var i = 0; i < startupImages.length; i++) {
			var image = startupImages[i];
			macro.renderImage(place, image.title, { idPrefix: "" });
		}
		var data = new Image();
		data.onload = function() {
			// note ie 8 only supports data uris up to 32k so cannot be relied on
			macro.supportsDataUris = this.width != 1 || this.height != 1 ? false : true;
			macro.supportsDataUris = macro.ieVersion && macro.ieVersion < 9 ? false : macro.supportsDataUris;
		};
		data.onerror = data.onload;
		data.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
	},
	refreshImage: function(src) {
		var elements = macro._image_tag_cache[src] ? macro._image_tag_cache[src] : [];
		if(macro._image_dimensions[src]) {
			macro._image_dimensions[src] = false;
		}
		for(var i = 0; i < elements.length; i++) {
			var el = $(elements[i]);
			var newSrc = "%0?nocache=%1".format(src, Math.random());
			el.attr("src", newSrc); // force reload
		}
	},
	isBinaryImageType: function(contentType) {
		return (contentType && contentType.indexOf("image") === 0 &&
			contentType.indexOf("+xml") != contentType.length - 4) ? true : false;
	},
	isImageTiddler: function(tiddler) {
		return macro.isSVGTiddler(tiddler) || macro.isBinaryImageTiddler(tiddler);
	},
	isSVGTiddler: function(tiddler) {
		var type = tiddler ? tiddler.fields['server.content-type'] : false;
		return type == "image/svg+xml";
	},
	isBinaryImageTiddler: function(tiddler) {
		return macro.isBinaryImageType(tiddler.fields['server.content-type']);
	},
	renderImage: function(place, imageSource, options) {
		var imageTiddler = store.getTiddler(imageSource);
		var container;
		var classes = ["image"];
		if(options.link) {
			classes = classes.concat(["imageLink", "externalLink"]);
			container = $("<a />").attr("href", options.link).appendTo(place)[0];
		} else if(options.tiddlyLink) {
			classes.push("imageLink");
			container = createTiddlyLink(place, options.tiddlyLink, false);
		} else {
			container = $("<span />").appendTo(place)[0];
		}
		$(container).addClass(classes.join(" "));

		options = options ? options : {};
		if(imageTiddler && macro.isBinaryImageTiddler(imageTiddler)) { // handle the case where we have an image url
			return macro._renderBinaryImageTiddler(container, imageTiddler, options);
		} else if(imageTiddler){ // handle the case where we have a tiddler
			return macro._renderSVGTiddler(container, imageTiddler, options);
		} else { // we have a string representing a url
			return macro._renderBinaryImageUrl(container, imageSource, options);
		}
	},
	_renderAlternateText: function(container, options) {
		var img;
		var src = options.src || "";
		if(options.width && options.height) {
			img = $("<img />").attr("src", src).addClass("svgImageText").attr("width", options.width).
				attr("height", options.height).appendTo(container);
		}
		var alt = options.alt;
		if(img && alt) {
			img.attr("alt", alt).attr("title", alt);
		} else if(alt) {
			$(container).addClass("svgImageText").text(alt);
		}
		macro._image_tag_cache[src] = img;
	},
	_renderSVGTiddler: function(place, tiddler, options) {
		if(!options) {
			options = {};
		}
		merge(options, { tiddler: tiddler, fix: true});

		if(macro.svgAvailable) {
			this._importSVG(place, options); // display the svg
		} else if(options.altImage) {
			var image = options.altImage;
			delete options.altImage;
			this._renderBinaryImageUrl(place, image, options);
		} else {
			this._renderAlternateText(place, options); // instead of showing the image show the alternate text.
		}
	},
	_renderBinaryImageTiddler: function(place, tiddler, options) {
		var resourceURI;
		var fields = tiddler.fields;
		if(fields["server.type"] == "tiddlyweb") { // construct an accurate url for the resource
			resourceURI = "%0/%1/tiddlers/%2".format(config.defaultCustomFields["server.host"],
				fields["server.workspace"], encodeURI(fields["server.title"]));
		} else { // guess the url for the resource
			resourceURI = tiddler.title;
		}
		var ctype = fields["server.content-type"] || tiddler.type;
		var text = tiddler.text;
		if(macro.supportsDataUris && ctype && text.indexOf("<html") == -1) {
			var uri = "data:%0;base64,%1".format(ctype, text);
			options.src = resourceURI;
			return macro._renderBinaryImageUrl(place, uri, options);
		} else if(options.src) {
			return macro._renderBinaryImageUrl(place, options.src, options);
		} else {
			return macro._renderBinaryImageUrl(place, resourceURI, options);
		}
	},
	_renderImageTag: function(container, src, width, height, options) {
		var img;
		img = $("<img />").appendTo(container);
		if(height) {
			img.attr("height", height);
		}
		if(width) {
			img.attr("width", width);
		}
		if(macro.ieVersion && macro.ieVersion < 7 && macro.shim && options.ie6png) {
			$(img).css({width: userW, height: userH,
					filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='%0', sizingMethod='scale')".format(src)
				}).attr("src", macro.shim);
		} else {
			img.attr("src", src);
		}
		if(!macro._image_tag_cache[options.srcUrl]) {
			macro._image_tag_cache[options.srcUrl] = [];
		}
		img = $(img).addClass(options.imageClass)[0];
		macro._image_tag_cache[options.srcUrl].push(img);
		return img;
	},
	_getDimensions: function(realDimensions, reqDimensions, preserve) {
		var w = realDimensions.width;
		var h = realDimensions.height;
		var reqh = reqDimensions.height;
		var reqw = reqDimensions.width;
		var finalw = w, finalh = h;
		var ratiow = reqw / w, ratioh = reqh / h;
		var scaledw = ratioh * w;
		var scaledh = ratiow * h;
		if(!reqw && reqh) {
			finalw = scaledw;
			finalh = reqh;
		} else if(reqw && !reqh) {
			finalw = reqw;
			finalh = scaledh;
		} else if(reqh && reqw) {
			var preserveWidth = w > h ? true : false;
			if(preserve) {
				if(preserveWidth && scaledh < reqh) {
					finalh = scaledh;
					finalw = reqw;
				} else {
					finalh = reqh;
					finalw = scaledw;
				}
			} else {
				finalw = reqw;
				finalh = reqh;
			}
		}
		return { width: parseInt(finalw, 10), height: parseInt(finalh, 10) };
	},
	_renderBinaryImageUrl: function(container, src, options) {
		var srcUrl = options.src ? options.src : src;
		srcUrl = srcUrl.indexOf("/") === -1 ? "/%0".format(srcUrl) : srcUrl; // for IE. 
		var image_dimensions = macro._image_dimensions[srcUrl];
		var image = new Image(); // due to weird scaling issues where you use just a width or just a height
		var createImageTag = function(dimensions, error) {
			if(error) {
				var altImage = options.altImage;
				if(altImage) {
					delete options.altImage;
					macro._renderBinaryImageUrl(container, altImage, options);
				} else {
					options.src = src;
					macro._renderAlternateText(container, options);
				}
			} else {
				var dim = macro._getDimensions(dimensions, { 
					width: options.width, height: options.height }, options.preserveAspectRatio);
				options.srcUrl = srcUrl;
				macro._renderImageTag(container, src, dim.width, dim.height, options);
			}
		};

		if(!image_dimensions) {
			image.onload = function() {
				var dimensions = { width: image.width, height: image.height};
				macro._image_dimensions[srcUrl] = dimensions;
				createImageTag(dimensions);
			};
			image.onerror = function() {
				createImageTag(null, true);
			};
			image.src = src;
		} else {
			createImageTag(image_dimensions);
		}
	},
	_generateIdPrefix: function(){
		return "twsvgfix_" + (this._fixPrefix++).toString() + "_";
	},
	_fixSVG: function(childNodes, idPrefix) {
		var urlPattern = /url\(\#([^\)]*)\)*/ig;
		var fixes = [
		{ attr: "id", pattern: /^(.*)$/ig },
		{ attr: "href", namespace: macro.xlinkns, pattern: /^#(.*)$/ig }
		];
		var url_fixes = ["filter", "fill", "mask", "stroke", "style"];
		for(var i = 0; i < url_fixes.length; i++) {
			fixes.push({ attr: url_fixes[i], pattern: urlPattern });
		}
		for(var t = 0; t < childNodes.length; t++) {
			var node = childNodes[t];
			for(var a = 0; a < fixes.length; a++) {
				var fix = fixes[a];
				var attr = fix.attr;
				var ns = fix.namespace || "";
				if(node.hasAttributeNS && node.hasAttributeNS(ns, attr)) {
					var v = node.getAttributeNS(ns, attr);
					fix.pattern.lastIndex = 0;
					var match = fix.pattern.exec(v);
					if(match) {
						// Make sure replacement string doesn't contain any single dollar signs
						var toReplace = match[1];
						if(toReplace.indexOf(idPrefix) !== 0 && toReplace.indexOf("twglobal_") !== 0) {
							var replacement = (idPrefix + toReplace).replace("$", "$$$$"); 
							v = v.replace(match[1], replacement);
						}
						node.setAttributeNS(ns, attr,v);
					}
				}
			}
			var children = node.childNodes;
			if(children.length > 0) {
				this._fixSVG(children, idPrefix);
			}
		}
	},
	_importSVG: function(place, options){
		options = options ? options : {};
		var svgDoc, tiddlerText = options.tiddler.text;
		if (window.DOMParser) {
			svgDoc = new DOMParser().parseFromString(tiddlerText, "application/xml").documentElement;
			var idPrefix = options.idPrefix || this._generateIdPrefix();
			this._fixSVG([svgDoc], idPrefix);
			var el = document.importNode(svgDoc, true);
			var svgHolder = document.createElementNS(macro.svgns,"svg");
			var width = options.width;
			var height = options.height;
			if(width || height) {
				if(width && height) { // set view box of containing svg element based on the svg viewbox and width and height.
					var viewBox = el.getAttribute("viewBox");
					var topLeft = "0 0";
					if(viewBox) {
						topLeft = viewBox.replace(/([0-9]*) +([0-9]*) +([0-9]*) +([0-9]*) */gi,"$1 $2");
					}
					svgHolder.setAttributeNS(macro.svgns, "viewBox", "0 0 %0 %1".format(width, height));
				} else {
					if(!width) {
						width = el.getAttribute("width");
					}
					if(!height) {
						height = el.getAttribute("height");
					}
				}
				svgHolder.setAttribute("width", width);
				svgHolder.setAttribute("height", height);

				el.setAttribute("width", "100%");
				el.setAttribute("height", "100%");
				svgHolder.setAttribute("class", "svgImage svgIcon %0".format(options.imageClass || ""));
				svgHolder.appendChild(el);
				place.appendChild(svgHolder);
			}
			else {
				var existing = el.className ? el.className.baseVal : "";
				el.setAttribute("class","svgImage %0".format(existing));
				place.appendChild(el);
			}
			// if a tiddler attribute is set this is read as a link
			$("[tiddler], [tiddlyLink]", place).attr("refresh", "link").click(function(ev) {
				var tiddler = $(ev.target).attr("tiddlyLink");
				if(tiddler) {
					story.displayTiddler(ev.target, tiddler);
				}
			});
		}
	},
	getArguments: function(paramString, params) {
		var args = paramString.parseParams("name", null, true, false, true)[0];
		var options = {};
		for(var id in args) {
			if(true) {
				var p = args[id];
				if(id == "def") {
					options[id] = p;
				} else {
					options[id] = p[0];
				}
			}
		}
		var width = isNaN(params[1]) ? false : parseInt(params[1], 10);
		var height = isNaN(params[2]) ? false : parseInt(params[2], 10);

		options.width = macro.lookupArgument(options, "width", width);
		options.height = macro.lookupArgument(options, "height", height);
		options.preserveAspectRatio = args.preserveAspectRatio && 
			args.preserveAspectRatio[0] == "yes" ? true : false;
		options.tiddlyLink = macro.lookupArgument(options, "tiddlyLink", false);
		options.link = macro.lookupArgument(options, "link", false);
		return options;
	},
	lookupArgument: function(args, id, ifEmpty) {
		return args[id] ? args[id] : ifEmpty;
	}
};

// update views
var _oldwikifiedview = config.macros.view.views.wikified;
// update wikifier to check tiddler type before rendering
merge(config.macros.view.views, {
	wikified: function(value, place, params, wikifier, paramString, tiddler) {
		if(macro.isImageTiddler(tiddler) && params[0] == "text") {
			var newplace = $("<div />").addClass("wikifiedImage").appendTo(place)[0];
			macro.renderImage(newplace, tiddler.title, { alt: macro.locale.badImage });
		} else {
			_oldwikifiedview.apply(this, arguments);
		}
	},
	image: function(value, place, params, wikifier, paramString, tiddler) {
		// a field can point to another tiddler whereas text is the current tiddler.
		var title = params[0] == "text" ? tiddler.title : value;
		var args = macro.getArguments(paramString, params);
		macro.renderImage(place, title, args);
	}
});
config.shadowTiddlers.StyleSheetImageMacro = [".wikifiedImage svg, .wikifiedImage .image { width: 80%; }",
	".svgImageText { background-color:[[ColorPalette::Error]]; color:#ddd; display: inline-block; }",
	"span.svgImageText { display: inline-block; overflow: hidden; }"
].join("");
store.addNotification("StyleSheetImageMacro", refreshStyles);

})(jQuery);
//}}}
http://dgerod.tiddlyspace.com
/*{{{*/
Background: rgb(227,241,227)
Foreground: rgb(13,27,13)
PrimaryPale: rgb(255,255,255)
PrimaryLight: rgb(189,222,189)
PrimaryMid: rgb(65,130,65)
PrimaryDark: rgb(39,78,39)
SecondaryPale: rgb(255,255,255)
SecondaryLight: rgb(222,193,189)
SecondaryMid: rgb(130,73,65)
SecondaryDark: rgb(78,44,39)
TertiaryPale: rgb(255,255,255)
TertiaryLight: rgb(189,193,222)
TertiaryMid: rgb(65,73,130)
TertiaryDark: rgb(39,44,78)
Error: #f88
/*}}}*/
Unless you're delighted with the default theme you can make some quick changes by generating a new random color palette, hit this button to cycle through some alternatives.

<<RandomColorPaletteButton saturation_pale:0.67 saturation_light:0.53
saturation_mid:0.43 saturation_dark:0.06 pale:0.99 light:0.85 mid:0.5 dark:0.31>>

You can also change the look and feel completely by installing a new theme. To do this, find one you like in the @themes space, note down the name, and include it in this space by going to the space menu. You can reach the space menu by clicking on the blue and pink circle at the top-right of the page and chooshing "THIS SPACE". Here are a few to check out:
* @pip
* @caspian-ii
* @basalt
* @simplicity
* @cheesecake
* @jelly-doughnut

(//Note that if you are using a custom TiddlySpace install, these themes may not be present.//)
A delta-2 robot is a parallel robot composed by two legs, each one has three rational joints but only the one attached to the fixed-frame (or top-plate) is not a passive joint. Therefore, to move the end-effector position (//TCP-0//) of the robot the two active joints must be controlled.

The delta-2 robot can be seen as a simplification of the [[delta-3 robot|http://en.wikipedia.org/wiki/Delta_robot]], and it is usually used in the packaging industry for pick products on a conveyor belt. You can see some models in Codian Robotics [[web page|http://codian-robotics.com/en/robotics/d2-robots]] and a video of two delta-2 robots working in [[you tube|http://www.youtube.com/watch?v=Z1KTCXi2IW0]].

{{center{[img[https://lh6.googleusercontent.com/-4hkcHL0zrFA/T7jUyQp0oiI/AAAAAAAAAHM/adLc0--zsOY/s288/D2R_RealRobot.png]]}}}
Due to its mechanical configuration this robot can only move its end-effector on plane XZ, see figure belowt. And its //TCP-0// is defined by //(x,0,z)//.

{{center{[img[https://lh4.googleusercontent.com/-HiBTYwDPmN4/T_BMqxfs0JI/AAAAAAAAAM4/Yo0TtxZ3Y_s/s288/D2R_ConfParams.png]]}}}
The kinematics of the delta-2 robot can be solved using a geometric method. For doing this, we model the robot (see figure abowe) using four kinematics parameters: $r_{f}$,$ l_{f}$, $l_{e}$, $r_{e}$.
The parameter $r_{f}$ is the distance between the center of the fixed-frame to the position of the active joint, $r_{e}$ is the distance between the center of the end-effector (//E//) and the position of the passive joint (//F//), and $l_{f}$ and $l_{e}$ are the lengths of the links of a leg. And the link 1 and link 2 of a robot leg are connected in point //G//.

The [[algorithms|https://github.com/dgerod/robotics-utils]] for solving the Kinematics Problem of the delta-2 robot have been developed using [[Scilab|http://www.scilab.org]].

!!! Inverse kinematics

For knowing the joins $(j_{1},j_{2})$ from the end-effector position (//TCP-0//) we must solve the inverse kinematics problem.

{{center{[img[https://lh6.googleusercontent.com/-61gF-sMcINY/T_BMqddcZUI/AAAAAAAAAM0/7fxfR82sGBg/s400/D2R_InvKinem.png]]}}}

For obtain the joint value of a leg we need to calculate the point //G//, it is calculated by the intersection of two circle. The first circle (green) is defined by its center //E//, the position of the end-effector, and length of link 2 ($l_{e}$) as radius. And the second circle (red) has point //F// as center and the length link 1 ($l_{f}$) as radius.
Once you know position of //G//, the value of the joint is calculated as the angle defined by the axis X and the line that connect //F// with //G//, that's the real position of the link 1.

This method is applied independently for each leg of the robot.

!!! Direct kinematics

And we can calculated the end-effector position (//TCP-0//) from the joint values //$(j_{1},j_{2})$// solving the kinematics problem.

{{center{[img[https://lh6.googleusercontent.com/-LjNdU5VXP9I/T_BMqH4pb4I/AAAAAAAAAMw/8kskr6CZ0Tc/s400/D2R_DirKinem.png]]}}}

The end-effector position (//E//) is obtained from the intersection of the two circles (cyan) defined by the link 2 of each robot leg. The center of each circles is defined by //G// and the radius by the length of the link ($l_{e}$). And the point //G// is calculated by trigonometry using the value of the joint, the length of the link 1 ($l_{f}$) and the position of //F//.
Links to source code, documents and more:
* CAD model of delta-2 robot in [[DXF|https://docs.google.com/open?id=0ByovaZlEMcTJUFZEblFpM0VKUjQ]] and [[PDF|https://docs.google.com/open?id=0ByovaZlEMcTJTlVuMVFmZ1I4dzA]].
* CAD model of delta-3 robot in [[DXF|https://docs.google.com/open?id=0ByovaZlEMcTJVlozM2lpNkdXLUE]] and [[PDF|https://docs.google.com/open?id=0ByovaZlEMcTJRlZwNl9zb2RhdUE]]. 
* The [[robotics-utils|https://github.com/dgerod/robotics-utils]] for Scilab and other languages.
* Note taking [[application|https://github.com/dgerod/tw-wnb]] based on TiddlyWiki.
* My [[Picasa Web|https://picasaweb.google.com/101542046887408327725]] albums and my [[YouTube|https://www.youtube.com/channel/UCRX6SIvzNbPf7FUBhXc7iAw]] channel.
* The [[source code|https://github.com/dgerod/dgerod-web]] of my web including this site.
* My code repositories in [[GitHub|https://github.com/dgerod]].


<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->

<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:xlink="http://www.w3.org/1999/xlink"
   version="1.1"
   width="14pt"
   height="14pt"
   viewBox="918 510 14 14"
   id="svg3070">
  <metadata
     id="metadata3089">
    <rdf:RDF>
      <cc:Work
         rdf:about="">
        <dc:format>image/svg+xml</dc:format>
        <dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
        <dc:title></dc:title>
      </cc:Work>
    </rdf:RDF>
  </metadata>
  <defs
     id="defs3072">
    <radialGradient
       cx="0"
       cy="0"
       r="1"
       id="Gradient"
       gradientUnits="userSpaceOnUse">
      <stop
         id="stop3075"
         style="stop-color:#ffffff;stop-opacity:1"
         offset="0" />
      <stop
         id="stop3077"
         style="stop-color:#2b2b2b;stop-opacity:1"
         offset="1" />
    </radialGradient>
    <radialGradient
       id="Obj_Gradient"
       xlink:href="#Gradient"
       gradientTransform="matrix(11.473944,0,0,11.473944,922.3752,513.7837)" />
  </defs>
  <g
     id="g3080"
     style="fill:none;stroke:none">
    <g
       id="g3082">
      <path
         d="m 929.6952,512.9018 c -2.5384,-2.53843 -6.654,-2.53843 -9.1924,0 -2.5384,2.5384 -2.5384,6.654 0,9.19238 2.5384,2.53839 6.654,2.53839 9.1924,0 2.5384,-2.53838 2.5384,-6.65398 0,-9.19238 m -4.5962,2.8407 2.07733,-2.07734 1.75547,1.75549 -2.0773,2.07735 2.0773,2.07732 -1.75547,1.75548 -2.07733,-2.07732 -2.07733,2.07732 -1.75547,-1.75548 2.0773,-2.07732 -2.0773,-2.07735 1.75547,-1.75549 z"
         id="path3084"
         style="fill:url(#Obj_Gradient)" />
      <path
         d="m 927.61447,515.38354 a 4.51205,4.2590378 0 1 1 -9.0241,0 4.51205,4.2590378 0 1 1 9.0241,0 z"
         transform="matrix(1.0218069,0,0,1.0462046,-18.063694,-21.648443)"
         id="path2394"
         style="fill:#000000;fill-opacity:0;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
    </g>
  </g>
</svg>
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
/*{{{*/
body {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}

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

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::Background]];}
.headerShadow {color:[[ColorPalette::Foreground]];}
.headerShadow a {font-weight:normal; color:[[ColorPalette::Foreground]];}
.headerForeground {color:[[ColorPalette::Background]];}
.headerForeground a {font-weight:normal; color:[[ColorPalette::PrimaryDark]];}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

#backstageArea {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::TertiaryMid]];}
#backstageArea a {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstageArea a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; }
#backstageArea a.backstageSelTab {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
#backstageButton a {background:none; color:[[ColorPalette::Background]]; border:none;}
#backstageButton a:hover {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstagePanel {background:[[ColorPalette::Background]]; border-color: [[ColorPalette::Background]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]];}
.backstagePanelFooter .button {border:none; color:[[ColorPalette::Background]];}
.backstagePanelFooter .button:hover {color:[[ColorPalette::Foreground]];}
#backstageCloak {background:[[ColorPalette::Foreground]]; opacity:0.6; filter:alpha(opacity=60);}
/*}}}*/
<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="100%" width="100%" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" viewBox="0 0 40 40"><metadata><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title/></cc:Work></rdf:RDF></metadata><defs><linearGradient id="lG3826" x1="7.0996" gradientUnits="userSpaceOnUse" y1="18.829" gradientTransform="matrix(1.5858347,0,0,1.8078238,1098.1851,351.13716)" x2="1.5461" y2="-0.95166"><stop stop-color="#000" offset="0"/><stop stop-color="#9c9b99" offset="1"/></linearGradient><linearGradient id="lG3828" y2="372.44" gradientUnits="userSpaceOnUse" y1="375.7" x2="1111.7" x1="1097.7"><stop style="stop-color:#ac9393;" offset="0"/><stop style="stop-color:#c8b7b7;" offset="1"/></linearGradient></defs><g transform="translate(-1080.9375,-357.3329)"><path style="stroke-width:0;stroke-miterlimit:4;fill:url(#lG3826);" d="m1080.9,357.32,39.996-0.0426-0.01,40.008c-15.507-25.519-15.36-25.95-39.988-39.965z"/><path style="stroke-dashoffset:0;stroke:#7aa3be;stroke-linecap:round;stroke-miterlimit:4;stroke-width:1.49999988;fill:#c1e6fd;" d="m1091.9,363.55c6.5716-6.4925,16.576-7.3925,23.147-0.90003,6.5717,6.4925,6.5717,17.019,0,23.511-4.4424-8.6113-12.288-15.713-23.147-22.611z"/><path style="stroke-dashoffset:0;stroke:#ce81b0;stroke-linecap:round;stroke-miterlimit:4;stroke-width:1.5;fill:#f4c4e2;" d="m1110.2,367.62c3.217,3.2168,3.217,8.4323,0,11.649-3.8194-4.2357-8.3307-8.1824-11.649-11.649,3.217-3.2168,8.4325-3.2168,11.649-0.00002z"/><path style="stroke-linejoin:bevel;stroke:#000000;stroke-linecap:round;stroke-dasharray:none;stroke-miterlimit:4;stroke-width:0.80000001;fill:url(#lG3828);" d="m1081,357.34c18.79,6.4752,32.53,16.56,39.894,39.892-11.19-17.028-14.878-19.19-27.352-14.96,6.2984-12.098,3.9371-13.19-12.542-24.932z"/></g></svg>
!!! Classical Mechanics and Physics
* //For the love of Physics//, Walter Lewin
!!! Motors and drives
* //Electric machines and drives//. H.Merz. VDE Verlag GMBH. 2002. ISBN: 3-8007-2602-5
!!! Robotics
* //Introduction To Robotics - Mechanics And Control//, John J.Craig 
!!! Delta-3 robot
* //Conception d'un robot parallele rapide a 4 degrees de liberte. R.Clavel//. PhD Thesis. Ecole Polytechnique Federale de Lausanne. 1991.
* //Descriptive Geometric Kinematic Analysis of Clavel’s “Delta” Robot//. P.J. Zsombor-Murray. Centre of Intelligent Machines, McGill University. April 1, 2004.
* //A Three Degree of Freedom Parallel Manipulator with Only Translational Degrees of Freedom//. R. E. Stamper. PhD Report. Institute For Systems Research. 1997.
* //Singularity-Free Fully-Isotropic Translational Parallel Manipulators//. M. Carricato. PhD Report. University of Bolognia. 2001.
R0lGODdhQgAWAO4AAP7+/v///3p6etvb28DAwMHBwZ2dnVlZWdLS0oODg6+vr/X19eTk5IyMjLi4uFBQUJSUlFRUVFZWVtzc3MnJyVJSUlhYWFFRUVNTU+zs7FVVVf39/erq6vb29szMzN3d3Xt7e2BgYFdXV6Kiovr6+qampk9PT0xMTPf392ZmZl9fX+Dg4EtLS97e3qGhofz8/PDw8Ovr6/v7+7W1tWxsbJWVlXh4eMrKys3NzXl5efHx8WRkZFpaWufn5+/v77Ozs7GxsePj44eHh2lpaU5OTnNzc01NTZaWlmdnZ3x8fOXl5WNjY5KSkqmpqYiIiN/f37m5ubS0tHBwcIaGhmVlZe3t7XZ2dm1tbZiYmJeXl25ubm9vb46OjtXV1QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAQgAWAAAH/4ABgoOEhYaHiImKi4yNjo+MAJKTlJWWl5eQAS+NmJ6fmJGSATJYXQGWAR4GJKigr6CiAChZJzsfrgCCOConRx2UGQMMsAAMw5cLAwO6i6M/LAcYVAOuqiERBydNkggNAuANCAAEAsyVBAngAgkElA7rCTcBBevrg6McAiYHD0hPgjyowHCAyBQYACgIaEBhAIUECsiZq6RAAAQEAxBAEBBRooKMJTrQ41igZAF8+UA8OBCBxgoc2A4YEYICVYIECybllHhOEgMBBioZmDiUkqB6Ew4ZzQCCn4Yr2Cw8cCISwAAB7iyV68mz0lUHACo62HlUQFJDlQLESFLhgAQRB/8qcKkpaeslu5OKWgIKIIM6ASUYlK1hoLADlEZhWNFwwEKEEa0m4UU3Ma+AS3wBLCDwzexIwoYRTwrgYwtjlhB0TUKA9W5lSfDGUWKdVTLHkWcLpV1RJJsGCXFdbHC14OZOYzknW81smZjmSUBxKx3dgsYFaUNSSLBQYcRwSQoZOkzQYDNHAuiZVbyYcSPYsOxLCDhZT4HJAlUEUU9x/YGNIDdIsN0FwrniTTzjlGNPVums00BtDYJz2Ej2eGbNBylUwMMDIHAgCBQCWnDBCC9Qcoxzr5x4yTI5RRLABEus5F8MqAgywwUiiMBCFMX0mIozAegAQQUmCOChUTNg8IAwFB/46OQozugiAxM5ZJALlEBoocSVT8IiSwAkVHXJBj1w2eUrsjTjiX5n+phmj4EAADs=
/*{{{*/
/**
 * SyntaxHighlighter
 * http://alexgorbatchev.com/SyntaxHighlighter
 *
 * SyntaxHighlighter is donationware. If you are using it, please donate.
 * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
 *
 * @version
 * 3.0.83 (July 02 2010)
 * 
 * @copyright
 * Copyright (C) 2004-2010 Alex Gorbatchev.
 *
 * @license
 * Dual licensed under the MIT and GPL licenses.
 */
.syntaxhighlighter a,
.syntaxhighlighter div,
.syntaxhighlighter code,
.syntaxhighlighter table,
.syntaxhighlighter table td,
.syntaxhighlighter table tr,
.syntaxhighlighter table tbody,
.syntaxhighlighter table thead,
.syntaxhighlighter table caption,
.syntaxhighlighter textarea {
  -moz-border-radius: 0 0 0 0 !important;
  -webkit-border-radius: 0 0 0 0 !important;
  background: none !important;
  border: 0 !important;
  bottom: auto !important;
  float: none !important;
  height: auto !important;
  left: auto !important;
  line-height: 1.1em !important;
  margin: 0 !important;
  outline: 0 !important;
  overflow: visible !important;
  padding: 0 !important;
  position: static !important;
  right: auto !important;
  text-align: left !important;
  top: auto !important;
  vertical-align: baseline !important;
  width: auto !important;
  box-sizing: content-box !important;
  font-family: "Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace !important;
  font-weight: normal !important;
  font-style: normal !important;
  font-size: 1em !important;
  min-height: inherit !important;
  min-height: auto !important;
}

.syntaxhighlighter {
  width: 100% !important;
  margin: 1em 0 1em 0 !important;
  position: relative !important;
  overflow: auto !important;
  font-size: .9em !important;
}
.syntaxhighlighter.source {
  overflow: hidden !important;
}
.syntaxhighlighter .bold {
  font-weight: bold !important;
}
.syntaxhighlighter .italic {
  font-style: italic !important;
}
.syntaxhighlighter .line {
  white-space: pre !important;
}
.syntaxhighlighter table {
  width: 100% !important;
}
.syntaxhighlighter table caption {
  text-align: left !important;
  padding: .5em 0 0.5em 1em !important;
}
.syntaxhighlighter table td.code {
  width: 100% !important;
}
.syntaxhighlighter table td.code .container {
  position: relative !important;
}
.syntaxhighlighter table td.code .container textarea {
  box-sizing: border-box !important;
  position: absolute !important;
  left: 0 !important;
  top: 0 !important;
  width: 100% !important;
  height: 100% !important;
  border: none !important;
  background: white !important;
  padding-left: 1em !important;
  overflow: hidden !important;
  white-space: pre !important;
}
.syntaxhighlighter table td.gutter .line {
  text-align: right !important;
  padding: 0 0.5em 0 1em !important;
}
.syntaxhighlighter table td.code .line {
  padding: 0 1em !important;
}
.syntaxhighlighter.nogutter td.code .container textarea, .syntaxhighlighter.nogutter td.code .line {
  padding-left: 0em !important;
}
.syntaxhighlighter.show {
  display: block !important;
}
.syntaxhighlighter.collapsed table {
  display: none !important;
}
.syntaxhighlighter.collapsed .toolbar {
  padding: 0.1em 0.8em 0em 0.8em !important;
  font-size: 1em !important;
  position: static !important;
  width: auto !important;
  height: auto !important;
}
.syntaxhighlighter.collapsed .toolbar span {
  display: inline !important;
  margin-right: 1em !important;
}
.syntaxhighlighter.collapsed .toolbar span a {
  padding: 0 !important;
  display: none !important;
}
.syntaxhighlighter.collapsed .toolbar span a.expandSource {
  display: inline !important;
}
.syntaxhighlighter .toolbar {
  position: absolute !important;
  right: 1px !important;
  top: 1px !important;
  width: 11px !important;
  height: 11px !important;
  font-size: 10px !important;
  z-index: 10 !important;
}
.syntaxhighlighter .toolbar span.title {
  display: inline !important;
}
.syntaxhighlighter .toolbar a {
  display: block !important;
  text-align: center !important;
  text-decoration: none !important;
  padding-top: 1px !important;
}
.syntaxhighlighter .toolbar a.expandSource {
  display: none !important;
}
.syntaxhighlighter.ie {
  font-size: .9em !important;
  padding: 1px 0 1px 0 !important;
}
.syntaxhighlighter.ie .toolbar {
  line-height: 8px !important;
}
.syntaxhighlighter.ie .toolbar a {
  padding-top: 0px !important;
}
.syntaxhighlighter.printing .line.alt1 .content,
.syntaxhighlighter.printing .line.alt2 .content,
.syntaxhighlighter.printing .line.highlighted .number,
.syntaxhighlighter.printing .line.highlighted.alt1 .content,
.syntaxhighlighter.printing .line.highlighted.alt2 .content {
  background: none !important;
}
.syntaxhighlighter.printing .line .number {
  color: #bbbbbb !important;
}
.syntaxhighlighter.printing .line .content {
  color: black !important;
}
.syntaxhighlighter.printing .toolbar {
  display: none !important;
}
.syntaxhighlighter.printing a {
  text-decoration: none !important;
}
.syntaxhighlighter.printing .plain, .syntaxhighlighter.printing .plain a {
  color: black !important;
}
.syntaxhighlighter.printing .comments, .syntaxhighlighter.printing .comments a {
  color: #008200 !important;
}
.syntaxhighlighter.printing .string, .syntaxhighlighter.printing .string a {
  color: blue !important;
}
.syntaxhighlighter.printing .keyword {
  color: #006699 !important;
  font-weight: bold !important;
}
.syntaxhighlighter.printing .preprocessor {
  color: gray !important;
}
.syntaxhighlighter.printing .variable {
  color: #aa7700 !important;
}
.syntaxhighlighter.printing .value {
  color: #009900 !important;
}
.syntaxhighlighter.printing .functions {
  color: #ff1493 !important;
}
.syntaxhighlighter.printing .constants {
  color: #0066cc !important;
}
.syntaxhighlighter.printing .script {
  font-weight: bold !important;
}
.syntaxhighlighter.printing .color1, .syntaxhighlighter.printing .color1 a {
  color: gray !important;
}
.syntaxhighlighter.printing .color2, .syntaxhighlighter.printing .color2 a {
  color: #ff1493 !important;
}
.syntaxhighlighter.printing .color3, .syntaxhighlighter.printing .color3 a {
  color: red !important;
}
.syntaxhighlighter.printing .break, .syntaxhighlighter.printing .break a {
  color: black !important;
}
/*}}}*/
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink" version="1.1" viewBox="506 234 68 36" width="30" height="30"><metadata xmlns:dc="http://purl.org/dc/elements/1.1/"><dc:date>2010-09-16 14:51Z</dc:date><!-- Produced by OmniGraffle Professional 5.2.3 --></metadata><defs></defs><g stroke="none" stroke-opacity="1" stroke-dasharray="none" fill="none" fill-opacity="1"><rect width="1118" height="783"/><g><path d="M 538.68195 244.31807 C 540.43927 246.07547 540.43927 248.9247 538.68195 250.68204 C 536.92456 252.4394 534.07532 252.4394 532.318 250.68204 C 530.5606 248.9247 530.5606 246.07547 532.318 244.31807 C 534.07532 242.56075 536.92456 242.56075 538.68195 244.31807 M 511.12607 257.99356 C 511.26108 258.13019 511.39728 258.26608 511.53473 258.40121 C 527.2556 273.86606 552.74414 273.86606 568.46515 258.40121 C 568.60248 258.26617 568.73853 258.13037 568.87354 257.9938 C 568.8736 257.99374 568.8736 257.99371 568.8736 257.99362 C 568.87366 257.99371 568.87366 257.9938 568.87372 257.9939 C 570.72504 256.12051 572.35046 254.11153 573.74994 252 C 573.74994 251.99997 573.74994 251.99994 573.74994 251.99992 C 572.35046 249.8884 570.72504 247.87938 568.87372 246.00606 C 568.87366 246.00613 568.87366 246.00621 568.8736 246.00627 C 568.73865 245.86966 568.60254 245.73383 568.46515 245.5987 C 552.74414 230.13387 527.2556 230.13387 511.53473 245.5987 C 511.39728 245.73383 511.26108 245.86974 511.12613 246.00635 C 511.126 246.00624 511.126 246.00616 511.12595 246.00606 C 509.2748 247.87938 507.64954 249.88837 506.24994 251.9998 L 506.24994 251.99983 C 506.24994 251.9999 506.25 251.99992 506.25 251.99997 C 506.25 252 506.24994 252.00005 506.24994 252.00009 L 506.24994 252.00012 C 507.64954 254.11157 509.2748 256.12051 511.12595 257.9939 C 511.126 257.99377 511.126 257.99365 511.12607 257.99359 Z M 515.44916 252 C 515.8548 251.55469 516.27502 251.11778 516.71014 250.68985 C 522.16632 245.32257 529.06055 242.23206 536.17273 241.41824 C 534.6662 241.96199 533.2525 242.83762 532.04498 244.04512 C 527.65155 248.43852 527.65155 255.56163 532.04498 259.95502 C 533.2522 261.16226 534.6656 262.03778 536.17175 262.58154 C 529.05988 261.76761 522.16608 258.6771 516.71014 253.31009 C 516.2751 252.88219 515.85486 252.44528 515.44922 252 Z M 564.55054 251.99995 C 564.14502 252.44525 563.7248 252.88217 563.28973 253.31009 C 557.83368 258.67712 550.93988 261.76764 543.828 262.58157 C 545.33423 262.03781 546.74756 261.1623 547.9549 259.95502 C 552.34833 255.56163 552.34833 248.43852 547.9549 244.04512 C 546.74744 242.83765 545.33374 241.96202 543.82715 241.41824 C 550.9394 242.23206 557.83356 245.3226 563.28973 250.68985 C 563.7248 251.11775 564.14502 251.55467 564.55054 251.99995 Z M 568.8736 257.99362 C 570.7249 256.12033 572.35028 254.11139 573.74988 252.00002" fill="black" class="glyph"/></g></g></svg>
!!!!Definitions
{{{
\def\function#1:#2->#3{{{#1} \colon {#2} \to {#3}}}
\def\mapsTo{\mapsto}
\def\map#1->#2{\parentheses{{#1} \mapsTo {#2}}}
}}}

!!!!Notes
{{{\function{f}:{X}->{Y} }}} is intended to denote a function $f$ mapping $X$ into $Y$.  {{{\map{x}->{x^2} }}} denotes a function with the rule {{{x \mapsTo x^2}}}.  One might define a function by:
{{{
Let $\function{f}:{\reals}->{\reals}$ be the map $\map{x}->{x^2}$.
}}}
:Let $\function{f}:{\reals}->{\reals}$ be the map $\map{x}->{x^2}$.
or
{{{
Let $\function{f}:{\reals}->{\reals}$ be such that $x \mapsTo x^2$.
}}}
:Let $\function{f}:{\reals}->{\reals}$ be such that $x \mapsTo x^2$.

!!!!Examples
{{{
\function{f}:{X}->{Y}
\function{h}:{X \cross X}->{X \cross Y}
x \mapsTo x^2
\map{x}->{x^2}
}}}
\[
\function{f}:{X}->{Y}\qquad
\function{h}:{X \cross X}->{X \cross Y}\qquad
x \mapsTo x^2\qquad
\map{x}->{x^2}
\]
----

!!!!Definitions
{{{
\def\compose{\circ}
\def\inverse#1{{{#1}^{-1}}}
\def\restriction#1#2{{{\left. {#1} \right\lvert}_{#2}}}
}}}

!!!!Notes
The standard $\LaTeX$ {{{\restriction}}} symbol can be accessed by {{{\LaTeXrestriction}}}.  The second argument to {{{\restriction}}} is essentially automatically delimited by virtue of being a subscript.

!!!!Examples
{{{
f \compose g
\inverse{f}
\restriction{f}{A}
\restriction{(f \compose g)}{C \intersect D}
}}}
\[
f \compose g\qquad
\inverse{f}\qquad
\restriction{f}{A}\qquad
\restriction{(f \compose g)}{C \intersect D}
\]
----

!!!!Definitions
{{{
\def\image#1#2{{{#2}\of{#1}}}
\def\preimage#1#2{{{#2}^{-1}\of{#1}}}
\def\fiber#1#2{\preimage{\singleton{#1}}{#2}}
}}}

!!!!Notes
{{{\image{A}{f} }}} is intended to read //the image of $A$ under $f$// or //the image of $A$ along $f$//; the others are read similarly.  The first arguments to these macros are all automatically delimited.

!!!!Examples
{{{
\image{A}{f}
\preimage{B}{f}
\fiber{y}{f}
}}}
\[
\image{A}{f}\quad
\preimage{B}{f}\quad
\fiber{y}{f}
\]
----

!!!!Definitions
{{{
\def\identity#1{{\operator{id}_{#1}}}
}}}

!!!!Notes
{{{\id}}} denotes the identity map and the intended usage is, for example, {{{\identity{X} }}}, denoting the identity on $X$.

!!!!Examples
{{{
\identity{X}
}}}
\[
\identity{X}
\]
----
There are a lot of interesting people using ~TiddlySpace that you might like to keep track of and interact with. There are a number of ways of doing this.

If you see a number in the speech bubble in one of your tiddlers, it means that someone is writing about the same thing as you. You can find out what they're saying by clicking on it. Likewise, if you see something interesting in someone else's space, you can respond to it and write up your own thoughts on the subject by clicking "Reply to this tiddler".

Additionally, if you find anyone interesting, or you find an interesting looking space and you'd like to know when it's changed, you can "follow" that space. To do this, simply create a tiddler with the title: {{{@space-name}}} and tag it {{{follow}}}. If you want, you can store some notes about that space in the body of the tiddler.

If you then want to know what happening, simply [[include|How do I include/exclude spaces?]]@docs the @tivity space and then visit your activity stream at [[/activity|/activity]], or just visit the @tapas space directly.

!Not sure who to follow?
Here's a few suggestions:
* @fnd
* @cdent
* @pmario
* @bengillies
* @dickon
/***
|''Name''|TiddlySpaceFollowingPlugin|
|''Version''|0.7.1|
|''Description''|Provides a following macro|
|''Author''|Jon Robson|
|''Requires''|TiddlySpaceConfig TiddlySpaceTiddlerIconsPlugin ErrorHandler|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
!Usage
Tag a tiddler with "follow" to express a list of followers.
Using the {{{<<followTiddlers X>>}}}
will reveal the number of tiddlers with name X in the set of spaces the *current* user viewing your space follows.
{{{<<following jon>>}}} will list all the users following Jon.
{{{<<followers jon>>}}} will list all the followers of jon.
{{{<linkedTiddlers>>}}} will list all tiddlers across TiddlySpace linked to the current tiddler
{{{<linkedTiddlers follow:yes>>}}} will list all tiddlers across TiddlySpace that come from your list of followers
adds spaceLink view type {{{<<view server.bag spaceLink>>}}} creates a link to the space described in server.bag
{{{<<view server.bag spaceLink title>>}}} makes a link to the tiddler with title expressed in the field title in space server.bag
If no name is given eg. {{{<<following>>}}} or {{{<<follow>>}}} it will default the current user.
!StyleSheet
.followTiddlersList li {
	list-style:none;
}

.followButton {
	width: 2em;
}

.followTiddlersList li .siteIcon {
	height:48px;
	width: 48px;
}

#sidebarTabs .followers li a,
.followers .siteIcon,
.followers .siteIcon div {
	display: inline;
}

.followTiddlersList li .externalImage, .followTiddlersList li .image {
	display: inline;
}

.scanResults li {
	list-style: none;
}
!Code
***/
//{{{
(function($) {
var LIMIT_FOLLOWING = 100;

var tweb = config.extensions.tiddlyweb;
var tiddlyspace = config.extensions.tiddlyspace;
var currentSpace = tiddlyspace.currentSpace.name;

var shadows = config.shadowTiddlers;
config.annotations.ScanTemplate = "This tiddler is the default template used in the display of tiddlers founding using the tsScan macro. To access attributes use the view macro e.g. {{{<<view title text>>}}}";
shadows.ScanTemplate = "<<view modifier SiteIcon width:24 height:24 spaceLink:yes label:no>> <<view title link>>";
shadows.FollowersTemplate = "<<view server.bag SiteIcon width:24 height:24 spaceLink:yes label:no>> <<view server.bag spaceLink>>";
shadows.FollowingTemplate = "<<view title SiteIcon width:24 height:24 spaceLink:yes label:no>> <<view title spaceLink>>";
shadows.FollowTiddlersBlackList = "";
shadows.FollowTiddlersHeading = "There are tiddlers in spaces you follow using the follow tag which use the title <<view title text>>";
shadows.FollowTiddlersTemplate = ["* <<view server.space SiteIcon width:24 height:24 spaceLink:yes label:no>> ",
	"<<view server.space spaceLink title external:no>> modified by <<view modifier spaceLink>> ",
	"in the <<view server.space spaceLink>> space (<<view modified date>> @ <<view modified date 0hh:0mm>>).\n"].join("");

var name = "StyleSheetFollowing";
shadows[name] = "/*{{{*/\n%0\n/*}}}*/".
	format(store.getTiddlerText(tiddler.title + "##StyleSheet"));
store.addNotification(name, refreshStyles);

// provide support for sucking in tiddlers from the server
tiddlyspace.displayServerTiddler = function(src, title, workspace, callback) {
	var adaptor = store.getTiddlers()[0].getAdaptor();
	var localTitle = tiddlyspace.getLocalTitle(title, workspace);
	var tiddler = new Tiddler(localTitle);
	tiddler.text = "Please wait while this tiddler is retrieved...";
	tiddler.fields.doNotSave = "true";
	store.addTiddler(tiddler);
	src = story.displayTiddler(src || null, tiddler.title);
	tweb.getStatus(function(status) {
		var context = {
			host: tweb.host, // TODO: inherit from source tiddler?
			workspace: workspace,
			headers: { "X-ControlView": "false" }
		};
		var getCallback = function(context, userParams) {
			var tiddler = context.tiddler;
			tiddler.title = localTitle;
			store.addTiddler(tiddler);
			story.refreshTiddler(localTitle, null, true); // overriding existing allows updating
			if(callback) {
				callback(src, tiddler);
			}
		};
		adaptor.getTiddler(title, context, null, getCallback);
	});
};

tiddlyspace.scroller = {
	runHandler: function(title, top, bottom, height) {
		var i;
		var handlers = tiddlyspace.scroller.handlers;
		var tidEl = story.getTiddler(title);
		if(tidEl) {
			var topEl = $(tidEl).offset().top + 20;
			if(top === false || (topEl > top && topEl < bottom)) {
				var h = handlers[title];
				for(i = 0; i < h.length; i++) {
					h[i]();
				}
				tiddlyspace.scroller.clearHandlers(title);
			}
		} else {
			tiddlyspace.scroller.clearHandlers(title);
		}
	},
	clearHandlers: function(title) {
		tiddlyspace.scroller.handlers[title] = [];
	},
	registerIsVisibleEvent: function(title, handler) {
		tiddlyspace.scroller.handlers[title] = tiddlyspace.scroller.handlers[title] || [];
		tiddlyspace.scroller.handlers[title].push(handler);
	},
	init: function() {
		this.handlers = {};
		this.interval = window.setInterval(function() {
			var top = $(window).scrollTop();
			var height = $(window).height();
			var bottom = top + height;
			var title;
			for(title in tiddlyspace.scroller.handlers) {
				if(title) {
					tiddlyspace.scroller.runHandler(title, top, bottom, height);
				}
			}
		}, 2000); // every 2 seconds check scroll position
	}
};
tiddlyspace.scroller.init();

var followMacro = config.macros.followTiddlers = {
	locale: {
		followListHeader: "Here are tiddlers from spaces you follow using the follow tag which use this title.",
		noTiddlersFromFollowers: "None of the spaces you follow contain a tiddler with this name.",
		errorMessage: "There was a problem retrieving tiddlers from the server. Please try again later."
	},
	init: function() {
		followMacro.lookup = {};
	},
	followTag: "follow",
	getHosts: function(callback) {
		tweb.getStatus(function(status) {
			callback(tweb.host, tiddlyspace.getHost(status.server_host, "%0"));
		});
	},
	getBlacklist: function() {
		return store.getTiddlerText("FollowTiddlersBlackList").split("\n");
	},
	handler: function(place, macroName, params, wikifier, paramString, tiddler) {
		var args = paramString.parseParams("anon")[0];
		var containingTiddler = story.findContainingTiddler(place).getAttribute('tiddler');
		var title = (args.anon && args.anon[0]) || tiddler.fields["server.title"] || tiddler.title;
		var tid = store.getTiddler(title);
		var user = params[1] || false;
		if(tid) {
			followMacro.makeButton(place, {
				url: "/search?q=title:%22" + encodeURIComponent(title) + "%22",
				containingTiddler: containingTiddler,
				blacklisted: followMacro.getBlacklist(), title: title, user: user,
				consultFollowRelationship: (args.follow &&
					args.follow[0] === 'false') ? false : true });
		}
	},
	makeButton: function(place, options) { // this is essentially the same code in TiddlySpaceFollowingPlugin
		var title = options.title;
		var blacklisted = options.blacklisted;
		var tiddler = store.getTiddler(title);
		var btn = $('<div class="followButton" />').addClass("notLoaded").appendTo(place)[0];
		if(blacklisted.contains(title)) {
			$(btn).remove();
			return;
		} else {
			var user = options.user;
			window.setTimeout(function() { // prevent multiple calls due to refresh
				tiddlyspace.scroller.registerIsVisibleEvent(options.containingTiddler, function() {
					var mkButton = function(followers, ignore) {
						if(!followers && !ignore) {
							$(btn).remove();
						} else {
							$("<a />").appendTo(btn);
							var scanOptions = { url: options.url,
								spaceField: options.spaceField || "bag", template: null, sort: "-modified",
								callback: function(tiddlers) {
									$(btn).removeClass("notLoaded");
									followMacro.constructInterface(btn, tiddlers);
								}
							};
							if(!ignore) {
								scanOptions.showBags = followMacro._getFollowerBags(followers);
							}
							scanOptions.hideBags = [tiddler.fields["server.bag"]];
							scanMacro.scan(null, scanOptions, user);
						}
					};
					if(options.consultFollowRelationship) {
						followMacro.getFollowers(mkButton);
					} else {
						mkButton([], true);
					}
				});
			}, 1000);
		}
	},
	constructInterface: function(container, tiddlers) {
		var txt = tiddlers.length;
		var className = txt > 0 ? "hasReplies" : "noReplies";
		var el = $(story.findContainingTiddler(container));
		$(container).empty().addClass(className);
		var btn = $("<a />").addClass("followedTiddlers").text(txt).
			click(function(ev) {
				followMacro.followingOnClick(ev);
			}).appendTo('<div class="followedTiddlers" />').appendTo(container)[0];
		$.data(btn, "tiddlers", tiddlers);
	},
	followingOnClick: function(ev) {
		var target = ev.target;
		var locale = followMacro.locale;
		var el = $('<div class="followTiddlersList" />')[0];
		var popup = Popup.create(target,"div");
		$(popup).addClass("taggedTiddlerList followList").click(function(ev) { // make it so only clicking on the document outside the popup removes the popup
			if(ev.target.parentNode != document) {
				ev.stopPropagation();
			}
		}).append(el);
		var tiddlers = $.data(target, "tiddlers") || [];
		scanMacro.template(el, tiddlers.slice(0,1), "FollowTiddlersHeading");
		scanMacro.template(el, tiddlers, "FollowTiddlersTemplate");
		if(tiddlers.length === 0) {
			$("<li />").text(locale.noTiddlersFromFollowers).appendTo(el);
		}
		Popup.show();
		ev.stopPropagation();
		return popup;
	},
	_getFollowerBags: function(followers) { // XXX: private or not?
		return $.map(followers, function(name, i) {
			return name != currentSpace ? "%0_public".format(name) : null;
		});
	},
	getFollowers: function(callback, username) {
		// returns a list of spaces being followed by the existing space
		var followersCallback = function(user) {
			if(!user.anon) {
				scanMacro.scan(null, { 
					url: "/search?q=bag:%0_public tag:%1 _limit:%2".format(user.name, followMacro.followTag, LIMIT_FOLLOWING),
					spaceField: "title", template: null, cache: true,
					callback: function(tiddlers) {
						var followers = [];
						for(var i = 0; i < tiddlers.length; i++) {
							followers.push(tiddlyspace.resolveSpaceName(tiddlers[i].title));
						}
						callback(followers);
					}
				});
			} else {
				callback(false);
			}
		};
		return !username ? tweb.getUserInfo(followersCallback) : followersCallback({ name: username });
	}
};

var scanMacro = config.macros.tsScan = {
	init: function () {
		this.scanned = {};
	},
	_tiddlerfy: function(jsontiddlers, options) {
		var tiddlers = [];
		var spaceField = options.spaceField || "bag"; // TODO: phase out use view types instead
		$.each(jsontiddlers, function(i, t) {
			var use = false;
			if(!options.showBags || (options.showBags && options.showBags.contains(t.bag))) {
				use = true;
			}
			if(options.hideBags && options.hideBags.contains(t.bag)) {
				use = false;
			}
			if(use) {
				var spaceName = t[spaceField];
				var tiddler = config.adaptors.tiddlyweb.toTiddler(t, tweb.host);
				tiddler.fields["server.space"] = tiddlyspace.resolveSpaceName(spaceName);
				tiddlers.push(tiddler);
			}
		});
		return tiddlers;
	},
	_scanCallback: function(place, jsontiddlers, options) {
		var locale = followersMacro.locale;
		var tiddlers = scanMacro._tiddlerfy(jsontiddlers, options);
		
		if(options.sort) {
			tiddlers = store.sortTiddlers(tiddlers, options.sort);
		}
		if(options.filter) {
			var _store = new TiddlyWiki();
			config.lastStore = _store;
			for(var i = 0; i < tiddlers.length; i++) {
				var clone = tiddlers[i];
				clone.title = tiddlyspace.getLocalTitle(clone.title, clone.fields['server.workspace']);
				_store.addTiddler(clone);
			}
			tiddlers = _store.filterTiddlers(options.filter);
		}
		if(place) {
			$(place).empty();
			var list = $("<ul />").appendTo(place)[0];
			scanMacro.template(list, tiddlers, options.template);
			if(tiddlers.length === 0) {
				$("<li />").text(options.emptyMessage || locale.noone).appendTo(list);
				$(list).addClass("emptyList");
			}
		}
		if(options.callback) {
			options.callback(tiddlers);
		}
	},
	constructSearchUrl: function(host, options) {
		if(options.url) {
			return options.url;
		}
		var inputs = options.searchValues;
		var tag = options.tag;
		var searchField = options.searchField || "title";
		var searchQuery = [];
		for(var i = 0; i < inputs.length; i++) {
			searchQuery.push('%0:"%1"'.format(searchField, inputs[i]));
		}
		var query = searchQuery.join(" OR ");
		query = tag ? "(%0) AND tag:%1".format(query, tag) : query;
		query = options.query ? "%0;%1;".format(query, options.query) : query;
		query = options.fat ? "%0&fat=1".format(query) : query;
		return '%0/search?q=%1'.format(host, query);
	},
	scan: function(place, options) { // TODO: make use of list macro with url filter
		var locale = followersMacro.locale;
		options.template = options.template ? options.template : "ScanTemplate";
		followMacro.getHosts(function(host, tsHost) {
			$(place).text(followersMacro.locale.pleaseWait);
			options = options ? options: {};
			var url = scanMacro.constructSearchUrl(host, options);
			if(options.cache && scanMacro.scanned[url]) {
				var tiddlers = scanMacro.scanned[url].tiddlers;
				var run = function(tiddlers) {
					scanMacro._scanCallback(place, tiddlers, options);
				};
				if(tiddlers) {
					run(tiddlers);
				} else {
					scanMacro.scanned[url].callbacks.push(run);
				}
			} else {
				var callback = function(tiddlers) {
					scanMacro._scanCallback(place, tiddlers, options);
				};
				if(scanMacro.scanned[url] && scanMacro.scanned[url].callbacks) {
					scanMacro.scanned[url].callbacks.push(callback);
				} else {
					scanMacro.scanned[url] = {
						callbacks: [callback]
					};
				}
				ajaxReq({
					url: url,
					dataType: "json",
					success: function(tiddlers) {
						scanMacro.scanned[url].tiddlers = tiddlers;
						var callbacks = scanMacro.scanned[url].callbacks;
						while(callbacks.length > 0) {
							callbacks.pop()(tiddlers);
						}
					},
					error: function(xhr) {
						$(place).empty();
						$("<span />").addClass("annotation error").text(locale.error.format(xhr.status)).appendTo(place);
					}
				});
			}
		});
	},
	template: function(place, tiddlers, template) { // TODO: make use of list macro.
		for(var i = 0; i < tiddlers.length; i++) {
			var tiddler = tiddlers[i];
			var item = $('<li class="spaceName" />').appendTo(place)[0];
			var spaceName = tiddler.fields["server.space"] || "";
			var templateText = store.getTiddlerText(template).replace(/\$1/mg, spaceName);
			wikify(templateText, item, null, tiddler);
		}
	},
	getOptions: function(paramString, tiddler) {
		var args = paramString.parseParams("name", null, true, false, true)[0];
		var options = { query: false, sort: false, tag: false, template: false, showBags: args.show || false,
			hideBags: args.hide || false, filter: false, spaceField: "bag", searchField: "title", fat: false,
			emptyMessage: false };
		for(var name in args) {
			if(name != "name") {
				if(name == "fat") {
					options[name] = true;
				} else {
					options[name] = args[name][0];
				}
			}
		}
		// if user has set searchField to modifier, then use the modifiers value if available otherwise use searchValues.
		var searchField = options.searchField;
		var searchValues = args[searchField] ? args[searchField] : args.searchValues;
		// if neither of those were used use the first parameter
		var defaultValues = tiddler ? [ tiddler.title ] : [];
		options.searchValues = searchValues ? searchValues : ( args.name ? [args.name[0]] : defaultValues);
		return options;
	},
	handler: function(place, macroName, params, wikifier, paramString, tiddler) {
		var container = $("<div />").addClass("scanResults resultsArea").appendTo(place)[0];
		var options = scanMacro.getOptions(paramString, tiddler);
		scanMacro.scan(container, options);
	}
};

var followersMacro = config.macros.followers = {
	locale: {
		loggedOut: "Please login to see the list of followers",
		noSupport: "We were unable to retrieve followers as your browser does not support following.",
		pleaseWait: "Please wait while we look this up...",
		error: "Error %0 occurred whilst retrieving data from server",
		noone: "None."
	},
	handler: function(place, macroName, params, wikifier, paramString, tiddler) {
		var locale = followersMacro.locale;
		var args = paramString.parseParams("name", null, true, false, true)[0];
		var username = args.name ? args.name[0] : false;
		var container = $('<div class="followers" />').text(locale.pleaseWait).
			appendTo(place)[0];
		var followersCallback = function(user) {
			if(user.anon) {
				$("<span />").text(locale.loggedOut).appendTo(container);
			} else {
				var options = scanMacro.getOptions(paramString);
				$.extend(options, {
					url: "/search?q=title:@%0 OR title:%0 tag:%1 _limit:%2".
						format(user.name, followMacro.followTag, LIMIT_FOLLOWING),
					spaceField: "bag",
					template: options.template ? options.template : "FollowersTemplate"
				});
				scanMacro.scan(container, options);
			}
		};
		return !username ? followersCallback({ name: currentSpace }) : followersCallback({ name: username });
	}
};

var followingMacro = config.macros.following = {
	locale: {
		pleaseWait: followersMacro.locale.pleaseWait,
		loggedOut: "Please login to see who you are following",
		noSupport: followersMacro.locale.noSupport,
		error: followersMacro.locale.error,
		noone: followersMacro.locale.noone
	},
	handler: function(place, macroName, params, wikifier, paramString, tiddler) {
		var locale = followingMacro.locale;
		var args = paramString.parseParams("name", null, true, false, true)[0];
		var fat = args.fat ? true : false;
		var username = args.name ? args.name[0] : false;
		var container = $('<div class="following" />').text(locale.pleaseWait).
			appendTo(place)[0];
		var followingCallback = function(user) {
			if(user.anon) {
				$("<span />").text(locale.loggedOut).appendTo(container);
			} else {
				var options = scanMacro.getOptions(paramString);
				$.extend(options, {
					url: "/search?q=bag:%0_public tag:%1 _limit:%2".format(user.name, followMacro.followTag, LIMIT_FOLLOWING),
					spaceField: "title",
					template: options.template ? options.template : "FollowingTemplate"
				});
				scanMacro.scan(container, options);
			}
		};
		return !username ? followingCallback({ name: currentSpace }) : followingCallback({ name: username });
	}
};

var linkedMacro = config.macros.linkedTiddlers = {
	handler: function(place, macroName, params, wikifier, paramString, tiddler) {
		var args = paramString.parseParams("anon")[0];
		var title = params[0] || tiddler.fields["server.title"] || tiddler.title;
		var tid = store.getTiddler(title);
		var containingTiddler = story.findContainingTiddler(place).getAttribute('tiddler');
		if(tid) {
			followMacro.makeButton(place, {
				spaceField: "recipe",
				url: "/bags/%0/tiddlers/%1/backlinks".format(tid.fields['server.bag'],
					encodeURIComponent(tid.title)),
				blacklisted: followMacro.getBlacklist(),
				title: title,
				containingTiddler: containingTiddler,
				user: params[1] || false,
				consultFollowRelationship: args.follow ? true : false });
		}
	}
};

if(config.options.chkFollowTiddlersIsLinkedTiddlers) {
	merge(config.macros.followTiddlers, config.macros.linkedTiddlers);
	config.shadowTiddlers.FollowTiddlersHeading = "These are the other tiddlers that link to this tiddler.";
}

})(jQuery);
//}}}
|''Name''|MochaTheme|

! Author Mode
|PageTemplate|MochaPageTemplate|
|ViewTemplate|ViewTemplate|
|EditTemplate|EditTemplate|
|StyleSheet|MochaStyleSheet|
|ColorPalette|MochaColorPalette|

! Read-Only Mode
|PageTemplateReadOnly|MochaPageTemplate|
|ViewTemplateReadOnly|ViewTemplate|
|EditTemplateReadOnly|EditTemplate|
|StyleSheetReadOnly|MochaStyleSheet|
|ColorPalette|MochaColorPalette|
!!!!Definitions
{{{
\def\functions{\function}
}}}

!!!!Notes
This is simply for enhanced readability in the situation when you want to define two or three functions with the same domain and codomain.

!!!!Examples
{{{
\functions{f, g}:{X}->{Y}
}}}
\[
\functions{f, g}:{X}->{Y}
\]
----

!!!!Definitions
{{{
\def\p{\parentheses}
\def\b{\brackets}
}}}

!!!!Notes
Because "parentheses" and "brackets" are rather long words for such common syntactic objects they are the first candidates for abbreviation.  The fact that parentheses and brackets in mathematical expressions are often verbally conveyed with pauses and syllable stressing adds further weight to this.
----

!!!!Definitions
{{{
\def\N{\naturals}
\def\Z{\integers}
\def\Q{\rationals}
\def\R{\reals}
\def\C{\complexNumbers}
}}}

!!!!Notes
To many people these abbreviations are //more// readable than the original commands.
----

!!!!Definitions
{{{
\def\sng{\singleton}
\def\Seq{\Sequence}
\def\seq{\sequence}
\def\pSet{\powerSet}
\def\fnSpace{\functionSpace}
\def\card{\cardinality}
}}}
----

!!!!Definitions
{{{
\def\fn{\function}
\def\fns{\functions}
\def\id{\identity}
}}}
----

!!!!Definitions
{{{
\def\homeo{\homeomorphic}
\def\sCC{\stoneCechCompactification}
}}}
!!! Why an eLNB is necessary?

A laboratory notebook is a document that researchers use for writing their hypotheses, experiments, initial analysis and interpretation of these experiments.

!!! What features we need?

A personal electronic laboratory notebook (ELNB) for replacing a hand-written notebook. This software application is also named as note taking application or personal wiki.

Basic features:
* Local application, not a web server.
* Windows and Linux versions, it should be used in both OS.
* A kind of blog with categories and tags.
* Dynamic tree views of the notes.
* Notes can be ordered by date.
* Caterogies and tags for notes, as in wiki.
* List all notes by creation date, category and tag.
* Inter links (notes links) and external links (files and web).
* Write a note using a WYSIWYG editor.
* Embed images, videos and so on.
* Export notes to RTF, XML and PDF.
* Spellcheck.

Advance features:
* Drag and drop support for images, text and video, mathematics
* LaTex Eq. support.
* Power search engine: ext, name, date, categories and tags. Use a Desktop Search (Copernic, Google Desktop, etc) application for doing this task could be an option.
My name is [[Diego Escudero|http://dgerod.xyz-lab.org.es]] and this is my personal wiki about Robotics and other things related to this topic. This site was created to __share things I learn and do__. 
!!! Tags
<<cloud -TagCloudHide>>
!!! Latest updates [[*|LatestUpdates]]
<<tiddler LatestUpdates>>

/*{{{*/
body {
	font-size: 1em;
	font-family: helvetica, arial, sans-serif;
	background-color: #fff;
	color: [[ColorPalette::Foreground]];
}

body ul { margin: 0; }

#popup {
	background-color: [[ColorPalette::TertiaryPale]];
}

#popup.confirmationPopup, .followList {
	font-size: 0.8em;
	padding: 1em;
	border: solid 1px [[ColorPalette::SecondaryMid]];
	background-color: [[ColorPalette::SecondaryPale]];
}

.followList .listTitle {
	text-decoration: underline;
}

#popup .followTiddlersList a {
	display: inline;
	padding: 0;
}

#popup li a {
	color: [[ColorPalette::PrimaryMid]];
	font-weight: bold;
}

#popup li a:hover {
	color: [[ColorPalette::PrimaryPale]];
	background: [[ColorPalette::PrimaryMid]];
}

#popup li.listTitle {
	border-bottom: 1px solid #000;
	font-weight: bold;
	margin-bottom: 10px;
}

#popup.followList {
	margin-left: 50px;
	margin-top: -30px;
}

.followTiddlersList .label {
	display: block;
	left: 10px;
	top: 0px;
	line-height: 16px;
	position: relative;
}

#popup .followTiddlersList .siteIcon{
	height: auto;
}

#popup .followTiddlersList li{
	clear: both;
	display: block;
	height: 48px;
	margin-bottom: 8px;
	position: relative;
}

#popup .followTiddlersList a{
	display: inline;
}

#displayArea {
	margin: 0;
	top: 0px;
	left: 0px;
	width: 100%;
	position: relative;
}

.revisionCloak {
	position: absolute;
	position: fixed !important;
	height: 100%;
	width: 100%;
	top: 0;
	left: 0;
	border: 0;
	margin: 0;
	padding: 0;
	opacity: 0.5;
	filter: alpha(opacity=50);
	background-color: #000;
}

/* *** Header *** */
.header {
	position: relative;
	background-color: [[ColorPalette::PrimaryMid]];
	_width: 100%; /* ie 6 demands */
}

.headerForeground {
	background-color: [[ColorPalette::PrimaryMid]];
	float: left;
	margin: 24px 16px 0px 72px;
	padding: 0;
	position: relative;
	top: 0;
	_width: 70%; /*ie6: needed for the background to actually be transparent*/
	_background-color: transparent; /*ie6: needed to show the search box*/
}

.clearFloat {
	clear: both;
}

#contentWrapper {
	position: relative;
	padding-top: 1px;
	top: -1px;
}

#tiddlerDisplay {
	_position: relative; /* ie 6*/
}

.siteTitle {
	clear: both;
	display: block;
	font-size: 32px;
	font-weight: bold;
	line-height: 32px;
}

.siteSubtitle {
	display: block;
	font-size: 14px;
	height: 16px;
	margin-bottom: 8px;
}

#sidebarSearch {
	padding: 0;
	position: absolute;
	right: 80px;
	top: 8px;
	width: 176px;
}

#sidebarSearch .txtOptionInput {
	width: 100%;
	margin-top: 5px;
	_color: #bbb; /* ie6 danger */
}

#sidebarSearch .txtOptionInput:focus {
	color: #000;
}

#sidebarSearch .searchButton {
	display: none;
}

/* *** Menu Bar *** */

#mainMenu {
	position: static;
	text-align: left;
	margin-left: 72px;
	float: left;
	width: auto;
	padding: 0;
	font-size: 1em;
	line-height: normal;
}

#mainMenu a {
	color: #fff;
	padding: 8px;
	font-size: 0.9em;
	margin-right: 16px;
}

#mainMenu a:hover {
	background-color: [[ColorPalette::PrimaryMid]];
	color: [[ColorPalette::Background]]
}

#sidebarOptions {
	margin-right: 72px;
	float: right;
	font-size: 1.1em;
	line-height: 1.6em;
	min-height: 1em;
	padding-top: 0;
}

#sidebarOptions a {
	margin-right: 8px;
}

.confirmationPopup .button,
#sidebarOptions .button {
	cursor: pointer;
	line-height: 1.4em;
	text-align: center;
	margin-right: 8px;
	margin-left:-2px;
}

.confirmationPopup .button {
	font-size: 0.9em;
	padding: 2px;
}

#sidebarOptions .button {
	font-size: 0.7em;
	float: left;
	width: 80px;
	padding: 0px;
        color: #fff;
}

.confirmationPopup a.button,
#sidebarOptions a {
	border: none;
	margin: 0 0.2em;
	padding: 0.6em 0.25em;
	display: inline;
	color: #666;
}

.confirmationPopup a.button:hover,
#sidebarOptions a:hover {
	color: #000;
}

.confirmationPopup a.button:active,
#sidebarOptions a:active {
	border: solid 1px [[ColorPalette::PrimaryMid]];
	background-color: #fff;
	background: -webkit-gradient( linear, left bottom, left top, color-stop(0.1,rgb(200,200,200)), color-stop(1, rgb(100,100,100)));
	background: -moz-linear-gradient(center bottom , rgb(200,200,200) 10%,rgb(100,100,100) 100%) repeat scroll 0 0 transparent;
}
/* *** Sidebar *** */

#sidebar .wizard table {
	margin: 0px;
}

.tabContents .listTitle:first-child {
	margin-top: 0px;
}

#menuBar {
	background: [[ColorPalette::PrimaryLight]];
	left: 0;
	right: 0;
	position: relative;
	margin: 0;
	padding: 0.5em 0 0.5em 0;
	min-height: 1em;
	overflow: hidden;
	_width: 100%; /* for ie 6 */
}

#sidebarOptions a.button:hover {
	color: [[ColorPalette::PrimaryPale]];
    background: [[ColorPalette::PrimaryMid]];
}

#tiddlerDisplay, #searchResults {
	margin: 16px 448px 0 72px;
}

#sidebarTabs {
	position: absolute;
	right: 72px;
	width: 352px;
	top: 0;
}

#sidebarTabs .tabsetWrapper .tabset {
	width: 87px;
	border-top: 1px solid [[ColorPalette::PrimaryPale]];
	border-left: 1px solid [[ColorPalette::PrimaryPale]];
	border-bottom: 1px solid [[ColorPalette::PrimaryPale]];
	height: auto;
	float: left;
	word-wrap: break-word;
	top: 0;
	padding: 0;
}

#sidebarTabs .tabsetWrapper .tabContents {
	background-color: [[ColorPalette::PrimaryPale]];
	border: 3px solid [[ColorPalette::PrimaryMid]];
	width: 242px;
	_width: 238px;
	left: -3px;
	_left: -5px;
	position: relative;
	min-height: 34em;
	padding: 8px;
	font-size: 0.8em;
}

/* ---- Side style --- */

#sidebarTabs .tabsetWrapper .tabset .tab {
	font-size: 0.9em;
	padding: 0.7em 8px 0.5em;
	color: #fff;
	background: [[ColorPalette::PrimaryLight]];
	border: none;
	line-height: 16px;
	position: relative;
	display: block;
	margin: 0;
}

#sidebarTabs .tabsetWrapper .tabset .tabSelected {
	color: [[ColorPalette::PrimaryMid]];
	background: [[ColorPalette::PrimaryPale]];
	border-top: 3px solid [[ColorPalette::PrimaryMid]];
	border-bottom: 3px solid [[ColorPalette::PrimaryMid]];
	border-left: 3px solid [[ColorPalette::PrimaryMid]];
	z-index: 10;
	margin-top: -1px;
	font-weight: bold;
}

#sidebarTabs .tabContents li {
	border: none;
	margin-left: 0;
	word-wrap: break-word;
}

.tabContents .timeline {
	background: [[ColorPalette::PrimaryPale]];
	margin-bottom: 8px;
}

#sidebarTabs .timeline li.listTitle {
	color: #132E43;
	margin-left: 8px 0;
	padding: 0.3em 0.11em;
	font-size: 1em;
	border-bottom: none;
}

#sidebarTabs .tabContents li a {
	display: block;
	text-align: left;
	margin: 0 0 1px 0;
	padding: 0.3em 1em;
	background: [[ColorPalette::PrimaryPale]];
}

#sidebarTabs .tabsetWrapper .tabset a:hover,
#sidebarTabs .tabContents li a:hover {
	color: [[ColorPalette::PrimaryPale]];
	background: [[ColorPalette::PrimaryMid]];
}

/* Activity Stream */
#sidebarTabs .tabContents .activityStream .feedItem a {
	display: inline-block;
	padding: 0;
	background: none;
}

/* ---- Tagging box --- */
.tagInfo {
	border: 1px solid #cccccc;
	padding: 10px 15px;
	-moz-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.2);
	box-shadow: 0 2px 2px rgba(0,0,0,0.2);
	color: [[ColorPalette::TertiaryMid]];
	background: -moz-linear-gradient(100% 100% 90deg, #f4f4f4, #e5e5e5);
	background: -webkit-gradient(linear, left top, right top, from(#e5e5e5), to(#f4f4f4));
	margin-top: 1em;
	font-size: 13px;
	margin: 0 0 0 56px;
}

.tagInfo ul {
	list-style: none;
	padding-left: 2.2em;
}

.tagInfo ul li {
	display: inline;
}

.tagInfo ul li.listTitle,
.tagInfo .tagging ul li.listTitle {
	color: [[ColorPalette::PrimaryMid]];
	font-size: 13px;
}

.tagInfo ul li a {
	border: none;
}

.tagInfo .tagging ul li {
	float: none;
	display: inline-block;
}

.tagInfo .tagging {
	padding: 0;
}

.viewRevision .toolbar {
	right: 48px;
	top: 8px;
}

.viewRevision .modifierIcon img,
.viewRevision .modifierIcon svg {
	margin-right: 8px;
}

.viewRevision .toolbar svg {
	width: 32px;
	height: 32px;
}

/* --- IE hacks from lattice --- */

/* ie hacks */
* html #menuBar {
	margin-bottom: 8px;
}
.toolbar .svgIconText {
	*display: inline;
}

div.tiddler .toolbar a {
	cursor: pointer;
	float: left\9;
	display: inline\9;
}

* html .toolbar {
	right: 8px;
}
* html .followButton a {
	margin-top: 0px;
	margin-right: 8px;
}
* html #tiddlerDisplay {
	margin-top: 0px;
}

/* for printing purposes */
@media print {
	#mainMenu,
	#sidebar,
	#messageArea,
	.toolbar,
	.followPlaceHolder,
	#backstageButton,
	#backstageArea,
	#sidebarTabs,
	#sidebarSearch .txtOptionInput,
	#sidebarOptions {
		display: none !important;
	}
	#displayArea {
		margin: 1em 1em 0em;
	}
	noscript {
		display:none; /* Fixes a feature in Firefox 1.5.0.2 where print preview displays the noscript content */
	}
	#tiddlerDisplay {
		margin: 16px 16px;
	}
}

@media all and (max-width: 960px){
	#tiddlerDisplay,
	#searchResults {
		margin: 16px 366px 0 16px;
	}

	#mainMenu {
		margin-left: 16px;
	}

	.headerForeground {
		margin-left: 16px;
	}

	#sidebarSearch {
		right: 16px;
	}

	#sidebarOptions {
		margin-right: 16px;
	}

	#sidebarTabs {
		right: 16px;
		width: 326px;
	}

	#sidebarTabs .tabsetWrapper .tabset {
		font-size: 0.9em;
		width: 77px;
	}

	#sidebarTabs .tabsetWrapper .tabContents {
		width: 226px;
		_width: 222px;
	}

	#sidebarTabs .tabContents li a {
		font-size: 0.9em;
	}
}
/*}}}*/
[[StyleSheetTiddler]]
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
A control system for a cardboard factory was developed and was introduced in the cutting phase of a machine that makes cardboard boxes. 

{{center{[img[https://lh4.googleusercontent.com/-JTykv8C3Dro/UM3e1hpoNkI/AAAAAAAAArI/MrzBG8FfPFs/s288/cardboard_cutter.png]]}}}

In order to carry out the control system, a vision system was used to obtain feedback information. The vision system was 2D because the information it gives to the control system is the displacement of a reference point in the image space.
(function() {
var getCSRFToken = function(window) {
	// XXX: should not use RegEx - cf.
	// http://www.quirksmode.org/js/cookies.html
	// https://github.com/TiddlySpace/tiddlyspace/commit/5f4adbe009ed4bda3ce39058a3fb07de1420358d
	var regex = /^(?:.*; )?csrf_token=([^(;|$)]*)(?:;|$)/;
	var match = regex.exec(document.cookie);
	var csrf_token = null;
	if (match && (match.length === 2)) {
		csrf_token = match[1];
	}

	return csrf_token;
};

if (typeof config !== 'undefined' && config.extensions &&
		config.extensions.tiddlyspace &&
		config.extensions.tiddlyspace.getCSRFToken === null) {
	config.extensions.tiddlyspace.getCSRFToken = getCSRFToken;
} else {
	window.getCSRFToken = getCSRFToken;
}
})(window);
//{{{
setStylesheet(store.getTiddlerText('SlimboxStyleSheet'),"SlimboxStyleSheet");
//}}}
@@Please do not modify this tiddler; it was created automatically upon space creation.@@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink" version="1.1" viewBox="434 218 68 68"
width="30" height="30">
<g stroke="none" stroke-opacity="1" stroke-dasharray="none" fill="none" fill-opacity="1">
	<g>
		<path d="M 478.39694 232.53705 L 478.39694 232.53705 
		C 477.1145 231.85132 475.77875 231.30147 474.41058 230.88734 L 474.41058 218.24994 L 461.58942 218.24994 
		L 461.58942 230.88734 C 460.22125 231.30147 458.8855 231.85132 457.60306 232.53705 L 448.66824 223.60214 
		L 439.6022 232.66814 L 448.53717 241.60304 C 447.8515 242.8854 447.30157 244.22116 446.88745 245.58936 
		L 434.25 245.58936 L 434.25 258.41052 L 446.88745 258.41052 
		C 447.30157 259.77869 447.8515 261.11447 448.53717 262.39688 L 439.6022 271.33173 L 448.66824 280.3978 
		L 457.60306 271.46283 C 458.8855 272.14862 460.22125 272.69846 461.58942 273.11252 L 461.58942 285.74988 
		L 474.41058 285.74988 L 474.41058 273.11252 C 475.77875 272.69846 477.1145 272.14862 478.39694 271.46283 
		L 487.33176 280.3978 L 496.39767 271.33173 L 487.46286 262.39688 
		C 488.14853 261.11447 488.69836 259.77869 489.11255 258.41052 L 501.74988 258.41052 L 501.74988 245.58936 
		L 489.11255 245.58936 C 488.69836 244.22116 488.14853 242.8854 487.46286 241.60304 L 496.39767 232.66814 
		L 487.33176 223.60214 Z M 475.3328 244.66714 C 479.3825 248.71698 479.3825 255.2829 475.3328 259.33273 
		C 471.28296 263.3826 464.71704 263.3826 460.66724 259.33273 
		C 456.61737 255.2829 456.61737 248.71698 460.66724 244.66714 
		C 464.71704 240.61734 471.28296 240.61734 475.3328 244.66714" fill="#111"
		class="glyph"/>
	</g>
</g>
</svg>
/***
!Description
!Examples
{{{<<postTimeline>>}}}
<<postTimeline>>
!Code
***/
//{{{

if ( !config.macros.dgerod ) config.macros.dgerod = {};

config.macros.dgerod.postTimeline = {

dateFormat: "DD MMM YYYY",
searchValue: "%article",
searchMatch: true,

handler : function( place,macroName,params )
{
        var field =  "wirtten";

        // Replace "%article" by "%post"
        // TBD	
	
        var tiddlers = store.reverseLookup( "tags",this.searchValue,this.searchMatch,field );
	var lastDay = "";
	
        //alert(tiddlers);

        // Sort tiddler by written date
        // TBD

        for( var t=tiddlers.length-1;  t>=last; t-- ) 
        {
               //alert( tiddlers[t].title );
 
		var tiddler = tiddlers[t];
		var theDay = tiddler[field].convertToLocalYYYYMMDDHHMM().substr(0,8);
                //theDay = Date.convertFromYYYYMMDDHHMM(store.getValue(tiddler,'written'));

                //alert( tiddler.title );

 		if( theDay != lastDay ) 
                {
			var ul = document.createElement("ul");
			addClass(ul,"timeline");
			place.appendChild(ul);
			createTiddlyElement(ul,"li",null,"listTitle",tiddler[field].formatString(dateFormat));
                        //createTiddlyElement(ul,"li",null,"listTitle",theDay.formatString(dateFormat));
			lastDay = theDay;
		}
		createTiddlyElement(ul,"li",null,"listLink").appendChild( createTiddlyLink(place,tiddler.title,true) );
	}
}   
};    

//config.macros.postTimeline = config.macros.dgerod.postTimeline;

//}}}
!Summary
This tiddlyspace is supposed to be a template for creating tiddlyspaces with $\LaTeX$ support.

!Creating you own mathematical tiddlyspace
* Create a tiddlyspace of your choice.
* Import all the tiddlers tagged {{{mathTemplateTiddler}}} from http://math-template.tiddlyspace.com. Strictly speaking, you don't need to import any tiddler tagged {{{doc}}} as these are purely documentation.
* Adjust the PageTemplate tiddler by inserting the line
{{{
<div style='display:none' macro='tiddler LatexNucleus##Init'></div>
}}}
as early as possible (try the very top and see whether it breaks some things - it shouldn't).
* If you want to, adjust the place that localTeX.js is loaded from in the [[PluginMathJax v1.3]] tiddler. If you do this, you need to change the last line in localTeX.js as well to the new location. Note that this is purely optional.
!!!!Definitions
{{{
\def\parentheses#1{{\left( {#1} \right)}}
\def\brackets#1{{\left[ {#1} \right]}}
\def\solidus#1/#2{{\left. {#1} \left/ \vphantom{#1} {#2} \right. \right.}}
\def\of{\parentheses}
\def\operator{\operatorname}
}}}

!!!!Notes
$\PopAll$The {{{\parentheses}}} command is for grouping elements of mathematics together wheras {{{\of}}} is for application of functions and operators.  There exist abbreviations {{{\p}}} and {{{\b}}} for {{{\parentheses}}} and {{{\brackets}}} respectively.

!!!!Examples
{{{
\p{\closure{A} \union \closure{B}} \setMinus \p{\closure{A} \intersect \closure{B}}
f\of{\sum_{k = 0}^{\infinity} y_k}
\operator{orb}\of{\Intersection_{k = n}^{\infinity} C_k}
\solidus{\b{\Union_{i \in I} A_i}_{\equivalent_{Y}}}/{\equivalent_{Z}}
}}}
\[
\p{\closure{A} \union \closure{B}} \setMinus \p{\closure{A} \intersect \closure{B}}\qquad
f\of{\sum_{k = 0}^{\infinity} y_k}\qquad
\operator{orb}\of{\Intersection_{k = n}^{\infinity} C_k}\qquad
\solidus{\b{\Union_{i \in I} A_i}_{\equivalent_{Y}}}/{\equivalent_{Z}}
\]
----

!!!!Definitions
{{{
\def\script{\mathcal}
\def\gothic{\mathfrak}
\def\blackboard{\mathbb}
\def\boldText{\mathbf}
\def\bold{\boldsymbol}
}}}

!!!!Notes
{{{\bold}}} is an old $\TeX$ command and {{{\mathbf}}} is its newer replacement.  Here we go back to {{{\bold}}} for readability.  {{{\blackBoard}}} is the command name used in BasicMacros 1.0 but this will probably be replaced in favour of {{{\blackboard}}} in a later version (because blackboard is one word).  Please use {{{\blackboard}}}.

!!!!Examples
{{{
\script{A}
\gothic{A}
\blackboard{N}
\boldText{ZFC}
\bold{v}
}}}
\[
\script{A}\qquad
\gothic{A}\qquad
\blackboard{N}\qquad
\boldText{ZFC}\qquad
\bold{v}
\]
----
! Usage
<<<
!! Gallery
{{{
<<tiddler "Picasa##gallery" with: USER_NAME (ALBUM_NAME or all)>>
}}}
; USER_NAME
: If you add this name to the link. {{{https://picasaweb.google.com/USER_NAME}}} and it shows an album overview, it will work :) See: https://picasaweb.google.com/PMarioJo as an example
; ALBUM_NAME
: eg: "all" will display all available albums.
: eg: "best of" will work for "best of 2012", "best of 2011" and so on.
''eg:''
{{{
<<tiddler "Picasa##gallery" with: PMarioJo all>>
}}}
<<tiddler "Picasa##gallery" with: PMarioJo all>>
<<<
<<<
!! Album
{{{
<<tiddler "Picasa##album" with: USER_NAME ALBUM_ID THUMB_SIZE>>
}}}
; USER_NAME
: If you add this name to the link. {{{https://picasaweb.google.com/USER_NAME}}} and it shows an album overview, it will work :) See: https://picasaweb.google.com/PMarioJo as an example
; ALBUM_ID
: eg: tricky
; THUMB_SIZE
: possible sizes are: 32, 48, 64, 72, 144, 160;
''eg:''
{{{
<<tiddler "Picasa##album" with: PMarioJo 5571439290287818385 144>>
}}}
<<tiddler "Picasa##album" with: PMarioJo 5571439290287818385 144>>
<<<
<<<
!! Authenticated Album
{{{
<<tiddler "Picasa##authGallery" with: USER_NAME SLICE_NAME THUMB_SIZE>>
}}}
; USER_NAME
: If you add this name to the link. {{{https://picasaweb.google.com/USER_NAME}}} and it shows an album overview, it will work :) See: https://picasaweb.google.com/PMarioJo as an example
; SLICE_NAME
: eg: A private tiddler SecretAlbums contains the information, needed to access "restricted" album pictures.
; THUMB_SIZE
: possible sizes are: 32, 48, 64, 72, 144, 160;
''eg:''
{{{
<<tiddler "Picasa##AuthAlbum" with: PMarioJo album1 144>>
}}}
<<tiddler "Picasa##AuthAlbum" with: PMarioJo album1 144>>
<<<
! Code
//{{{
!! gallery
<script>
 var ID = 'i' + new Date().getTime();
 jQuery('<div id="'+ID+'"></div>').prependTo(place);

 jQuery("#"+ID).EmbedPicasaGallery('$1',{
    matcher: ('$2' !== 'all') ? /$2/ : /./,
    loading_animation: 'loading.gif',
    album_title_tag:    '<h3/>'
 });
</script>
!! album
<script>
 var ID = 'i' + new Date().getTime();
 jQuery('<div id="'+ID+'"></div>').prependTo(place);

 jQuery("#"+ID).EmbedPicasaGallery('$1',{
  albumid: "$2",
  size: $3, // thumb size (32,48,64,72,144,160))
  loading_animation: 'loading.gif',
  msg_more: 'show<br/>more',
  show_more: 5
 });
</script>
!! AuthAlbum
<script>
var ID = 'i' + new Date().getTime();
jQuery('<div id="'+ID+'"></div>').prependTo(place);

var secrets = store.getTiddlerText('SecretAlbums::$2').split(',');
secrets.map(function(el){el.trim()});

jQuery('#'+ID).EmbedPicasaGallery('$1',{
	albumid: secrets[0],
	authkey: secrets[1],
	size: $3, 		// thumb size (32,48,64,72,144,160))
	loading_animation: 'loading.gif',
	msg_more: 'show<br/>more',
	show_more: 5
});
</script>
!!
//}}}
/*{{{*/

#lbOverlay {
	position: fixed;
	z-index: 9999;
	left: 0;
	top: 0;
	width: 100%;
	height: 100%;
	background-color: #000;
	cursor: pointer;
}

#lbCenter, #lbBottomContainer {
	position: absolute;
	z-index: 9999;
	overflow: hidden;
	background-color: #fff;
}

.lbLoading {
	background: #fff url(loading.gif) no-repeat center;
}

#lbImage {
	position: absolute;
	left: 0;
	top: 0;
	border: 10px solid #fff;
	background-repeat: no-repeat;
}

#lbPrevLink, #lbNextLink {
	display: block;
	position: absolute;
	top: 0;
	width: 50%;
	outline: none;
}

#lbPrevLink {
	left: 0;
}

#lbPrevLink:hover {
	background: transparent url(prevlabel.gif) no-repeat 0 15%;
}

#lbNextLink {
	right: 0;
}

#lbNextLink:hover {
	background: transparent url(nextlabel.gif) no-repeat 100% 15%;
}

#lbBottom {
	font-family: Verdana, Arial, Geneva, Helvetica, sans-serif;
	font-size: 10px;
	color: #666;
	line-height: 1.4em;
	text-align: left;
	border: 10px solid #fff;
	border-top-style: none;
}

#lbCloseLink {
	display: block;
	float: right;
	width: 66px;
	height: 22px;
	background: transparent url(closelabel.gif) no-repeat center;
	margin: 5px 0;
	outline: none;
}

#lbCaption, #lbNumber {
	margin-right: 71px;
}

#lbCaption {
	font-weight: bold;
}

/*}}}*/

/***
|Name|SinglePageModePlugin|
|Source|http://www.TiddlyTools.com/#SinglePageModePlugin|
|Documentation|http://www.TiddlyTools.com/#SinglePageModePluginInfo|
|Version|2.9.7|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|Show tiddlers one at a time with automatic permalink, or always open tiddlers at top/bottom of page.|
This plugin allows you to configure TiddlyWiki to navigate more like a traditional multipage web site with only one tiddler displayed at a time.
!!!!!Documentation
>see [[SinglePageModePluginInfo]]
!!!!!Configuration
<<<
<<option chkSinglePageMode>> Display one tiddler at a time
><<option chkSinglePagePermalink>> Automatically permalink current tiddler
><<option chkSinglePageKeepFoldedTiddlers>> Don't close tiddlers that are folded
><<option chkSinglePageKeepEditedTiddlers>> Don't close tiddlers that are being edited
<<option chkTopOfPageMode>> Open tiddlers at the top of the page
<<option chkBottomOfPageMode>> Open tiddlers at the bottom of the page
<<option chkSinglePageAutoScroll>> Automatically scroll tiddler into view (if needed)

Notes:
* The "display one tiddler at a time" option can also be //temporarily// set/reset by including a 'paramifier' in the document URL: {{{#SPM:true}}} or {{{#SPM:false}}}.
* If more than one display mode is selected, 'one at a time' display takes precedence over both 'top' and 'bottom' settings, and if 'one at a time' setting is not used, 'top of page' takes precedence over 'bottom of page'.
* When using Apple's Safari browser, automatically setting the permalink causes an error and is disabled.
<<<
!!!!!Revisions
<<<
2010.11.30 2.9.7 use story.getTiddler()
2008.10.17 2.9.6 changed chkSinglePageAutoScroll default to false
| Please see [[SinglePageModePluginInfo]] for previous revision details |
2005.08.15 1.0.0 Initial Release.  Support for BACK/FORWARD buttons adapted from code developed by Clint Checketts.
<<<
!!!!!Code
***/
//{{{
version.extensions.SinglePageModePlugin= {major: 2, minor: 9, revision: 7, date: new Date(2010,11,30)};
//}}}
//{{{
config.paramifiers.SPM = { onstart: function(v) {
	config.options.chkSinglePageMode=eval(v);
	if (config.options.chkSinglePageMode && config.options.chkSinglePagePermalink && !config.browser.isSafari) {
		config.lastURL = window.location.hash;
		if (!config.SPMTimer) config.SPMTimer=window.setInterval(function() {checkLastURL();},1000);
	}
} };
//}}}
//{{{
if (config.options.chkSinglePageMode==undefined)
	config.options.chkSinglePageMode=true;
if (config.options.chkSinglePagePermalink==undefined)
	config.options.chkSinglePagePermalink=true;
if (config.options.chkSinglePageKeepFoldedTiddlers==undefined)
	config.options.chkSinglePageKeepFoldedTiddlers=false;
if (config.options.chkSinglePageKeepEditedTiddlers==undefined)
	config.options.chkSinglePageKeepEditedTiddlers=false;
if (config.options.chkTopOfPageMode==undefined)
	config.options.chkTopOfPageMode=false;
if (config.options.chkBottomOfPageMode==undefined)
	config.options.chkBottomOfPageMode=false;
if (config.options.chkSinglePageAutoScroll==undefined)
	config.options.chkSinglePageAutoScroll=false;
//}}}
//{{{
config.SPMTimer = 0;
config.lastURL = window.location.hash;
function checkLastURL()
{
	if (!config.options.chkSinglePageMode)
		{ window.clearInterval(config.SPMTimer); config.SPMTimer=0; return; }
	if (config.lastURL == window.location.hash) return; // no change in hash
	var tids=decodeURIComponent(window.location.hash.substr(1)).readBracketedList();
	if (tids.length==1) // permalink (single tiddler in URL)
		story.displayTiddler(null,tids[0]);
	else { // restore permaview or default view
		config.lastURL = window.location.hash;
		if (!tids.length) tids=store.getTiddlerText("DefaultTiddlers").readBracketedList();
		story.closeAllTiddlers();
		story.displayTiddlers(null,tids);
	}
}


if (Story.prototype.SPM_coreDisplayTiddler==undefined)
	Story.prototype.SPM_coreDisplayTiddler=Story.prototype.displayTiddler;
Story.prototype.displayTiddler = function(srcElement,tiddler,template,animate,slowly)
{
	var title=(tiddler instanceof Tiddler)?tiddler.title:tiddler;
	var tiddlerElem=story.getTiddler(title); // ==null unless tiddler is already displayed
	var opt=config.options;
	var single=opt.chkSinglePageMode && !startingUp;
	var top=opt.chkTopOfPageMode && !startingUp;
	var bottom=opt.chkBottomOfPageMode && !startingUp;
	if (single) {
		story.forEachTiddler(function(tid,elem) {
			// skip current tiddler and, optionally, tiddlers that are folded.
			if (	tid==title
				|| (opt.chkSinglePageKeepFoldedTiddlers && elem.getAttribute("folded")=="true"))
				return;
			// if a tiddler is being edited, ask before closing
			if (elem.getAttribute("dirty")=="true") {
				if (opt.chkSinglePageKeepEditedTiddlers) return;
				// if tiddler to be displayed is already shown, then leave active tiddler editor as is
				// (occurs when switching between view and edit modes)
				if (tiddlerElem) return;
				// otherwise, ask for permission
				var msg="'"+tid+"' is currently being edited.\n\n";
				msg+="Press OK to save and close this tiddler\nor press Cancel to leave it opened";
				if (!confirm(msg)) return; else story.saveTiddler(tid);
			}
			story.closeTiddler(tid);
		});
	}
	else if (top)
		arguments[0]=null;
	else if (bottom)
		arguments[0]="bottom";
	if (single && opt.chkSinglePagePermalink && !config.browser.isSafari) {
		window.location.hash = encodeURIComponent(String.encodeTiddlyLink(title));
		config.lastURL = window.location.hash;
		document.title = wikifyPlain("SiteTitle") + " - " + title;
		if (!config.SPMTimer) config.SPMTimer=window.setInterval(function() {checkLastURL();},1000);
	}
	if (tiddlerElem && tiddlerElem.getAttribute("dirty")=="true") { // editing... move tiddler without re-rendering
		var isTopTiddler=(tiddlerElem.previousSibling==null);
		if (!isTopTiddler && (single || top))
			tiddlerElem.parentNode.insertBefore(tiddlerElem,tiddlerElem.parentNode.firstChild);
		else if (bottom)
			tiddlerElem.parentNode.insertBefore(tiddlerElem,null);
		else this.SPM_coreDisplayTiddler.apply(this,arguments); // let CORE render tiddler
	} else
		this.SPM_coreDisplayTiddler.apply(this,arguments); // let CORE render tiddler
	var tiddlerElem=story.getTiddler(title);
	if (tiddlerElem&&opt.chkSinglePageAutoScroll) {
		// scroll to top of page or top of tiddler
		var isTopTiddler=(tiddlerElem.previousSibling==null);
		var yPos=isTopTiddler?0:ensureVisible(tiddlerElem);
		// if animating, defer scroll until after animation completes
		var delay=opt.chkAnimate?config.animDuration+10:0;
		setTimeout("window.scrollTo(0,"+yPos+")",delay); 
	}
}

if (Story.prototype.SPM_coreDisplayTiddlers==undefined)
	Story.prototype.SPM_coreDisplayTiddlers=Story.prototype.displayTiddlers;
Story.prototype.displayTiddlers = function() {
	// suspend single/top/bottom modes when showing multiple tiddlers
	var opt=config.options;
	var saveSPM=opt.chkSinglePageMode; opt.chkSinglePageMode=false;
	var saveTPM=opt.chkTopOfPageMode; opt.chkTopOfPageMode=false;
	var saveBPM=opt.chkBottomOfPageMode; opt.chkBottomOfPageMode=false;
	this.SPM_coreDisplayTiddlers.apply(this,arguments);
	opt.chkBottomOfPageMode=saveBPM;
	opt.chkTopOfPageMode=saveTPM;
	opt.chkSinglePageMode=saveSPM;
}
//}}}
!Summary
Here is documentation on how to use the macros defined in [[BasicMacros]].  These macros are available by default online so you can use them without loading a macroset.

!Documentation
[[Miscellaneous basics|BasicMacros Documentation, Miscellaneous basics]]
[[Symbols|BasicMacros Documentation, Symbols]]
[[Sets and set operations|BasicMacros Documentation, Sets and set operations]]
[[Functions and function operations|BasicMacros Documentation, Functions and function operations]]
[[Topology related notation|BasicMacros Documentation, Topology related notation]]
[[General notation|BasicMacros Documentation, General notation]]
[[Abbreviations and aliases|BasicMacros Documentation, Abbreviations and aliases]]
//{{{
/*
	Slimbox v2.04 - The ultimate lightweight Lightbox clone for jQuery
	(c) 2007-2010 Christophe Beyls <http://www.digitalia.be>
	MIT-style license.
*/
(function(w){var E=w(window),u,f,F=-1,n,x,D,v,y,L,r,m=!window.XMLHttpRequest,s=[],l=document.documentElement,k={},t=new Image(),J=new Image(),H,a,g,p,I,d,G,c,A,K;w(function(){w("body").append(w([H=w('<div id="lbOverlay" />')[0],a=w('<div id="lbCenter" />')[0],G=w('<div id="lbBottomContainer" />')[0]]).css("display","none"));g=w('<div id="lbImage" />').appendTo(a).append(p=w('<div style="position: relative;" />').append([I=w('<a id="lbPrevLink" href="#" />').click(B)[0],d=w('<a id="lbNextLink" href="#" />').click(e)[0]])[0])[0];c=w('<div id="lbBottom" />').appendTo(G).append([w('<a id="lbCloseLink" href="#" />').add(H).click(C)[0],A=w('<div id="lbCaption" />')[0],K=w('<div id="lbNumber" />')[0],w('<div style="clear: both;" />')[0]])[0]});w.slimbox=function(O,N,M){u=w.extend({loop:false,overlayOpacity:0.8,overlayFadeDuration:400,resizeDuration:400,resizeEasing:"swing",initialWidth:250,initialHeight:250,imageFadeDuration:400,captionAnimationDuration:400,counterText:"Image {x} of {y}",closeKeys:[27,88,67],previousKeys:[37,80],nextKeys:[39,78]},M);if(typeof O=="string"){O=[[O,N]];N=0}y=E.scrollTop()+(E.height()/2);L=u.initialWidth;r=u.initialHeight;w(a).css({top:Math.max(0,y-(r/2)),width:L,height:r,marginLeft:-L/2}).show();v=m||(H.currentStyle&&(H.currentStyle.position!="fixed"));if(v){H.style.position="absolute"}w(H).css("opacity",u.overlayOpacity).fadeIn(u.overlayFadeDuration);z();j(1);f=O;u.loop=u.loop&&(f.length>1);return b(N)};w.fn.slimbox=function(M,P,O){P=P||function(Q){return[Q.href,Q.title]};O=O||function(){return true};var N=this;return N.unbind("click").click(function(){var S=this,U=0,T,Q=0,R;T=w.grep(N,function(W,V){return O.call(S,W,V)});for(R=T.length;Q<R;++Q){if(T[Q]==S){U=Q}T[Q]=P(T[Q],Q)}return w.slimbox(T,U,M)})};function z(){var N=E.scrollLeft(),M=E.width();w([a,G]).css("left",N+(M/2));if(v){w(H).css({left:N,top:E.scrollTop(),width:M,height:E.height()})}}function j(M){if(M){w("object").add(m?"select":"embed").each(function(O,P){s[O]=[P,P.style.visibility];P.style.visibility="hidden"})}else{w.each(s,function(O,P){P[0].style.visibility=P[1]});s=[]}var N=M?"bind":"unbind";E[N]("scroll resize",z);w(document)[N]("keydown",o)}function o(O){var N=O.keyCode,M=w.inArray;return(M(N,u.closeKeys)>=0)?C():(M(N,u.nextKeys)>=0)?e():(M(N,u.previousKeys)>=0)?B():false}function B(){return b(x)}function e(){return b(D)}function b(M){if(M>=0){F=M;n=f[F][0];x=(F||(u.loop?f.length:0))-1;D=((F+1)%f.length)||(u.loop?0:-1);q();a.className="lbLoading";k=new Image();k.onload=i;k.src=n}return false}function i(){a.className="";w(g).css({backgroundImage:"url("+n+")",visibility:"hidden",display:""});w(p).width(k.width);w([p,I,d]).height(k.height);w(A).html(f[F][1]||"");w(K).html((((f.length>1)&&u.counterText)||"").replace(/{x}/,F+1).replace(/{y}/,f.length));if(x>=0){t.src=f[x][0]}if(D>=0){J.src=f[D][0]}L=g.offsetWidth;r=g.offsetHeight;var M=Math.max(0,y-(r/2));if(a.offsetHeight!=r){w(a).animate({height:r,top:M},u.resizeDuration,u.resizeEasing)}if(a.offsetWidth!=L){w(a).animate({width:L,marginLeft:-L/2},u.resizeDuration,u.resizeEasing)}w(a).queue(function(){w(G).css({width:L,top:M+r,marginLeft:-L/2,visibility:"hidden",display:""});w(g).css({display:"none",visibility:"",opacity:""}).fadeIn(u.imageFadeDuration,h)})}function h(){if(x>=0){w(I).show()}if(D>=0){w(d).show()}w(c).css("marginTop",-c.offsetHeight).animate({marginTop:0},u.captionAnimationDuration);G.style.visibility=""}function q(){k.onload=null;k.src=t.src=J.src=n;w([a,g,c]).stop(true);w([I,d,g,G]).hide()}function C(){if(F>=0){q();F=x=D=-1;w(a).hide();w(H).stop().fadeOut(u.overlayFadeDuration,j)}return false}})(jQuery);

// AUTOLOAD CODE BLOCK (MAY BE CHANGED OR REMOVED)
if (!/android|iphone|ipod|series60|symbian|windows ce|blackberry/i.test(navigator.userAgent)) {
	jQuery(function($) {
		$("a[rel^='lightbox']").slimbox({/* Put custom options here */}, null, function(el) {
			return (this == el) || ((this.rel.length > 8) && (this.rel == el.rel));
		});
	});
}

//}}}
[[Virtual Robot Simulator|http://robotica.isa.upv.es/virtualrobot]] is a freeware application developed in C/C++ by the [[Robotics Group|http://robotica.isa.upv.es]]. It can be used for simulating any type of industrial robots, individually or grouped in multi-robot work cells for their off-line automatically part-program generation and testing, as well as for on-line programming and monitoring. 

{{center{[img[https://lh4.googleusercontent.com/-ZD80YerAOCE/UM3YPduBI9I/AAAAAAAAAqI/Qsn99daQNn0/s288/vrs_sw-design.png]] [img[https://lh3.googleusercontent.com/-dnUrjQyhXuA/UM3YPVV88pI/AAAAAAAAAqE/NSn4YlmFENM/s288/vrs_screenshot.png]]}}}

Objectives for this work were:
* Create a graphic control/component (model-view-controller) of VRS so it can be easily added inside other applications to be used as a robot viewer/monitoring.
* Re-factor internal code of VRS: 1) libraries/modules structure, 2) divide the core in simulation and graphics layers.
* Simplify use of client communication library (VREAL).
* And added other simple but useful features as directory manager of robot/environment models.
This work was done together with [[ROBSTAR project|ROBSTAR: A Robot for Advance Storage Areas of Nuclear Material]] as this new graphic component was used inside the ROBSTAR control application.
[[dgerod.xyz-lab.org.es|http://dgerod.xyz-lab.org.es]]
[[CC BY 3.0|http://creativecommons.org/licenses/by/3.0]]



LyogQSBjb21tYW5kIGxvY2FsaXphdGlvbiBzeXN0ZW0gZm9yIE1hdGhKYXggTGFUZVggKi8KCi8qIFRvIHVzZSwgbWFrZSBzdXJlIFRlWC9uZXdjb21tYW5kLmpzIGlzIGxvYWRlZCBleHBsaWNpdGx5IGFzIGFuIGV4dGVuc2lvbiAqLwoKTWF0aEpheC5IdWIuUmVnaXN0ZXIuU3RhcnR1cEhvb2soIlRlWCBuZXdjb21tYW5kIFJlYWR5IixmdW5jdGlvbiAoKSB7CiAgdmFyIFZFUlNJT04gPSAiMS4wLjEiOwogIAogIHZhciBURVggPSBNYXRoSmF4LklucHV0SmF4LlRlWDsKICB2YXIgVEVYREVGID0gVEVYLkRlZmluaXRpb25zOwogIHZhciBHTE9CQUxTVE9SRSA9IG51bGw7CQkvKiBXZSBpbml0aWFsaXNlIHRoaXMgdG8gbnVsbCBmb3IgdGhlIHB1cnBvc2Ugb2Ygc2FmZXR5IGNoZWNrcyBsYXRlciAtIGl0IHNob3VsZCBiZSBudWxsIGFueXdheSAqLwogIHZhciBTVE9SRURCQVNJQ01BQ1JPUyA9IG51bGw7CgogIC8qCiAgICogTm90IGV2ZXJ5dGhpbmcgaW4gVEVYREVGIGlzIGEgbGlzdCBvZiBjb21tYW5kcy4gIFRoZSBmb2xsb3dpbmcgaXMKICAgKiBhIGxpc3Qgb2YgYWxsIG9mIHRoZSBvYmplY3RzIGluIFRFWERFRiB0aGF0IHdlIHdhbnQgdG8gY29uc2lkZXIKICAgKiB3aGVuIGNvcHlpbmcgY29tbWFuZHMuICBIb3BlZnVsbHkgcmVzdHJpY3Rpbmcgb3Vyc2VsdmVzIHRvIHRoaXMKICAgKiBzdWJzZXQgb2YgVEVYREVGIGlzIGFsbCB3ZSdsbCBuZWVkIHRvIGdldCB1bmV2YWwgd29ya2luZyBpbgogICAqIENocm9taXVtLgogICAqLwogIHZhciBjb21tYW5kTGlzdHMgPSBbIm1hdGhjaGFyMG1pIiwgIm1hdGhjaGFyMG1vIiwgIm1hdGhjaGFyNyIsICJkZWxpbWl0ZXIiLCAibWFjcm9zIiwgImVudmlyb25tZW50Il07CgogIC8qIFdlIG5vdyBtYW5hZ2UgdGhlIHZhcmlhYmxlcyB3ZSBuZWVkIGZvciB0aGUgc3RhY2tzLgkqLwoKICAvKiBtYWNyb1N0YWNrIGlzIGEgdHdvIHBhcnQgYXJyYXkuIFRoZSBmaXJzdCBwYXJ0IHN0b3JlcyB0aGUgY29udHJvbCBzdHJpbmdzIChjcyksIHdoaWxlCSoKICAgKiB0aGUgc2Vjb25kIHBhcnQgc3RvcmVzIHRoZSBkaXNwbGFjZWQgZGVmaW5pdGlvbi4gVGhlc2UgbWlnaHQgYmUgY29tYmluZWQgaW50byBhIHNpbmdsZQkqCiAgICogYXJyYXksIGJ1dCBpdHMgZG9uZSB0aGlzIHdheSBmb3Igbm93IHRvIHN0b3Agb2JqZWN0cyBnZXR0aW5nIG11ZGRsZWQuCQkJKi8KICB2YXIgbWFjcm9TdGFjayA9IG5ldyBBcnJheSgibmFtZSIsICJkZWZpbml0aW9uIik7CgogIC8qIFRoZXNlIGNvbnN0YW50cyBqdXN0IGltcHJvdmUgbGVnaWJpbGl0eSAtIHRoaW5rIG9mIGkgYXMgImluZGV4IgkqCiAgICogc28gaW5kZXggb2YgTkFNRVMsIGluZGV4IG9mIERFRmlOaXRpb25TLgkJCQkqLwogIGNvbnN0IGlOQU1FUyA9IDA7CiAgY29uc3QgaURFRm5TID0gMTsKCiAgLyogSW5pdGlhbGlzZSBtYWNybyBzdGFjayAqLwogIG1hY3JvU3RhY2tbaU5BTUVTXSA9IFtdOwkvKiBbXSBpcyBhbiBlbXB0eSBhcnJheTsgc2FtZSBhcyBzYXlpbmcgbmV3IEFycmF5KCk7ICovCiAgbWFjcm9TdGFja1tpREVGblNdID0gW107CiAgbWFjcm9TdGFja1tpTkFNRVNdWzBdID0gW107CiAgbWFjcm9TdGFja1tpREVGblNdWzBdID0gW107CgogIC8qIFRoaXMgdmFyaWFibGUgaXMgdXNlZCB0byB0cmFjayB0aGUgc3RhY2sgKi8KICB2YXIgaGVpZ2h0ID0gMDsKICAKICBNYXRoSmF4Lkh1Yi5JbnNlcnQoVEVYREVGLHsKICAgIG1hY3JvczogewoJU2F2ZUdsb2JhbHM6CSdTYXZlR2xvYmFsJywKCUNsZWFuOgkJJ0NsZWFuTG9jYWxzJywKCU1ldGFOZXdDb206CSdNZXRhTmV3Q29tbWFuZCcsCglNZXRhRGVmOgknTWV0YURlZmluZScsCglQdXNoTWFjcm9zOgkncHVzaE1hY3JvcycsCglQb3BNYWNyb3M6CSdwb3BNYWNyb3MnLAoJUG9wQWxsOgkJJ3BvcEFsbCcsCglsZXQ6CQknTGV0JwogICAgfQogIH0pCgogVEVYLlBhcnNlLkF1Z21lbnQoewoKCS8qIF9jaGVja1N0YWNrOiBpbnRlcm5hbCBmdW5jdGlvbiB0aGF0IG1ha2VzIHN1cmUgdGhlIHN0YWNrIGF0IGl0cyBjdXJyZW50IGhlaWdodCBpdCBpbml0aWFsaXplZCwgYW5kIGZpeGVzIGl0IGlmIGl0cyBub3QgKi8KCV9jaGVja1N0YWNrOiBmdW5jdGlvbigpewoKCQkvKiBJZiBvdXIgY3VycmVudCBoZWlnaHQgaGFzIG5vdGhpbmcgaW4gaXQsIGluaXRpYWxpc2UgdGhlIGxldmVsLiBOb3RlIHdlIG1heSBoYXZlIGRpc3BsYWNlZCBub3RoaW5nCSoKCQkgKiBzbyBpdHMgbm8gZ29vZCBjaGVja2luZyB0aGUgaURFRm5TIHBhcnQgb2YgbWFjcm9TdG9yZQkJCQkJCSovCgkJaWYobWFjcm9TdGFja1tpTkFNRVNdW2hlaWdodF0gPT0gbnVsbCkJCS8qIEl0IHRoZSBzdGFjayBpcyBub3QgaW5pdGlhbGl6ZWQgKi8KCQkJewoJCQkJbWFjcm9TdGFja1tpTkFNRVNdW2hlaWdodF0gPSBbXTsJLyogRml4IGl0ICovCgkJCQltYWNyb1N0YWNrW2lERUZuU11baGVpZ2h0XSA9IFtdOwoJCQl9Cgl9LAoJCgoJLyogU2F2ZUdsb2JhbDogc3RvcmUgdGhlIGdsb2JhbCBzZXQgb2YgZGVmaW5pdGlvbnMuIFRoaXMgc2hvdWxkIG9ubHkgYmUgY2FsbGVkIG9uY2UuICovCglTYXZlR2xvYmFsOiBmdW5jdGlvbiAoKSB7CgkJaWYoR0xPQkFMU1RPUkUgPT0gbnVsbCkJLyogV2UgaGF2ZW4ndCBkZWZpbmVkIHRoZSBnbG9iYWwgZGVmaW5pdGlvbiBzZXQgeWV0ICovCgkJewoJCQkvKiBHTE9CQUxTVE9SRSBpcyBnb2luZyB0byBiZSBhIGNvcHkgb2YgVEVYREVGLiBJdCB3aWxsIGJlIGFuIGFzc29jaWF0aXZlIGFycmF5LiBJbml0aWFsaXplIGl0LiAqLwoJCQlHTE9CQUxTVE9SRSA9IFtdOwoKCQkJLyogTm93IHdlIGl0ZXJhdGUgb3ZlciB0aGUgZW50cmllcyBvZiBURVhERUYgYW5kIGNvcHkgdGhlbSBvdmVyIHRvIEdMT0JBTFNUT1JFICovCgkJCWZvciggdmFyIGlMSVNUIGluIGNvbW1hbmRMaXN0cyApewoJCQkJR0xPQkFMU1RPUkVbaUxJU1RdID0gZXZhbCh1bmV2YWwoVEVYREVGW2lMSVNUXSkpOwoJCQl9OwoKCQkJLyogVGhyb3cgYSB3YXJuaW5nIGlmIG1hbnkgbG9jYWwgZW52aXJvbm1lbnRzIGhhdmUgYmVlbiBzdGFja2VkIHVwICovCgkJCWlmKG1hY3JvU3RhY2tbaU5BTUVTXVsxXSAhPSBudWxsKQoJCQl7CgkJCQlhbGVydCgiWW91IGNhbGxlZCBcXFNhdmVHbG9iYWxzLCBidXQgeW91IHBvc3NpYmx5IGhhdmUgbmVzdGVkIGxvY2FsIGVudmlyb25tZW50cy4gXG4gT25seSB0aGUgYmFzZSBsZXZlbCBpcyBndWFyYW50ZWVkIHRvIGJlIHNhdmVkLiIpOwoJCQl9CgoJCQkvKiBOb3cgd2Ugd2FudCBoZWlnaHQgdG8gYmUgc2l0dGluZyBhdCAxIGFmdGVyIGFsbCB0aGlzLCBidXQgaWYgd2UgbmV2ZXIgd2VudCB0aGF0IGhpZ2gJKgoJCQkgKiBiZWZvcmUgc2F2aW5nLCBpdCB3aWxsIGJlIHNpdHRpbmcgYXQgMCBhdCB0aGUgbWludXRlLiBGaXggdGhpcy4JCQkqLwoJCQlpZihoZWlnaHQgPT0gMCl7CgkJCQloZWlnaHQgPSAxOwoJCQkJLyogV2UgaGF2ZSBub3RoaW5nIGF0IHRoaXMgaGVpZ2h0LCBzbyBpbml0aWFsaXplIHRoZSBhcnJheXMgc28gd2UgZG9uJ3QgY2F1c2UgYW55IGNyYXNoZXMgKi8KCQkJCXRoaXMuX2NoZWNrU3RhY2soKTsKCQkJfQoKCQkJLyogQ29weSB0aGUgbG9jYWwgbWFjcm9TdGFjayBmb3IgYmFja3VwIC0gdGhpcyBjb3BpZXMgdGhlIHdob2xlIHRoaW5nLCBhbmQgbm90ZSBiZWNhdXNlIG9mIHRoZSBhYm92ZQkqCgkJCSAqIGl0cyBhbHJlYWR5IHNldCB1cCBhdCBoZWlnaHQgMS4JCQkJCQkJCQkqLwkKCQkJU1RPUkVEQkFTSUNNQUNST1MgPSBldmFsKHVuZXZhbChtYWNyb1N0YWNrKSk7CgoJCX0KCQllbHNlCS8qIFdlJ3ZlIGFscmVhZHkgc2F2ZWQgdGhlIGdsb2JhbCBkZWZpbml0aW9uIHNldCwgc28gdGhyb3cgYW4gZXJyb3IgKi8KCQl7CgkJCVRFWC5FcnJvcigiR2xvYmFscyB3ZXJlIGFscmVhZHkgc2F2ZWQuIik7CgkJfQoJICAgIH0sCgoJLyogSW1wbGVtZW50IFxDbGVhbjogdGhpcyByZXN0b3JlcyB0aGUgZ2xvYmFsIG1hY3JvIHN0YXRlIHRvIHRoYXQgc2F2ZWQgYnkgXFNhdmVHbG9iYWxzLgkqCgkgKiBJdCBzaG91bGRuJ3Qgd29yayBpZiBcU2F2ZUdsb2JhbHMgaGFzIG5vdCBiZWVuIGNhbGxlZC4JCQkJCSovCglDbGVhbkxvY2FsczogZnVuY3Rpb24gKCkgewoJCWlmKEdMT0JBTFNUT1JFICE9IG51bGwpCS8qIFdlIHNhdmVkIHNvbWV0aGluZyB0byByZXN0b3JlICovCgkJewoJCQkvKiBDb3B5IGJhY2sgR0xPQkFMU1RPUkUgaW50byBURVhERUYgdG8gcmVzdG9yZSB0aGUgb2xkIGVudmlyb25tZW50LiBURVhERUYgbWF5IGhhdmUgaGFkIHNvbWUgZW50cmllcwkqCgkJCSAqIGFkZGVkLCBvciBwb3NzaWJseSByZW1vdmVkLiBUbyBkZWFsIHdpdGggdGhvc2UgYWRkZWQgd2UgbG9vcCBvdmVyIFRFWERFRidzIGVudHJpZXMgYW5kIGRlbGV0ZQkqCgkJCSAqIGFueXRoaW5nIHRoYXQgaGFzIGJlZW4gYWRkZWQsIHdoaWxlIHJlc3RvcmluZyB0aGUgdmFsdWVzIGZyb20gR0xPQkFMU1RPUkUuIFNlY29uZGx5LCB0byBkZWFsIHdpdGgJKgoJCQkgKiB0aG9zZSBlbnRyaWVzIHRoYXQgbWF5IGhhdmUgYmVlbiByZW1vdmVkLCB3ZSBsb29wIG92ZXIgR0xPQkFMU1RPUkUncyBlbnRyaWVzLCBhbmQgaWYgY29ycmVzcG9uZGluZwkqCgkJCSAqIGVudHJpZXMgZG8gbm90IGV4aXN0IGluIFRFWERFRiwgd2UgY29weSB0aGVtIGFjcm9zcy4JCQkJCQkJKi8KCQkJZm9yKCB2YXIgaUxJU1QgaW4gY29tbWFuZExpc3RzICl7CgkJCQlpZiggR0xPQkFMU1RPUkVbaUxJU1RdICE9IG51bGwpewoJCQkJCVRFWERFRltpTElTVF0gPSBldmFsKHVuZXZhbChHTE9CQUxTVE9SRVtpTElTVF0pKTsKCQkJCX0KCQkJCWVsc2UKCQkJCXsKCQkJCQlkZWxldGUgVEVYREVGW2lMSVNUXTsJLyogRGVhbCB3aXRoIGVudHJpZXMgYWRkZWQgdG8gVEVYREVGICovCgkJCQl9CgkJCX07CgkJCS8qIE5vdyBkZWFsIHdpdGggYW55IGVudHJpZXMgcmVtb3ZlZCBmcm9tIFRFWERFRiAqLwoJCQlmb3IoIHZhciBpTElTVCBpbiBHTE9CQUxTVE9SRSl7CgkJCQlpZihURVhERUZbaUxJU1RdID09IG51bGwpewoJCQkJCVRFWERFRltpTElTVF0gPSBldmFsKHVuZXZhbChHTE9CQUxTVE9SRVtpTElTVF0pKTsKCQkJCX0KCQkJfTsKCgkJCS8qIE5vdyB3ZSBkZWFsIHdpdGggY29uZmlndXJpbmcgbWFjcm9TdGFjayAqLwoKCQkJLyogUmVjb3ZlciB0aGUgc2F2ZWQgbWFjcm8gc3RhY2sgYW5kIHNldCB0aGUgY29ycmVjdCBoZWlnaHQgKi8KCQkJbWFjcm9TdGFjayA9IGV2YWwodW5ldmFsKFNUT1JFREJBU0lDTUFDUk9TKSk7CgkJCWhlaWdodCA9IG1hY3JvU3RhY2tbaU5BTUVTXS5sZW5ndGggLSAxOwoKCQkJLyogQ2hlY2sgdGhlIHN0YWNrIGlzIGF0IGxlYXN0IHRoZSBtaW5pbXVtIGhlaWdodCAtIGl0IHNob3VsZCBiZSwgYnV0IGNoZWNrIGFueXdheSAqLwoJCQlpZihoZWlnaHQgPT0gMCl7CgkJCQloZWlnaHQgPSAxOwoJCQkJLyogV2UgaGF2ZSBub3RoaW5nIGF0IHRoaXMgaGVpZ2h0LCBzbyBpbml0aWFsaXplIHRoZSBhcnJheXMgc28gd2UgZG9uJ3QgY2F1c2UgYW55IGNyYXNoZXMgKi8KCQkJCXRoaXMuX2NoZWNrU3RhY2soKTsKCQkJfQoKCgkJCS8qIENsZWFuIGF3YXkgYW55IG9sZCBsb2NhbCBlbnZpcm9ubWVudHMgKi8KCQkJdGhpcy5wb3BBbGwoKTsKCQkJCgkJfQoJCWVsc2UJLyogV2UgZGlkbid0IGNhbGwgXFNhdmVHbG9iYWxzIGZpcnN0ICovCgkJewoJCQlURVguRXJyb3IoIk5vdGhpbmcgd2FzIHNhdmVkIHRvIHJlc3RvcmUuIikKCQl9CgkgICAgfSwKCgkvKiBfcmVjb3JkTWFjcm86IFRoaXMgaXMgYW4gaW50ZXJuYWwgZnVuY3Rpb24gd2hpY2ggYWJzdHJhY3RzIG91dCB0aGUgcHJvY2VzcyBvZiBzdG9yaW5nCSoKCSAqIG1hY3JvcyBvbiB0aGUgc3RhY2suIFRoaXMgc2hvdWxkIGhlbHAgcmVkdWNlIGNvZGUgZHVwbGljYXRpb24uCQkJCSovCglfcmVjb3JkTWFjcm86IGZ1bmN0aW9uIChjb21zKXsKCQkvKiBDaGVjayB0aGUgc3RhY2sgYXQgdGhlIGN1cnJlbnQgaGVpZ2h0IGlzIGluaXRpYWxpemVkIHByb3Blcmx5ICovCgkJdGhpcy5fY2hlY2tTdGFjaygpOwoKCQkvKiBOb3cgd2Ugc2F2ZSB0aGUgbmFtZSBvZiB0aGUgY29tbWFuZCB3ZSB3YW50IHRvIHJlY29yZCAqLwoJCShtYWNyb1N0YWNrW2lOQU1FU11baGVpZ2h0XSkucHVzaChjb21zKTsKCQkvKiBBbmQgdGhlIChwb3NzaWJseSBOVUxMKSBkaXNwbGFjZWQgZGVmaW5pdGlvbiAqLwoJCShtYWNyb1N0YWNrW2lERUZuU11baGVpZ2h0XSkucHVzaChURVhERUYubWFjcm9zW2NvbXNdKTsKCQkvKiBUaGUgZXZhbCB1bmV2YWwgaXMgZm9yIHNhZmV0eS4gTXkgb3RoZXIgYXJyYXlzIGVuZGVkIHVwIHJlZmVyZW5jaW5nLiBJIHNoYWxsIHRlc3QgdGhpcyBsYXRlciA8PFRFU1Q+PiAgTm90ZSB1c2VkIGluIHBvcCgpLiovCgl9LAoKCS8qIEltcGxlbWVudCBcTWV0YU5ld0NvbSwgb3VyIG5ldyBcbmV3Y29tbWFuZCBmdW5jdGlvbiAqLwoJTWV0YU5ld0NvbW1hbmQ6IGZ1bmN0aW9uIChuYW1lKXsKCQl2YXIgY3MgPSB0aGlzLnRyaW1TcGFjZXModGhpcy5HZXRBcmd1bWVudChuYW1lKSksCgkJbiAgPSB0aGlzLnRyaW1TcGFjZXModGhpcy5HZXRCcmFja2V0cyhuYW1lKSksCgkJZGVmID0gdGhpcy5HZXRBcmd1bWVudChuYW1lKTsKCgkJaWYgKG4gPT09ICcnKSB7biA9IG51bGx9CgkJaWYgKGNzLmNoYXJBdCgwKSA9PT0gIlxcIikge2NzID0gY3Muc3Vic3RyKDEpfQoKCQkvKiBWYXJpb3VzIGVycm9yIGNoZWNrcyAqLwoJCWlmICghY3MubWF0Y2goL14oLnxbYS16XSspJC9pKSkge1RFWC5FcnJvcigiSWxsZWdhbCBjb250cm9sIHNlcXVlbmNlIG5hbWUgZm9yICIrbmFtZSl9CgkJaWYgKG4gIT0gbnVsbCAmJiAhbi5tYXRjaCgvXlswLTldKyQvKSkge1RFWC5FcnJvcigiSWxsZWdhbCBudW1iZXIgb2YgcGFyYW1ldGVycyBzcGVjaWZpZWQgaW4gIituYW1lKX0KCgkJLyogUmVjb3JkIHRoZSBjaGFuZ2UgaW4gbWFjcm8qLwoJCXRoaXMuX3JlY29yZE1hY3JvKGNzKTsKCgkJLyogV3JpdGUgdGhlIG5ldyBtYWNybyAqLwoJCVRFWERFRi5tYWNyb3NbY3NdID0gWydNYWNybycsZGVmLG5dOwoJfSwKCgkvKiBJbXBsZW1lbnQgXE1ldGFEZWYgb3VyIG5ldyBcZGVmIGZ1bmN0aW9uICovCglNZXRhRGVmaW5lOiBmdW5jdGlvbiAobmFtZSl7IAoJCXZhciBjcyA9IHRoaXMuR2V0Q1NuYW1lKG5hbWUpLAoJCXBhcmFtcyA9IHRoaXMuR2V0VGVtcGxhdGUobmFtZSwiXFwiK2NzKSwKCQlkZWYgICAgPSB0aGlzLkdldEFyZ3VtZW50KG5hbWUpOwoKCQkvKiBSZWNvcmQgdGhlIGNoYW5nZSBpbiBtYWNybyAqLwoJCXRoaXMuX3JlY29yZE1hY3JvKGNzKTsKCgkJLyogV3JpdGUgdGhlIG5ldyBvbmUgKi8KCQlpZiAoIShwYXJhbXMgaW5zdGFuY2VvZiBBcnJheSkpCgkJewoJCQlURVhERUYubWFjcm9zW2NzXSA9IFsnTWFjcm8nLGRlZixwYXJhbXNdCgkJfQoJCWVsc2UKCQl7CgkJCVRFWERFRi5tYWNyb3NbY3NdID0gWydNYWNyb1dpdGhUZW1wbGF0ZScsZGVmLHBhcmFtc1swXSxwYXJhbXNbMV1dCgkJfQoJfSwKCgkvKiBwdXNoTWFjcm9zOiBzYXZlIHRoZSBjdXJyZW50IHNldCBvZiBtYWNyb3MgYW5kIGdyYWIgYSBuZXcgZW52aXJvbm1lbnQgdGhhdCBjYW4gYmUgdGhyb3duIGF3YXkgbGF0ZXIgKi8KCXB1c2hNYWNyb3M6IGZ1bmN0aW9uKCl7CgkJLyogV2Ugd2FudCB0byBzdGFydCByZWNvcmRpbmcgc3R1ZmYgb24gYSBuZXcgbGV2ZWwgb2YgbWFjcm9TdGFjayAqLwoJCW1hY3JvU3RhY2tbaU5BTUVTXS5wdXNoKG5ldyBBcnJheSgpKTsKCQltYWNyb1N0YWNrW2lERUZuU10ucHVzaChuZXcgQXJyYXkoKSk7CgoJCS8qIE9mIGNvdXJzZSBub3cgdGhlIGhlaWdodCBpbmNyZWFzZXMgKi8KCQloZWlnaHQrKzsKCX0sCgoJLyogcG9wTWFjcm9zOiBSZXN0b3JlIHRoZSBlbnZpcm9ubWVudCBiZWZvcmUgdGhlIHByZXZpb3VzIHB1c2ggKi8KCXBvcE1hY3JvczogZnVuY3Rpb24oKXsKCQkvKiBXZSBkb24ndCB3YW50IHRvIHRvdWNoIGFueSBzYXZlZCBnbG9iYWwgbWFjcm9zIC0gaWYgd2UncmUgc2FmZSwgY29weSBiYWNrIHRoZSBvbGQgZW52aXJvbm1lbnQgKi8KCQlpZigoR0xPQkFMU1RPUkU9PW51bGwpIHx8IChoZWlnaHQgPiAwKSkKCQl7CgkJCXdoaWxlKG1hY3JvU3RhY2tbaU5BTUVTXVtoZWlnaHRdLmxlbmd0aCA+MCkKCQkJewoJCQkJVEVYREVGLm1hY3Jvc1ttYWNyb1N0YWNrW2lOQU1FU11baGVpZ2h0XS5wb3AoKV0gPSBldmFsKHVuZXZhbChtYWNyb1N0YWNrW2lERUZuU11baGVpZ2h0XS5wb3AoKSkpOwoJCQl9CgoJCQkvKiBOb3cgd2UgZGVjcmVhc2UgaGVpZ2h0IHRvIHRoZSBhcHByb3ByaWF0ZSB2YWx1ZSAqLwoJCQlpZigoR0xPQkFMU1RPUkU9PW51bGwpICYmIChoZWlnaHQgPiAwKSkge2hlaWdodCA9IGhlaWdodCAtIDE7fQoJCQllbHNlIGlmKChHTE9CQUxTVE9SRSE9bnVsbCkgJiYgKGhlaWdodCA+IDEpKSB7aGVpZ2h0ID0gaGVpZ2h0IC0gMTt9CgkJfQoJfSwKCgkvKiBwb3BBbGwgcG9wcyBldmVyeXRoaW5nIG9uIHRoZSBzdGFjaywgYW5kIGxlYXZlcyB5b3Ugd2l0aCB0aGUgYmFzZSBnbG9iYWwgZW52aXJvbm1lbnQgKi8KCXBvcEFsbDogZnVuY3Rpb24oKXsKCQkvKiBGaXJzdCBsZXRzIHBvcCBkb3duIHRvIGxldmVsIDEuIE5vdGUgdGhhdCBwb3BNYWNyb3MoKSBtYW5hZ2VzIHRoZSBoZWlnaHQgZm9yIHVzLiAqLwoJCXdoaWxlKGhlaWdodCA+IDEpewoJCQl0aGlzLnBvcE1hY3JvcygpOwoJCX0KCgkJLyogV2UgZG8gb25lIGZ1cnRoZXIgcG9wIHRvIGdldCBiYWNrIHRvIGdsb2JhbHMgLSBub3RlIGlmIHdlIGluY2x1ZGVkIHRoaXMgaW4gdGhlIGxvb3AJKgoJCSAqIHdpdGggZ2xvYmFscyBzYXZlZCB0aGVuIGhlaWdodCB3b3VsZCBzdGF5IGF0IHRoZSB2YWx1ZSAxIGFuZCB3ZSdkIGdldCBhbiBpbmZpbml0ZQkqCgkJICogbG9vcC4gcG9wTWFjcm9zKCkgaGFuZGxlcyBhbGwgdGhlIHNwZWNpYWwgY2FzZXMgZm9yIHVzLgkJCQkqLwoJCXRoaXMucG9wTWFjcm9zKCk7Cgl9LAoKCS8qIEltcGxlbWVudCBcbGV0IGNvbW1hbmQgKi8KCUxldDogZnVuY3Rpb24gKG5hbWUpIHsKCgkJLyoKCQkqIFdlIHVzZSBHZXRDU25hbWUgcmF0aGVyIHRoYW4gR2V0QXJndW1lbnQgYmVjYXVzZQoJCSogd2Ugd2FudCB0byB0aHJvdyBhbiBlcnJvciBpZiBhbiBhcmd1bWVudCBpcwoJCSogZW5jbG9zZWQgaW4gYnJhY2VzLgoJCSovCgkJdmFyIHRhcmdldE5hbWUgPSB0aGlzLkdldENTbmFtZShuYW1lKTsKCgkJLyoKCQkqIFRoZSBmb2xsb3dpbmcgbGluZSBhbGxvd3MgZm9yIGFuIG9wdGlvbmFsICc9JwoJCSogc3ltYm9sIGJldHdlZW4gdGhlIHNvdXJjZSBhbmQgdGFyZ2V0IGNvbW1hbmQKCQkqIG5hbWVzLgoJCSovCgkJaWYgKHRoaXMuR2V0TmV4dCgpID09PSAnPScpIHt0aGlzLmkrK307CgoJCXZhciBzb3VyY2VOYW1lID0gdGhpcy5HZXRDU25hbWUobmFtZSk7CgoJCWlmICghdGFyZ2V0TmFtZS5tYXRjaCgvXigufFthLXpdKykkL2kpKSB7VEVYLkVycm9yKCJJbGxlZ2FsIGNvbnRyb2wgc2VxdWVuY2UgbmFtZSBmb3IgIiArIG5hbWUpfTsKCQlpZiAoIXNvdXJjZU5hbWUubWF0Y2goL14oLnxbYS16XSspJC9pKSkge1RFWC5FcnJvcigiSWxsZWdhbCBjb250cm9sIHNlcXVlbmNlIG5hbWUgZm9yICIgKyBuYW1lKX07CgoKCQkvKiBUaGUgZm9sbG93aW5nIGl0ZXJhdGlvbiBtYWtlcyBzdXJlIHRoYXQgdGhlIGNvbW1hbmQgXHRhcmdldE5hbWUgaXMgbWFkZSB0byBjb2luY2lkZSB3aXRoIFxzb3VyY2VOYW1lLCoKCQkgKiBjb3JyZXNwb25kaW5nIG9mIGNvdXJzZSB0byBcbGV0XHRhcmdldE5hbWVcc291cmNlTmFtZS4JCQkJCQkqLwoJCWZvciAodmFyIGNvbW1hbmRMaXN0IGluIGNvbW1hbmRMaXN0cykgewoKCQkvKgoJCSogTWFrZSBzdXJlIHRoYXQgZm9yIGVhY2ggZGljdGlvbmFyeSB0aGF0IHRoZQoJCSogZW50cnkgZm9yICdzb3VyY2VOYW1lJyBpcyBpZGVudGljYWwgdG8gdGhhdAoJCSogZm9yICd0YXJnZXROYW1lJy4KCQkqLwoJCQlpZiAoVEVYREVGW2NvbW1hbmRMaXN0XVtzb3VyY2VOYW1lXSkgewoJCQkJVEVYREVGW2NvbW1hbmRMaXN0XVt0YXJnZXROYW1lXSA9IFRFWERFRltjb21tYW5kTGlzdF1bc291cmNlTmFtZV07CS8qIE5vdGUsIHRoaXMgaXMgYSByZWZlcmVuY2UgKi8KCQkJfQoJCQllbHNlIGlmIChURVhERUZbY29tbWFuZExpc3RdW3RhcmdldE5hbWVdKSB7CgkJCQlkZWxldGUgVEVYREVGW2NvbW1hbmRMaXN0XVt0YXJnZXROYW1lXQkvKiBpLmUuIGlmIG91ciBmaXJzdCBhcmd1bWVudCB3YXMgbm90aGluZywgcmVtb3ZlIGl0ICovCgkJCX0KCQl9OwogICAgICAgIH0KCgogICAgfSk7CgogIE1hdGhKYXguSHViLlN0YXJ0dXAuc2lnbmFsLlBvc3QoIlRlWCBsb2NhbCBSZWFkeSIpOwoKfSk7CgovKgogKiBBIGZpeCB0aGFua3MgdG8gYW4gZS1tYWlsIGZyb20gRGF2aWRlLgogKgogKiBUaGUgb2xkIGxpbmU6CiAqIE1hdGhKYXguQWpheC5sb2FkQ29tcGxldGUoIkxvY2FsIEV4dGVuc2lvbiIpOwogKgogKiBPbmUgZG9lc24ndCBmZWVkICdsb2FkQ29tcGxldGUnIHNvbWUgYXJiaXRyYXJ5IGZsYWcgbGlrZSB0aGlzLgogKiBJbnN0ZWFkIHlvdSBtdXN0IHBhc3MgYmFjayB0aGUgZmlsZW5hbWUuCiAqLwpNYXRoSmF4LkFqYXgubG9hZENvbXBsZXRlKCJodHRwOi8vb3hrdW5lbmdyb3VwLnRpZGRseXNwYWNlLmNvbS9sb2NhbFRlWC5qcyIpOwo=
<<search>>[[dashboard|PrivateDashboard]]<<closeAll>><<permaview>>
The theory workspace is calculated as intersection of a hexagonal prism and three rotational volumes. 

{{center{[img[https://lh4.googleusercontent.com/-jELmyLj1S9g/UOR7s5Z4TYI/AAAAAAAAAsQ/lJtbnwRc-cw/s288/delta-3_real_workspace.png]]}}}

However, it can be easy modeled using two simples volumes: a cylinder and a frustum cone; and this is how it is used in real applications.

{{center{[img[https://lh6.googleusercontent.com/-EALSbKUflSk/T7jVCW54qTI/AAAAAAAAAsI/QYLJIcYZ048/s288/Fig_Workspace-1.png]][img[https://lh6.googleusercontent.com/-P3MOJx-1lTA/T7jVC1mOnTI/AAAAAAAAAsI/Uuhna4UtywE/s288/Fig_Workspace-2.png]]}}}{{center{  {{small{Workspace defined as a cylinder and a frustum cone}}} }}} 

{{center{[img[https://lh6.googleusercontent.com/-qMjUjmIa-x8/UM2ctLZp4PI/AAAAAAAAApo/w_mleKFzEbo/s288/delta3_simulation.png]]}}}

A servo system is a control system that converts a small mechanical motion into one requiring much greater power. It is composed by two elements: a [[servo-drive|http://en.wikipedia.org/wiki/Servo_drive]] and a [[servo-motor|http://en.wikipedia.org/wiki/Servo_motor]].
<!--{{{-->
<div style='display:none' macro='tiddler LatexNucleus##Init'></div>

<div id='header' class='header'>
<div class='headerShadow'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span> <span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>

<div id='sidebar'>
<div id='titleLine'></div>
<div id='sidebarOptions' refresh='content' tiddler='MainMenu'></div>
<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>

<!--}}}-->
excludeSearch excludeLists excludeMissing excludePublisher systemConfig &siteSettings &plugin &pluginDoc &templateTiddler doc macroset [[BasicMacros Documentation]] syntax meta mathTemplateTiddler discussion %article %project %post %toRSS #todo #ongoing takenotepackage app theme @gareth styleSheet TiddlyPediaTheme systemTheme
A mobile robot manipulator for dry storage of nuclear materials.

The ROBSTAR will be used for inventory and handling tasks in a nuclear storage area. This area is a storage laboratory that has a size of 4.8m x 4.8m and including two windows, a door, three PuO2 storage pits and one storage rack and a battery-charger docking station.

The ROBSTAR consist of a lightweight SCARA-type manipulator mounted on a small-size vehicle.

{{center{[img[https://lh6.googleusercontent.com/-0mSeqVSNwmI/T7jVTWnczXI/AAAAAAAAApk/tdaobCVAvfQ/s800/Robstar_3dModel.jpg]][img[https://lh6.googleusercontent.com/-09ur1_e7b9Y/T7jVTULI39I/AAAAAAAAApg/wgZ7Il4MKog/s800/Robstar_RobotPicture.jpg]]}}}

The platform is a vehicle with differential wheels configuration, equipped with a number of sensors for navigation and safety purposes: 2 bumpers, an inertial system, 2 lasers, etc. The mobile platform will also have a transport pad for one PuO2 container. The SCARA arm has 6 DOF and it is equipped with different sensors: a force/torque sensor to monitor external forces, and a CCD camera coupled to an artificial vision system.

The controller is composed of only one embedded computer for the vehicle and the manipulator, and the GENERIS control software. GENERIS is a generic, opened, and multi-robot software control system. It has been developed by the Joint Research Centre, and it runs over VxWorks OS. 
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
<!--{{{-->
<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>
<!--}}}-->
//{{{
/**
 * SyntaxHighlighter
 * http://alexgorbatchev.com/SyntaxHighlighter
 *
 * SyntaxHighlighter is donationware. If you are using it, please donate.
 * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
 *
 * @version
 * 3.0.83 (July 02 2010)
 * 
 * @copyright
 * Copyright (C) 2004-2010 Alex Gorbatchev.
 *
 * @license
 * Dual licensed under the MIT and GPL licenses.
 */
;(function()
{
	// CommonJS
	typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null;

	function Brush()
	{
		// Contributed by Gheorghe Milas and Ahmad Sherif
	
		var keywords =  'and assert break class continue def del elif else ' +
						'except exec finally for from global if import in is ' +
						'lambda not or pass print raise return try yield while';

		var funcs = '__import__ abs all any apply basestring bin bool buffer callable ' +
					'chr classmethod cmp coerce compile complex delattr dict dir ' +
					'divmod enumerate eval execfile file filter float format frozenset ' +
					'getattr globals hasattr hash help hex id input int intern ' +
					'isinstance issubclass iter len list locals long map max min next ' +
					'object oct open ord pow print property range raw_input reduce ' +
					'reload repr reversed round set setattr slice sorted staticmethod ' +
					'str sum super tuple type type unichr unicode vars xrange zip';

		var special =  'None True False self cls class_';

		this.regexList = [
				{ regex: SyntaxHighlighter.regexLib.singleLinePerlComments, css: 'comments' },
				{ regex: /^\s*@\w+/gm, 										css: 'decorator' },
				{ regex: /(['\"]{3})([^\1])*?\1/gm, 						css: 'comments' },
				{ regex: /"(?!")(?:\.|\\\"|[^\""\n])*"/gm, 					css: 'string' },
				{ regex: /'(?!')(?:\.|(\\\')|[^\''\n])*'/gm, 				css: 'string' },
				{ regex: /\+|\-|\*|\/|\%|=|==/gm, 							css: 'keyword' },
				{ regex: /\b\d+\.?\w*/g, 									css: 'value' },
				{ regex: new RegExp(this.getKeywords(funcs), 'gmi'),		css: 'functions' },
				{ regex: new RegExp(this.getKeywords(keywords), 'gm'), 		css: 'keyword' },
				{ regex: new RegExp(this.getKeywords(special), 'gm'), 		css: 'color1' }
				];
			
		this.forHtmlScript(SyntaxHighlighter.regexLib.aspScriptTags);
	};

	Brush.prototype	= new SyntaxHighlighter.Highlighter();
	Brush.aliases	= ['py', 'python'];

	SyntaxHighlighter.brushes.Python = Brush;

	// CommonJS
	typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
})();
//}}}
//{{{

slideShowSrc =
"<div><embed type=\"application/x-shockwave-flash\" src=\"https://picasaweb.google.com/s/c/bin/slideshow.swf\" width=\"600\" height=\"400\" flashvars=\"host=picasaweb.google.com&hl=en_US&feat=flashalbum&RGB=0x000000&feed=https://picasaweb.google.com/data/feed/api/user/101542046887408327725/albumid/5744574092705046017%3Falt%3Drss%26kind%3Dphoto%26hl%3Den_US\" pluginspage=\"http://www.macromedia.com/go/getflashplayer\"></embed></div>";

// Only install once
if (!version.extensions.Picasa) 
{

version.extensions.Picasa = {
	major: 1, minor: 0, revision: 0, 
	date: new Date(2012,8,12), 
};

config.macros.slideShow = {
   handler: function (place, macroName, params, wikifier, paramString, tiddler)
{ 
    // this will run when macro is called from a tiddler
    //wikify("Hello", place);

    wikify( slideShowSrc,place );
}};

};

//}}}
Things to be improved in the site:
* Add "written" custom field
* Replace create data by written field in RSS (YPipes)
* Finish "latestUpdates" macro, %article sorted by "written" field.
* Create "updateTimeline" macro, list tiddlers filtered by %article and %project.
[[Welcome]] [[My Notes]] [[My Works]] [[Storage]] [[About]]

/***
http://tiddlystyles.com/#theme:TiddlyPedia
***/

/*{{{*/
body{
 background: #f9f9f9 url(http://tiddlythemes.com/empties/headbg.jpg) no-repeat top left;
}

#titleLine{
 display: block;
 _background: transparent url(wiki.png) no-repeat 18px -7px;
 background: transparent url(http://tiddlythemes.com/empties/wiki.png) no-repeat 18px -7px;
 _background: transparent;
 height: 120px;
 _height: 135px;
 width: 150px;
 color: #000;
 border: 1px;
 padding: 0;
 margin: 0;
}

* html #titleLine{
 filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://tiddlythemes.com/empties/wiki.png',sizingMethod='scale');
}

#contentWrapper #siteTitle a{
 display: inline;
 font-weight: bold;
 color: #000;
 font-size: 13px;
}

#siteSubtitle{
 padding: 0;
}

#siteTitle, #mainMenu{
 position: static;
}

#contentWrapper #sidebar{
 top: 0;
 left: 0;
}

#displayArea {
 margin: 0 0 0 15em;
}

#messageArea{
 position: fixed;
 top: 0;
 right: 0;
 font-size: 10px;
 border: 1px solid #aaa;
 background: #fff;
 z-index: 25;
}

#messageArea a:link{
 color: #002bb8;
 text-decoration: none;
}

#messageArea a:hover{
 text-decoration: underline;
}

.viewer{
 background: #fff;
 border: 1px solid #aaa;
 padding: 1em;
margin: 0;
}

.body{
 padding: 1px;
}

.title{
 background: #fff;
 border: 1px solid #aaa;
 display: inline;
 margin-left: .5em;
 padding: 2px .5em;
 border-bottom: 0;
 font-weight: bold;
 color: #000;
 font-size: 1.2em;
}

.toolbar{
 visibility: visible;
 display: inline;
 padding: 0;
 font-family: sans-serif;
}

.toolbar a.button:link,.toolbar a.button:visited{
 background: #fff;
 border: 1px solid #aaa;
 color:#002bb8;
 font-size: 11px;
 padding-bottom: 0;
 margin-right: .25em;
}

/* TiddlyPedia was Created by Clinton Checketts based on the Monobook skin of Wikipedia */

#contentWrapper .toolbar .button:hover{
 border-bottom: 1px solid #fff;
 background: #fff;
 color:#002bb8;
}

.toolbar a.button:hover{
 border-bottom: 1px solid #fff;
 background: #fff;
 color:#000;
}

#displayArea .viewer a,a.button:link,a.button:visited,
a.tiddlyLink:link,a.tiddlyLink:visited,
#sidebarOptions .sliderPanel a{
 color:#002bb8;
 background: transparent;
 border: 0;
}

.viewer a:hover,a.button:hover,a.button:active,
a.tiddlyLink:hover,a.tiddlyLink:active,
.viewer a.button:hover,
#sidebarOptions .sliderPanel a:hover{
 color:#002bb8;
 background: transparent;
 text-decoration: underline;
}

#mainMenu{
 font-family: sans-serif;
 text-align: left;
 font-size: x-small;
 width: 100%;
 margin: 0;
 padding: 0;
}

#mainMenu h1{
 font-size: 11px;
 font-weight: normal;
 padding: 0;
 margin: 0;
 background: transparent;
}

#mainMenu ul{
 font-size: 11px;
 border: 1px solid #aaa;
 padding: .25em 0;
 margin: 0;
 list-style-type: square;
 list-style-image: url(http://tiddlythemes.com/empties/bullet.gif);
 background: #fff;
 width: 100%;
}

#mainMenu li{
 margin: 0 0 0 2em;
 padding: 0;
}

#contentWrapper #mainMenu a:link,#contentWrapper #mainMenu a:visited{
 color:#002bb8;
 padding: 0;
 margin: 0;
 background: transparent;
}

#mainMenu .externalLink {
 text-decoration: none;
}

#mainMenu .externalLink:hover {
 text-decoration: underline;
}

#sidebar{
 padding: .5em;
 font-family: sans-serif;
}

#sidebarOptions{
 border: 1px solid #aaa;
 background: #fff;
 margin-top: .5em;
 width: 100%;
}

#sidebar .sliderPanel{
 margin: 0;
}

#contentWrapper #sidebarOptions .button,#contentWrapper #sidebarOptions .button:hover{
 color:#002bb8;
 padding: .1em 0 .1em 2em;
 background: transparent url(http://tiddlythemes.com/empties/bullet.gif) 10px -2px no-repeat;
}

#sidebarOptions input{
 width: 80%;
 margin: 0 .5em;
}

#sidebarTabs{
 background: #fff;
 margin-top: .5em;
 width: 100%;
}

#sidebarTabs .tabContents,#sidebarTabs .tabContents .tabContents{
 border: 1px solid #aaa;
 background: #fff;
}

#sidebarTabs .tabSelected,#sidebarTabs .tabcontents .tabSelected {
 background: #fff;
 border: 1px solid #aaa;
 border-bottom: 0;
 cursor: default;
 padding-bottom: 3px;
 color: #000;
}

#sidebarTabs .tabUnselected,#sidebarTabs .tabContents .tabUnselected{
 background: #aaa;
 padding-bottom: 0;
 color: #000; 
}

#contentWrapper #sidebarTabs .tiddlyLink,#contentWrapper #sidebarTabs .button,
#contentWrapper #sidebarTabs a.tiddlyLink:hover,#contentWrapper #sidebarTabs a.button:hover{
 background: transparent;
 color: #002bb8;
}

.footer{
 margin: -1em 0 1em 0; 
}

.footer .button:hover,.editorFooter .button:hover{
background: transparent;
 color: #002bb8;
 border-bottom: 1px solid #002bb8;
}

#popup{
 background: #e9e9e9;
 color: #000;
}

#popup hr{
 border-color: #aaa;
 background-color: #aaa;
}

#popup a{
 color: #000;
}

#popup a:hover,#contentWrapper #sidebarTabs #popup a:hover{
 background: #666;
 color: #fff;
 text-decoration: none;
}

#displayArea .tiddler a.tiddlyLinkNonExisting{
 color: #ba0000;
}

#displayArea .tiddler a.externalLink{
 text-decoration: none;
 color:#002bb8;
 padding-right: 1em;
 background: transparent url(http://tiddlythemes.com/empties/external.png) 100% 50% no-repeat;
}

#displayArea .tiddler a.externalLink:hover{
 text-decoration: underline;
}

.viewer pre{
 background: #e9e9e9;
 border: 1px solid #666;
}

.viewer h1, .viewer h2, .viewer h3, .viewer h4, .viewer h5, .viewer h6{
 background: transparent;
 border-bottom: .2em solid #aaa;
}

#sidebar .sliderPanel{
 background: #e9e9e9;
}

#sidebar .sliderPanel input{width: auto;}

.tagged, .tagging, .listTitle{
 float: none;
 display: inline;
}

.tagged li, .tagging li,
.tagged ul, .tagging ul{
 display: inline;
}

/*}}}*/
<<newTiddler label:"new note" title:"New Note" tag:"%article">><<newTiddler label:"new work" title:"New Work" tag:"%project">><<newTiddler>> [[site configuration|SiteConfig]] [[all tiddlers|SideBarTabs]]
@@Please do not modify this tiddler; it was created automatically upon space creation.@@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink" version="1.1" viewBox="301 225 48 52"
width="30" height="30">
<g stroke="none" stroke-opacity="1" stroke-dasharray="none" fill="none" fill-opacity="1">
	<g>
		<path d="M 333.00003 234 L 306 258.75003 L 301.5 270 L 312.75 265.50003 L 339.75 240.74998 Z M 337.5 229.50002 
		L 335.24988 231.75008 L 341.99997 238.50003 L 344.24997 236.24995 Z M 342 225.00003 L 339.74988 227.25009 
		L 346.5 234.00005 L 348.75 231.75003 Z M 301.5 273.9719 C 301.5 273.9719 309.59888 277.99927 317.70013 273.97183 
		C 325.80066 269.94437 341.99997 276.65686 341.99997 276.65686 L 341.99997 273.97195 
		C 341.99997 273.97195 325.80014 267.2594 317.70013 271.28687 C 309.6 275.31451 301.5 271.28683 301.5 271.28683 Z" 
		fill="#101010" class="glyph"/>
	</g>
</g>
</svg>
/***
https://raw.github.com/tiddlyweb/chrjs/master/main.js
***/
//{{{
// TiddlyWeb adaptor
// v0.14.3

/*jslint vars: true, unparam: true, nomen: true, white: true */
/*global jQuery */

var tiddlyweb = (function($) {

"use strict";

var tw = {
	routes: {
		// host is the TiddlyWeb instance's URI (including server_prefix)
		// placeholders "_type" & "name" refer to the respective bag/recipe
		root     : "{host}/",
		bags     : "{host}/bags",
		bag      : "{host}/bags/{name}",
		recipes  : "{host}/recipes",
		recipe   : "{host}/recipes/{name}",
		tiddlers : "{host}/{_type}s/{name}/tiddlers",
		tiddler  : "{host}/{_type}s/{name}/tiddlers/{title}",
		revisions: "{host}/{_type}s/{name}/tiddlers/{title}/revisions",
		revision : "{host}/{_type}s/{name}/tiddlers/{title}/revisions/{revision}",
		search   : "{host}/search?q={query}"
	}
};

var convertTimestamp, supplant;

// host (optional) is the URI of the originating TiddlyWeb instance
tw.Resource = function(type, host) {
	if(arguments.length) { // initialization
		this._type = type;
		if(host !== false) {
			this.host = host !== undefined ? host.replace(/\/$/, "") : null;
		}
	}
};
$.extend(tw.Resource.prototype, {
	// retrieves resource from server
	// callback is passed resource, status, XHR (cf. jQuery.ajax success)
	// errback is passed XHR, error, exception, resource (cf. jQuery.ajax error)
	// filters is an optional filter string (e.g. "select=tag:foo;limit=5")
	get: function(callback, errback, filters) {
		var uri = this.route();
		if(filters) {
			var separator = uri.indexOf("?") === -1 ? "?" : ";";
			uri += separator + filters;
		}
		var self = this;
		return $.ajax({
			url: uri,
			type: "GET",
			dataType: "json",
			success: function(data, status, xhr) {
				var resource = self.parse(data);
				resource.etag = xhr.getResponseHeader("Etag");
				callback(resource, status, xhr);
			},
			error: function(xhr, error, exc) {
				errback(xhr, error, exc, self);
			}
		});
	},
	// sends resource to server
	// callback is passed data, status, XHR (cf. jQuery.ajax success)
	// errback is passed XHR, error, exception, resource (cf. jQuery.ajax error)
	put: function(callback, errback) {
		var self = this;
		var options = {
			url: this.route(),
			type: "PUT",
			contentType: "application/json",
			data: JSON.stringify(this.baseData()),
			success: function(data, status, xhr) {
				callback(self, status, xhr);
			},
			error: function(xhr, error, exc) {
				errback(xhr, error, exc, self);
			}
		};
		if(this.ajaxSetup) {
			this.ajaxSetup(options);
		}
		return $.ajax(options);
	},
	// deletes resource on server
	// callback is passed data, status, XHR (cf. jQuery.ajax success)
	// errback is passed XHR, error, exception, resource (cf. jQuery.ajax error)
	"delete": function(callback, errback) {
		var self = this;
		var options = {
			url: this.route(),
			type: "DELETE",
			success: function(data, status, xhr) {
				callback(self, status, xhr);
			},
			error: function(xhr, error, exc) {
				errback(xhr, error, exc, self);
			}
		};
		if(this.ajaxSetup) {
			this.ajaxSetup(options);
		}
		return $.ajax(options);
	},
	// returns an object carrying only the essential information of the resource
	baseData: function() {
		var data = {},
			self = this;
		$.each(this.data, function(i, item) {
			var value = self[item];
			if(value !== undefined) {
				data[item] = value;
			}
		});
		return data;
	},
	// returns corresponding instance from a raw object (if applicable)
	parse: function(data) {
		return data;
	},
	// list of accepted keys in serialization
	data: [],
	// returns resource's URI
	route: function() {
		return supplant(tw.routes[this._type], this);
	}
});

var Container = function(type, name, host) {
	if(arguments.length) { // initialization
		tw.Resource.apply(this, [type, host]);
		this.name = name;
		this.desc = "";
		this.policy = new tw.Policy({});
	}
};
Container.prototype = new tw.Resource();
$.extend(Container.prototype, {
	tiddlers: function() {
		return new tw.TiddlerCollection(this);
	},
	parse: function(data) {
		var type = tw._capitalize(this._type),
			container = new tw[type](this.name, this.host);
		data.policy = new tw.Policy(data.policy);
		return $.extend(container, data);
	},
	data: ["desc", "policy"]
});

// attribs is an object whose members are merged into the instance (e.g. query)
tw.Collection = function(type, host, attribs) {
	if(arguments.length) { // initialization
		tw.Resource.apply(this, [type, host]);
		$.extend(this, attribs);
	}
};
tw.Collection.prototype = new tw.Resource();

tw.TiddlerCollection = function(container, tiddler) {
	if(arguments.length) { // initialization
		tw.Collection.apply(this, [tiddler ? "revisions" : "tiddlers"]);
		this.container = container || null;
		this.tiddler = tiddler || null;
	}
};
tw.TiddlerCollection.prototype = new tw.Collection();
$.extend(tw.TiddlerCollection.prototype, {
	parse: function(data) {
		var container = this.container;
		return $.map(data, function(item, i) {
			var tiddler = new tw.Tiddler(item.title, container),
				bag = item.bag;
			tiddler = tw.Tiddler.prototype.parse.apply(tiddler, [item]);
			if(!tiddler.bag && bag) { // XXX: bag always present!?
				tiddler.bag = new tw.Bag(bag, container.host);
			}
			if(!tiddler.recipe && item.recipe) {
				tiddler.recipe = new tw.Recipe(item.recipe, container.host);
			}
			delete item.recipe;
			return $.extend(tiddler, item);
		});
	},
	route: function() {
		var params = this.container;
		if(this.tiddler) {
			var container = this.tiddler.bag || this.tiddler.recipe;
			params = {
				_type: container._type,
				host: container.host,
				name: container.name,
				title: this.tiddler.title
			};
		}
		return supplant(tw.routes[this._type], params);
	}
});

tw.Search = function(query, host) {
	tw.Collection.apply(this, ["search", host]);
	this.query = query;
};
tw.Search.prototype = new tw.Collection();
$.extend(tw.Search.prototype, {
	parse: function(data) {
		this.container = { // XXX: hacky
			_type: "bag",
			host: this.host
		};
		var tiddlers = tw.TiddlerCollection.prototype.parse.apply(this, arguments);
		delete this.container;
		return tiddlers;
	}
});

// title is the name of the tiddler
// container (optional) is an instance of either Bag or Recipe
// optionally accepts a single object representing tiddler attributes
tw.Tiddler = function(title, container) {
	tw.Resource.apply(this, ["tiddler", false]);
	this.title = title;
	this.bag = container && container._type === "bag" ? container : null;
	this.recipe = container && container._type === "recipe" ? container : null;
	var self = this;
	$.each(this.data, function(i, item) {
		self[item] = undefined; // exposes list of standard attributes for inspectability
	});
	if(title && title.title) { // title is an object of tiddler attributes
		$.extend(this, title);
	}
};
tw.Tiddler.prototype = new tw.Resource();
$.extend(tw.Tiddler.prototype, {
	revisions: function() {
		return new tw.TiddlerCollection(this.bag || this.recipe, this);
	},
	route: function() {
		var container = this.bag || this.recipe;
		var params = $.extend({}, this, {
			host: container ? container.host : null,
			_type: this.bag ? "bag" : (this.recipe ? "recipe" : null),
			name: container ? container.name : null
		});
		return supplant(tw.routes[this._type], params);
	},
	parse: function(data) {
		var tiddler = new tw.Tiddler(this.title),
			container = this.bag || this.recipe;
		if(data.bag) {
			tiddler.bag = new tw.Bag(data.bag, container.host);
			delete data.bag;
		}
		delete data.recipe;
		tiddler.created = data.created ? convertTimestamp(data.created) : new Date();
		delete data.created;
		tiddler.modified = data.modified ? convertTimestamp(data.modified) : new Date();
		delete data.modified;
		if(this.recipe) {
			tiddler.recipe = this.recipe;
		}
		return $.extend(tiddler, data);
	},
	data: ["created", "creator", "modifier", "modified", "tags", "type", "text",
			"fields"],
	ajaxSetup: function(options) {
		var self = this;
		if(this.etag && (options.type === "PUT" || options.type === "DELETE")) {
			options.beforeSend = function(xhr) {
				xhr.setRequestHeader("If-Match", self.etag);
			};
		}
		if(options.type === "PUT") {
			var callback = options.success;
			options.success = function(data, status, xhr) {
				var loc = xhr.getResponseHeader("Location"),
					etag = xhr.getResponseHeader("Etag");
				if(loc && etag) {
					self.etag = etag;
					if(!self.bag) {
						var bag = loc.split("/bags/").pop().split("/")[0];
						self.bag = new tw.Bag(bag, self.recipe.host);
					}
					callback(self, status, xhr);
				} else { // IE
					self.get(callback, options.error);
				}
			};
		}
	}
});

tw.Revision = function(id, tiddler) {
	var container = tiddler.bag || tiddler.recipe;
	tw.Tiddler.apply(this, [tiddler.title, container]);
	this._type = "revision";
	this.revision = id;
};
tw.Revision.prototype = new tw.Tiddler();
$.extend(tw.Revision.prototype, {
	revisions: false,
	data: false,
	put: false,
	"delete": false
});

tw.Bag = function(name, host) {
	Container.apply(this, ["bag", name, host]);
};
tw.Bag.prototype = new Container();

tw.Recipe = function(name, host) {
	Container.apply(this, ["recipe", name, host]);
	this.recipe = [];
};
tw.Recipe.prototype = new Container();
$.extend(tw.Recipe.prototype, {
	data: ["recipe"].concat(Container.prototype.data)
});

tw.Policy = function(constraints) { // TODO: validation?
	var self = this;
	$.each(this.constraints, function(i, item) {
		self[item] = constraints[item];
	});
};
tw.Policy.prototype.constraints = ["read", "write", "create", "delete",
	"manage", "accept", "owner"];

/*
 * utilities
 */

tw._capitalize = function(str) {
	return str.charAt(0).toUpperCase() + str.slice(1);
};

// convert YYYYMMDDhhmmss timestamp to Date instance
convertTimestamp = function(t) {
	if (t.match(/^\d{12,17}$/)) {
		return new Date(Date.UTC(
			parseInt(t.substr(0, 4), 10),
			parseInt(t.substr(4, 2), 10) - 1,
			parseInt(t.substr(6, 2), 10),
			parseInt(t.substr(8, 2), 10),
			parseInt(t.substr(10, 2), 10),
			parseInt(t.substr(12, 2) || "0", 10),
			parseInt(t.substr(14, 3) || "0", 10)
		));
	} else {
		return new Date(Date.parse(t));
	}
};

// adapted from Crockford (http://javascript.crockford.com/remedial.html)
supplant = function(str, obj) {
	return str.replace(/{([^{}]*)}/g, function (a, b) {
		var r = obj[b];
		r = typeof r === "string" || typeof r === "number" ? r : a;
		return $.inArray(b, ["host", "query"]) !== -1 ? r : encodeURIComponent(r); // XXX: special-casing
	});
};

return tw;

}(jQuery));
//}}}
/***
|Name|PlayerPlugin|
|Source|http://www.TiddlyTools.com/#PlayerPlugin|
|Version|1.1.4|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|Embed a media player in a tiddler|
!!!!!Usage
<<<
{{{<<player [id=xxx] [type] [URL] [width] [height] [autoplay|true|false] [showcontrols|true|false] [extras]>>}}}

''id=xxx'' is optional, and specifies a unique identifier for each embedded player.  note: this is required if you intend to display more than one player at the same time.

''type'' is optional, and is one of the following: ''windows'', ''realone'', ''quicktime'', ''flash'', ''image'' or ''iframe''.  If the media type is not specified, the plugin automatically detects Windows, Real, QuickTime, Flash video or JPG/GIF images by matching known file extensions and/or specialized streaming-media transfer protocols (such as RTSP:).  For unrecognized media types, the plugin displays an error message.

''URL'' is the location of the media content

''width'' and ''height'' are the dimensions of the video display area (in pixels)

''autoplay'' or ''true'' or ''false'' is optional, and specifies whether the media content should begin playing as soon as it is loaded, or wait for the user to press the "play" button.  Default is //not// to autoplay.

''showcontrols'' or ''true'' or ''false'' is optional, and specifies whether the embedded media player should display its built-in control panel (e.g., play, pause, stop, rewind, etc), if any.  Default is to display the player controls.

''extras'' are optional //pairs// of parameters that can be passed to the embedded player, using the {{{<param name=xxx value=yyy>}}} HTML syntax.

''If you use [[AttachFilePlugin]] to encode and store a media file within your document, you can play embedded media content by using the title of the //attachment tiddler//'' as a parameter in place of the usual reference to an external URL.  When playing an attached media content, you should always explicitly specify the media type parameter, because the name used for the attachment tiddler may not contain a known file extension from which a default media type can be readily determined.
<<<
!!!!!Configuration
<<<
Default player size:
width: <<option txtPlayerDefaultWidth>> height: <<option txtPlayerDefaultHeight>>
<<<
!!!!!Examples
<<<
+++[Windows Media]...
Times Square Live Webcam
{{{<<player id=1 http://www.earthcam.com/usa/newyork/timessquare/asx/tsq_stream.asx>>}}}
===
+++[RealOne]...
BBC London: Live and Recorded news
{{{<<player id=2 http://www.bbc.co.uk/london/realmedia/news/tvnews.ram>>}}}
===
+++[Quicktime]...
America Free TV: Classic Comedy
{{{<<player id=3 http://www.americafree.tv/unicast_mov/AmericaFreeTVComedy.mov>>}}}
===
+++[Flash]...
YouTube Video
{{{<<player id=6 flash http://www.youtube.com/v/OdT9z-JjtJk 400 300>>}}}
===
+++[Still Images]...
GIF (best for illustrations, animations, diagrams, etc.)
{{{<<player id=7 image images/meow.gif auto auto>>}}}
JPG (best for photographs, scanned images, etc.)
{{{<<player id=8 image images/meow2.jpg 200 150>>}}}
===
<<<
!!!!!Revisions
<<<
2008.05.10 [1.1.4] in handlers(), immediately return if no params (prevents error in macro).  Also, refactored auto-detect code to make type mapping configurable.
2007.10.15 [1.1.3] in loadURL(), add recognition for .PNG (still image), fallback to iframe for unrecognized media types
2007.08.31 [1.1.2] added 'click-through' link for JPG/GIF images
2007.06.21 [1.1.1] changed "hidecontrols" param to "showcontrols" and recognize true/false values in addition to 'showcontrols', added "autoplay" param (also recognize true/false values), allow "auto" as value for type param
2007.05.22 [1.1.0] added support for type=="iframe" (displays src URL in an IFRAME)
2006.12.06 [1.0.1] in handler(), corrected check for config.macros.attach (instead of config.macros.attach.getAttachment) so that player plugin will work when AttachFilePlugin is NOT installed.  (Thanks to Phillip Ehses for bug report)
2006.11.30 [1.0.0] support embedded media content using getAttachment() API defined by AttachFilePlugin or AttachFilePluginFormatters.  Also added support for 'image' type to render JPG/GIF still images
2006.02.26 [0.7.0] major re-write.  handles default params better.  create/recreate player objects via loadURL() API for use with interactive forms and scripts.
2006.01.27 [0.6.0] added support for 'extra' macro params to pass through to object parameters
2006.01.19 [0.5.0] Initial ALPHA release
2005.12.23 [0.0.0] Started
<<<
!!!!!Code
***/
//{{{
version.extensions.PlayerPlugin= {major: 1, minor: 1, revision: 4, date: new Date(2008,5,10)};

config.macros.player = {};
config.macros.player.html = {};
config.macros.player.handler= function(place,macroName,params) {
	if (!params.length) return; // missing parameters - do nothing
	var id=null;
	if (params[0].substr(0,3)=="id=") id=params.shift().substr(3);
	var type="";
	if (!params.length) return; // missing parameters - do nothing
	var p=params[0].toLowerCase();
	if (p=="auto" || p=="windows" || p=="realone" || p=="quicktime" || p=="flash" || p=="image" || p=="iframe")
		type=params.shift().toLowerCase();
	var url=params.shift(); if (!url || !url.trim().length) url="";
	if (url.length && config.macros.attach!=undefined) // if AttachFilePlugin is installed
		if ((tid=store.getTiddler(url))!=null && tid.isTagged("attachment")) // if URL is attachment
			url=config.macros.attach.getAttachment(url); // replace TiddlerTitle with URL
	var width=params.shift();
	var height=params.shift();
	var autoplay=false;
	if (params[0]=='autoplay'||params[0]=='true'||params[0]=='false')
		autoplay=(params.shift()!='false');
	var show=true;
	if (params[0]=='showcontrols'||params[0]=='true'||params[0]=='false')
		show=(params.shift()!='false');
	var extras="";
	while (params[0]!=undefined)
		extras+="<param name='"+params.shift()+"' value='"+params.shift()+"'> ";
	this.loadURL(place,id,type,url,width,height,autoplay,show,extras);
}

if (config.options.txtPlayerDefaultWidth==undefined) config.options.txtPlayerDefaultWidth="100%";
if (config.options.txtPlayerDefaultHeight==undefined) config.options.txtPlayerDefaultHeight="480"; // can't use "100%"... player height doesn't stretch right :-(

config.macros.player.typeMap={
	windows: ['mms', '.asx', '.wvx', '.wmv', '.mp3'],
	realone: ['rtsp', '.ram', '.rpm', '.rm', '.ra'],
	quicktime: ['.mov', '.qt'],
	flash: ['.swf', '.flv'],
	image: ['.jpg', '.gif', '.png'],
	iframe: ['.htm', '.html', '.shtml', '.php']
};

config.macros.player.loadURL=function(place,id,type,url,width,height,autoplay,show,extras) {

	if (id==undefined) id="tiddlyPlayer";
	if (!width) var width=config.options.txtPlayerDefaultWidth;
	if (!height) var height=config.options.txtPlayerDefaultHeight;
	if (url && (!type || !type.length || type=="auto")) { // determine type from URL
		u=url.toLowerCase();
		var map=config.macros.player.typeMap;
		for (var t in map) for (var i=0; i<map[t].length; i++)
			if (u.indexOf(map[t][i])!=-1) var type=t;
	}
	if (!type || !config.macros.player.html[type]) var type="none";
	if (!url) var url="";
	if (show===undefined) var show=true;
	if (!extras) var extras="";
	if (type=="none" && url.trim().length) type="iframe"; // fallback to iframe for unrecognized media types

	// adjust parameter values for player-specific embedded HTML
	switch (type) {
		case "windows":
			autoplay=autoplay?"1":"0"; // player-specific param value
			show=show?"1":"0"; // player-specific param value
			break;
		case "realone":
			autoplay=autoplay?"true":"false";
			show=show?"block":"none";
			height-=show?60:0; // leave room for controls
			break;
		case "quicktime":
			autoplay=autoplay?"true":"false";
			show=show?"true":"false";
			break;
		case "image":
			show=show?"block":"none";
			break;
		case "iframe":
			show=show?"block":"none";
			break;
	}

	// create containing div for player HTML
	// and add or replace player in TW DOM structure
	var newplayer = document.createElement("div");
	newplayer.playerType=type;
	newplayer.setAttribute("id",id+"_div");
	var existing = document.getElementById(id+"_div");
	if (existing && !place) place=existing.parentNode;
	if (!existing)
		place.appendChild(newplayer);
	else {
		if (place==existing.parentNode) place.replaceChild(newplayer,existing)
		else { existing.parentNode.removeChild(existing); place.appendChild(newplayer); }
	}

	var html=config.macros.player.html[type];
	html=html.replace(/%i%/mg,id);
	html=html.replace(/%w%/mg,width);
	html=html.replace(/%h%/mg,height);
	html=html.replace(/%u%/mg,url);
	html=html.replace(/%a%/mg,autoplay);
	html=html.replace(/%s%/mg,show);
	html=html.replace(/%x%/mg,extras);
	newplayer.innerHTML=html;
}
//}}}

// // Player-specific API functions: isReady(id), isPlaying(id), toggleControls(id), showControls(id,flag)

//{{{
// status values:
// Windows: 0=Undefined, 1=Stopped, 2=Paused, 3=Playing, 4=ScanForward, 5=ScanReverse
//          6=Buffering, 7=Waiting, 8=MediaEnded, 9=Transitioning, 10=Ready, 11=Reconnecting
// RealOne: 0=Stopped, 1=Contacting, 2=Buffering, 3=Playing, 4=Paused, 5=Seeking
// QuickTime: 'Waiting', 'Loading', 'Playable', 'Complete', 'Error:###'
// Flash: 0=Loading, 1=Uninitialized, 2=Loaded, 3=Interactive, 4=Complete
config.macros.player.isReady=function(id)
{
	var d=document.getElementById(id+"_div"); if (!d) return false;
	var p=document.getElementById(id); if (!p) return false;
	if (d.playerType=='windows') return !((p.playState==0)||(p.playState==7)||(p.playState==9)||(p.playState==11));
	if (d.playerType=='realone') return (p.GetPlayState()>1);
	if (d.playerType=='quicktime') return !((p.getPluginStatus()=='Waiting')||(p.getPluginStatus()=='Loading'));
	if (d.playerType=='flash') return (p.ReadyState>2);
	return true;
}
config.macros.player.isPlaying=function(id)
{
	var d=document.getElementById(id+"_div"); if (!d) return false;
	var p=document.getElementById(id); if (!p) return false;
	if (d.playerType=='windows') return (p.playState==3);
	if (d.playerType=='realone') return (p.GetPlayState()==3);
	if (d.playerType=='quicktime') return (p.getPluginStatus()=='Complete');
	if (d.playerType=='flash') return (p.ReadyState<4);
	return false;
}
config.macros.player.showControls=function(id,flag) {
	var d=document.getElementById(id+"_div"); if (!d) return false;
	var p=document.getElementById(id); if (!p) return false;
	if (d.playerType=='windows') { p.ShowControls=flag; p.ShowStatusBar=flag; }
	if (d.playerType=='realone') { alert('show/hide controls not available'); }
	if (d.playerType=='quicktime')      // if player not ready, retry in one second
		{ if (this.isReady(id)) p.setControllerVisible(flag); else setTimeout('config.macros.player.showControls("'+id+'",'+flag+')',1000); }
	if (d.playerType=='flash') { alert('show/hide controls not available'); }
}
config.macros.player.toggleControls=function(id) {
	var d=document.getElementById(id+"_div"); if (!d) return false;
	var p=document.getElementById(id); if (!p) return false;
	if (d.playerType=='windows') var flag=!p.ShowControls;
	if (d.playerType=='realone') var flag=true; // TBD
	if (d.playerType=='quicktime') var flag=!p.getControllerVisible();
	if (d.playerType=='flash') var flag=true; // TBD
	this.showControls(id,flag);
}
config.macros.player.fullScreen=function(id) {
	var d=document.getElementById(id+"_div"); if (!d) return false;
	var p=document.getElementById(id); if (!p) return false;
	if (d.playerType=='windows') p.DisplaySize=3;
	if (d.playerType=='realone') p.SetFullScreen();
	if (d.playerType=='quicktime') { alert('full screen not available'); }
	if (d.playerType=='flash') { alert('full screen not available'); }
}
//}}}

// // Player HTML

//{{{
// placeholder (no player)
config.macros.player.html.none=' \
	<table id="%i%" width="%w%" height="%h%" style="background-color:#111;border:0;margin:0;padding:0;"> \
	<tr style="background-color:#111;border:0;margin:0;padding:0;"> \
	<td width="%w%" height="%h%" style="background-color:#111;color:#ccc;border:0;margin:0;padding:0;text-align:center;"> \
	&nbsp; \
	%u% \
	&nbsp; \
	</td></tr></table>';
//}}}

//{{{
// JPG/GIF/PNG still images
config.macros.player.html.image='\
	<a href="%u%" target="_blank"><img width="%w%" height="%h%" style="display:%s%;" src="%u%"></a>';
//}}}

//{{{
// IFRAME web page viewer
config.macros.player.html.iframe='\
	<iframe id="%i%" width="%w%" height="%h%" style="display:%s%;background:#fff;" src="%u%"></iframe>';
//}}}

//{{{
// Windows Media Player
// v7.1 ID: classid=CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6
// v9	ID: classid=CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95
config.macros.player.html.windows=' \
	<object id="%i%" width="%w%" height="%h%" style="margin:0;padding:0;width:%w%;height:%h%px;" \
		classid="CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95" \
		codebase="http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=6,4,5,715" \
		align="baseline" border="0" \
		standby="Loading Microsoft Windows Media Player components..." \
		type="application/x-oleobject"> \
		<param name="FileName" value="%u%"> <param name="ShowControls" value="%s%"> \
		<param name="ShowPositionControls" value="1"> <param name="ShowAudioControls" value="1"> \
		<param name="ShowTracker" value="1"> <param name="ShowDisplay" value="0"> \
		<param name="ShowStatusBar" value="1"> <param name="AutoSize" value="1"> \
		<param name="ShowGotoBar" value="0"> <param name="ShowCaptioning" value="0"> \
		<param name="AutoStart" value="%a%"> <param name="AnimationAtStart" value="1"> \
		<param name="TransparentAtStart" value="0"> <param name="AllowScan" value="1"> \
		<param name="EnableContextMenu" value="1"> <param name="ClickToPlay" value="1"> \
		<param name="InvokeURLs" value="1"> <param name="DefaultFrame" value="datawindow"> \
		%x% \
		<embed src="%u%" style="margin:0;padding:0;width:%w%;height:%h%px;" \
			align="baseline" border="0" width="%w%" height="%h%" \
			type="application/x-mplayer2" \
			pluginspage="http://www.microsoft.com/windows/windowsmedia/download/default.asp" \
			name="%i%" showcontrols="%s%" showpositioncontrols="1" \
			showaudiocontrols="1" showtracker="1" showdisplay="0" \
			showstatusbar="%s%" autosize="1" showgotobar="0" showcaptioning="0" \
			autostart="%a%" autorewind="0" animationatstart="1" transparentatstart="0" \
			allowscan="1" enablecontextmenu="1" clicktoplay="0" invokeurls="1" \
			defaultframe="datawindow"> \
		</embed> \
	</object>';
//}}}

//{{{
// RealNetworks' RealOne Player
config.macros.player.html.realone=' \
	<table width="%w%" style="border:0;margin:0;padding:0;"><tr style="border:0;margin:0;padding:0;"><td style="border:0;margin:0;padding:0;"> \
	<object id="%i%" width="%w%" height="%h%" style="margin:0;padding:0;" \
		CLASSID="clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA"> \
		<PARAM NAME="CONSOLE" VALUE="player"> \
		<PARAM NAME="CONTROLS" VALUE="ImageWindow"> \
		<PARAM NAME="AUTOSTART" Value="%a%"> \
		<PARAM NAME="MAINTAINASPECT" Value="true"> \
		<PARAM NAME="NOLOGO" Value="true"> \
		<PARAM name="BACKGROUNDCOLOR" VALUE="#333333"> \
		<PARAM NAME="SRC" VALUE="%u%"> \
		%x% \
		<EMBED width="%w%" height="%h%" controls="ImageWindow" type="audio/x-pn-realaudio-plugin" style="margin:0;padding:0;" \
			name="%i%" \
			src="%u%" \
			console=player \
			maintainaspect=true \
			nologo=true \
			backgroundcolor=#333333 \
			autostart=%a%> \
		</OBJECT> \
	</td></tr><tr style="border:0;margin:0;padding:0;"><td style="border:0;margin:0;padding:0;"> \
	<object id="%i%_controls" width="%w%" height="60" style="margin:0;padding:0;display:%s%" \
		CLASSID="clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA"> \
		<PARAM NAME="CONSOLE" VALUE="player"> \
		<PARAM NAME="CONTROLS" VALUE="All"> \
		<PARAM NAME="NOJAVA" Value="true"> \
		<PARAM NAME="MAINTAINASPECT" Value="true"> \
		<PARAM NAME="NOLOGO" Value="true"> \
		<PARAM name="BACKGROUNDCOLOR" VALUE="#333333"> \
		<PARAM NAME="SRC" VALUE="%u%"> \
		%x% \
		<EMBED WIDTH="%w%" HEIGHT="60" NOJAVA="true" type="audio/x-pn-realaudio-plugin" style="margin:0;padding:0;display:%s%" \
			controls="All" \
			name="%i%_controls" \
			src="%u%" \
			console=player \
			maintainaspect=true \
			nologo=true \
			backgroundcolor=#333333> \
		</OBJECT> \
	</td></tr></table>';
//}}}

//{{{
// QuickTime Player
config.macros.player.html.quicktime=' \
	<OBJECT ID="%i%" WIDTH="%w%" HEIGHT="%h%" style="margin:0;padding:0;" \
		CLASSID="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" \
		CODEBASE="http://www.apple.com/qtactivex/qtplugin.cab"> \
		<PARAM name="SRC" VALUE="%u%"> \
		<PARAM name="AUTOPLAY" VALUE="%a%"> \
		<PARAM name="CONTROLLER" VALUE="%s%"> \
		<PARAM name="BGCOLOR" VALUE="#333333"> \
		<PARAM name="SCALE" VALUE="aspect"> \
		<PARAM name="SAVEEMBEDTAGS" VALUE="true"> \
		%x% \
		<EMBED name="%i%" WIDTH="%w%" HEIGHT="%h%" style="margin:0;padding:0;" \
			SRC="%u%" \
			AUTOPLAY="%a%" \
			SCALE="aspect" \
			CONTROLLER="%s%" \
			BGCOLOR="#333333" \
			EnableJavaSript="true" \
			PLUGINSPAGE="http://www.apple.com/quicktime/download/"> \
		</EMBED> \
	</OBJECT>';
//}}}

//{{{
// Flash Player
config.macros.player.html.flash='\
	<object id="%i%" width="%w%" height="%h%" style="margin:0;padding:0;" \
		classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" \
		codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,29,0"> \
		<param name="movie" value="%u%"> \
		<param name="quality" value="high"> \
		<param name="SCALE" value="exactfit"> \
		<param name="bgcolor" value="333333"> \
		%x% \
		<embed name="%i%" src="%u%" style="margin:0;padding:0;" \
			height="%h%" width="%w%" quality="high" \
			pluginspage="http://www.macromedia.com/go/getflashplayer" \
			type="application/x-shockwave-flash" scale="exactfit"> \
		</embed> \
	</object>';
//}}}
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AP8zZgAAAGYA//8zAADMMwD/mTMAAGYzAP8zMwAAADMAzP8AAADMAADMmQAAAGYAAMwzAAAAAADuzAAA3QAAALvMAACqAAAAiMwAAHcAAABVmQAARAAAACKZAAARAADuAJkA3QAAALsAmQCqAAAAiACZAHcAAABVAJkARAAAACIAZgARAADuAABm3QAAALsAAGaqAAAAiAAAZncAAABVAABmRAAAACIAAGYRAAAA7u7uM93d3QC7u7szqqqqAIiIiDN3d3cAVVVVM0RERAAiIiIzERERAAAAADMBAQEBAQEBAQEBpXl5eXl5eXl5eXmlAQEBAQEBAQEBAQEBAQEBAQEBgHl5eXl5eXl5eXl5eXl5gAEBAQEBAQEBAQEBAQEB/Xp5eXlVT04qKioqTk9VeXl5ev0BAQEBAQEBAQEBAaV5eXlPKioqKioqKioqKioqT3l5eaUBAQEBAQEBAQGAeXlVTioqKioqKioqKioqKioqTlV5eYABAQEBAQEBgHl5VSoqKioqKioqKioqKioqKioqKlV5eYABAQEBAaV5eVUqKioqKioqKioqKioqKioqKioqKlV5eaUBAQEBeXlVKioqKioqKioqKioqKioqKioqKioqKlV5eQEBAXl5eU4qKioqKioqKjExMTExMSoqKioqKioqTnl5eQEBeXlPKioqKioqKjEyMjIyMjIyMjEqKioqKioqT3l5AXp5eSoqKioqKioxMjIxBwcHBzEyMjEqKioqKioqeXl6eXlVKioqKioqMTIxBwcHBwcHBwcxMjEqKioqKipVeXl5eU8qKioqKioyMgcHBwcHBwcHBwcyMioqKioqKk95eXl5TioqKioqMTIxBwcHBwcHBwcHBzEyMSoqKioqTnl5eXkqKioqKioxMgcHBwcHBwcHBwcHBzIxKioqKioqeXl5eSoqKioqKjEyBwcHBwcHBwcHBwcHMjEqKioqKip5eXl5KioqKioqMTIHBwcHBwcHBwcHBwcyMSoqKioqKnl5eXkqKioqKioxMgcHBwcHBwcHBwcHBzIxKioqKioqeXl5eU4qKioqKjEyMQcHBwcHBwcHBwcxMjEqKioqKk55eXl5TyoqKioqKjIyBwcHBwcHBwcHBzIyKioqKioqT3l5eXlVKioqKioqMTIxBwcHBwcHBwcxMjEqKioqKipVeXl6eXkqKioqKioqMTIyMQcHBwcxMjIxKioqKioqKnl5egF5eU8qKioqKioqMTIyMjIyMjIyMSoqKioqKipPeXkBAXl5eU4qKioqKioqKjExMTExMSoqKioqKioqTnl5eQEBAXl5VSoqKioqKioqKioqKioqKioqKioqKipVeXkBAQEB+nl5VSoqKioqKioqKioqKioqKioqKioqVXl5+gEBAQEBenl5VSoqKioqKioqKioqKioqKioqKlV5eXoBAQEBAQEBeXl5VU4qKioqKioqKioqKioqKk5VeXl5AQEBAQEBAQEBenl5eU8qKioqKioqKioqKipPeXl5egEBAQEBAQEBAQEB+nl5eXlVT04qKioqTk9VeXl5efoBAQEBAQEBAQEBAQEBAXl5eXl5eXl5eXl5eXl5eXkBAQEBAQEBAQEBAQEBAQEBAQF6eXl5eXl5eXl5eXoBAQEBAQEBAQEB/+AH//+AAf/+AAB//AAAP/gAAB/wAAAP4AAAB8AAAAPAAAADgAAAAYAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAYAAAAHAAAADwAAAA+AAAAfwAAAP+AAAH/wAAD/+AAB//4AB///gB/8oAAAAIAAAAEAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAACAAAAAwAAAAMAAAADAAAABG1bSA61m3JXuqB4mbuhd8m9o3jqvaF4+b2hePm9o3jqu6F3ybqgeJm1m3JXbVtIDgAAAAQAAAADAAAAAwAAAAMAAAACAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAAwAAAAUAAAAGAAAACI98Wye0nXWavKF4876kev++pHr/vqR6/76kev++pHr/vqR6/76kev++pHr/vqR6/76kev+8oXjztJ11mo98WycAAAAIAAAABgAAAAUAAAADAAAAAgAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAgAAAAQAAAAHAAAAChwcHBKulnGJvaN5+L6kev++pHr/y7GJ/9/Fnv/s1K7/9t25//rivv/64r7/9t25/+zUrv/fxZ7/y7GJ/76kev++pHr/vaN5+K6WcYkcHBwSAAAACgAAAAcAAAAEAAAAAgAAAAEAAAAAAAAAAAAAAAEAAAADAAAABwAAAAtuYkUst552z76kev++pHr+1LuS//Latf/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD/8tq1/9S7kv++pHr+vqR6/7eeds9uYkUsAAAACwAAAAcAAAADAAAAAQAAAAAAAAABAAAAAgAAAAQAAAAIi3hbNbqgd+a+pHr/xayD/+3Vr//85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA/+3Vr//FrIP/vqR6/7qgd+aJdVg0AAAACAAAAAQAAAACAAAAAQAAAAEAAAACAAAABIl8WSW8oXjlvqR6/8yyiv/54Lz//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//ngvP/Msor/vqR6/7yheOWJfFklAAAABAAAAAIAAAABAAAAAAAAAAFfXz8Iu6F4zL6kev/Msor/+uK+//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//rivv/Msor/vqR6/7uheMxfXz8IAAAAAQAAAAAAAAAAAAAAAbqid4K+pHr/xayD//ngvP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//fgvP/FrIP/vqR6/7qid4IAAAABAAAAAAAAAAC3l28gvaN5+L6kev7t1a///OXA//zlwP/85cD//OXA//zlwP/85cD//OXA/+/Twv/Qq8f/u5HK/7OGzP+zhsz/u5HK/9Crx//v08L//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA/+3Vr/++pHr+vaN5+LeXbyAAAAAAAAAAALuheJa+pHr/1LuS//zlwP/85cD//OXA//zlwP/85cD//OXA//riwP/Pq8f/r4HM/6+Bzf+vgc3/r4HN/6+Bzf+vgc3/r4HN/6+BzP/Pq8f/+uLA//zlwP/85cD//OXA//zlwP/85cD//OXA/9S5kv++pHr/u6F4lgAAAACii3MLvKF4876kev/y2rX//OXA//zlwP/85cD//OXA//zlwP/64sD/w5vJ/6+Bzf+vg83/w5vc/9W06v/dwPD/3cDw/9W06v/Dm9z/r4PN/6+Bzf/Dm8n/+uLA//zlwP/85cD//OXA//zlwP/85cD/8tq1/76kev+8oXjzootzC72feFW+pHr/y7GJ//zlwP/85cD//OXA//zlwP/85cD//OXA/8+rx/+vgc3/tIfQ/9a16//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//Wtev/tIfQ/6+Bzf/Pq8f//OXA//zlwP/85cD//OXA//zlwP/85cD/y7GJ/76kev+9n3hVvaF4mL6kev/fxZ7//OXA//zlwP/85cD//OXA//zlwP/v08L/r4HM/6+Dzf/Wtev/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//Wtev/r4PN/6+BzP/v08L//OXA//zlwP/85cD//OXA//zlwP/fxZ7/vqR6/72heJi8oXfIvqR6/+zUrv/85cD//OXA//zlwP/85cD//OXA/9Crx/+vgc3/w5vc/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//Dm9z/r4HN/9Crx//85cD//OXA//zlwP/85cD//OXA/+zUrv++pHr/vKF3yL2jeOq+pHr/9t25//zlwP/85cD//OXA//zlwP/85cD/u5HK/6+Bzf/VtOr/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/9W06v+vgc3/u5HK//zlwP/85cD//OXA//zlwP/85cD/9t25/76kev+9o3jqvaF4+b6kev/64r7//OXA//zlwP/85cD//OXA//zlwP+zhsz/r4HN/93A8P/hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/3cDw/6+Bzf+zhsz//OXA//zlwP/85cD//OXA//zlwP/64r7/vqR6/72hePm9oXj5vqR6//rivv/85cD//OXA//zlwP/85cD//OXA/7OGzP+vgc3/3cDw/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//dwPD/r4HN/7OGzP/85cD//OXA//zlwP/85cD//OXA//rivv++pHr/vaF4+b2jeOq+pHr/9t25//zlwP/85cD//OXA//zlwP/85cD/u5HK/6+Bzf/VtOr/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/9W06v+vgc3/u5HK//zlwP/85cD//OXA//zlwP/85cD/9t25/76kev+9o3jqvKF3yL6kev/s1K7//OXA//zlwP/85cD//OXA//zlwP/Qq8f/r4HN/8Ob3P/hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/w5vc/6+Bzf/Qq8f//OXA//zlwP/85cD//OXA//zlwP/s1K7/vqR6/7yhd8i9oXiYvqR6/9/Fnv/85cD//OXA//zlwP/85cD//OXA/+/Twv+vgcz/r4PN/9a16//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/9a16/+vg83/r4HM/+/Twv/85cD//OXA//zlwP/85cD//OXA/9/Fnv++pHr/vaF4mL2feFW+pHr/y7GJ//zlwP/85cD//OXA//zlwP/85cD//OXA/8+rx/+vgc3/tIfQ/9a16//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//Wtev/tIfQ/6+Bzf/Pq8f//OXA//zlwP/85cD//OXA//zlwP/85cD/y7GJ/76kev+9n3hVootzC7yhePO+pHr/8tq1//zlwP/85cD//OXA//zlwP/85cD/+uLA/8Obyf+vgc3/r4PN/8Ob3P/VtOr/3cDw/93A8P/VtOr/w5vc/6+Dzf+vgc3/w5vJ//riwP/85cD//OXA//zlwP/85cD//OXA//Latf++pHr/vKF486KLcwsAAAAAu6N3l76kev/Uu5L//OXA//zlwP/85cD//OXA//zlwP/85cD/+uLA/8+rx/+vgcz/r4HN/6+Bzf+vgc3/r4HN/6+Bzf+vgc3/r4HM/8+rx//64sD//OXA//zlwP/85cD//OXA//zlwP/85cD/1LmS/76kev+7oXiWAAAAAAAAAAC3l28gvaN5+L6kev7t1a///OXA//zlwP/85cD//OXA//zlwP/85cD//OXA/+/Twv/Qq8f/u5HK/7OGzP+zhsz/u5HK/9Crx//v08L//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA/+3Vr/++pHr+vaN5+LeXbyAAAAAAAAAAAAAAAAC6oneCvqR6/8Wsg//54Lz//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/34Lz/xayD/76kev+6oneCAAAAAAAAAAAAAAAAAAAAAH9/VQa8oHjLvqR6/8yyiv/64r7//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD/+uK+/8yyiv++pHr/vKB4y39/VQYAAAAAAAAAAAAAAAAAAAAAAAAAALKhbh67o3nkvqR6/8yyiv/54Lz//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//ngvP/Msor/vqR6/7ujeeSyoW4eAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALqbdim7o3nkvqR6/8Wsg//t1a///OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/t1a//xayD/76kev+7o3nkupt2KQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALKhbh68oHjLvqR6/76kev7Uu5L/8tq1//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/y2rX/1LmS/76kev6+pHr/vKB4y7Khbh4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH9/VQa6oneCvaN5+L6kev++pHr/y7GJ/9/Fnv/s1K7/9t25//rivv/64r7/9t25/+zUrv/fxZ7/y7GJ/76kev++pHr/vaN5+Lqid4J/f1UGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC3l28gu6F4lryhePO+pHr/vqR6/76kev++pHr/vqR6/76kev++pHr/vqR6/76kev++pHr/vKF487uheJa3l28gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAootzC72feFW9oXiYvKF3yL2jeOq9oXj5vaF4+b2jeOq8oXfIvaF4mL2feFWii3MLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gB///gAH//gAAf/wAAD/4AAAf8AAAD+AAAAfAAAADwAAAA4AAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAGAAAABwAAAA8AAAAPgAAAH8AAAD/gAAB/8AAA//gAAf/+AAf//4Af/
<!--{{{-->
<div class='title' macro='view title'></div>
<div class='toolbar' macro='toolbar +saveTiddler -cancelTiddler deleteTiddler'></div>
<div class='editor' macro='edit title'></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>
<!--}}}-->
/***
|''Name''|BinaryUploadPlugin|
|''Version''|0.3.16|
|''Author''|Ben Gillies and Jon Robson|
|''Type''|plugin|
|''Source''|http://github.com/TiddlySpace/tiddlyspace/raw/master/src/plugins/BinaryUploadPlugin.js|
|''Description''|Upload a binary file to TiddlyWeb|
|''CoreVersion''|2.6.1|
|''Requires''|TiddlySpaceConfig TiddlyWebConfig|
!Usage
{{{
<<binaryUpload bag:<name> edit:tags edit:title tags:<default tags> title:<title> >>
}}}
* {{{bag:<name>}}}: optional; if left out, the file will be saved to the current workspace
* {{{edit:tags}}}: specifies that you want to tag the file being uploaded
* {{{edit:title}}}: specifies that you want to set the title to something other than the filename
* {{{tags:<default tags>}}}: specifies a default set of tags to apply to the file (requires {{{edit:tags}}} to be set)
* {{{title:<title>}}}: predefines the title of the binary tiddler
!Requires
TiddlyWeb
tiddlywebplugins.form
!Code
***/
//{{{
(function($) {

var tiddlyspace = config.extensions.tiddlyspace;

var macro = config.macros.binaryUpload = {
	locale: {
		titleDefaultValue: "Please enter a title...",
		tagsDefaultValue: "Please enter some tags...",
		titlePrefix: "title: ",
		tagsPrefix: "tags: ",
		loadSuccess: 'Tiddler %0 successfully uploaded',
		loadError: "An error occurred when uploading the tiddler %0",
		uploadInProgress: "Please wait while the file is uploaded...",
		membersOnly: "Only members can upload."
	},
	renderInputFields: function(container, options) {
		var locale = macro.locale;
		var editableFields = options.edit;
		var includeFields = {
			tags:  editableFields && editableFields.contains("tags") ? true : false,
			title: editableFields && editableFields.contains("title") ? true : false
		};
		var fields = ["title", "tags"];
		for(var i = 0; i < fields.length; i++) {
			var fieldName = fields[i];
			var userDefault = options[fieldName];
			var defaultValue = userDefault ? userDefault[0] : false;
			if(includeFields[fieldName] || defaultValue) {
				var localeDefault = locale["%0DefaultValue".format(fieldName)];
				var className = defaultValue ? "userInput" : "userInput notEdited";
				var inputEl;
				var val = defaultValue || localeDefault || "";
				var iContainer = $("<div />").addClass("binaryUpload%0".format(fieldName)).
					appendTo(container);
				if(defaultValue && !includeFields[fieldName]) {
					var label = locale["%0Prefix".format(fieldName)];
					$("<span />").text(label).appendTo(iContainer);
					$("<span />").addClass("disabledInput").text(val).appendTo(iContainer);
					inputEl = $("<input />").attr("type", "hidden");
				} else {
					inputEl = $("<input />").attr("type", "text");
				}
				inputEl.attr("name", fieldName).
					addClass("%0Edit".format(fieldName)).
					val(val).addClass(className).appendTo(iContainer);
			}
		}
	},
	getTiddlerName: function(fileName) {
		var fStart = fileName.lastIndexOf("\\");
		var fStart2 = fileName.lastIndexOf("/");
		fStart = fStart < fStart2 ? fStart2 : fStart;
		fileName = fileName.substr(fStart+1);
		return fileName;
	},
	errorHandler: function(fileName) {
		displayMessage("upload of file %0 failed".format(fileName));
	},
	uploadFile: function(place, baseURL, workspace, options) {
		var pleaseWait = $(".uploadProgress", place);
		var iframeName = options.target;
		var form = $("form", place);
		var existingVal = $("input[name=title]", form).val();
		var fileName = existingVal || $('input:file', form).val();
		if(!fileName) {
			return false; // the user hasn't selected a file yet
		}
		fileName = macro.getTiddlerName(fileName);
		$("input[name=title]", place).val(fileName);
		// we need to go somewhere afterwards to ensure the onload event triggers
		var redirectTo = "/%0/tiddlers.txt?select=title:%1".
			format(workspace, fileName);
		var token = tiddlyspace ? tiddlyspace.getCSRFToken() : "";
		var action = "%0?csrf_token=%1&redirect=%2"
			.format(baseURL, token, redirectTo);
		form[0].action = action; // dont use jquery to work with ie
		form[0].target = iframeName;
		// do not refactor following line... won't work in IE6 otherwise
		$(place).append($('<iframe name="' + iframeName + '" id="' + iframeName + '"/>').css('display','none'));
		macro.iFrameLoader(iframeName, function() {
			var content = document.getElementById(iframeName).contentWindow.document.documentElement;
			if($(content).text().indexOf(fileName) > -1) {
				options.callback(place, fileName, workspace, baseURL);
			} else {
				macro.errorHandler(fileName);
			}
			form.show(1000);
			pleaseWait.hide(1000);
		});
		form.hide(1000);
		pleaseWait.show(1000);
		return true;
	},
	createUploadForm: function(place, options) {
		var locale = macro.locale;
		if(readOnly) {
			$('<div class="annotation" />').text(locale.membersOnly).
				appendTo(place);
			return;
		}
		var bag = options.bag;
		options.callback = options.callback ? options.callback :
			function(place, fileName, workspace, baseurl) {
				macro.displayFile(place, fileName, workspace);
				displayMessage(locale.loadSuccess.format(fileName));
				$("input[type=text]", place).val("");
			};
		var defaults = config.defaultCustomFields;
		place = $("<div />").addClass("container").appendTo(place)[0];
		var workspace = bag ? "bags/%0".format(bag) : config.defaultCustomFields["server.workspace"];
		var baseURL = defaults["server.host"];
		baseURL += (baseURL[baseURL.length - 1] !== "/") ? "/" : "";
		baseURL = "%0%1/tiddlers".format(baseURL, workspace);
		//create the upload form, complete with invisible iframe
		var iframeName = "binaryUploadiframe%0".format(Math.random());
		// do not refactor following line of code to work in IE6.
		var form = $('<form action="%0" method="POST" enctype="multipart/form-data" />'.
					format(baseURL)).addClass("binaryUploadForm").
			appendTo(place)[0];
		macro.renderInputFields(form, options);
		$(form).
			append('<div class="binaryUploadFile"><input type="file" name="file" /></div>').
			append('<div class="binaryUploadSubmit"><input type="submit" value="Upload" disabled /></div>').
			submit(function(ev) {
				this.target = iframeName;
				options.target = iframeName;
				macro.uploadFile(place, baseURL, workspace, options);
			})
			.find('[type="file"]').bind('change', function() {
				$(form).find('[type="submit"]').prop('disabled', false);
			}).end();
		$('<div />').addClass("uploadProgress").text(locale.uploadInProgress).hide().appendTo(place);
		$("input[name=file]", place).change(function(ev) {
			var target = $(ev.target);
			var fileName = target.val();
			var title = $("input[type=text][name=title]", place);
			if(!title.val()) {
				title.val(fileName);
			}
		});
	},
	handler: function(place, macroName, params, wikifier, paramString, tiddler) {
		params = paramString.parseParams(null, null, true);
		macro.createUploadForm(place, params[0]);
	},
	iFrameLoader: function(iframeName, callback) {
		var iframe = document.getElementById(iframeName); //jQuery doesn't seem to want to do this!?
		var locale = macro.locale;
		$(".userInput").addClass("notEdited"); // reset editing
		var finishedLoading = function() {
			callback();
		};
		var iFrameLoadHandler = function() {
			finishedLoading.apply();
			return;
		};

		iframe.onload = iFrameLoadHandler;
		//IE
		completeReadyStateChanges = 0;
		iframe.onreadystatechange = function() {
			if (++(completeReadyStateChanges) == 3) {
				iFrameLoadHandler();
			}
		};
	},
	displayFile: function(place, title, workspace) {
		var adaptor = store.getTiddlers()[0].getAdaptor();
		var context = {
			workspace: workspace,
			host: config.defaultCustomFields['server.host']
		};
		adaptor.getTiddler(title, context, null, function(context) {
			if(context.status) {
				store.addTiddler(context.tiddler);
				story.displayTiddler(place, title);
				var image = config.macros.image;
				if(image && image.refreshImage) {
					image.refreshImage("/%0/tiddlers/%1".format(workspace, title));
					image.refreshImage(title);
					image.refreshImage("/%0".format(title));
					image.refreshImage("%0/%1/tiddlers/%2".format(config.extensions.tiddlyweb.host, workspace, title));
				}
			} else {
				displayMessage(macro.locale.loadError.format(title));
			}
		});
	}
};

if(tiddlyspace) {
	config.macros.binaryUploadPublic = {
		handler: function(place, macroName, params, wikifier, paramString, tiddler) {
			var options = paramString.parseParams(null, null, true)[0];
			var bag = tiddlyspace.getCurrentBag("public");
			options.bag = bag;
			macro.createUploadForm(place, options);
		}
	};
	config.messages.privacySetting = config.options.chkPrivateMode ?
		"private" : "public";
	config.macros.binaryUpload.defaultWorkspace = tiddlyspace.
		getCurrentWorkspace(config.messages.privacySetting);
}

})(jQuery);
//}}}
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="utf-8"/>
	<title>TiddlySpace Apps</title>
	<link rel="stylesheet" href="/bags/common/tiddlers/reset.css" />
	<link rel="stylesheet" href="/bags/common/tiddlers/appspage.css" />
	<!--[if lt IE 7 ]>
	<link rel="stylesheet" href="/bags/common/tiddlers/appspageie6.css" />
	<![endif]-->
</head>
<body>
	
	<div id="wrapper">
		<div id="TSbar"></div>
		<div id="main-content">
			<div id="space-details">
				<a href="/_space"><img class="siteicon"></a>
				<div id="title-subtitle">
					<h1 class="spaceaddress">
						<span class="spaceName"></span><span class="hostName"></span>
					</h1>
					<p class="tagline"><span class="subTitle"></span><a class="managespaces" href="/_space">manage space</a></p>
				</div>
			</div>
			<div id="holder">
				<div id="appswitcher-wrapper">
					<div id="appswitcher">
						<h2>Your Apps</h2>
						<ul id="app-list">
							<li class="htmlserialisation">
								<a href="/tiddlers.html?select=tag:!excludeLists;sort=-modified">
									<img src="/bags/common/tiddlers/browse_read_blue.png" alt="Icon for the HTML Serialisation" class="app-img" />
									BROWSE
								</a>
							</li>
							<li class="tiddlywiki">
								<a href="/tiddlers.wiki">
									<img src="/bags/common/tiddlers/tiddlywiki2_blue.png" alt="Icon for TiddlyWiki" class="app-img" />
									TIDDLYWIKI
								</a>
							</li>
						</ul>
						<div id="addapp">
							<button class="inactive">Add More!</button>
						</div>
					</div>
					<div id="app-desc">
						<ul>
							<li class="htmlserialisationdesc"><p>an easy to understand HTML representation of your content.</p></li>
							<li class="tiddlywikidesc"><p>use TiddlyWiki to create, edit and organise your content.</p></li>
						</ul>
					</div>
					<div style="clear: both;"></div>
				</div>
			</div>
		</div>
		<div id="footer"><!-- ie doesn't support footer tag -->
			<div id="footer-content">
				<div class="links">
					<a href="http://blog.tiddlyspace.com">blog</a>
					<a href="http://featured.tiddlyspace.com">featured</a>
					<a href="http://docs.tiddlyspace.com">documentation</a>
					<a href="https://github.com/TiddlySpace/tiddlyspace">source</a>
				</div>
				<p>TiddlySpace 2011, created by <a href="http://osmosoft.com">Osmosoft</a></p>
			</div>
		</div>
	</div>
	
	<script type="text/javascript" src="/bags/common/tiddlers/backstage.js"></script>
	<script type="text/javascript" src="/bags/common/tiddlers/jquery.js"></script>
	<script type="text/javascript" src="/bags/tiddlyspace/tiddlers/chrjs"></script>
	<script type="text/javascript" src="/bags/common/tiddlers/chrjs-store.js"></script>
	<script type="text/javascript" src="/bags/common/tiddlers/jquery-json.js"></script>
	<script type="text/javascript" src="/bags/common/tiddlers/appspage.js"></script>
</body>
</html>
!!!!Definitions
{{{
\def\Set#1{{\left\lbrace {#1} \right\rbrace}}
\def\set#1:#2{\Set{{#1} \colon {#2}}}
\def\singleton{\Set}
\def\emptySet{\emptyset}
}}}

!!!!Notes
{{{\Set}}} is the raw form of set definition and is suitable for defining finite sets and explicit infinite sets.  {{{\set}}} is for the usual conditional way of defining a set.

!!!!Examples
{{{
\Set{a, b, c}
\Set{0, 1, 2, \dots}
\set{a_n}:{n \in \omega}
\set{\sum_{k = r}^{n} k^2}:{r \le n \in \naturals}
\singleton{x}
\emptySet
}}}
\[
\Set{a, b, c}\qquad
\Set{0, 1, 2, \dots}\qquad
\set{a_n}:{n \in \omega}\qquad
\set{\sum_{k = r}^{n} k^2}:{r \le n \in \naturals}\qquad
\singleton{x}\qquad
\emptySet
\]
----

!!!!Definitions
{{{
\def\Sequence#1{{\left\langle {#1} \right\rangle}}
\def\sequence#1:#2{\Sequence{{#1} \colon {#2}}}
\def\tuple{\parentheses}
\def\emptyTuple{\tuple{}}
}}}

!!!!Notes
{{{\Sequence}}} is the raw form of sequence definition and is suitable for defining finite sequences and explicit infinite sequences.  {{{\sequence}}} is for the usual conditional way of defining a sequence.

!!!!Examples
{{{
\Sequence{a_0, a_1, a_2, \dots}
\sequence{{a_n}^\half}:{n \in \omega}
\tuple{x, y}
\emptyTuple
}}}
\[
\Sequence{a_0, a_1, a_2, \dots}\qquad
\sequence{{a_n}^\half}:{n \in \omega}\qquad
\tuple{x, y}\qquad
\emptyTuple
\]
----

!!!!Definitions
{{{
\def\family#1:#2{{\parentheses{#1}_{#2}}}
}}}

!!!!Notes
{{{\family}}} is for an indexed collection of objects.

!!!!Examples
{{{
\family{A_i}:{i \in I}
}}}
\[
\family{A_i}:{i \in I}
\]
----

!!!!Definitions
{{{
\def\subset{\subseteq}
\def\superset{\supseteq}
\def\union{\cup}
\def\Union{\bigcup}
\def\intersect{\cap}
\def\Intersection{\bigcap}
\def\setMinus{\setminus}
\def\cross{\times}
\def\product{\prod}
}}}

!!!!Notes
The standard $\LaTeX$ {{{\subset}}} symbol can be accessed by {{{\LaTeXsubset}}}.

!!!!Examples
{{{
Y \subset X
X \superset Y
A \union B
\Union_{i = 0}^{\infinity} C_i
A \intersect B
\Intersection_{n \in \omega} C_n
A \setMinus B
X \cross Y
\product_{i = 0}^{\infinity} X_i
}}}
\[
Y \subset X\qquad
X \superset Y\qquad
A \union B\qquad
\Union_{i = 0}^{\infinity} C_i\qquad
A \intersect B\qquad
\Intersection_{n \in \omega} C_n\qquad
A \setMinus B\qquad
X \cross Y\qquad
\product_{i = 0}^{\infinity} X_i
\]
----

!!!!Definitions
{{{
\def\powerSet#1{{\script{P}\of{#1}}}
\def\functionSpace#1#2{{{#2}^{#1}}}
\def\cardinality#1{{\left\lvert {#1} \right\rvert}}
\def\isEmpty{= \emptySet}
\def\isNonempty{\not= \emptySet}
}}}

!!!!Notes
{{{\functionSpace{X}{Y} }}} is intended to denote the set of all functions which map $X$ to $Y$.  {{{\isEmpty}}} and {{{\inNonempty}}} are only made available for readability and should only be used for this purpose.

!!!!Examples
{{{
\powerSet{X}
\functionSpace{\omega}{2}
\cardinality{X}
A \isEmpty
B \isNonempty
}}}
\[
\powerSet{X}\qquad
\functionSpace{\omega}{2}\qquad
\cardinality{X}\qquad
A \isEmpty\qquad
B \isNonempty
\]
----
<!--{{{-->
<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>
<!--}}}-->
[[TiddlyWiki|http://www.tiddlywiki.com]] is a reusable non-linear personal web notebook . It's a single HTML file which contains CSS, JavaScript, and the content. The content is divided into a series of sections, or Tiddlers.

TiddlyWiki has been used by different people as a software framework to build specialisations including task management tool, web clipping tools, a collaborative note taking tool, etc.

__TiddlyWiki - Work Notebook__ (tw-wnb) is a tuning version of TiddlyWiki for managing [[your daily work|Why use an eLNB?]]. It allows you to add to-do tasks by priorities(now/next/future), attach tiddlers to activities (or projects), write meeting minutes and more.

{{center{[img[https://lh3.googleusercontent.com/-npoEs0oEFug/UOcFfIOzYTI/AAAAAAAAAtA/ibRcT1NW7U0/s400/tw-wnb_app_screenshot.png]]}}}

I have created this TiddlyWiki version because no other version satisfies my personal requirements. For doing this I modified some existing plug-ins but I have also developed my own plug-ins in Javascript, html templates, CSS styles, etc. 

The source code of this note taking application is on [[Google code|https://code.google.com/p/tw-wnb]] web.
/***
|Requires|ShCore.js|
***/
//{{{
/**
 * SyntaxHighlighter
 * http://alexgorbatchev.com/SyntaxHighlighter
 *
 * SyntaxHighlighter is donationware. If you are using it, please donate.
 * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
 *
 * @version
 * 3.0.83 (July 02 2010)
 * 
 * @copyright
 * Copyright (C) 2004-2010 Alex Gorbatchev.
 *
 * @license
 * Dual licensed under the MIT and GPL licenses.
 */
;(function()
{
	// CommonJS
	typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null;

	function Brush()
	{
		function getKeywordsCSS(str)
		{
			return '\\b([a-z_]|)' + str.replace(/ /g, '(?=:)\\b|\\b([a-z_\\*]|\\*|)') + '(?=:)\\b';
		};
	
		function getValuesCSS(str)
		{
			return '\\b' + str.replace(/ /g, '(?!-)(?!:)\\b|\\b()') + '\:\\b';
		};

		var keywords =	'ascent azimuth background-attachment background-color background-image background-position ' +
						'background-repeat background baseline bbox border-collapse border-color border-spacing border-style border-top ' +
						'border-right border-bottom border-left border-top-color border-right-color border-bottom-color border-left-color ' +
						'border-top-style border-right-style border-bottom-style border-left-style border-top-width border-right-width ' +
						'border-bottom-width border-left-width border-width border bottom cap-height caption-side centerline clear clip color ' +
						'content counter-increment counter-reset cue-after cue-before cue cursor definition-src descent direction display ' +
						'elevation empty-cells float font-size-adjust font-family font-size font-stretch font-style font-variant font-weight font ' +
						'height left letter-spacing line-height list-style-image list-style-position list-style-type list-style margin-top ' +
						'margin-right margin-bottom margin-left margin marker-offset marks mathline max-height max-width min-height min-width orphans ' +
						'outline-color outline-style outline-width outline overflow padding-top padding-right padding-bottom padding-left padding page ' +
						'page-break-after page-break-before page-break-inside pause pause-after pause-before pitch pitch-range play-during position ' +
						'quotes right richness size slope src speak-header speak-numeral speak-punctuation speak speech-rate stemh stemv stress ' +
						'table-layout text-align top text-decoration text-indent text-shadow text-transform unicode-bidi unicode-range units-per-em ' +
						'vertical-align visibility voice-family volume white-space widows width widths word-spacing x-height z-index';

		var values =	'above absolute all always aqua armenian attr aural auto avoid baseline behind below bidi-override black blink block blue bold bolder '+
						'both bottom braille capitalize caption center center-left center-right circle close-quote code collapse compact condensed '+
						'continuous counter counters crop cross crosshair cursive dashed decimal decimal-leading-zero default digits disc dotted double '+
						'embed embossed e-resize expanded extra-condensed extra-expanded fantasy far-left far-right fast faster fixed format fuchsia '+
						'gray green groove handheld hebrew help hidden hide high higher icon inline-table inline inset inside invert italic '+
						'justify landscape large larger left-side left leftwards level lighter lime line-through list-item local loud lower-alpha '+
						'lowercase lower-greek lower-latin lower-roman lower low ltr marker maroon medium message-box middle mix move narrower '+
						'navy ne-resize no-close-quote none no-open-quote no-repeat normal nowrap n-resize nw-resize oblique olive once open-quote outset '+
						'outside overline pointer portrait pre print projection purple red relative repeat repeat-x repeat-y rgb ridge right right-side '+
						'rightwards rtl run-in screen scroll semi-condensed semi-expanded separate se-resize show silent silver slower slow '+
						'small small-caps small-caption smaller soft solid speech spell-out square s-resize static status-bar sub super sw-resize '+
						'table-caption table-cell table-column table-column-group table-footer-group table-header-group table-row table-row-group teal '+
						'text-bottom text-top thick thin top transparent tty tv ultra-condensed ultra-expanded underline upper-alpha uppercase upper-latin '+
						'upper-roman url visible wait white wider w-resize x-fast x-high x-large x-loud x-low x-slow x-small x-soft xx-large xx-small yellow';

		var fonts =		'[mM]onospace [tT]ahoma [vV]erdana [aA]rial [hH]elvetica [sS]ans-serif [sS]erif [cC]ourier mono sans serif';
	
		this.regexList = [
			{ regex: SyntaxHighlighter.regexLib.multiLineCComments,		css: 'comments' },	// multiline comments
			{ regex: SyntaxHighlighter.regexLib.doubleQuotedString,		css: 'string' },	// double quoted strings
			{ regex: SyntaxHighlighter.regexLib.singleQuotedString,		css: 'string' },	// single quoted strings
			{ regex: /\#[a-fA-F0-9]{3,6}/g,								css: 'value' },		// html colors
			{ regex: /(-?\d+)(\.\d+)?(px|em|pt|\:|\%|)/g,				css: 'value' },		// sizes
			{ regex: /!important/g,										css: 'color3' },	// !important
			{ regex: new RegExp(getKeywordsCSS(keywords), 'gm'),		css: 'keyword' },	// keywords
			{ regex: new RegExp(getValuesCSS(values), 'g'),				css: 'value' },		// values
			{ regex: new RegExp(this.getKeywords(fonts), 'g'),			css: 'color1' }		// fonts
			];

		this.forHtmlScript({ 
			left: /(&lt;|<)\s*style.*?(&gt;|>)/gi, 
			right: /(&lt;|<)\/\s*style\s*(&gt;|>)/gi 
			});
	};

	Brush.prototype	= new SyntaxHighlighter.Highlighter();
	Brush.aliases	= ['css'];

	SyntaxHighlighter.brushes.CSS = Brush;

	// CommonJS
	typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
})();
//}}}
/***
|Name|DisableWikiLinksPlugin|
|Source|http://www.TiddlyTools.com/#DisableWikiLinksPlugin|
|Version|1.6.0|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|selectively disable TiddlyWiki's automatic ~WikiWord linking behavior|
This plugin allows you to disable TiddlyWiki's automatic ~WikiWord linking behavior, so that WikiWords embedded in tiddler content will be rendered as regular text, instead of being automatically converted to tiddler links.  To create a tiddler link when automatic linking is disabled, you must enclose the link text within {{{[[...]]}}}.
!!!!!Usage
<<<
You can block automatic WikiWord linking behavior for any specific tiddler by ''tagging it with<<tag excludeWikiWords>>'' (see configuration below) or, check a plugin option to disable automatic WikiWord links to non-existing tiddler titles, while still linking WikiWords that correspond to existing tiddlers titles or shadow tiddler titles.  You can also block specific selected WikiWords from being automatically linked by listing them in [[DisableWikiLinksList]] (see configuration below), separated by whitespace.  This tiddler is optional and, when present, causes the listed words to always be excluded, even if automatic linking of other WikiWords is being permitted.  

Note: WikiWords contained in default ''shadow'' tiddlers will be automatically linked unless you select an additional checkbox option lets you disable these automatic links as well, though this is not recommended, since it can make it more difficult to access some TiddlyWiki standard default content (such as AdvancedOptions or SideBarTabs)
<<<
!!!!!Configuration
<<<
<<option chkDisableWikiLinks>> Disable ALL automatic WikiWord tiddler links
<<option chkAllowLinksFromShadowTiddlers>> ... except for WikiWords //contained in// shadow tiddlers
<<option chkDisableNonExistingWikiLinks>> Disable automatic WikiWord links for non-existing tiddlers
Disable automatic WikiWord links for words listed in: <<option txtDisableWikiLinksList>>
Disable automatic WikiWord links for tiddlers tagged with: <<option txtDisableWikiLinksTag>>
<<<
!!!!!Revisions
<<<
2008.07.22 [1.6.0] hijack tiddler changed() method to filter disabled wiki words from internal links[] array (so they won't appear in the missing tiddlers list)
2007.06.09 [1.5.0] added configurable txtDisableWikiLinksTag (default value: "excludeWikiWords") to allows selective disabling of automatic WikiWord links for any tiddler tagged with that value.
2006.12.31 [1.4.0] in formatter, test for chkDisableNonExistingWikiLinks
2006.12.09 [1.3.0] in formatter, test for excluded wiki words specified in DisableWikiLinksList
2006.12.09 [1.2.2] fix logic in autoLinkWikiWords() (was allowing links TO shadow tiddlers, even when chkDisableWikiLinks is TRUE).  
2006.12.09 [1.2.1] revised logic for handling links in shadow content
2006.12.08 [1.2.0] added hijack of Tiddler.prototype.autoLinkWikiWords so regular (non-bracketed) WikiWords won't be added to the missing list
2006.05.24 [1.1.0] added option to NOT bypass automatic wikiword links when displaying default shadow content (default is to auto-link shadow content)
2006.02.05 [1.0.1] wrapped wikifier hijack in init function to eliminate globals and avoid FireFox 1.5.0.1 crash bug when referencing globals
2005.12.09 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.DisableWikiLinksPlugin= {major: 1, minor: 6, revision: 0, date: new Date(2008,7,22)};

if (config.options.chkDisableNonExistingWikiLinks==undefined) config.options.chkDisableNonExistingWikiLinks= false;
if (config.options.chkDisableWikiLinks==undefined) config.options.chkDisableWikiLinks=false;
if (config.options.txtDisableWikiLinksList==undefined) config.options.txtDisableWikiLinksList="DisableWikiLinksList";
if (config.options.chkAllowLinksFromShadowTiddlers==undefined) config.options.chkAllowLinksFromShadowTiddlers=true;
if (config.options.txtDisableWikiLinksTag==undefined) config.options.txtDisableWikiLinksTag="excludeWikiWords";

// find the formatter for wikiLink and replace handler with 'pass-thru' rendering
initDisableWikiLinksFormatter();
function initDisableWikiLinksFormatter() {
	for (var i=0; i<config.formatters.length && config.formatters[i].name!="wikiLink"; i++);
	config.formatters[i].coreHandler=config.formatters[i].handler;
	config.formatters[i].handler=function(w) {
		// supress any leading "~" (if present)
		var skip=(w.matchText.substr(0,1)==config.textPrimitives.unWikiLink)?1:0;
		var title=w.matchText.substr(skip);
		var exists=store.tiddlerExists(title);
		var inShadow=w.tiddler && store.isShadowTiddler(w.tiddler.title);
		// check for excluded Tiddler
		if (w.tiddler && w.tiddler.isTagged(config.options.txtDisableWikiLinksTag))
			{ w.outputText(w.output,w.matchStart+skip,w.nextMatch); return; }
		// check for specific excluded wiki words
		var t=store.getTiddlerText(config.options.txtDisableWikiLinksList);
		if (t && t.length && t.indexOf(w.matchText)!=-1)
			{ w.outputText(w.output,w.matchStart+skip,w.nextMatch); return; }
		// if not disabling links from shadows (default setting)
		if (config.options.chkAllowLinksFromShadowTiddlers && inShadow)
			return this.coreHandler(w);
		// check for non-existing non-shadow tiddler
		if (config.options.chkDisableNonExistingWikiLinks && !exists)
			{ w.outputText(w.output,w.matchStart+skip,w.nextMatch); return; }
		// if not enabled, just do standard WikiWord link formatting
		if (!config.options.chkDisableWikiLinks)
			return this.coreHandler(w);
		// just return text without linking
		w.outputText(w.output,w.matchStart+skip,w.nextMatch)
	}
}

Tiddler.prototype.coreAutoLinkWikiWords = Tiddler.prototype.autoLinkWikiWords;
Tiddler.prototype.autoLinkWikiWords = function()
{
	// if all automatic links are not disabled, just return results from core function
	if (!config.options.chkDisableWikiLinks)
		return this.coreAutoLinkWikiWords.apply(this,arguments);
	return false;
}

Tiddler.prototype.disableWikiLinks_changed = Tiddler.prototype.changed;
Tiddler.prototype.changed = function()
{
	this.disableWikiLinks_changed.apply(this,arguments);
	// remove excluded wiki words from links array
	var t=store.getTiddlerText(config.options.txtDisableWikiLinksList,"").readBracketedList();
	if (t.length) for (var i=0; i<t.length; i++)
		if (this.links.contains(t[i]))
			this.links.splice(this.links.indexOf(t[i]),1);
};
//}}}
!!!!Definitions
{{{
\def\homeomorphic{\cong}
\def\convergesTo{\to}
}}}

!!!!Examples
{{{
X \homeomorphic Y
a_n \convergesTo a_\omega
}}}
\[
X \homeomorphic Y\qquad
a_n \convergesTo a_\omega
\]
----

!!!!Definitions
{{{
\def\closure#1{\overline{#1}}
\def\closureIn#1#2{{\closure{#2}^{#1}}}
\def\interior#1{{\operator{int}\of{#1}}}
\def\interiorIn#1#2{{\operator{int}_{#1}\of{#2}}}
}}}

!!!!Notes
~MathJax does not currently support macros with optional arguments.  Consequently, depending on whether or not the parent space is to be made explicit, there are two commands for both closure and interior.  In all cases the primary argument is delimited.

!!!!Examples
{{{
\closure{A}
\closureIn{X}{A}
\interior{A}
\interiorIn{X}{A}
}}}
\[
\closure{A}\qquad
\closureIn{X}{A}\qquad
\interior{A}\qquad
\interiorIn{X}{A}
\]
----

!!!!Definitions
{{{
\def\collection{\script}
\def\collections{\gothic}
\def\topology{\collection}
\def\cover{\collection}
\def\filter{\collection}
\def\ideal{\collection}
}}}

!!!!Notes
The primary purpose of these macros is to improve readability.  For example one might write:
{{{
Let $\filter{F}$ be a filter on $X$ and fix $F \in \filter{F}$.
}}}
:Let $\filter{F}$ be a filter on $X$ and fix $F \in \filter{F}$.

!!!!Examples
{{{
\topology{T}
\cover{U}
\filter{F}
\ideal{I}
a \in A \in \collection{A} \in \collections{A}
}}}
\[
\topology{T}\qquad
\cover{U}\qquad
\filter{F}\qquad
\ideal{I}\qquad
a \in A \in \collection{A} \in \collections{A}
\]
----

!!!!Definitions
{{{
\def\interval#1#2,#3#4{{\left#1 {#2}, {#3} \right#4}}
\def\unitInterval{\interval[0, 1]}
\def\plane{{\functionSpace{2}{\reals}}}
\def\stoneCechCompactification#1{{\beta{#1}}}
}}}

!!!!Notes
With {{{\interval}}}, the intension is for the first and last arguments (the delimiters) to be given without enclosing braces to improve readability.

!!!!Examples
{{{
\interval[a, b]
\interval({-\infinity}, {-\third}]
\unitInterval
\plane
\stoneCechCompactification{\naturals}
}}}
\[
\interval[a, b]\qquad
\interval({-\infinity}, {-\third}]\qquad
\unitInterval\qquad
\plane\qquad
\stoneCechCompactification{\naturals}
\]
----
/***
|''Name''|TiddlySpaceInitialization|
|''Version''|0.7.3|
|''Description''|Initializes new TiddlySpaces the first time they are created|
|''Status''|@@beta@@|
|''Source''|http://github.com/TiddlySpace/tiddlyspace/blob/master/src/plugins/TiddlySpaceInit.js|
|''CoreVersion''|2.6.1|
|''Requires''|TiddlySpaceConfig RandomColorPalettePlugin chrjs ImageMacroPlugin|
!TODO
* robust error notification and recovery
!MarkupPreHead
<!--{{{-->
<link href="/bags/%0_public/tiddlers.atom" rel="alternate"
	type="application/atom+xml" title="%0's public feed" />
<link rel="canonical" href="%1/" />
<!--}}}-->
!Code
***/
//{{{
(function($) {

var versionField = "tiddlyspaceinit_version";
var markupPreHead = store.getTiddlerText(tiddler.title + "##MarkupPreHead", "");
var tiddlyspace = config.extensions.tiddlyspace;
var currentSpace = tiddlyspace.currentSpace;
var tweb = config.extensions.tiddlyweb;

var plugin = config.extensions.TiddlySpaceInit = {
	version: "0.6",
	SiteTitle: "%0",
	SiteSubtitle: "a TiddlySpace",
	flagTitle: "%0SetupFlag",
	flagWarning: "Please do not modify this tiddler; it was created " +
		"automatically upon space creation.",

	dispatch: function(ev) {
		var title = plugin.flagTitle.format([currentSpace.name]);
		config.annotations[title] = plugin.flagWarning;
		if(currentSpace.type != "private") {
			return;
		}
		var tiddlers = [];
		var tid = store.getTiddler(title);
		if(tid) {
			curVersion = parseFloat(tid.fields[versionField]);
			reqVersion = parseFloat(plugin.version);
			if(curVersion < reqVersion) {
				plugin.update(curVersion, tid);
				tid.fields[versionField] = plugin.version;
				tid.incChangeCount();
				tid = store.saveTiddler(tid);
				tiddlers.push(tid);
			}
		} else { // first run
			tid = new Tiddler(title);
			tid.tags = ["excludeLists", "excludeSearch", "excludePublisher"];
			tid.fields = $.extend({}, config.defaultCustomFields);
			tid.fields[versionField] = plugin.version;
			tid.text = "@@%0@@".format([plugin.flagWarning]);
			tid = store.saveTiddler(tid);
			tiddlers = tiddlers.concat(plugin.firstRun(), tid);
		}
		autoSaveChanges(null, tiddlers);
	},
	update: function(curVersion, flagTiddler) {
		if(curVersion < 0.2) {
			this.createAvatar();
		}
		if(curVersion < 0.3) {
			flagTiddler.tags.pushUnique("excludePublisher"); // XXX: never persisted
		}
		if(curVersion < 0.5) { // v0.4 was faulty
			this.setupMarkupPreHead();
		}
		if(curVersion < 0.6) {
			this.purgeSystemSettings();
		}
	},
	pubTid: {
		tags: ["excludeLists", "excludeSearch"],
		fields: $.extend({}, config.defaultCustomFields, {
			"server.workspace": tiddlyspace.getCurrentWorkspace("public")
		})
	},
	makeTiddlerIfNot: function(tiddler) {
		if (!store.tiddlerExists(tiddler.title)) {
			$.extend(true, tiddler, plugin.pubTid);
			return [store.saveTiddler(tiddler)];
		} else {
			return [];
		}
	},
	firstRun: function() {
		var tiddlers = [];
		// generate Site*itle
		$.each(["SiteTitle", "SiteSubtitle"], function(i, item) {
			var tid = new Tiddler(item);
			tid.text = plugin[item].format([currentSpace.name]);
			tiddlers.push.apply(tiddlers,
				plugin.makeTiddlerIfNot(tid));
		});
		// generate public ColorPalette
		var tid = new Tiddler("ColorPalette");
		tid.text = config.macros.RandomColorPalette.generatePalette({
			saturation_pale: 0.67, saturation_light: 0.53,
			saturation_mid: 0.43, saturation_dark: 0.06,
			pale: 0.99, light: 0.85, mid: 0.5, dark: 0.31
		},
			false);
		tiddlers.push.apply(tiddlers, plugin.makeTiddlerIfNot(tid));
		this.createAvatar();
		this.setupMarkupPreHead();
		return tiddlers;
	},
	// remove _cookie slices (TiddlyWiki 2.6.2 beta 6 remnants)
	purgeSystemSettings: function() {
		var ss = store.getTiddler("SystemSettings");
		if(ss) {
			var lines = ss.text.split("\n");
			var persistentOptions = $.grep(lines, function(line, i) {
				return line.indexOf("_cookie:") == -1;
			});
			ss.text = persistentOptions.join("\n");
			ss = store.saveTiddler(ss);
			autoSaveChanges(null, [ss]);
		}
	},
	createAvatar: function() {
		var avatar = "SiteIcon";
		var host = tweb.host;
		var notify = function(xhr, error, exc) {
			displayMessage("ERROR: could not create avatar - " + // TODO: i18n
				"%0: %1".format([xhr.statusText, xhr.responseText]));
			// TODO: resolve!?
		};

		var pubBag = tiddlyspace.getCurrentBag("public");
		var tid = new tiddlyweb.Tiddler(avatar);
		tid.bag = new tiddlyweb.Bag(pubBag, host);

		var callback = function(data, status, xhr) {}; // avatar already exists; do nothing
		var errback = function(xhr, error, exc) {
			if(xhr.status != 404) {
				return;
			}
			// copy default avatar
			var _notify = function(tid, status, xhr) {
				displayMessage("created avatar"); // TODO: i18n
				var image = config.macros.image;
				if(image && image.refreshImage) {
					var uri = "/%0/tiddlers/SiteIcon".
						format(tiddlyspace.getCurrentWorkspace("public"));
					image.refreshImage(uri);
					image.refreshImage("SiteIcon");
				}
			};
			var _callback = function(tid, status, xhr) {
				tid.title = avatar;
				tid.bag.name = pubBag;
				delete tid.etag;
				tid.put(_notify, notify); // TODO: add to current session document (via adaptor?)
			};
			tweb.getUserInfo(function(user) {
				var avatarTitle = currentSpace.name == user.name ?
					"defaultUserIcon" : "defaultSiteIcon";
				var tid = new tiddlyweb.Tiddler(avatarTitle);
				tid.bag = new tiddlyweb.Bag("common", host);
				tid.get(_callback, notify);
			});
		};
		tid.get(callback, errback);
	},
	savePublicTiddlerText: function(title, text, pubWorkspace) {
		var tid = new Tiddler(title);
		tid.text = text;
		tid.tags = ["excludeLists"];
		tid.fields = $.extend({}, config.defaultCustomFields);
		tid.fields["server.workspace"] = pubWorkspace;
		tid.fields["server.page.revision"] = "false";
		tid = store.saveTiddler(tid);
		autoSaveChanges(null, [tid]);
	},
	setupMarkupPreHead: function() {
		var pubWorkspace = tiddlyspace.getCurrentWorkspace("public");
		var existing = store.getTiddler("MarkupPreHead");
		if(!existing || existing.fields["server.workspace"] != pubWorkspace) {
			var context = this;
			tweb.getStatus(function(status) {
				var text = markupPreHead.format(currentSpace.name,
					tiddlyspace.getHost(status.server_host, currentSpace.name));
				context.savePublicTiddlerText("MarkupPreHead", text,
					pubWorkspace);
			});
		}
		// also set up DefaultTiddlers
		var title = "DefaultTiddlers";
		existing = store.getTiddler(title) || new Tiddler(title);
		if(existing.fields["server.workspace"] != pubWorkspace) {
			var text = existing.text || store.getShadowTiddlerText(title);
			this.savePublicTiddlerText(title, text, pubWorkspace);
		}
	}
};

$(document).bind("startup", plugin.dispatch);

})(jQuery);
//}}}
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
Once we have developed the [[kinematics algorithms|Kinematics of a delta-2 robot]] of a delta-2 robot, we want to test it in real instead of in a virtual environment. Therefore, we are going to build a real delta-2 robot but using cardboard instead of metal pieces 

Why we decide to use cardboard? Because we have not money, we have not tools to cut metal and we like cardboard. In addition, for a quick test cardboard is good enough.

First thing is to design the model in CAD and build it using cardboard. Below you see the model we created:
* [[PDF|https://docs.google.com/open?id=0ByovaZlEMcTJTlVuMVFmZ1I4dzA]] file to print and cut.
* [[DXF|https://docs.google.com/open?id=0ByovaZlEMcTJUFZEblFpM0VKUjQ]] file.

<<tiddler "Picasa##album" with: d9er0d 5794261003698967697 144>>
Once the cardboard pieces were ready and the robot is mounted, testing starts; see next videos of the first tests. And you can see more videos in my [[YouTube|http://www.youtube.com/playlist?list=PL7EE27202FC7AC46D]] channel.

Testing the servo-motors.
{{left{<<player id=1 flash https://www.youtube.com/v/cc2xYT8JAiE 300 200>>}}}
First movements.
{{left{<<player id=2 flash https://www.youtube.com/v/H0CIaOnfgWg 300 200>>}}}
{{left{<<player id=3 flash https://www.youtube.com/v/r3wATvpXe1w 300 200>>}}}
This work was done together with [[@ferran_carlas|https://twitter.com/ferran_carlas/status/257111797352517632]]. 
It is a library for collision detection based on a modification of the GJK algorithm done by  Prof. [[M.Mellado|http://personales.upv.es/mmellado/mrtn/mrtn.html]] during his Ph.D.

This modification uses spherical volumes: sphere, bi-sphere, tri-sphere and tetra-sphere, to model objects (see figure below). The library returns whether there is a collision between two objects or not, and the distance between these two objects as well.

{{center{[img[https://lh6.googleusercontent.com/-V5JA5i01_EQ/T7jVUJ55aSI/AAAAAAAAApU/r_85l8T1RLQ/s800/vrs_using_acdlib.png]]}}}

The library was developed in C/C++ and it is included in [[Virtual Robot Simulator|http://robotica.isa.upv.es/virtualrobot]] software. You can download it from [[here|https://docs.google.com/open?id=0ByovaZlEMcTJa1V3THpmY0IxZFE]].
<!--{{{-->
<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> (created <span macro='view written 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>
<!--}}}-->
/*{{{*/
/*Mocha TiddlyWiki Theme*/
/*Version 1.0*/
/*Design and CSS originally by Anthony, ported to TiddlyWiki by Saq Imtiaz.*/
/*Updated by dgerod for this web*/

#contentWrapper { 
 margin: 0 3.4em;
 font-family: Lucida Grande, Tahoma, Arial, Helvetica, sans-serif; 
 font-size: 1.2em;
 line-height: 1.6em;
}

.header { 
 padding-top: 10px;
 clear: both;
 border-bottom: 4px solid #948979; 
 background: [[ColorPalette::Background]];
}

.headerShadow { 
 padding: 2.6em 0em 0.5em 0em; 
}

.siteTitle {
 font-family: 'Trebuchet MS' sans-serif;
 font-weight: bold;
 font-size: 3em;
 margin-bottom: 30px;
 color:[[ColorPalette::SecondaryDark]];
}

.siteTitle a { 
 border-bottom:1px dotted #cc6633;
}

.siteSubtitle {
 font-size: 1.5em;
 display: block;
 margin: .5em 3em; 
}

#mainMenu {
 position:relative;
 float:left;
 margin-bottom:1em;
 display:inline;
 text-align:left;
 padding: 2em 0.5em 0.5em 0em;
 width:10em;
 font-size:1.2em;
}

#sidebar {
 position:relative;
 float:right;
 margin-bottom:1em;
 padding-top:2em;
 display:inline;
}

#displayArea {
 margin: 0em 17em 0em 15em;
}

.tagClear { 
 clear:none;
}

#contentFooter { 
 clear: both; padding: 0.5em 1em;
} 

 #contentFooter a {
 border-bottom: 1px dotted #BFB6B3;
 }
 
 #contentFooter a:hover {
 }

 a,#sidebarOptions .sliderPanel a{
 text-decoration: none;
 }

 a:hover,#sidebarOptions .sliderPanel a:hover {
 }

.viewer .button, .editorFooter .button{
 border: 1px solid #CC6714;
}

.viewer .button:hover, 
.editorFooter .button:hover {
}

.viewer .button:active, .viewer .highlight,.editorFooter .button:active, .editorFooter .highlight {
 color:#fff; 
 background:#575352;
 border-color:#575352;
}

 #mainMenu a {
 display: block;
 padding: 5px;
 border-bottom: 1px solid;
 }

 #mainMenu a:link, #navlist a:visited {
 text-decoration: none;
 }
 
 #mainMenu a:hover {
 }

#mainMenu br {
 display:none;
}

#sidebarOptions a {
 text-decoration: none;
 }

#sidebarOptions a:hover {
 }

#sidebarOptions {
 line-height:1.4em;
}

 .tiddler {
 padding-bottom: 40px;
 border-bottom: 2px; 
 }

.title {
 color: #CC6633;
 _color: [[ColorPalette::Background]];
}
.subtitle, .subtitle a 
{ 
 font-size: 1.0em;margin:0.2em;
}
.shadow .title {
 color:#948979;
}

.selected .toolbar a { color:#999999; } 
.selected .toolbar a:hover { color:#4F4B45; background:transparent;border:1px solid #fff; } 

.toolbar .button:hover, .toolbar .highlight, .toolbar .marked, .toolbar a.button:active { color:#4F4B45; background:transparent;border:1px solid #fff; }

.listLink,#sidebarTabs .tabContents { line-height:1.5em; }
.listTitle { color:#888; }

#sidebarTabs .tabContents {background:#fff;}
#sidebarTabs .tabContents .tiddlyLink, #sidebarTabs .tabContents .button{color:#999;}
#sidebarTabs .tabContents .tiddlyLink:hover,#sidebarTabs .tabContents .button:hover{color:#4F4B45;background:#fff}

#sidebarTabs .tabContents .button:hover, #sidebarTabs .tabContents .highlight, #sidebarTabs .tabContents .marked, #sidebarTabs .tabContents a.button:active{color:#4F4B45;background:#fff}

.tabSelected{color:#fff; background:#948979;}

.tabUnselected {
 background: #ccc;
}

.tabSelected, .tabSelected:hover {
 color: #fff;
 background: #948979;
 border: solid 1px #948979;
 padding-bottom:1px;
}

.tabUnselected {
 color: #999;
 background: #eee;
 border: solid 1px #ccc;
 padding-bottom:1px;
}

#sidebarTabs .tabUnselected { border-bottom: none;padding-bottom:3px; }
#sidebarTabs .tabSelected{ padding-bottom:3px; }

#sidebarTabs .tabUnselected:hover { border-bottom: none;padding-bottom:3px;color:#4F4B45 }

#sidebarOptions .sliderPanel {
 background: #fff; border:none;
 font-size: 1em;
}
#sidebarOptions .sliderPanel a {font-weight:normal;}
#sidebarOptions .sliderPanel input {border:1px solid #999;}

.viewer blockquote {
 border-left: 3px solid #948979;
}

.viewer table {
 border: 2px solid [[ColorPalette::TertiaryDark]];
}

.viewer th, thead td {
 background: #948979;
 border: 1px solid #948979;
 color: #fff;
}

.viewer pre {
 border: 1px solid #948979;
 background: #f5f5f5;
}

.viewer code {
 color: #2F2A29;
}

.viewer hr {
 border-top: dashed 1px #948979;
}

.editor input {
 border: 1px solid #948979;
}

.editor textarea {
 border: 1px solid #948979;
}

.popup {
 background: #948979;
 border: 1px solid #948979;
}

.popup li.disabled {
 color: #000;
}

.popup li a, .popup li a:visited {
 color: #eee;
 border: none;
}

.popup li a:hover {
 background: #575352;
 color: #fff;
 border: none;
}

.tagging, .tagged {
 border: 1px solid #eee;
 background-color: #F7F7F7;
}

.selected .tagging, .selected .tagged {
 background-color: #eee;
 border: 1px solid #BFBAB3;
}

 .tagging .listTitle, .tagged .listTitle {
 color: #bbb;
}

.selected .tagging .listTitle, .selected .tagged .listTitle {
 color: #666; 
}

.tagging .button, .tagged .button {
 color:#aaa;
}
.selected .tagging .button, .selected .tagged .button {
 color:#4F4B45;
}

.highlight, .marked {background:transparent; color:#111; border:none; text-decoration:underline;}

.tagging .button:hover, .tagged .button:hover, .tagging .button:active, .tagged .button:active {
 border: none; background:transparent; text-decoration:underline; color:#000;
}

h1,h2,h3,h4,h5 { color: #666; background: transparent; padding-bottom:2px; font-family: Arial, Helvetica, sans-serif; }
h1 {font-size:18px;}
h2 {font-size:16px;}
h3 {font-size: 14px;}

#messageArea {
 border: 4px solid #948979;
 background: #f5f5f5;
 color: #999;
 font-size: 90%;
}

#messageArea a:hover { background:#f5f5f5;}

#messageArea .button{
 color: #666;
 border: 1px solid #CC6714;
}

#messageArea .button:hover {
 color: #fff;
 background: #948979;
 border-color: #948979;
} 

* html .viewer pre {
 margin-left: 0em;
}

* html .editor textarea, * html .editor input {
 width: 98%;
}

.searchBar { float:right;font-size: 1.0em; }
.searchBar .button { color:#999;display:block; }
.searchBar .button:hover { border:1px solid #fff;color:#4F4B45; }
.searchBar input { 
 background-color: #FFF;
 color: #999999;
 border: 1px solid #CCC; margin-right:3px;
}

#sidebarOptions .button:active, #sidebarOptions .highlight {
 background:#F5F5F5;
}

*html #contentFooter { 
 padding:0.25em 1em 0.5em 1em; 
}

#noticeBoard {
 font-size: 0.65em; 
 position:relative;
 display:block;
 clear: both;  
 margin-right:0.5em; 
 margin-top:60px; 
 padding:5px; 
}

#mainMenu #noticeBoard a,#mainMenu #noticeBoard .tiddlyLink {
 display:inline;
 border:none;
 padding:5px 2px;
}

#noticeBoard a:hover {
 border:none;
} 

#noticeBoard br {
 display:inline;
}

#mainMenu #noticeBoard .button {
 border: 1px solid #DF9153;
 padding:2px;
}

#mainMenu .button:hover {
 border-color: #DF9153;
}

#noticeBoard .button:hover {
}
/*}}}*/
/***
|''Name:''|TiddlySpaceLinkPlugin|
|''Description:''|Formatter to reference other spaces from wikitext |
|''Author:''|PaulDowney (psd (at) osmosoft (dot) com) |
|''Source:''|http://github.com/TiddlySpace/tiddlyspace/raw/master/src/plugins/TiddlySpaceLinkPlugin.js|
|''Version:''|1.4.2|
|''License:''|[[BSD License|http://www.opensource.org/licenses/bsd-license.php]] |
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev |
|''~CoreVersion:''|2.4|
!!Documentation
This plugin provides wikitext formatters for referencing another [[space|Space]] on the same TiddlySpace server, as in the following examples:
<<<
  {{{@space}}} -- @space 
  {{{~@space}}} -- ~@space 
  {{{Tiddler@space}}} -- Tiddler@space
  {{{[[Tiddler Title]]@space}}} -- [[Tiddler Title]]@space 
  {{{[[Link text|Tiddler Title]]@space}}} -- [[Link text|Tiddler Title]]@space
<<<
Links to tiddlers with a title begining with an "@" remain as tiddlyLinks:
<<<
  {{{[[@tiddler]]}}} -- [[@tiddler]]
<<<
and these may be changed into a space link using {{{@@}}}:
<<<
  {{{[[@@space]]}}} -- [[@@space]]
  {{{[[Link to an another space|@@space]]}}} -- [[Link to another space|@@space]]
  {{{[[@space|@@space]]}}} -- [[@space|@@space]]
<<<
TiddlySpace includes the [[TiddlySpaceLinkPlugin]] which provides WikiText markup for linking to other spaces on the same server. For example @glossary is a link to the {{{glossary}}} space and [[Small Trusted Group]]@glossary a link to an individual tiddler in the @glossary space. Prefixing the link with a tilde escapes the link, for example {{{~@space}}}.
Email addresses, for example joe.bloggs@example.com and mary@had.a.little.lamb.org should be unaffected.
!!Features
The plugin provides external links decorated so that other plugins may be included to add features such as the ability to dynamically pull externally linked tiddlers into the current TiddlyWiki.
Wikitext linking to a space on another server, for example from a tiddler in a space on tiddlyspace.com to a tiddler or a space on example.com, isn't currently supported. 
!!Code
***/
//{{{
/*jslint onevar: false nomen: false plusplus: false */
/*global jQuery config createTiddlyText createExternalLink createTiddlyLink */

function createSpaceLink(place, spaceName, title, alt, isBag) {
	var link, a, currentSpaceName, label;
	try {
		if (spaceName === config.extensions.tiddlyspace.currentSpace.name) {
			title = title || spaceName;
			a = createTiddlyLink(place, title, false);
			jQuery(a).text(alt || title);
			return a;
		}
	} catch (ex1) {
		currentSpaceName = false;
	}

	a = jQuery("<a />").addClass('tiddlySpaceLink externalLink').appendTo(place)[0];
	if(title) {
		jQuery(a).attr('tiddler', title);
	}
	if(isBag) {
		jQuery(a).attr('bag', spaceName);
	} else {
		jQuery(a).attr('tiddlyspace', spaceName);
	}

	config.extensions.tiddlyweb.getStatus(function(status) {
		link = status.server_host.url;
		if (title) {
			label = alt || title;
			link = link + "/" + encodeURIComponent(title);
		} else {
			label = alt || spaceName;
		}
		// assumes a http URI without user:pass@ prefix
		if(!isBag) {
			link = link.replace("http://", "http://" + spaceName.toLowerCase() + ".");
		} else {
			link += "/bags/" + spaceName + "/tiddlers.wiki";
		}
		jQuery(a).attr("href", link).text(label);
	});
	return a;
}

(function ($) {

	config.textPrimitives.spaceName = "[a-zA-Z][a-zA-Z0-9-]*[a-zA-Z0-9]";
	config.textPrimitives.spaceNameStrict = "[a-z][a-z0-9-]*";
	config.textPrimitives.bareTiddlerLetter = config.textPrimitives.anyLetterStrict;

	config.formatters.splice(0, 0, {
		name: "spacenameLink",
		match: config.textPrimitives.unWikiLink + "?" + config.textPrimitives.bareTiddlerLetter + "*@" + config.textPrimitives.spaceName + "\\.?.?",
		lookaheadRegExp: new RegExp(config.textPrimitives.unWikiLink + "?(" + config.textPrimitives.bareTiddlerLetter + "*)@(" + config.textPrimitives.spaceName + ")", "mg"),
		handler: function (w) {
			if (w.matchText.substr(w.matchText.length - 2, 1) === '.' && w.matchText.substr(w.matchText.length - 1, 1).match(/[a-zA-Z]/)) {
				w.outputText(w.output, w.matchStart, w.nextMatch);
				return;
			}
			if (w.matchText.substr(0, 1) === config.textPrimitives.unWikiLink) {
				w.outputText(w.output, w.matchStart + 1, w.nextMatch);
				return;
			}
			this.lookaheadRegExp.lastIndex = w.matchStart;
			var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
			if (lookaheadMatch && lookaheadMatch.index === w.matchStart) {
				createSpaceLink(w.output, lookaheadMatch[2], lookaheadMatch[1]);
				w.nextMatch = this.lookaheadRegExp.lastIndex;
			}
		}
	},
	{
		name: "tiddlySpaceLink",
		match: "\\[\\[[^\\|\\]]*\\|*@@" + config.textPrimitives.spaceName + "\\]",
		lookaheadRegExp: new RegExp("\\[\\[(.*?)(?:\\|@@(.*?))?\\]\\]", "mg"),
		handler: function (w) {
			this.lookaheadRegExp.lastIndex = w.matchStart;
			var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
			if (lookaheadMatch && lookaheadMatch.index === w.matchStart) {
				var alt = lookaheadMatch[2] ? lookaheadMatch[1] : lookaheadMatch[1].replace(/^@@/, "");
				var space = lookaheadMatch[2] || alt;
				createSpaceLink(w.output, space, "", alt);
				w.nextMatch = this.lookaheadRegExp.lastIndex;
			}
		}
	},
	{
		name: "tiddlyLinkSpacenameLink",
		match: "\\[\\[[^\\[]*\\]\\]@",
		lookaheadRegExp: new RegExp("\\[\\[(.*?)(?:\\|(.*?))?\\]\\]@(" + config.textPrimitives.spaceName + ")", "mg"),
		handler: function (w) {
			this.lookaheadRegExp.lastIndex = w.matchStart;
			var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
			if (lookaheadMatch && lookaheadMatch.index === w.matchStart) {
				var title = lookaheadMatch[2] || lookaheadMatch[1];
				var alt = lookaheadMatch[1] || lookaheadMatch[2];
				createSpaceLink(w.output, lookaheadMatch[3], title, alt);
				w.nextMatch = this.lookaheadRegExp.lastIndex;
			}
		}
	});

	// ensure space links don't appear as missing links
	config.textPrimitives.brackettedLink = "\\[\\[([^\\]][^@\\]][^\\]]*)\\]\\](?=[^@])";
	config.textPrimitives.titledBrackettedLink = "\\[\\[([^\\[\\]\\|]+)\\|([^\\[\\]\\|]+)\\]\\](?=[^@])";

	// reevaluate derrived expressions ..
	config.textPrimitives.tiddlerForcedLinkRegExp = new RegExp("(?:" + config.textPrimitives.titledBrackettedLink + ")|(?:" +
		config.textPrimitives.brackettedLink + ")|(?:" +
		config.textPrimitives.urlPattern + ")","mg");
	config.textPrimitives.tiddlerAnyLinkRegExp = new RegExp("("+ config.textPrimitives.wikiLink + ")|(?:" +
		config.textPrimitives.titledBrackettedLink + ")|(?:" +
		config.textPrimitives.brackettedLink + ")|(?:" +
		config.textPrimitives.urlPattern + ")","mg");

	// treat space links in titledBracketedLink as external links
	var missingTiddlySpaceLink = new RegExp("^@@" + config.textPrimitives.spaceName + "$", "");
	var isExternalLink = config.formatterHelpers.isExternalLink;
	config.formatterHelpers.isExternalLink = function(link) {
		return missingTiddlySpaceLink.test(link) || isExternalLink(link);
	};

}(jQuery));
//}}}
R0lGODlhPwAgAMQaALGxsYSEhNLS0v39/WJiYm1tbenp6dzc3MfHx7q6upqamo+Pj6Wlpby8vN3d3Xl5efT09OXl5bu7u9ra2v7+/ra2tvv7+8zMzFdXV////zMzMwAAAAAAAAAAAAAAAAAAACH5BAEAABoALAAAAAA/ACAAAAXwYCaOZGmeaKqamra+cPy6cm3feK7vfO//wKBwSCwaj8jkDoBpYh4IkbO5cGQE06ZAgWmQGhhAkKkAMAgYQwZTAJgJhCsm4HYbHE9SID3GCEQIYWsBIwx+WGIlD3wZBhgLQkx/GYFicyMLaYgmYIlMUX1lZ3wYBAEBBZdYBaenIhAEBSIFspFOpqClAWgAEHKsrSNcDpVDkiaXZCKbJngMXGq2kySXGalqzCYPqZDGfsiEcoRYdHXTYBig0uCYh1mCr7FK8/T1IhETB/r7+gP2KxcqJBhIMIEEC/9UUBjAsGHDhBAjSpxIseIQGhZTtAgBADs=
@@Please do not modify this tiddler; it was created automatically upon space creation.@@
/***
|''Requires''|slimbox2.js|
***/
//{{{
/**************************************************************************
 * Name:   EmbedPicasaGallery
 * Author: Tobias Oetiker <tobi@oetiker.ch>
 * Demo:   http://tobi.oetiker.ch/photo/
 * $Id: jquery.EmbedPicasaGallery.js 236 2011-06-16 09:11:38Z oetiker $
 **************************************************************************
 Description:
 
 This little script asks picasa web for a list of albums and for a list
 of pictures in the album. It then emits a series of <div class="pic-thumb"/>
 elements containing thumbnail images. The divs are inserted inside the element
 marked with a particular id. Clicking on an album will display thumbnails of the
 images in the album and clicking on a thumbnail will show the image itself
 using slimbox.
 
 The script itself uses jQuery (http://www.jquery.org) and slimbox2
 (http://www.digitalia.be/software/slimbox2) to work. So you have to load
 these two guys before loading the gallery script. You can load them in the
 header or the body of the document, this does not matter.
 
  <script type="text/javascript" src="js/jquery.js"></script>
  <link rel="stylesheet" href="css/slimbox2.css" type="text/css" media="screen" />
  <script type="text/javascript" src="slimbox2.js"></script>
  <script type="text/javascript" src="js/jquery.EmbedPicasaGallery.js"></script>

 Once loaded, call the picasaGallery function. This activates the
 code. With the id argument you tell it, where to put the gallery.

  <script type="text/javascript">
  jQuery(document).ready(function() {
  jQuery("#images").EmbedPicasaGallery('oetiker',{
      matcher:            /./,         // string or regexp to match album title
      size:               72,        // thumbnail size (32, 48, 64, 72, 144, 160)
      msg_loading_list :  'Loading album list from PicasaWeb',
      msg_back :          'back',
      msg_more :          'more',
      authkey :           'optional-picasa-authkey',
      albumid :           'go-directly-to-this-album-ignore-matcher',
      auto_open:          false, //opens the first album
      album_title_tag:    '<h2/>',
      hide_back:          false, //hide the back button
      thumb_id_prefix:    'pThumb_',
      show_more:      null,       // show only the first x images when the album gets opened
      loading_animation: 'css/loading.gif',
      thumb_finalizer:    function(){var $a = jQuery(this); ... use this to do something to the anchor AFTER slimbox got there },
      thumb_tuner:        function($img,entry,i){ ... $img is the img of the thumbnail, entry is the picasa image info ...}
      link_mapper: function(el){  // see http://code.google.com/p/slimbox/wiki/jQueryAPI#The_linkMapper_function
            return [
                     el.href,
                     '<a href="'+el.href+'">'+el.title+'</a>'
                   ]
            }
   });
  });
  </script>

 Finally inside the document, add a div tag with the id set to the name
 chosen above.
 
 <div id="images"></div>

**********************************************************************************/

(function($) {
    // setup a namespace for us
    var nsp = 'EmbedPicasaGallery', authkey;

    // Private Variables and Functions in the _ object
    // note that this will refer to _ unless you
    // call using the call or apply methods

    // Public Variables and Methods
    $[nsp] = {
        defaultOptions: {
            matcher : RegExp('.+'),
            size    : 72,
            msg_loading_list : 'Loading album list from PicasaWeb',
            msg_back : 'back',
            msg_more : 'more',
            album_title_tag: '<h2/>',
            auto_open: false,
            thumb_id_prefix: 'pThumb_',
            thumb_tuner: null,
            thumb_finalizer: null,
            loading_animation: null,
            show_more: null,
            hide_back: false,
            link_mapper: function(el){
                    return [
                        el.href,
                        '<a href="'+el.href+'">'+el.title+'</a>'
                    ]
                }
        } 
    };
    $.fn[nsp] = function(user,opts) {
        var localOpts,
            Cache = {};

        localOpts = $.extend( 
            {}, // start with an empty map
            $[nsp].defaultOptions, // add defaults
            opts // add options
        );

        function showOverview() {
            var $this,
                meta_opts,
                albumCount,
                $album_list,
                authkey = '';

            if ( Cache.__overview ){
                 Cache.__overview.show();
                 return;
            }
            $this = $(this);
            $this.empty();
            meta_opts = localOpts;
            if ($.meta){
                meta_opts = $.extend({}, localOpts, $this.data());
            }
            albumCount = 0;
            $album_list = $('<div/>')
                .addClass('album-list')
                .css('position','relative')
                .css('overflow','hidden')
                .append($('<div/>').text(meta_opts.msg_loading_list));


            function appendImage(i,item){
                var title,$div,$img;
                title = item.media$group.media$title.$t;
                if (title.match(meta_opts.matcher)){
                    albumCount++;
                    $img = $('<img/>')
                        .attr('title',title)
                        .attr('src',item.media$group.media$thumbnail[0].url)
                    $div = $('<div/>')
                        .addClass('album-cover')
                        .css({
                            'float': 'left',
                            marginRight: '10px',
                            marginBottom: '10px'
                        })
                        .click(function () {
                           $album_list.hide();
                           showAlbum($this,meta_opts,item.gphoto$id.$t,title,item.gphoto$numphotos.$t);
                        })
                        .hover(
                            function () { $(this).css("cursor","pointer")},
                            function () { $(this).css("cursor","default")}
                        )
                        .append( $img )
                        .append(
                            $('<div/>')
                            .addClass('album-title')
                            .css({
                                'font-size': '10px'
                            })
                            .text(title)
                            .width( meta_opts.size )
                        )                    
                    $album_list.append($div);
                };
            }
            
            function renderAlbumList(data){
                var $albums,maxHeight=0;
                $album_list.empty();
        		if (data.feed && data.feed.entry){
    	            $.each(data.feed.entry,appendImage);
        		} else {
          		    $this.text('Warning: No picasa albums found for user ' + user);
		        }
                Cache.__overview = $album_list;
                $albums = $album_list.children();


                if (meta_opts.auto_open){
                    $albums.eq(0).click();
                    return;
                }
                $('.album-title',$album_list)
                .each(function(){                        
                     var h = $(this).outerHeight();
                     if (h > maxHeight){
                        maxHeight = h
                     }
                })
                .each(function(){
                    $(this).height(maxHeight)
                });

            }


            if (meta_opts.authkey){
                authkey = '&authkey=' + meta_opts.authkey;
            }
 
    	    if (meta_opts.albumid) {
       	       showAlbum($this,meta_opts,meta_opts.albumid)
    	    }
	        else {
                $this.prepend($album_list);
                $.getJSON('http://picasaweb.google.com/data/feed/api/user/' 
                    + user + '?kind=album&access=visible' + authkey 
                    + '&alt=json-in-script&thumbsize=' + meta_opts.size + 'c&callback=?',
                    renderAlbumList
               );
	        }
        };

        function showAlbum($this,meta_opts,album,title,photoCount){                        
            if ( Cache[album] ){
               Cache[album].show();
               return;
            };

            var i,$album,albumPics=[],$picDiv;

            $album = $('<div/>').addClass('album')
                .css('position','relative')
                .css('overflow','hidden');
        
            if (title){
                $album.append($(meta_opts.album_title_tag).text(title))
            }
            function makeDiv(){            
               var $div = $('<div/>')
                   .css({
                        'float': 'left',
                        marginRight: '10px',
                        marginBottom: '10px',
                        width: meta_opts.size+'px',
                        height: meta_opts.size+'px'
                    });
               if (meta_opts.loading_animation){
                   $div.css('background','url(' + meta_opts.loading_animation + ') no-repeat center center');            
               }
               return $div;
            }

            function makeButton(text){
                return $("<div/>")                    
                    .addClass("pic-thumb")
                    .width(meta_opts.size)
                    .height(meta_opts.size)
                    .css({borderWidth: '0px',
                         'float' : 'left',
                         marginRight: '10px',
                         marginBottom: '10px',
                         cursor: 'pointer'
                     })
                    .append($("<div/>")
                        .html('<br/>'+text)
                        .css({'borderStyle':'outset',
                              'borderWidth':'1px',
                              'textAlign'  :'center',
                              'width'       : (meta_opts.size - 2) + 'px',
                              'height'      : (meta_opts.size - 2) + 'px'
                        })
                    );                 
            }

            if (Cache.__overview && !meta_opts.hide_back){            
                $album.append(makeButton(meta_opts.msg_back)
                    .click(function(){$album.hide();showOverview()})
                );
            }
            $this.prepend($album);
            
            if (photoCount){
                for (i=0;i<photoCount && (!meta_opts.show_more || i<meta_opts.show_more);i++) {
                    $picDiv = makeDiv();
                    $album.append($picDiv);
                    albumPics.push($picDiv);
                }
            }

            function makeImage(i,item){
               var title = item.media$group.media$description.$t || item.media$group.media$title.$t;  
               var $div = albumPics[i] || makeDiv();

               var $img = $('<img/>')
               	   .css('borderWidth','0px')
	           .hide()
                   .load(function(){                   
                       if (meta_opts.thumb_tuner){
                           meta_opts.thumb_tuner(this,item);
                       }
		       $img.show();
                   });




               var thumbs = item.media$group.media$thumbnail;
	       var gotOne = false;
               for (var i = 0; i<thumbs.length;i++){
                    if (thumbs[i].width == meta_opts.size && thumbs[i].height == meta_opts.size){
                        $img.attr("src", thumbs[i].url);
			gotOne = true;
                        break;
                    }
               }
	       if (!gotOne){
	           $img.attr("alt","Sorry, no matching thumbnail found.");
	       }
	          
               var $a = $("<a/>")
                   .attr("href",item.content.src)
                   .attr("title",title)
                   .append($img);

               $div
                   .attr("id", meta_opts.thumb_id_prefix + item.gphoto$id.$t )
                   .append($a);


               return $div; 
            }

            function renderAlbum(data){
                var images = data.feed.entry;
                var hiddenImages = [];
                for (var i=0;i<images.length;i++){
                    var $div = makeImage(i,images[i]);
                    if (!meta_opts.show_more || i < meta_opts.show_more){
                        $div.show();
                    }
                    else {
                        $div.hide();
                        hiddenImages.push($div);
                    }
                    $album.append($div);

                    if (meta_opts.show_more && i == meta_opts.show_more){
                        var $moreButton = makeButton(meta_opts.msg_more);
                        $album.append($moreButton
                            .click(function(){
                                var start = 0;
                                jQuery.each(hiddenImages,function(i,$img){
                                    window
                                        .setTimeout(
                                            function(){
                                                $img.fadeIn('fast');
                                            },
                                            50*(start++)
                                        );
                                });
                                $moreButton.hide();
                            })
                        );                        
                    }            
                }
                if ($.fn.slimbox){
                    $('a',$album).slimbox({},meta_opts.link_mapper);
                }
                if (meta_opts.thumb_callback){
                    $('a',$album).each(meta_opts.thumb_callback);
                }
                Cache[album] = $album;
            }
            authkey = '';
            if (meta_opts.authkey){
               authkey = '&authkey=' + meta_opts.authkey;
            }
            $.getJSON('http://picasaweb.google.com/data/feed/api/user/' 
                + user + '/albumid/' 
                + album + '?kind=photo&access=visible' + authkey + '&alt=json-in-script&thumbsize='+meta_opts.size+'c&imgmax=800&callback=?',
                renderAlbum
            );
        };

        return this.each(showOverview);
    };
})(jQuery);

//}}}
|~ViewToolbar|+editTiddler closeTiddler closeOthers +cloneTiddler > fields refreshTiddler changeToPublic changeToPrivate revisions syncing permalink references jump < |
|~EditToolbar|+saveTiddler saveDraft -cancelTiddler deleteTiddler|
|~RevisionToolbar|> fields revert|
/***
|Name|InlineJavascriptPlugin|
|Source|http://www.TiddlyTools.com/#InlineJavascriptPlugin|
|Documentation|http://www.TiddlyTools.com/#InlineJavascriptPluginInfo|
|Version|1.9.6|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|Insert Javascript executable code directly into your tiddler content.|
''Call directly into TW core utility routines, define new functions, calculate values, add dynamically-generated TiddlyWiki-formatted output'' into tiddler content, or perform any other programmatic actions each time the tiddler is rendered.
!!!!!Documentation
>see [[InlineJavascriptPluginInfo]]
!!!!!Revisions
<<<
2010.12.15 1.9.6 allow (but ignore) type="..." syntax
|please see [[InlineJavascriptPluginInfo]] for additional revision details|
2005.11.08 1.0.0 initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.InlineJavascriptPlugin= {major: 1, minor: 9, revision: 6, date: new Date(2010,12,15)};

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

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

// // GLOBAL FUNCTION: $(...) -- 'shorthand' convenience syntax for document.getElementById()
//{{{
if (typeof($)=='undefined') { function $(id) { return document.getElementById(id.replace(/^#/,'')); } }
//}}}
<!--{{{-->
<div style='display:none' macro='tiddler LatexNucleus##Init'></div>

<div id='header' class='header'>
<div class='headerShadow'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>

</div>
<div id='mainMenu'>
<span refresh='content' tiddler='MainMenu'></span>
<span id='noticeBoard' refresh='content' tiddler='NoticeBoard'></span>
</div>
<div id='sidebar'>
<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarPanel'></div>
</div>
<div id='displayArea'>
<div id='messageArea'></div>
<div id='tiddlerDisplay'></div>
</div>
<!--}}}-->
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
My wiki about Robotics, AI, mechanics... and more.
/***
|''Name''|TiddlySpaceRevisionView|
|''Description''|Show tiddler revisions in a stack of cards view|
|''Author''|BenGillies|
|''Version''|0.2.0|
|''Status''|beta|
|''Source''|http://github.com/TiddlySpace/tiddlyspace|
|''CodeRepository''|http://github.com/TiddlySpace/tiddlyspace|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''CoreVersion''|2.6.0|
|''Requires''|TiddlyWebAdaptor|
!Usage
The viewRevisions macro can be attached to any element, which should be passed
in as a parameter.

For example:

&lt;&lt;viewRevisions page:10 link:"<<view modified date>>"&gt;&gt;

would show the revisions "stack of cards" view, 10 at a time, when the modified
date is clicked.
!Code
***/
//{{{
(function($) {

var me = config.macros.viewRevisions = {
	revisionTemplate: "RevisionTemplate",
	revSuffix: " [rev. #%0]", // text to append to each tiddler title
	defaultPageSize: 5, // default number of revisions to show
	defaultLinkText: "View Revisions", // when there's nothing else to use
	offsetTop: 30, // in px
	offsetLeft: 10, // in px
	shiftDownDelay: 50, // in ms
	visibleSlideAmount: 20, // amount of revisions to show on left hand edge after sliding
	zIndex: 100, // default z-index
	handler: function(place, macroName, params, wikifier, paramString, tiddler) {
		params = paramString.parseParams(null, null, true)[0];
		var tiddlerElem = story.findContainingTiddler(place);

		var revButton;
		var pageSize = parseInt(params.page[0], 10) || me.defaultPageSize;
		var linkObj = params.link ? params.link[0] || me.defaultLinkText : false;
		if(linkObj) {
			revButton = $('<span class="button openRevisions" />')
				.appendTo(place);
			wikify(linkObj, revButton[0], null, tiddler);
		} else {
			revButton = place;
		}

		$(revButton).click(function() {
			if (!$(tiddlerElem).hasClass("revisions")) {
				me.showRevisions(tiddlerElem, tiddler, pageSize);
			} else {
				me.closeRevisions(tiddlerElem);
			}
		});
	},

	// initialisation for revision view
	showRevisions: function(tiddlerElem, tiddler, pageSize) {
		var context = {
			host: tiddler.fields["server.host"],
			workspace: tiddler.fields["server.workspace"]
		};
		$(tiddlerElem).addClass("revisions").attr("revName", tiddler.title);
		// ensure toolbar commands deactivate RevisionsView
		$("a", ".toolbar", tiddlerElem).each(function(index, btn) {
			var _onclick = btn.onclick;
			btn.onclick = function(e) {
				me.closeRevisions(tiddlerElem);
				_onclick.apply(this, arguments);
			};
		});
		// ensure default action deactivates RevisionsView
		var _ondblclick = tiddlerElem.ondblclick;
		tiddlerElem.ondblclick = function(e) {
			me.closeRevisions(tiddlerElem);
			_ondblclick.apply(this, arguments);
		};
		var type = tiddler.fields["server.type"];
		var adaptor = new config.adaptors[type]();
		var userParams = {
			tiddlerElem: tiddlerElem,
			pageSize: pageSize,
			title: tiddler.title
		};
		me.createCloak(tiddlerElem);
		adaptor.getTiddlerRevisionList(tiddler.title, null, context, userParams,
				function(context, userParams) {
					// strip the current revision
					context.revisions.shift();
					me.expandStack(context, userParams);
				});
	},

	// fetch the actual revision and put it in the tiddler div
	showRevision: function(place, revision, callback) {
		var context = {
			host: revision.fields["server.host"],
			workspace: revision.fields["server.workspace"]
		};
		var userParams = {
			revElem: place
		};
		var type = revision.fields["server.type"];
		var adaptor = new config.adaptors[type]();
		var revNo = revision.fields["server.page.revision"];
		adaptor.getTiddlerRevision(revision.title, revNo, context, userParams,
			function(context, userParams) {
				var tiddler = context.tiddler;
				tiddler.title += me.revSuffix
					.format([$(place).attr("revision")]);
				tiddler.fields.doNotSave = true;
				if (store.getTiddler(tiddler.title)) {
					store.deleteTiddler(tiddler.title);
				}
				store.addTiddler(tiddler);

				//now, populate the existing div
				var revElem = userParams.revElem;
				$(revElem).attr("id", story.tiddlerId(tiddler.title));
				$(revElem).attr("refresh", "tiddler");
				var getTemplate = function() {
					var themeName = config.options.txtTheme;
					if (themeName) {
						return store.getTiddlerSlice(themeName,
							me.revisionTemplate) || me.revisionTemplate ||
							"ViewTemplate";
					} else {
						return (store.getTiddler(me.revisionTemplate)) ?
							me.revisionTemplate : "ViewTemplate";
					}
				};
				var template = getTemplate();
				story.refreshTiddler(tiddler.title, template, true);
				callback(tiddler);
			});
	},

	createCloak: function(promoteElem) {
		var el = $(promoteElem);
		// cache styles for resetting later
		el.data({
			top: el.css("top"),
			left: el.css("left"),
			zIndex: el.css("z-index")
		});

		$('<div class="revisionCloak" />').css("z-index", me.zIndex)
			.click(function() {
				me.closeRevisions(promoteElem);
			})
			.appendTo(document.body);

		el.css("z-index", me.zIndex + 1);
	},

	// clean up, removing all evidence of revision view
	closeRevisions: function(promoteElem) {
		var el = $(promoteElem);
		// revert the original tiddler back to its previous state
		el.removeAttr("revName").removeClass("revisions").css({
			top: el.data("top"),
			left: el.data("left"),
			zIndex: el.data("zIndex")
		});

		// remove any revisions still in the store
		var revisions = $(".revisions");
		revisions.each(function(index, revision) {
			var revAttributes = revision.attributes;
			if ((revAttributes.revname) &&
					(revAttributes.revision)) {
				var revName = revAttributes.revname.value;
				var revNo = revAttributes.revision.value;
				var title = revName + me.revSuffix.format([revNo]);

				if (store.getTiddler(title)) {
					store.deleteTiddler(title);
				}
			}
		});

		// delete the previous revisions
		revisions.remove();

		// remove the cloak
		$(".revisionCloak").remove();
	},

	// calback from getting list of revisions
	expandStack: function(context, userParams) {
		var pageSize = userParams.pageSize;

		var from = userParams.from || 0;
		var tiddlerElem = userParams.tiddlerElem;

		userParams.defaultHeight = $(tiddlerElem).height();
		userParams.defaultWidth = $(tiddlerElem).width();
		if (from < context.revisions.length) {
			me.displayNextRevision(tiddlerElem, userParams, context, from,
				from + pageSize - 1);
		}
	},

	// place the next div above and behind the previous one
	displayNextRevision: function(tiddlerElem, userParams, context, from, to) {
		var revision = context.revisions[from];
		var callback = function() {
			var revText = revBtn.getRevisionText(tiddlerElem, revision);
			tiddlerElem = me.createRevisionObject(tiddlerElem, context,
				userParams, revText);
			$(tiddlerElem)
				.attr("revision", (context.revisions.length - from));
			if ((from < to) && ((from + 1) < context.revisions.length)){
				me.displayNextRevision(tiddlerElem, userParams, context,
					from + 1, to);
			} else if ((context.revisions.length - 1) > to) {
				me.showMoreButton(tiddlerElem, context, userParams, to + 1);
			}
		};
		me.shiftVisibleDown(userParams.title, callback);
	},

	createRevisionObject: function(tiddlerElem, context, userParams, text) {
		var newPosition = me.calculatePosition(tiddlerElem, context);
		return $('<div class="revisions tiddler" />')
			.css({
				position: "absolute",
				top: newPosition.top,
				left: newPosition.left,
				"z-index": me.zIndex + 1,
				height: userParams.defaultHeight,
				width: userParams.defaultWidth
			})
			.attr("revName", userParams.title)
			.append(text)
			.insertBefore(tiddlerElem);
	},

	// move the already present revisions down by 1 to fit the next one in
	shiftVisibleDown: function(title, callback) {
		var revisions = $("[revName='%0'].revisions".format([title]));
		var revisionCount = revisions.length;

		$(revisions).animate({top: "+=" + me.offsetTop},
				me.shiftDownDelay, function() {
					revisionCount -= 1;
					if ((callback) && (!revisionCount)) {
						callback();
					}
				});
	},

	// where we put the new revision
	calculatePosition: function(elem, context) {
		var offset = $(elem).offset();
		var currentPosition = $(elem).position();
		var newPosition = {
			top: currentPosition.top - me.offsetTop
		};
		if ((context.restrictLeft) ||
				((offset.left - me.offsetLeft) <
				$("#contentWrapper").offset().left)) {
			newPosition.left = $(elem).position().left;
			context.restrictLeft = true;
		} else {
			newPosition.left = currentPosition.left - me.offsetLeft;
		}
		return newPosition;
	},

	// equivalent of displayNextRevision, but for the more button
	showMoreButton: function(tiddlerElem, context, userParams, moreIndex) {
		userParams.from = moreIndex + 1;
		me.shiftVisibleDown(userParams.title, function() {
			var btn = me.createRevisionObject(tiddlerElem, context, userParams,
				"");

			var more = createTiddlyButton(btn[0], "more...", "show more revisions",
				function() {
					if ($(".viewRevision").length) {
						return;
					}
					userParams.tiddlerElem = btn[0];
					$(btn).text("")
						.append(revBtn
							.getRevisionText(btn[0], context.revisions[moreIndex]))
						.attr("revision", context.revisions.length - moreIndex);
					me.expandStack(context, userParams);
				});
			$(more).css("float", "right");
		});
	},

	stripRevFromTitle: function(revisionTitle) {
		return revisionTitle.split(/ ?\[rev\. #[0-9]+\]$/)[0];
	},

	onClickRevision: function(revElem, revision, callback) {
		// don't do anything if we are still loading
		if ($(".revisions").hasClass("loading")) {
			return null;
		}

		var origTitle = me.stripRevFromTitle(revision.title);
		if ($(revElem).hasClass("viewRevision")) {
			$(".revisions").addClass("loading");
			me.slideIn(revElem, revision, origTitle, function() {
				store.deleteTiddler(revision.title);
				revision.title = origTitle;
				$(revElem).text("").append(revBtn.getRevisionText(revElem,
						revision))
					.removeAttr("tags").removeAttr("tiddler")
					.removeAttr("refresh").removeAttr("template")
					.removeAttr("id");
				$(".revisions").removeClass("loading");
				if (callback) {
					callback();
				}
			});
			$(revElem).removeAttr("prevPos").removeClass("viewRevision");
		} else {
			var viewRevision = function() {
				var prevPos = $(revElem).position().left;
				$(revElem).addClass("viewRevision").attr("prevPos", prevPos);
				$(".revisions").addClass("loading");
				me.showRevision(revElem, revision, function(rev) {
					me.slideOut(revElem, rev, origTitle, function() {
						$(".revisions").removeClass("loading");
					});
				});
			};
			// make sure another revision isn't already out
			if ($(".viewRevision").length) {
				var newRevElem = $(".viewRevision")[0];
				var newRevision = store.getTiddler($(newRevElem)
					.attr("tiddler"));
				me.onClickRevision(newRevElem, newRevision, viewRevision);
			} else {
				viewRevision();
			}
		}
	},

	slideOut: function(revElem, revision, title, callback) {
		var leftMostPos = $("[revName='%0'].revisions".format([title]))
			.offset().left;
		var width = $(revElem).width();
		var originalLeftPos = $(story.getTiddler(title))
			.position().left;

		var slideAmount = leftMostPos + width - me.visibleSlideAmount;
		$("[revName='%0'].revisions:not(.viewRevision)".format([title]))
			.animate({left: "-=" + slideAmount}, 1000);
		$(revElem)
			.attr("baseHeight", $(revElem).css("height"))
			.css("height", "auto")
			.animate({left: originalLeftPos}, 1000, callback);
	},

	slideIn: function(revElem, revision, title, callback) {
		var slideAmount = $(revElem).offset().left -
			$(story.getTiddler(title)).offset().left;
		var origRevPos = $(revElem).attr("prevPos");

		$("[revName='%0'].revisions:not(.viewRevision)".format([title]))
			.animate({left: "+=" + slideAmount}, 1000);
		$(revElem).animate({left: origRevPos}, 1000, function() {
			$(revElem)
				.css("height", $(revElem).attr("baseHeight"))
				.removeAttr("baseHeight");
			callback();
		});
	}
};

var revBtn;
config.macros.slideRevision = revBtn = {
	btnText: "created by %0 at %1 on %2",
	handler: function(place, macroName, params, wikifier, paramString, tiddler) {
		var btn = revBtn.getRevisionText(place, tiddler);
		$(place).append(btn);
	},

	getRevisionText: function(place, revision) {
		var text = revBtn.btnText.format([revision.modifier,
			revision.modified.formatString("0hh:0mm"),
			revision.modified.formatString("0DD MMM YYYY")]);
		var btn = $('<a href="javascript:;" class="button revButton" />')
			.text(text)
			.click(function() {
				var revElem = story.findContainingTiddler(this);
				me.onClickRevision(revElem, revision);
			});
		return btn;
	}
};

})(jQuery);
//}}}
My name is [[Diego Escudero|http://dgerod.xyz-lab.org.es]] and I am a [[Roboticist|http://en.wikipedia.org/wiki/Roboticist]]. 

The system has been built using four infra-red sensors, Sharp G2D02. It was designed for being mounted on a mobile platform, and its mission is to avoid the platform collisions with objects in the environment. The infra-red sensors are used as distance measurer (10-80 cm), and a Microchip micro-controlled, PIC16F877, was used as the control unit for the system.

{{center{[img[https://lh5.googleusercontent.com/-LH7RCyd-VIk/UM3dUC_nNqI/AAAAAAAAAqo/T4qI1nMnNsk/s288/infrared_system_board.png]] [img[https://lh6.googleusercontent.com/-_SO3ejgAvSU/UM3dTnlmMbI/AAAAAAAAAqk/n32qCdbmG_c/s288/infrared_system_vrs.png]]}}}

The mounted system has been tested in a virtual environment (see figure above), this environment was created using [[Virtual Robot Simulator|http://robotica.isa.upv.es/virtualrobot]]. And the communications between the PC and the infrared system was done using the RS232 port. 
The [[NJ|http://www.ia.omron.com/products/family/3074/]] is a machine controller composed by two software engines: a PLC and a Motion Control, and it is developed by OMRON Industrial Automation. 

Main objective of this project was to add specific robot functionality for the packaging industry in this controller, most of the functionality is added to the Motion Control Engine. 

{{center{<<player id=1 flash https://www.youtube.com/v/_RyuWKFbFQc 400 300>>}}}
The robots included in this upgraded version of NJ are Cartesian XYZ, Planar 2R, Delta-2 robot and Delta-3 robot; other functionality as synchronizing a robot with a conveyor is also included. During this project the study and analysis of the robots (kinematics, workspace, trajectories and so on) were  done.

{{center{[img[https://lh3.googleusercontent.com/-qMjUjmIa-x8/UM2ctLZp4PI/AAAAAAAAApo/w_mleKFzEbo/s288/delta3_simulation.png]] [img[https://lh4.googleusercontent.com/-bu9HIxRPpbU/UMySgaqOw2I/AAAAAAAAAoA/4N6tQHzvnc4/s288/mini-delta-3.png]]}}}

After simulating using [[Scilab|http://www.scilab.org]], a prototype was developed using the [[TrajeXia|http://industrial.omron.eu/en/products/catalogue/motion_and_drives/motion_controllers/stand_alone/trajexia/default.html]] controller from OMRON and UG-D4 robot from Codian. The prototype was programmed in structure text, a language supported by [[IEC 61131 standard|http://en.wikipedia.org/wiki/IEC_61131-3]]. 

Once the prototype was created the integration phase in NJ product starts. To be able to add these robot functionalities in the system we have designed and added a new module (the Robot Control Module) to the NJ. And the development was done using ANSI-C99 over QNX RTOS. 
dgerod's scratchpad
/***
|''Name''|PluginMathJax|
|''Description''|Displays TeX math using MathJax|
|''Author''|[[Canada East|http://tiddlywiki.canada-east.ca/]]|
|''Version''|1.3|
|''Date''|2010-10-07|
|''CodeRepository''|[[PluginMathJax|http://tiddlywiki.canada-east.ca/#PluginMathJax]]|
|''CoreVersion''|[[2.6.1|http://www.tiddlywiki.com]]|
|''Requires''|[[MathJax v1.01|http://www.mathjax.org/]]|
|''Feedback''|[[Contact|https://spreadsheets.google.com/viewform?formkey=dGg2RkpxZW5zWTh6QjZxOXgzZUlfakE6MQ]]|
|''Tweaks''|~MathJax location and default HTML-CSS scale changed by Gareth Davies.  I've also added a hook to a ~MathJax extension for managing local definitions written by Richard Lupton and I've set the newcommand extension to load on start-up.|
!Description
This plugin uses [[MathJax|http://www.mathjax.org/]] to typeset ([[AMS|http://www.ams.org/publications/authors/tex/amslatex]]) [[LaTeX|http://www.latex-project.org/]]  math. It can also be configured to use additional MathJax functionality.
>"MathJax is an open source JavaScript display engine for mathematics that works in all modern browsers."
!Notes
Right click any math display for a MathJax menu. The user can select the renderer and zoom settings. It performs best in [[Webkit|http://en.wikipedia.org/wiki/List_of_web_browsers#WebKit-based_browsers]] based browsers. Larger math displays such as the additional examples tiddler below can put quite a load on IE. PluginMathJax is based on: [[Plugin: jsMath|http://bob.mcelrath.org/tiddlyjsmath.html]]
!Installation
#''Backup'' your TiddlyWiki!
#It is required that the MathJax directory is installed in '''js/MathJax/''' in the same location as the TiddlyWiki html file.<br>(Or edit the script source where commented in the plugin code below after installation to match the location of your MathJax install.)
#Install this plugin (and examples tiddler linked below if desired).
!Usage
|!Source|!Output|h
|{{{The variable $x$ is real.}}}|The variable $x$ is real.|
|{{{The variable \(y\) is complex.}}}|The variable \(y\) is complex.|
|{{{This \[\int_a^b x = \frac{1}{2}(b^2-a^2)\] is an easy integral.}}}|This \[\int_a^b x = \frac{1}{2}(b^2-a^2)\] is an easy integral.|
|{{{This $$\int_a^b \sin x = -(\cos b - \cos a)$$ is another easy integral.}}}|This $$\int_a^b \sin x = -(\cos b - \cos a)$$ is another easy integral.|
|{{{Block formatted equations may also use the 'equation' environment \begin{equation}  \int \tan x = -\ln \cos x \end{equation} }}}|Block formatted equations may also use the 'equation' environment \begin{equation}  \int \tan x = -\ln \cos x \end{equation}|
|{{{Equation arrays are also supported \begin{eqnarray} a &=& b \\ c &=& d \end{eqnarray} }}}|Equation arrays are also supported \begin{eqnarray} a &=& b \\ c &=& d \end{eqnarray} |
|{{{I spent \$7.38 on lunch.}}}|I spent \$7.38 on lunch.|
|{{{I had to insert a backslash (\\) into my document}}}|I had to insert a backslash (\\) into my document|
| <br>[[Complete list of supported LaTeX commands|http://www.mathjax.org/resources/docs/?tex.html#supported-latex-commands]] |>|
!Examples
[[Additional MathJax Examples|MathJax Examples]]
!Configuration
MathJax can be manually configured if desired by editing the code below (advanced). See the [[MathJax documentation|http://www.mathjax.org/resources/docs/?configuration.html#configuration-options-by-component]] for details.
!Revision History
*v1.3, 2010-10-07, returned to original formatters design, kept modified wikify and recommended way of loading MathJax dynamically, removed the tex2jax extension and corrected several browser compatibility issues (InnerHTML for Opera and IE9).
*v1.2, 2010-10-05, removed some redundant MathJax config entries, moved modified wikify and MathJax.Hub.Queue call.
*v1.1, 2010-10-03, autoLinkWikiWords disabled in absence of DisableWikiLinksPlugin, modifed wikify.
*v1.0, 2010-09-26, Initial Release
!Code
***/
//{{{

if(!version.extensions.PluginMathJax) { 
    version.extensions.PluginMathJax = { installed: true };

    config.extensions.PluginMathJax = {

        install: function() {

            var script = document.createElement("script");
            script.type = "text/javascript";

            // *** Use the location of your MathJax! *** :
            /*
             * Gareth: The following line assumes you have
             * MathJax installed on your server in a sensible
             * location.  I've commented this out.
             */
            //script.src = "js/MathJax/MathJax.js";

            /*
             * Because this tiddlywiki is currently hosted on
             * tiddlyspace.com I've had to point to the 'MathJax
             * Content Delivery Network' instead.
             */
            script.src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"
            // EndGareth

            /*
             * Gareth: Richard's local definition ~MathJax
             * extension (implementation of TeXs \let command)
             * has been added to the list of extensions along
             * with the newcommand extension upon which it
             * depends.  Also, the scale option for HTML-CSS was
             * changed from 115 to 100.
             */
            var mjconfig = 'MathJax.Hub.Config({' +
            'jax: ["input/TeX","output/HTML-CSS"],' +
            'extensions: ["TeX/AMSmath.js", "TeX/AMSsymbols.js", "TeX/newcommand.js", "http://oxkunengroup.tiddlyspace.com/localTeX.js"],' +
            '"HTML-CSS": {' +
                'scale: 100' +
                '}' +
            '});' +

            'MathJax.Hub.Startup.onload();';

            var ie9RegExp = /^9\./;
            var UseInnerHTML = (config.browser.isOpera || config.browser.isIE && ie9RegExp.test(config.browser.ieVersion[1]));

            if (UseInnerHTML) {script.innerHTML = mjconfig;}
                else {script.text = mjconfig;}

            script.text = mjconfig;

            document.getElementsByTagName("head")[0].appendChild(script);

            // Define wikifers for latex
            config.formatterHelpers.mathFormatHelper = function(w) {
                var e = document.createElement(this.element);
                e.type = this.type;
                var endRegExp = new RegExp(this.terminator, "mg");
                endRegExp.lastIndex = w.matchStart+w.matchLength;
                var matched = endRegExp.exec(w.source);
                if(matched) {
                    var txt = w.source.substr(w.matchStart+w.matchLength,
                        matched.index-w.matchStart-w.matchLength);
                    if(this.keepdelim) {
                      txt = w.source.substr(w.matchStart, matched.index+matched[0].length-w.matchStart);
                    }
                    if (UseInnerHTML) {
                        e.innerHTML = txt;
                    } else {
                        e.text = txt;
                    }
                    w.output.appendChild(e);
                    w.nextMatch = endRegExp.lastIndex;
                }
            }

            config.formatters.push({
              name: "displayMath1",
              match: "\\\$\\\$",
              terminator: "\\\$\\\$\\n?",
              termRegExp: "\\\$\\\$\\n?",
              element: "script",
              type: "math/tex; mode=display",
              handler: config.formatterHelpers.mathFormatHelper
            });

            config.formatters.push({
              name: "inlineMath1",
              match: "\\\$", 
              terminator: "\\\$",
              termRegExp: "\\\$",
              element: "script",
              type: "math/tex",
              handler: config.formatterHelpers.mathFormatHelper
            });

            var backslashformatters = new Array(0);

            backslashformatters.push({
              name: "inlineMath2",
              match: "\\\\\\\(",
              terminator: "\\\\\\\)",
              termRegExp: "\\\\\\\)",
              element: "script",
              type: "math/tex",
              handler: config.formatterHelpers.mathFormatHelper
            });

            backslashformatters.push({
              name: "displayMath2",
              match: "\\\\\\\[",
              terminator: "\\\\\\\]\\n?",
              termRegExp: "\\\\\\\]\\n?",
              element: "script",
              type: "math/tex; mode=display",
              handler: config.formatterHelpers.mathFormatHelper
            });

            backslashformatters.push({
              name: "displayMath3",
              match: "\\\\begin\\{equation\\}",
              terminator: "\\\\end\\{equation\\}\\n?",
              termRegExp: "\\\\end\\{equation\\}\\n?",
              element: "script",
              type: "math/tex; mode=display",
              handler: config.formatterHelpers.mathFormatHelper
            });

            // These can be nested.  e.g. \begin{equation} \begin{array}{ccc} \begin{array}{ccc} ...
            backslashformatters.push({
              name: "displayMath4",
              match: "\\\\begin\\{eqnarray\\}",
              terminator: "\\\\end\\{eqnarray\\}\\n?",
              termRegExp: "\\\\end\\{eqnarray\\}\\n?",
              element: "script",
              type: "math/tex; mode=display",
              keepdelim: true,
              handler: config.formatterHelpers.mathFormatHelper
            });

            // The escape must come between backslash formatters and regular ones.
            // So any latex-like \commands must be added to the beginning of
            // backslashformatters here.
            backslashformatters.push({
                name: "escape",
                match: "\\\\.",
                handler: function(w) {
                    w.output.appendChild(document.createTextNode(w.source.substr(w.matchStart+1,1)));
                    w.nextMatch = w.matchStart+2;
                }
            });

          config.formatters=backslashformatters.concat(config.formatters);

          old_wikify = wikify;
          wikify = function(source,output,highlightRegExp,tiddler)
          {
              old_wikify.apply(this,arguments);
              if (window.MathJax) {MathJax.Hub.Queue(["Typeset",MathJax.Hub,output])}
          };

        }
    };

  config.extensions.PluginMathJax.install();

}

//}}}
/***
This function returns the date stored in "written" field of a tiddler.
***/
//{{{

version.extensions.getWrittenDate = { major: 1, minor: 0, revision: 3, date: new Date(2012,12,7) };

store.getWrittenField = function ( tiddler )
{
       return store.getValue(tiddler,'written');
};

store.getWrittenFieldAsDate = function ( tiddler )
{
       return Date.convertFromYYYYMMDDHHMM(store.getValue(tiddler,'written'));
};

store.getWrittenDate = function ( tiddler )
{
       return Date.convertFromYYYYMMDDHHMM(store.getValue(tiddler,'written')).formatString('YYYY-0MM-0DD');
};

store.getWrittenDateAsStr = function ( tiddler )
{
       return Date.convertFromYYYYMMDDHHMM(store.getValue(tiddler,'written')).formatString('YYYY-0MM-0DD');
};

//}}}
<<forEachTiddler
      where 'tiddler.tags.contains("%article") && 
                  ! tiddler.tags.contains("#todo")'
      sortBy 'tiddler.title'
      write "'* [[' + tiddler.title + '|' + tiddler.title + ']]' + '\n'">>
/***
|''Name''|TiddlySpaceToolbar|
|''Description''|augments tiddler toolbar commands with SVG icons|
|''Author''|Osmosoft|
|''Version''|0.6.6|
|''Status''|@@beta@@|
|''Source''|http://github.com/TiddlySpace/tiddlyspace/raw/master/src/plugins/TiddlySpaceToolbar.js|
|''CodeRepository''|http://github.com/TiddlySpace/tiddlyspace|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''CoreVersion''|2.5.0|
|''Requires''|ImageMacroPlugin|
|''Keywords''|toolbar icons SVG|
!Description
replaces tiddler toolbar commands with SVG icons if available
!Notes
requires [[ImageMacroPlugin|http://svn.tiddlywiki.org/Trunk/contributors/JonRobson/plugins/ImageMacroPlugin/plugins/ImageMacroPlugin.tid]]

SVG icons are drawn from tiddlers titled {{{<command>.svg}}}
In readonly mode a tiddler called {{{<command>ReadOnly.svg}}} will be used if it exists.
!TODO
* rename (IconToolbarPlugin?)
* support more than one more popup menu in the toolbar.
!Code
***/
//{{{
(function($) {

if(!config.macros.image) {
	throw "Missing dependency: ImageMacroPlugin";
}

var macro = config.macros.toolbar;

macro.icons = {
	cloneTiddler: "editTiddler"
};

var _handler = macro.handler;
macro.handler = function(place, macroName, params, wikifier,
		paramString, tiddler) {
	var toolbar = $(place);
	toolbar.attr({
		refresh: "macro",
		macroName: macroName
	}).data("args", arguments);
	var status = _handler.apply(this, arguments);
	if(tiddler.isReadOnly()) {
		toolbar.addClass("toolbarReadOnly");
	} else {
		toolbar.removeClass("toolbarReadOnly");
	}
	var parsedParams = paramString.parseParams("name")[0];
	if(parsedParams.icons && parsedParams.icons == "yes") {
		this.augmentCommandButtons(place);
	}
	if(parsedParams.more && parsedParams.more == "popup") {
		// note we must override the onclick event like in createTiddlyButton
		// otherwise the click event is the popup AND the slider
		$(".moreCommand", place).each(function(i, el) {
			el.onclick = macro.onClickMorePopUp;
		});
		// buttons that are after a less command should not be in more menu.
		$(".lessCommand ~ .button", place).appendTo(place);
		$(".lessCommand", place).remove();
	}
	return status;
};

macro.refresh = function(place, params) {
	var args = $(place).empty().data("args");
	this.handler.apply(this, args);
};

var imageMacro = config.macros.image;
macro.augmentCommandButtons = function(toolbar) {
	$(".button", toolbar).each(function(i, el) {
		var cmd = $(el).attr("commandname");
		cmd = cmd ? cmd : "moreCommand"; // XXX: special-casing of moreCommand due to ticket #1234
		var icon = store.tiddlerExists(cmd) ? cmd : macro.icons[cmd];
		var text = $(el).text();
		if(readOnly) {
			var readOnlyAlternative = "%0ReadOnly".format([icon]);
			if(store.tiddlerExists(readOnlyAlternative)) {
				icon = readOnlyAlternative;
			}
		}
		if(store.tiddlerExists(icon)) {
			$(el).css({display: "inline-block"}).empty();
			imageMacro.renderImage(el, icon, { alt: text });
		}
	});
};

// provide onClickMore to provide extra commands in a popup
macro.onClickMorePopUp = function(ev) {
	ev = ev || window.event;
	var sibling = this.nextSibling;
	if(sibling) {
		var commands = sibling.childNodes;
		var popup = Popup.create(this);
		$(popup).addClass("taggedTiddlerList");
		for(var i = 0; i < commands.length; i++) {
			var li = createTiddlyElement(popup, "li", null);
			var oldCommand = commands[i];
			var command = oldCommand.cloneNode(true);
			command.onclick = oldCommand.onclick;
			li.appendChild(command);
		}
		Popup.show();
	}
	ev.cancelBubble = true;
	if(ev.stopPropagation) {
		ev.stopPropagation();
	}
	return false;
};

})(jQuery);
//}}}
/***
|''Name''|TiddlySpaceSearcher|
|''Version''|0.2.5|
|''Requires''|TiddlySpaceConfig TiddlySpaceFollowingPlugin|
***/
//{{{
(function($) {
var tiddlyspace = config.extensions.tiddlyspace;
var tsScan = config.macros.tsScan;

config.shadowTiddlers.SearchTemplate = "<<view server.bag SiteIcon label:no width:24 height:24 preserveAspectRatio:yes>> <<view server.bag spaceLink title external:no>> in space <<view server.bag spaceLink>>";
config.shadowTiddlers.StyleSheetSearch = [".resultsArea .siteIcon { display: inline; }",
	".searchForm {text-align: left;}"].join("\n");
store.addNotification("StyleSheetSearch", refreshStyles);

var search = config.macros.tsSearch = {
	locale: {
		advanced: "Advanced Options",
		header: "Search",
		resultsHeader: "Results (%0)",
		find: "find",
		noResults: "No tiddlers matched your search query",
		query: "QUERY: ",
		error: "please provide a search query or a tag, modifier or title!",
		titleAdvanced: "where the title is",
		modifierAdvanced: "where the last modifier is",
		spaceAdvanced: "only in the space: ",
		notspaceAdvanced: "but not in the spaces: ",
		tagsAdvanced: "with the tags: "
	},
	andConstructor: function(container, label, fieldname, negationMode) {
		var tags = $("<div />").appendTo(container);
		$('<span />').text(label).appendTo(tags);
		var id = "area" + Math.random();
		container = $("<span />").attr("id", id).appendTo(tags)[0];
		function add(container) {
			var el = $('<input type="text" />').attr("field", fieldname).appendTo(container);
			if(negationMode) {
				el.attr("negation", "true");
			}
		}
		add(container);
		var el = $("<button />").text("AND").click(function(ev) {
			add($(ev.target).data("container"));
			ev.preventDefault();
		}).appendTo(tags);
		$(el).data("container", container);
	},
	fieldConstructor: function(container, label, field) {
		container = $("<div />").appendTo(container)[0];
		$("<span />").text(label).appendTo(container);
		$("<input />").attr("text", "input").attr("field", field).appendTo(container);
	},
	advancedOptions: function(form) {
		var locale = search.locale;
		var container = $("<div />").addClass("tsAdvancedOptions").appendTo(form)[0];
		$("<h2/ >").text(search.locale.advanced).appendTo(container);
		$("<div />").addClass("separator").appendTo(container);
		search.fieldConstructor(container, locale.titleAdvanced, "title");
		search.fieldConstructor(container, locale.modifierAdvanced, "modifier");
		search.fieldConstructor(container, locale.spaceAdvanced, "space");
		search.andConstructor(container, locale.notspaceAdvanced, "space", true);
		search.andConstructor(container, locale.tagsAdvanced, "tag");
	},
	constructSearchQuery: function(form) {
		var data = [], select = [];
		var query = $("[name=q]", form).val();
		if(query) {
			data.push("q=%0".format(query));
		}

		// add tags, fields etc..
		$("[field]", form).each(function(i, el) {
			var val = $(el).val();
			var name = $(el).attr("field");
			var negate = $(el).attr("negation") == "true";
			if(val && name) {
				val = encodeURIComponent(val);
				val = negate ? "!" + val : val;
				if(name == "space") {
					val += "_public";
					name = "bag";
				}
				if(negate) {
					select.push("select=%0:%1".format(name,val));
				} else {
					var prefix = data.length === 0 ? "q=" : "";
					data.push('%0%1:"%2"'.format(prefix, name, val));
				}
			}
		});
		var dataString = data.join(" ");
		if(dataString.length === 0 && !query) {
			return false;
		}
		var selectStatement = select.join("&");
		if(dataString.length > 0 && selectStatement.length > 0) {
			dataString += "&";
		}
		dataString += selectStatement;
		return "/search?%0".format(dataString);
	},
	constructForm: function(place) {
		var locale = search.locale;
		$("<h1 />").text(locale.header).appendTo(place);
		var form = $("<form />").appendTo(place)[0];
		$('<input type="text" name="q" />').appendTo(form);
		$('<input type="submit" />').val(locale.find).appendTo(form);
		search.advancedOptions(form);
		var query = $('<h2 class="query"/>').appendTo(place)[0];
		var results = $("<div />").appendTo(place).addClass("resultsArea")[0];
		var lookup = function(url) {
			if(!url) {
				results.empty().addClass("error").text(locale.error);
				return;
			}
			config.extensions.tiddlyweb.getStatus(function(status) {
				$(query).text(locale.query);
				var href = status.server_host.url + url;
				$("<a />").attr("href", href).text(href).appendTo(query);
				tsScan.scan(results, { url: url, emptyMessage: search.locale.noResults, cache: true,
					template: "SearchTemplate", sort: "title", callback: function(tiddlers) {
						$("<h2 />").text(locale.resultsHeader.format(tiddlers.length)).prependTo(results);
					}
				});
			});
		};
		$(form).submit(function(ev) {
			ev.preventDefault();
			var url = search.constructSearchQuery(form);
			config.macros.tsSearch.lastSearch = url;
			lookup(url);
		});
		if(search.lastSearch) {
			lookup(search.lastSearch);
		}
		return form;
	},
	handler: function(place) {
		var container = $("<div />").addClass("searchForm").appendTo(place)[0];
		search.constructForm(container);
	}
};

})(jQuery);
//}}}
@@Please do not modify this tiddler; it was created automatically upon space creation.@@
/***
|''Name:''|ForEachTiddlerPlugin|
|''Version:''|1.0.8 (2007-04-12)|
|''Source:''|http://tiddlywiki.abego-software.de/#ForEachTiddlerPlugin|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]|
|''Copyright:''|&copy; 2005-2007 [[abego Software|http://www.abego-software.de]]|
|''TiddlyWiki:''|1.2.38+, 2.0|
|''Browser:''|Firefox 1.0.4+; Firefox 1.5; InternetExplorer 6.0|
!Description

Create customizable lists, tables etc. for your selections of tiddlers. Specify the tiddlers to include and their order through a powerful language.

''Syntax:'' 
|>|{{{<<}}}''forEachTiddler'' [''in'' //tiddlyWikiPath//] [''where'' //whereCondition//] [''sortBy'' //sortExpression// [''ascending'' //or// ''descending'']] [''script'' //scriptText//] [//action// [//actionParameters//]]{{{>>}}}|
|//tiddlyWikiPath//|The filepath to the TiddlyWiki the macro should work on. When missing the current TiddlyWiki is used.|
|//whereCondition//|(quoted) JavaScript boolean expression. May refer to the build-in variables {{{tiddler}}} and  {{{context}}}.|
|//sortExpression//|(quoted) JavaScript expression returning "comparable" objects (using '{{{<}}}','{{{>}}}','{{{==}}}'. May refer to the build-in variables {{{tiddler}}} and  {{{context}}}.|
|//scriptText//|(quoted) JavaScript text. Typically defines JavaScript functions that are called by the various JavaScript expressions (whereClause, sortClause, action arguments,...)|
|//action//|The action that should be performed on every selected tiddler, in the given order. By default the actions [[addToList|AddToListAction]] and [[write|WriteAction]] are supported. When no action is specified [[addToList|AddToListAction]]  is used.|
|//actionParameters//|(action specific) parameters the action may refer while processing the tiddlers (see action descriptions for details). <<tiddler [[JavaScript in actionParameters]]>>|
|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|

See details see [[ForEachTiddlerMacro]] and [[ForEachTiddlerExamples]].

!Revision history
* v1.0.8 (2007-04-12)
** Adapted to latest TiddlyWiki 2.2 Beta importTiddlyWiki API (introduced with changeset 2004). TiddlyWiki 2.2 Beta builds prior to changeset 2004 are no longer supported (but TiddlyWiki 2.1 and earlier, of cause)
* v1.0.7 (2007-03-28)
** Also support "pre" formatted TiddlyWikis (introduced with TW 2.2) (when using "in" clause to work on external tiddlers)
* v1.0.6 (2006-09-16)
** Context provides "viewerTiddler", i.e. the tiddler used to view the macro. Most times this is equal to the "inTiddler", but when using the "tiddler" macro both may be different.
** Support "begin", "end" and "none" expressions in "write" action
* v1.0.5 (2006-02-05)
** Pass tiddler containing the macro with wikify, context object also holds reference to tiddler containing the macro ("inTiddler"). Thanks to SimonBaird.
** Support Firefox 1.5.0.1
** Internal
*** Make "JSLint" conform
*** "Only install once"
* v1.0.4 (2006-01-06)
** Support TiddlyWiki 2.0
* v1.0.3 (2005-12-22)
** Features: 
*** Write output to a file supports multi-byte environments (Thanks to Bram Chen) 
*** Provide API to access the forEachTiddler functionality directly through JavaScript (see getTiddlers and performMacro)
** Enhancements:
*** Improved error messages on InternetExplorer.
* v1.0.2 (2005-12-10)
** Features: 
*** context object also holds reference to store (TiddlyWiki)
** Fixed Bugs: 
*** ForEachTiddler 1.0.1 has broken support on win32 Opera 8.51 (Thanks to BrunoSabin for reporting)
* v1.0.1 (2005-12-08)
** Features: 
*** Access tiddlers stored in separated TiddlyWikis through the "in" option. I.e. you are no longer limited to only work on the "current TiddlyWiki".
*** Write output to an external file using the "toFile" option of the "write" action. With this option you may write your customized tiddler exports.
*** Use the "script" section to define "helper" JavaScript functions etc. to be used in the various JavaScript expressions (whereClause, sortClause, action arguments,...).
*** Access and store context information for the current forEachTiddler invocation (through the build-in "context" object) .
*** Improved script evaluation (for where/sort clause and write scripts).
* v1.0.0 (2005-11-20)
** initial version

!Code
***/
//{{{

	
//============================================================================
//============================================================================
//		   ForEachTiddlerPlugin
//============================================================================
//============================================================================

// Only install once
if (!version.extensions.ForEachTiddlerPlugin) {

if (!window.abego) window.abego = {};

version.extensions.ForEachTiddlerPlugin = {
	major: 1, minor: 0, revision: 8, 
	date: new Date(2007,3,12), 
	source: "http://tiddlywiki.abego-software.de/#ForEachTiddlerPlugin",
	licence: "[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]",
	copyright: "Copyright (c) abego Software GmbH, 2005-2007 (www.abego-software.de)"
};

// For backward compatibility with TW 1.2.x
//
if (!TiddlyWiki.prototype.forEachTiddler) {
	TiddlyWiki.prototype.forEachTiddler = function(callback) {
		for(var t in this.tiddlers) {
			callback.call(this,t,this.tiddlers[t]);
		}
	};
}

//============================================================================
// forEachTiddler Macro
//============================================================================

version.extensions.forEachTiddler = {
	major: 1, minor: 0, revision: 8, date: new Date(2007,3,12), provider: "http://tiddlywiki.abego-software.de"};

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

config.macros.forEachTiddler = {
	 // Standard Properties
	 label: "forEachTiddler",
	 prompt: "Perform actions on a (sorted) selection of tiddlers",

	 // actions
	 actions: {
		 addToList: {},
		 write: {}
	 }
};

// ---------------------------------------------------------------------------
//  The forEachTiddler Macro Handler 
// ---------------------------------------------------------------------------

config.macros.forEachTiddler.getContainingTiddler = function(e) {
	while(e && !hasClass(e,"tiddler"))
		e = e.parentNode;
	var title = e ? e.getAttribute("tiddler") : null; 
	return title ? store.getTiddler(title) : null;
};

config.macros.forEachTiddler.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
	// config.macros.forEachTiddler.traceMacroCall(place,macroName,params,wikifier,paramString,tiddler);

	if (!tiddler) tiddler = config.macros.forEachTiddler.getContainingTiddler(place);
	// --- Parsing ------------------------------------------

	var i = 0; // index running over the params
	// Parse the "in" clause
	var tiddlyWikiPath = undefined;
	if ((i < params.length) && params[i] == "in") {
		i++;
		if (i >= params.length) {
			this.handleError(place, "TiddlyWiki path expected behind 'in'.");
			return;
		}
		tiddlyWikiPath = this.paramEncode((i < params.length) ? params[i] : "");
		i++;
	}

	// Parse the where clause
	var whereClause ="true";
	if ((i < params.length) && params[i] == "where") {
		i++;
		whereClause = this.paramEncode((i < params.length) ? params[i] : "");
		i++;
	}

	// Parse the sort stuff
	var sortClause = null;
	var sortAscending = true; 
	if ((i < params.length) && params[i] == "sortBy") {
		i++;
		if (i >= params.length) {
			this.handleError(place, "sortClause missing behind 'sortBy'.");
			return;
		}
		sortClause = this.paramEncode(params[i]);
		i++;

		if ((i < params.length) && (params[i] == "ascending" || params[i] == "descending")) {
			 sortAscending = params[i] == "ascending";
			 i++;
		}
	}

	// Parse the script
	var scriptText = null;
	if ((i < params.length) && params[i] == "script") {
		i++;
		scriptText = this.paramEncode((i < params.length) ? params[i] : "");
		i++;
	}

	// Parse the action. 
	// When we are already at the end use the default action
	var actionName = "addToList";
	if (i < params.length) {
	   if (!config.macros.forEachTiddler.actions[params[i]]) {
			this.handleError(place, "Unknown action '"+params[i]+"'.");
			return;
		} else {
			actionName = params[i]; 
			i++;
		}
	} 
	
	// Get the action parameter
	// (the parsing is done inside the individual action implementation.)
	var actionParameter = params.slice(i);


	// --- Processing ------------------------------------------
	try {
		this.performMacro({
				place: place, 
				inTiddler: tiddler,
				whereClause: whereClause, 
				sortClause: sortClause, 
				sortAscending: sortAscending, 
				actionName: actionName, 
				actionParameter: actionParameter, 
				scriptText: scriptText, 
				tiddlyWikiPath: tiddlyWikiPath});

	} catch (e) {
		this.handleError(place, e);
	}
};

// Returns an object with properties "tiddlers" and "context".
// tiddlers holds the (sorted) tiddlers selected by the parameter,
// context the context of the execution of the macro.
//
// The action is not yet performed.
//
// @parameter see performMacro
//
config.macros.forEachTiddler.getTiddlersAndContext = function(parameter) {

	var context = config.macros.forEachTiddler.createContext(parameter.place, parameter.whereClause, parameter.sortClause, parameter.sortAscending, parameter.actionName, parameter.actionParameter, parameter.scriptText, parameter.tiddlyWikiPath, parameter.inTiddler);

	var tiddlyWiki = parameter.tiddlyWikiPath ? this.loadTiddlyWiki(parameter.tiddlyWikiPath) : store;
	context["tiddlyWiki"] = tiddlyWiki;
	
	// Get the tiddlers, as defined by the whereClause
	var tiddlers = this.findTiddlers(parameter.whereClause, context, tiddlyWiki);
	context["tiddlers"] = tiddlers;

	// Sort the tiddlers, when sorting is required.
	if (parameter.sortClause) {
		this.sortTiddlers(tiddlers, parameter.sortClause, parameter.sortAscending, context);
	}

	return {tiddlers: tiddlers, context: context};
};

// Returns the (sorted) tiddlers selected by the parameter.
//
// The action is not yet performed.
//
// @parameter see performMacro
//
config.macros.forEachTiddler.getTiddlers = function(parameter) {
	return this.getTiddlersAndContext(parameter).tiddlers;
};

// Performs the macros with the given parameter.
//
// @param parameter holds the parameter of the macro as separate properties.
//				  The following properties are supported:
//
//						place
//						whereClause
//						sortClause
//						sortAscending
//						actionName
//						actionParameter
//						scriptText
//						tiddlyWikiPath
//
//					All properties are optional. 
//					For most actions the place property must be defined.
//
config.macros.forEachTiddler.performMacro = function(parameter) {
	var tiddlersAndContext = this.getTiddlersAndContext(parameter);

	// Perform the action
	var actionName = parameter.actionName ? parameter.actionName : "addToList";
	var action = config.macros.forEachTiddler.actions[actionName];
	if (!action) {
		this.handleError(parameter.place, "Unknown action '"+actionName+"'.");
		return;
	}

	var actionHandler = action.handler;
	actionHandler(parameter.place, tiddlersAndContext.tiddlers, parameter.actionParameter, tiddlersAndContext.context);
};

// ---------------------------------------------------------------------------
//  The actions 
// ---------------------------------------------------------------------------

// Internal.
//
// --- The addToList Action -----------------------------------------------
//
config.macros.forEachTiddler.actions.addToList.handler = function(place, tiddlers, parameter, context) {
	// Parse the parameter
	var p = 0;

	// Check for extra parameters
	if (parameter.length > p) {
		config.macros.forEachTiddler.createExtraParameterErrorElement(place, "addToList", parameter, p);
		return;
	}

	// Perform the action.
	var list = document.createElement("ul");
	place.appendChild(list);
	for (var i = 0; i < tiddlers.length; i++) {
		var tiddler = tiddlers[i];
		var listItem = document.createElement("li");
		list.appendChild(listItem);
		createTiddlyLink(listItem, tiddler.title, true);
	}
};

abego.parseNamedParameter = function(name, parameter, i) {
	var beginExpression = null;
	if ((i < parameter.length) && parameter[i] == name) {
		i++;
		if (i >= parameter.length) {
			throw "Missing text behind '%0'".format([name]);
		}
		
		return config.macros.forEachTiddler.paramEncode(parameter[i]);
	}
	return null;
}

// Internal.
//
// --- The write Action ---------------------------------------------------
//
config.macros.forEachTiddler.actions.write.handler = function(place, tiddlers, parameter, context) {
	// Parse the parameter
	var p = 0;
	if (p >= parameter.length) {
		this.handleError(place, "Missing expression behind 'write'.");
		return;
	}

	var textExpression = config.macros.forEachTiddler.paramEncode(parameter[p]);
	p++;

	// Parse the "begin" option
	var beginExpression = abego.parseNamedParameter("begin", parameter, p);
	if (beginExpression !== null) 
		p += 2;
	var endExpression = abego.parseNamedParameter("end", parameter, p);
	if (endExpression !== null) 
		p += 2;
	var noneExpression = abego.parseNamedParameter("none", parameter, p);
	if (noneExpression !== null) 
		p += 2;

	// Parse the "toFile" option
	var filename = null;
	var lineSeparator = undefined;
	if ((p < parameter.length) && parameter[p] == "toFile") {
		p++;
		if (p >= parameter.length) {
			this.handleError(place, "Filename expected behind 'toFile' of 'write' action.");
			return;
		}
		
		filename = config.macros.forEachTiddler.getLocalPath(config.macros.forEachTiddler.paramEncode(parameter[p]));
		p++;
		if ((p < parameter.length) && parameter[p] == "withLineSeparator") {
			p++;
			if (p >= parameter.length) {
				this.handleError(place, "Line separator text expected behind 'withLineSeparator' of 'write' action.");
				return;
			}
			lineSeparator = config.macros.forEachTiddler.paramEncode(parameter[p]);
			p++;
		}
	}
	
	// Check for extra parameters
	if (parameter.length > p) {
		config.macros.forEachTiddler.createExtraParameterErrorElement(place, "write", parameter, p);
		return;
	}

	// Perform the action.
	var func = config.macros.forEachTiddler.getEvalTiddlerFunction(textExpression, context);
	var count = tiddlers.length;
	var text = "";
	if (count > 0 && beginExpression)
		text += config.macros.forEachTiddler.getEvalTiddlerFunction(beginExpression, context)(undefined, context, count, undefined);
	
	for (var i = 0; i < count; i++) {
		var tiddler = tiddlers[i];
		text += func(tiddler, context, count, i);
	}
	
	if (count > 0 && endExpression)
		text += config.macros.forEachTiddler.getEvalTiddlerFunction(endExpression, context)(undefined, context, count, undefined);

	if (count == 0 && noneExpression) 
		text += config.macros.forEachTiddler.getEvalTiddlerFunction(noneExpression, context)(undefined, context, count, undefined);
		

	if (filename) {
		if (lineSeparator !== undefined) {
			lineSeparator = lineSeparator.replace(/\\n/mg, "\n").replace(/\\r/mg, "\r");
			text = text.replace(/\n/mg,lineSeparator);
		}
		saveFile(filename, convertUnicodeToUTF8(text));
	} else {
		var wrapper = createTiddlyElement(place, "span");
		wikify(text, wrapper, null/* highlightRegExp */, context.inTiddler);
	}
};


// ---------------------------------------------------------------------------
//  Helpers
// ---------------------------------------------------------------------------

// Internal.
//
config.macros.forEachTiddler.createContext = function(placeParam, whereClauseParam, sortClauseParam, sortAscendingParam, actionNameParam, actionParameterParam, scriptText, tiddlyWikiPathParam, inTiddlerParam) {
	return {
		place : placeParam, 
		whereClause : whereClauseParam, 
		sortClause : sortClauseParam, 
		sortAscending : sortAscendingParam, 
		script : scriptText,
		actionName : actionNameParam, 
		actionParameter : actionParameterParam,
		tiddlyWikiPath : tiddlyWikiPathParam,
		inTiddler : inTiddlerParam, // the tiddler containing the <<forEachTiddler ...>> macro call.
		viewerTiddler : config.macros.forEachTiddler.getContainingTiddler(placeParam) // the tiddler showing the forEachTiddler result
	};
};

// Internal.
//
// Returns a TiddlyWiki with the tiddlers loaded from the TiddlyWiki of 
// the given path.
//
config.macros.forEachTiddler.loadTiddlyWiki = function(path, idPrefix) {
	if (!idPrefix) {
		idPrefix = "store";
	}
	var lenPrefix = idPrefix.length;
	
	// Read the content of the given file
	var content = loadFile(this.getLocalPath(path));
	if(content === null) {
		throw "TiddlyWiki '"+path+"' not found.";
	}
	
	var tiddlyWiki = new TiddlyWiki();

	// Starting with TW 2.2 there is a helper function to import the tiddlers
	if (tiddlyWiki.importTiddlyWiki) {
		if (!tiddlyWiki.importTiddlyWiki(content))
			throw "File '"+path+"' is not a TiddlyWiki.";
		tiddlyWiki.dirty = false;
		return tiddlyWiki;
	}
	
	// The legacy code, for TW < 2.2
	
	// Locate the storeArea div's
	var posOpeningDiv = content.indexOf(startSaveArea);
	var posClosingDiv = content.lastIndexOf(endSaveArea);
	if((posOpeningDiv == -1) || (posClosingDiv == -1)) {
		throw "File '"+path+"' is not a TiddlyWiki.";
	}
	var storageText = content.substr(posOpeningDiv + startSaveArea.length, posClosingDiv);
	
	// Create a "div" element that contains the storage text
	var myStorageDiv = document.createElement("div");
	myStorageDiv.innerHTML = storageText;
	myStorageDiv.normalize();
	
	// Create all tiddlers in a new TiddlyWiki
	// (following code is modified copy of TiddlyWiki.prototype.loadFromDiv)
	var store = myStorageDiv.childNodes;
	for(var t = 0; t < store.length; t++) {
		var e = store[t];
		var title = null;
		if(e.getAttribute)
			title = e.getAttribute("tiddler");
		if(!title && e.id && e.id.substr(0,lenPrefix) == idPrefix)
			title = e.id.substr(lenPrefix);
		if(title && title !== "") {
			var tiddler = tiddlyWiki.createTiddler(title);
			tiddler.loadFromDiv(e,title);
		}
	}
	tiddlyWiki.dirty = false;

	return tiddlyWiki;
};


	
// Internal.
//
// Returns a function that has a function body returning the given javaScriptExpression.
// The function has the parameters:
// 
//	 (tiddler, context, count, index)
//
config.macros.forEachTiddler.getEvalTiddlerFunction = function (javaScriptExpression, context) {
	var script = context["script"];
	var functionText = "var theFunction = function(tiddler, context, count, index) { return "+javaScriptExpression+"}";
	var fullText = (script ? script+";" : "")+functionText+";theFunction;";
	return eval(fullText);
};

// Internal.
//
config.macros.forEachTiddler.findTiddlers = function(whereClause, context, tiddlyWiki) {
	var result = [];
	var func = config.macros.forEachTiddler.getEvalTiddlerFunction(whereClause, context);
	tiddlyWiki.forEachTiddler(function(title,tiddler) {
		if (func(tiddler, context, undefined, undefined)) {
			result.push(tiddler);
		}
	});
	return result;
};

// Internal.
//
config.macros.forEachTiddler.createExtraParameterErrorElement = function(place, actionName, parameter, firstUnusedIndex) {
	var message = "Extra parameter behind '"+actionName+"':";
	for (var i = firstUnusedIndex; i < parameter.length; i++) {
		message += " "+parameter[i];
	}
	this.handleError(place, message);
};

// Internal.
//
config.macros.forEachTiddler.sortAscending = function(tiddlerA, tiddlerB) {
	var result = 
		(tiddlerA.forEachTiddlerSortValue == tiddlerB.forEachTiddlerSortValue) 
			? 0
			: (tiddlerA.forEachTiddlerSortValue < tiddlerB.forEachTiddlerSortValue)
			   ? -1 
			   : +1; 
	return result;
};

// Internal.
//
config.macros.forEachTiddler.sortDescending = function(tiddlerA, tiddlerB) {
	var result = 
		(tiddlerA.forEachTiddlerSortValue == tiddlerB.forEachTiddlerSortValue) 
			? 0
			: (tiddlerA.forEachTiddlerSortValue < tiddlerB.forEachTiddlerSortValue)
			   ? +1 
			   : -1; 
	return result;
};

// Internal.
//
config.macros.forEachTiddler.sortTiddlers = function(tiddlers, sortClause, ascending, context) {
	// To avoid evaluating the sortClause whenever two items are compared 
	// we pre-calculate the sortValue for every item in the array and store it in a 
	// temporary property ("forEachTiddlerSortValue") of the tiddlers.
	var func = config.macros.forEachTiddler.getEvalTiddlerFunction(sortClause, context);
	var count = tiddlers.length;
	var i;
	for (i = 0; i < count; i++) {
		var tiddler = tiddlers[i];
		tiddler.forEachTiddlerSortValue = func(tiddler,context, undefined, undefined);
	}

	// Do the sorting
	tiddlers.sort(ascending ? this.sortAscending : this.sortDescending);

	// Delete the temporary property that holds the sortValue.	
	for (i = 0; i < tiddlers.length; i++) {
		delete tiddlers[i].forEachTiddlerSortValue;
	}
};


// Internal.
//
config.macros.forEachTiddler.trace = function(message) {
	displayMessage(message);
};

// Internal.
//
config.macros.forEachTiddler.traceMacroCall = function(place,macroName,params) {
	var message ="<<"+macroName;
	for (var i = 0; i < params.length; i++) {
		message += " "+params[i];
	}
	message += ">>";
	displayMessage(message);
};


// Internal.
//
// Creates an element that holds an error message
// 
config.macros.forEachTiddler.createErrorElement = function(place, exception) {
	var message = (exception.description) ? exception.description : exception.toString();
	return createTiddlyElement(place,"span",null,"forEachTiddlerError","<<forEachTiddler ...>>: "+message);
};

// Internal.
//
// @param place [may be null]
//
config.macros.forEachTiddler.handleError = function(place, exception) {
	if (place) {
		this.createErrorElement(place, exception);
	} else {
		throw exception;
	}
};

// Internal.
//
// Encodes the given string.
//
// Replaces 
//	 "$))" to ">>"
//	 "$)" to ">"
//
config.macros.forEachTiddler.paramEncode = function(s) {
	var reGTGT = new RegExp("\\$\\)\\)","mg");
	var reGT = new RegExp("\\$\\)","mg");
	return s.replace(reGTGT, ">>").replace(reGT, ">");
};

// Internal.
//
// Returns the given original path (that is a file path, starting with "file:")
// as a path to a local file, in the systems native file format.
//
// Location information in the originalPath (i.e. the "#" and stuff following)
// is stripped.
// 
config.macros.forEachTiddler.getLocalPath = function(originalPath) {
	// Remove any location part of the URL
	var hashPos = originalPath.indexOf("#");
	if(hashPos != -1)
		originalPath = originalPath.substr(0,hashPos);
	// Convert to a native file format assuming
	// "file:///x:/path/path/path..." - pc local file --> "x:\path\path\path..."
	// "file://///server/share/path/path/path..." - FireFox pc network file --> "\\server\share\path\path\path..."
	// "file:///path/path/path..." - mac/unix local file --> "/path/path/path..."
	// "file://server/share/path/path/path..." - pc network file --> "\\server\share\path\path\path..."
	var localPath;
	if(originalPath.charAt(9) == ":") // pc local file
		localPath = unescape(originalPath.substr(8)).replace(new RegExp("/","g"),"\\");
	else if(originalPath.indexOf("file://///") === 0) // FireFox pc network file
		localPath = "\\\\" + unescape(originalPath.substr(10)).replace(new RegExp("/","g"),"\\");
	else if(originalPath.indexOf("file:///") === 0) // mac/unix local file
		localPath = unescape(originalPath.substr(7));
	else if(originalPath.indexOf("file:/") === 0) // mac/unix local file
		localPath = unescape(originalPath.substr(5));
	else // pc network file
		localPath = "\\\\" + unescape(originalPath.substr(7)).replace(new RegExp("/","g"),"\\");	
	return localPath;
};

// ---------------------------------------------------------------------------
// Stylesheet Extensions (may be overridden by local StyleSheet)
// ---------------------------------------------------------------------------
//
setStylesheet(
	".forEachTiddlerError{color: #ffffff;background-color: #880000;}",
	"forEachTiddler");

//============================================================================
// End of forEachTiddler Macro
//============================================================================


//============================================================================
// String.startsWith Function
//============================================================================
//
// Returns true if the string starts with the given prefix, false otherwise.
//
version.extensions["String.startsWith"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
String.prototype.startsWith = function(prefix) {
	var n =  prefix.length;
	return (this.length >= n) && (this.slice(0, n) == prefix);
};



//============================================================================
// String.endsWith Function
//============================================================================
//
// Returns true if the string ends with the given suffix, false otherwise.
//
version.extensions["String.endsWith"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
String.prototype.endsWith = function(suffix) {
	var n = suffix.length;
	return (this.length >= n) && (this.right(n) == suffix);
};


//============================================================================
// String.contains Function
//============================================================================
//
// Returns true when the string contains the given substring, false otherwise.
//
version.extensions["String.contains"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
String.prototype.contains = function(substring) {
	return this.indexOf(substring) >= 0;
};

//============================================================================
// Array.indexOf Function
//============================================================================
//
// Returns the index of the first occurance of the given item in the array or 
// -1 when no such item exists.
//
// @param item [may be null]
//
version.extensions["Array.indexOf"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
Array.prototype.indexOf = function(item) {
	for (var i = 0; i < this.length; i++) {
		if (this[i] == item) {
			return i;
		}
	}
	return -1;
};

//============================================================================
// Array.contains Function
//============================================================================
//
// Returns true when the array contains the given item, otherwise false. 
//
// @param item [may be null]
//
version.extensions["Array.contains"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
Array.prototype.contains = function(item) {
	return (this.indexOf(item) >= 0);
};

//============================================================================
// Array.containsAny Function
//============================================================================
//
// Returns true when the array contains at least one of the elements 
// of the item. Otherwise (or when items contains no elements) false is returned.
//
version.extensions["Array.containsAny"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
Array.prototype.containsAny = function(items) {
	for(var i = 0; i < items.length; i++) {
		if (this.contains(items[i])) {
			return true;
		}
	}
	return false;
};


//============================================================================
// Array.containsAll Function
//============================================================================
//
// Returns true when the array contains all the items, otherwise false.
// 
// When items is null false is returned (even if the array contains a null).
//
// @param items [may be null] 
//
version.extensions["Array.containsAll"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
Array.prototype.containsAll = function(items) {
	for(var i = 0; i < items.length; i++) {
		if (!this.contains(items[i])) {
			return false;
		}
	}
	return true;
};


} // of "install only once"

// Used Globals (for JSLint) ==============
// ... DOM
/*global 	document */
// ... TiddlyWiki Core
/*global 	convertUnicodeToUTF8, createTiddlyElement, createTiddlyLink, 
			displayMessage, endSaveArea, hasClass, loadFile, saveFile, 
			startSaveArea, store, wikify */
//}}}


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

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

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

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

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

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

Notes to be written:
<<forEachTiddler
      where 'tiddler.tags.contains("#todo")'
      sortBy 'tiddler.title'
      write "'* [['+tiddler.title+'|'+tiddler.title+']]\n'">>
Click the "new tiddler" button towards the top right of the screen to write something in your space. You'll need to give it a title, some content and, optionally, some tags that will help you identify it later.

!Stuck for ideas?
Not sure what to write about? Not sure what to keep in your space? Other people use ~TiddlySpace for almost anything. How about some of the following:

* [[Save interesting sites|http://bookmarks.tiddlyspace.com]], images or articles from around the web so that you can refer back to them.
* [[Record your family tree|http://familytree.tiddlyspace.com]], store notes on long lost relatives or ancestors and map their relationship to you.
* [[Make up a pocketbook|http://pocketbook.tiddlyspace.com]] to store some useful information in, then print it out, [[fold it up|http://www.pocketmod.com/]], and take it with you.
* [[Plan your holiday|http://the-web-is-your-oyster.tiddlyspace.com/]], record where you're planning to go, note down places of interest and refer back to it later.
* [[Create a mindmap|http://mindmaps.tiddlyspace.com/]] to visualise your inner thoughts and see how they relate to each other.
* [[Set up a questionnaire|http://questionnaire.tiddlyspace.com/]] and get all your friends to answer it.

If you don't like any of those ideas, you can still use this space directly to keep notes and link them together, make a todo list and keep track of everything you're doing, or any one of a hundred million other things.

Still stuck? Check out the @featured space for more suggestions.

You can also [[socialise with others|How to socialise]].
<code  class="brush:js">
function create_tw_news ( url,webTag ) 
{
  // Clear the content in the div for the next feed.
  $('#'+String(webTag)).empty();
 
  // Use the JQuery get to grab the URL from the selected item
  $.get( url, function(data) 
  { 
    // Convert text to JSON object
    var json = $.parseJSON(data);    
    $('#'+String(webTag)).append('<ul>');
    
    // Loop JSON to generate items    
    for( var id=0; id<json.length; id++ )
    {  
      var item = json[id];
      var title = String(item["title"]);      
      var date = Date.convertFromYYYYMMDDHHMM(item["fields"].written)
      var webpage = "http://dgerod.tiddlyspace.com";
      var link = webpage + "/#[[" + title + "]]";
      
      // Create item and write it
      var html = '<li>' + '<a href="' + link + '">' + title + '</a> - ' + date.format("isoDate") + '</li>';     
      // Put that feed content on the screen as text 
      $('#'+String(webTag)).append(html); 
    }
    
    $('#'+String(webTag)).append('</ul>');
  });
};
</code>

<code class="brush:html">
<div id="feedContent"></div>
</code>
/*{{{*/
Background: rgb(227,241,227)
Background: rgb(255,255,255)
Foreground: rgb(13,27,13)
PrimaryPale: rgb(255,255,255)
PrimaryLight: rgb(189,222,189)
PrimaryMid: rgb(65,130,65)
PrimaryDark: rgb(39,78,39)
SecondaryPale: rgb(255,255,255)
SecondaryLight: rgb(222,193,189)
SecondaryMid: rgb(130,73,65)
SecondaryDark: rgb(78,44,39)
TertiaryPale: rgb(255,255,255)
TertiaryLight: rgb(189,193,222)
TertiaryMid: rgb(65,73,130)
TertiaryDark: rgb(39,44,78)
Error: #f88
/*}}}*/
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div macro='annotations'></div>
<div class='editor' macro='edit text'></div>
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser excludeLists'></span></div>
<!--}}}-->
/***
|''Name''|TiddlySpaceFilters|
|''Description''|provide TiddlySpace-specific filter extensions|
|''Author''|Jon Robson|
|''Version''|0.6.1|
|''Status''|@@beta@@|
|''CoreVersion''|2.6.2|
|''Requires''|TiddlySpaceConfig|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
!Usage
{{{
<<tsList Private>>
<<tsList Public>>
<<tsList Draft>>
}}}
!Code
***/
//{{{
(function($) {

var tiddlyspace = config.extensions.tiddlyspace;
var privateBag = tiddlyspace.getCurrentBag("private");
var publicBag = tiddlyspace.getCurrentBag("public");

config.filterHelpers = {
	is: {
		"private": function(tiddler) {
			var bag = tiddler.fields["server.bag"];
			return bag == privateBag;
		},
		"public": function(tiddler) {
			var bag = tiddler.fields["server.bag"];
			return bag == publicBag;
		},
		draft: function(tiddler) {
			var fields = tiddler.fields;
			var bag = fields["server.bag"];
			return (privateBag == bag && fields["publish.name"]) ? true : false;
		},
		local: function(tiddler) {
			return config.filterHelpers.is["public"](tiddler) ||
				config.filterHelpers.is["private"](tiddler);
		},
		unsynced: function(tiddler) {
			return tiddler ? tiddler.isTouched() : false;
		}
	}
};

config.filters.is = function(results, match) {
	var candidates = store.getTiddlers("title");
	var type = match[3];
	for (var i = 0; i < candidates.length; i++) {
		var tiddler = candidates[i];
		var helper = config.filterHelpers.is[type];
		if(helper && helper(tiddler)) {
			results.pushUnique(tiddler);
		}
	}
	return results;
};

})(jQuery);
//}}}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink" version="1.1" viewBox="450 366 38 57"
width="30" height="30">
	<g stroke="none" stroke-opacity="1" stroke-dasharray="none" fill="none" fill-opacity="1">
		<g>
			<path d="M 452.1094 421.2422 L 450 421.2422 L 450 423 L 487.9688 423 L 487.9688 421.2422 L 485.8595 421.2422 
			L 485.8595 377.29688 L 487.9688 377.29688 L 487.9688 375.53906 L 485.8595 375.53906 
			C 485.8595 375.53906 481.12463 371.59341 473.02023 370.52802 C 472.6824 368.9689 471.72098 366.75 468.9844 366.75 
			C 466.24783 366.75 465.28638 368.9689 464.94864 370.52802 
			C 456.84418 371.59341 452.1094 375.53906 452.1094 375.53906 L 450 375.53906 L 450 377.29688 L 452.1094 377.29688 
			Z M 467.12247 370.32086 L 467.12247 370.32086 C 467.3805 369.42395 467.90762 368.50781 468.9844 368.50781 
			C 470.0612 368.50781 470.5883 369.42395 470.84634 370.32086 
			C 470.24136 370.2848 469.62054 370.26562 468.9844 370.26562 
			C 468.34827 370.26562 467.72748 370.2848 467.12247 370.32086 Z M 454.21875 420.92804 L 454.21875 420.92804 
			C 455.46762 420.42087 456.32816 419.35281 456.32816 418.11716 L 456.32816 377.29688 L 458.4375 377.29688 
			L 458.4375 421.2422 L 454.21875 421.2422 Z M 460.5469 420.92804 L 460.5469 420.92804 
			C 461.79578 420.42087 462.65625 419.35281 462.65625 418.11716 L 462.65625 377.29688 L 464.76566 377.29688 
			L 464.76566 421.2422 L 460.5469 421.2422 Z M 466.87503 420.92804 L 466.87503 420.92804 
			C 468.1239 420.42087 468.9844 419.35281 468.9844 418.11716 L 468.9844 377.29688 L 471.09378 377.29688 
			L 471.09378 421.2422 L 466.87503 421.2422 Z M 473.2032 420.92804 L 473.2032 420.92804 
			C 474.45203 420.42087 475.31256 419.35281 475.31256 418.11716 L 475.31256 377.29688 L 477.4219 377.29688 
			L 477.4219 421.2422 L 473.2032 421.2422 Z M 479.5313 420.92804 L 479.5313 420.92804 
			C 480.78018 420.42087 481.64066 419.35281 481.64066 418.11716 L 481.64066 377.29688 L 483.75006 377.29688 
			L 483.75006 421.2422 L 479.5313 421.2422 Z" fill="black" class="glyph"/>
		</g>
	</g>
</svg>
/***
|''Name''|RandomColorPalettePlugin|
|''Description''|Adds a random color palette to TiddlyWiki|
|''Author''|Jon Robson|
|''Version''|1.4.0|
|''Status''|stable|
|''Source''|https://github.com/jdlrobson/TiddlyWikiPlugins/raw/master/plugins/RandomColorPalettePlugin/RandomColorPalettePlugin.js|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
!Usage
{{{
<<RandomColorPalette>>
}}}
Sets and saves a random color palette on execution

{{{
<<RandomColorPaletteButton>>
}}}
Creates a button, which when clicked will change the color palette
More information at http://macros.tiddlyspace.com/#%5B%5BRandomColorPaletteButton%20macro%5D%5D
!Code
***/
//{{{
RGB.prototype.toRGBString = function() {
	return "rgb(%0,%1,%2)".format(parseInt(this.r * 255, 10),
		parseInt(this.g * 255, 10), parseInt(this.b * 255, 10))
}
function HSL_TO_RGB(h, s, l) { // h (hue) between 0 and 360, s (saturation) & l (lightness) between 0 and 1
	var c = l <= 0.5 ? 2 * l * s : ( 2 - (2 * l)) * s;
	var h1 = h / 60;
	var x = c * (1 - Math.abs((h1 % 2) - 1)); 
	var r, g, b;
	if(typeof(h) == 'undefined') {
		r = 0;
		g = 0;
		b = 0;
	} else if(0 <= h1 && h1 < 1) {
		r = c;
		g = x;
		b = 0;
	} else if(1 <= h1 && h1 < 2) {
		r = x;
		g = c;
		b = 0;
	} else if(2 <= h1 && h1 < 3) {
		r = 0;
		g = c;
		b = x;
	} else if(3 <= h1 && h1 < 4) {
		r = 0;
		g = x;
		b = c;
	} else if(4 <= h1 && h1 < 5) {
		r = x;
		g = 0;
		b = c;
	} else if(5 <= h1 && h1 < 6) {
		r = c;
		g = 0;
		b = x;
	}
	m = l - (0.5 * c);
	return new RGB(r + m, g + m, b + m);
}

(function($){
	var macro = config.macros.RandomColorPalette = {
		messagesOn: false, 
		changedPaletteText: "We have assigned you a random theme by adjusting the [[ColorPalette]] tiddler.\nDon't like it? Click <<RandomColorPalette>> for another one.", 
		handler: function(place, macroName, params, wikifier, paramString, tiddler) {
			paramString = paramString || "";
			var options = macro.getOptions(paramString);
			macro.generatePalette(options, true);
		},
		optionTypes: {
			floats: ["hue", "saturation", "darkest", "lightness", "huevariance", "dark", "pale", "light", "mid",
				"saturation_light", "saturation_pale", "saturation_mid", "saturation_dark"
			]
		},
		getOptions: function(paramString) {
			var args = paramString.parseParams("name", null, true, false, true)[0];
			var options = {};
			var numbers = macro.optionTypes.floats;
			for(var i in args) {
				options[i] = numbers.indexOf(i) > -1 ? parseFloat(args[i][0], 10) : args[i][0];
			}
			return options;
		},
		generateRandomNumber: function(min, max, info) {
			var num = (Math.random() * 1);
			info = !info ? { attempts:0 } : info;
			info.attempts += 1;
			var good = true;
			if(min == max) {
				return max;
			}
			if(min && num < min) {
				good = false;
			} else if(max && num > max) {
				good = false;
			}
			if(!good) {
				if(info.attempts < 5) {
					return macro.generateRandomNumber(min, max, info);
				} else {
					if(max) {
						return max;
					} else if(min) {
						return min;
					} else {
						return 1;
					}
				}
			}
			return num;
		},
		getExistingPalette: function(asJSON) {
			var title = "ColorPalette";
			var tiddlerText;
			if(store.tiddlerExists(title)) {
				tiddlerText = store.getTiddlerText(title);
			} else if(store.isShadowTiddler(title)){
				tiddlerText = config.shadowTiddlers[title];
			}
			if(asJSON) {
				var json = {};
				if(tiddlerText) {
					var lines = tiddlerText.split("\n");
					for(var i = 0; i < lines.length; i++) {
						var definition = lines[i].split(":");
						if(definition.length == 2) {
							var name = definition[0].trim();
							var value = definition[1].trim();
							json[name] = value;
						}
					}
				}
				return json;
			} else {
				return tiddlerText;
			}
		},
		generatePalette: function(options, save) {
			var outputRGB = options.rgb;
			var palette = macro.getExistingPalette(true);
			var hue = options.hue || Math.floor(Math.random() * 359);
			var saturation = options.saturation || macro.generateRandomNumber(0.3, 0.7);
			var dark = options.dark || options.darkest || macro.generateRandomNumber(0, 0.10);
			var pale = options.pale || options.lightness || macro.generateRandomNumber(0.90, 1);
			var delta = ( ( pale - dark ) / 3 );
			var mid = options.mid || dark + delta;
			var light = options.light || dark + (delta * 2);
			var lightness_values = {Dark: dark, Mid: mid, Light: light, Pale: pale};
			var saturation_values = {};
			for(i in lightness_values) {
				if(true) {
					saturation_values[i] = options["saturation_" + i.toLowerCase()] || saturation;
				}
			}

			var opposite_hue = (hue + 180) % 360;
			var seed = options.huevariance || Math.floor((85 * Math.random()) + 5); // we want it to be at least 5 degrees
			var huetwo = (opposite_hue + seed) % 360;
			var huethree = (opposite_hue - seed) % 360;
			if(huetwo < 0) {
				huetwo = 360 + huetwo;
			}
			if(huethree < 0) {
				huethree = 360 + huethree;
			}
			for(var j in lightness_values) {
				if(true) {
					var saturation = saturation_values[j];
					palette["Primary" + j] = HSL_TO_RGB(hue, saturation, lightness_values[j]);
					palette["Secondary" + j] = HSL_TO_RGB(huetwo, saturation, lightness_values[j]);
					palette["Tertiary" + j] = HSL_TO_RGB(huethree, saturation, lightness_values[j]);
				}
			}
			palette.Background = HSL_TO_RGB(hue, saturation, 0.92);
			palette.Foreground = HSL_TO_RGB(hue, saturation, 0.08);
			palette.ColorPaletteParameters = ["HSL([", hue, "|", seed, "], [", saturation_values.Pale, "|",
				saturation_values.Light, "|", saturation_values.Mid, "|", saturation_values.Dark, "],",
				"[", dark, "|", mid, "|", light, "|", pale, "])"].join("");
			// construct new ColorPalette
			var text = ["/*{{{*/\n"];
			var colorcode;
			for(var id in palette) {
				if(true) {
					var color = palette[id];
					colorcode = outputRGB ? color.toRGBString() : color.toString();
					text.push("%0: %1\n".format(id, colorcode));
				}
			}
			text.push("/*}}}*/");
			text = text.join("");
			if(save) {
				macro.saveColorPalette(text);
			}
			return text;
		},
		saveColorPalette: function(text) {
			var tid = store.getTiddler("ColorPalette");
			if(!tid) {
				tid = new Tiddler("ColorPalette");
				tid.fields = merge({}, config.defaultCustomFields);
			} // TODO: detect that the ColorPalette in the space comes from outside recipe
			tid.fields["server.page.revision"] = "false"; // edit conflicts dont matter

			// save the color palette in tid
			tid = store.saveTiddler(tid.title, tid.title, text, tid.modifier, tid.modified,
				tid.tags, tid.fields, false, tid.created, tid.creator);
			// an interval is used to cope with users clicking on the palette button quickly.
			if(macro._nextSave) {
				window.clearTimeout(macro._nextSave);
			}
			macro._nextSave = window.setTimeout(function() {
					autoSaveChanges(null, [tid]);
				}, 2000);
			// temporary workaround for IE.
			$.twStylesheet.remove({ id: "StyleSheetColors" });
			$.twStylesheet.remove({ id: "StyleSheet" });
			refreshAll();
			macro.reportChange();
			return tid;
		},
		reportChange: function() {
			if(macro.messagesOn) { // only display message once..
				var msgPlace = getMessageDiv();
				if(!$(".changedPalette", msgPlace)[0]) {
					var tempPlace = document.createElement("div");
					wikify("{{changedPalette{" + macro.changedPaletteText + "}}}", tempPlace);
					msgPlace.appendChild(tempPlace);
				}
			}
		}
	};
	var btnMacro = config.macros.RandomColorPaletteButton = {
			text: "New ColorPalette",
			tooltip: "Generate a random colour scheme for your TiddlyWiki",
			makeButton: function(place, options) {
				var btnHandler = function(ev) {
					var t = $(ev.target);
					var options = t.data("options");
					macro.generatePalette(options, true);
					ev.preventDefault();
					return false;
				};
				var btn = createTiddlyButton(place, this.text, this.tooltip, btnHandler);
				$(btn).data("options", options);
				return btn;
			},
			handler: function(place, macroName, params, wikifier, paramString, tiddler) {
				var options = macro.getOptions(paramString);
				btnMacro.makeButton(place, options);
			}
	};
})(jQuery);
//}}}
@@Please do not modify this tiddler; it was created automatically upon space creation.@@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink" version="1.1" viewBox="78 222 60 60" 
width="30" height="30">
<g stroke="none" stroke-opacity="1" stroke-dasharray="none" fill="none" fill-opacity="1">
	<g>
		<path d="M 107.92718 244.14815 L 86.651474 222.89253 L 78.85206 230.69925 L 100.120415 251.9476 L 78.774 273.27396 
		L 86.57342 281.08075 L 107.927216 259.74707 L 129.39981 281.19946 L 137.19922 273.39267 L 115.73397 251.94763 
		L 137.121155 230.58054 L 129.32175 222.77374 Z" fill="black" class="glyph"/>
	</g>
</g>
</svg>
/***
|''Name''|TiddlyWebConfig|
|''Description''|configuration settings for TiddlyWebWiki|
|''Author''|FND|
|''Version''|1.3.2|
|''Status''|stable|
|''Source''|http://svn.tiddlywiki.org/Trunk/association/plugins/TiddlyWebConfig.js|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''Requires''|TiddlyWebAdaptor ServerSideSavingPlugin|
|''Keywords''|serverSide TiddlyWeb|
!Code
***/
//{{{
(function($) {

if(!config.extensions.ServerSideSavingPlugin) {
	throw "Missing dependency: ServerSideSavingPlugin";
}
if(!config.adaptors.tiddlyweb) {
	throw "Missing dependency: TiddlyWebAdaptor";
}

if(window.location.protocol != "file:") {
	config.options.chkAutoSave = true;
}

var adaptor = tiddler.getAdaptor();
var recipe = tiddler.fields["server.recipe"];
var workspace = recipe ? "recipes/" + recipe : "bags/common";

var plugin = config.extensions.tiddlyweb = {
	host: tiddler.fields["server.host"].replace(/\/$/, ""),
	username: null,
	status: {},

	getStatus: null, // assigned later
	getUserInfo: function(callback) {
		this.getStatus(function(status) {
			callback({
				name: plugin.username,
				anon: plugin.username ? plugin.username == "GUEST" : true
			});
		});
	},
	hasPermission: function(type, tiddler) {
		var perms = tiddler.fields["server.permissions"];
		if(perms) {
			return perms.split(", ").contains(type);
		} else {
			return true;
		}
	}
};

config.defaultCustomFields = {
	"server.type": tiddler.getServerType(),
	"server.host": plugin.host,
	"server.workspace": workspace
};

// modify toolbar commands

config.shadowTiddlers.ToolbarCommands = config.shadowTiddlers.ToolbarCommands.
	replace("syncing ", "revisions syncing ");

config.commands.saveTiddler.isEnabled = function(tiddler) {
	return plugin.hasPermission("write", tiddler) && !tiddler.isReadOnly();
};

config.commands.deleteTiddler.isEnabled = function(tiddler) {
	return !readOnly && plugin.hasPermission("delete", tiddler);
};

// hijack option macro to disable username editing
var _optionMacro = config.macros.option.handler;
config.macros.option.handler = function(place, macroName, params, wikifier,
		paramString) {
	if(params[0] == "txtUserName") {
		params[0] = "options." + params[0];
		var self = this;
		var args = arguments;
		args[0] = $("<span />").appendTo(place)[0];
		plugin.getUserInfo(function(user) {
			config.macros.message.handler.apply(self, args);
		});
	} else {
		_optionMacro.apply(this, arguments);
	}
};

// hijack isReadOnly to take into account permissions and content type
var _isReadOnly = Tiddler.prototype.isReadOnly;
Tiddler.prototype.isReadOnly = function() {
	return _isReadOnly.apply(this, arguments) ||
		!plugin.hasPermission("write", this);
};

var getStatus = function(callback) {
	if(plugin.status.version) {
		callback(plugin.status);
	} else {
		var self = getStatus;
		if(self.pending) {
			if(callback) {
				self.queue.push(callback);
			}
		} else {
			self.pending = true;
			self.queue = callback ? [callback] : [];
			var _callback = function(context, userParams) {
				var status = context.serverStatus || {};
				for(var key in status) {
					if(key == "username") {
						plugin.username = status[key];
						config.macros.option.propagateOption("txtUserName",
							"value", plugin.username, "input");
					} else {
						plugin.status[key] = status[key];
					}
				}
				for(var i = 0; i < self.queue.length; i++) {
					self.queue[i](plugin.status);
				}
				delete self.queue;
				delete self.pending;
			};
			adaptor.getStatus({ host: plugin.host }, null, _callback);
		}
	}
};
(plugin.getStatus = getStatus)(); // XXX: hacky (arcane combo of assignment plus execution)

})(jQuery);
//}}}
/***
|''Name''|ToggleTiddlerPrivacyPlugin|
|''Version''|0.7.1|
|''Status''|@@beta@@|
|''Description''|Allows you to set the privacy of new tiddlers and external tiddlers within an EditTemplate, and allows you to set a default privacy setting|
|''CoreVersion''|2.6.1|
|''Requires''|TiddlySpaceConfig|
|''Source''|http://github.com/TiddlySpace/tiddlyspace/raw/master/src/plugins/ToggleTiddlerPrivacyPlugin.js|
!Notes
When used in conjunction with TiddlySpaceTiddlerIconsPlugin changing the privacy setting will also interact with any privacy icons.

Currently use of
{{{<<setPrivacy defaultValue:public>>}}} is in conflict with {{{<<newTiddler fields:"server.workspace:x_private">>}}}

There is an option, found in the tweak tab of the backstage, called txtPrivacyMode. Set this to either ''public'' or ''private'' depending on your security preference. If you choose not to set it then it will default to ''public''.
!Params
defaultValue:[private|public]
Allows you to set the default privacy value (Default is private)

!Code
***/
//{{{
(function($) {

	var tiddlyspace = config.extensions.tiddlyspace,
		macro;
	macro = config.macros.setPrivacy = {
		handler: function(place, macroName, params, wikifier, paramString, tiddler) {
			if(readOnly) {
				return;
			}
			var el = $(story.findContainingTiddler(place)),
				args = paramString.parseParams("name",
					null, true, false, true)[0],
				container = $("<div />").
					addClass("privacySettings").
					appendTo(place)[0],
				currentSpace = tiddlyspace.currentSpace.name,
				currentBag = tiddler ? tiddler.fields["server.bag"] : false,
				// XXX: is the following reliable?
				isNewTiddler = el.hasClass("missing") || !currentBag,
				tiddlerStatus = tiddlyspace.getTiddlerStatusType(tiddler),
				customFields = el.attr("tiddlyfields"),
				defaultValue = "public",
				options = config.macros.tiddlerOrigin ?
						config.macros.tiddlerOrigin.getOptions(paramString) :
						{};
			customFields = customFields ? customFields.decodeHashMap() : {};
			if(isNewTiddler || !["public", "private", "unsyncedPrivate",
					"unsyncedPublic"].contains(tiddlerStatus)) {
				if(args.defaultValue) {
					defaultValue = args.defaultValue[0].toLowerCase();
				} else {
					defaultValue = config.options.chkPrivateMode ?
							"private" : "public";
				}
				defaultValue = defaultValue ?
						"%0_%1".format(currentSpace, defaultValue) :
						customFields["server.bag"];
				this.createRoundel(container, tiddler, currentSpace,
						defaultValue, options);
			}
		},
		updateEditFields: function(tiddlerEl, bag) {
			var saveBagField = $('[edit="server.bag"]', tiddlerEl),
				saveWorkspaceField = $('[edit="server.workspace"]', tiddlerEl),
				input = $("<input />").attr("type", "hidden"),
				workspace = "bags/" + bag;
			if(saveBagField.length === 0) {
				input.clone().attr("edit", "server.bag").val(bag).
					appendTo(tiddlerEl);
			} else {
				saveBagField.val(bag);
			}
			// reset to prevent side effects
			$(tiddlerEl).attr("tiddlyFields", "");
			if(saveWorkspaceField.length === 0) {
				input.clone().attr("edit", "server.workspace").
					val(workspace).appendTo(tiddlerEl);
			} else {
				saveWorkspaceField.val(workspace);
			}
		},
		setBag: function(tiddlerEl, newBag, options) {
			var bagStatus,
				title = $(tiddlerEl).attr("tiddler"),
				tiddler = store.getTiddler(title),
				originButton = $(".originButton", tiddlerEl)[0],
				refreshIcon,
				newWorkspace = "bags/" + newBag,
				rPrivate = $("input[type=radio].isPrivate", tiddlerEl),
				rPublic = $("input[type=radio].isPublic", tiddlerEl);
			refreshIcon = function(type) {
				var originMacro = config.macros.tiddlerOrigin;
				if(originButton && originMacro) {
					options.noclick = true;
					originMacro.showPrivacyRoundel(tiddler, type,
							originButton, options);
				}
			};
			macro.updateEditFields(tiddlerEl, newBag);
			if(tiddler) {
				tiddler.fields["server.bag"] = newBag;
				// for external tiddlers
				tiddler.fields["server.workspace"] = newWorkspace;
			}
			if(newBag.indexOf("_public") > -1) {
				rPrivate.attr("checked", false);
				rPublic.attr("checked", true);
				bagStatus = "public";
			} else {
				rPublic.attr("checked", false); // explicitly do this for ie
				rPrivate.attr("checked", true);
				bagStatus = "private";
			}
			refreshIcon(bagStatus);
		},
		createRoundel: function(container, tiddler, currentSpace,
							   defaultValue, options) {
			var privateBag = "%0_private".format(currentSpace),
				publicBag = "%0_public".format(currentSpace),
				rbtn = $("<input />").attr("type", "radio").
					attr("name", tiddler.title),
				el = story.findContainingTiddler(container);
			rbtn.clone().val("private").addClass("isPrivate").
				appendTo(container);
			$("<label />").text("private").appendTo(container); // TODO: i18n
			rbtn.clone().val("public").addClass("isPublic")
				.appendTo(container);
			$("<label />").text("public").appendTo(container); // TODO: i18n
			$("[type=radio]", container).click(function(ev) {
				var btn = $(ev.target);
				tiddler.fields["server.page.revision"] = "false";
				if(btn.hasClass("isPrivate")) { // private button clicked.
					$(el).addClass("isPrivate").removeClass("isPublic");
					macro.setBag(el, privateBag, options);
				} else {
					$(el).addClass("isPublic").removeClass("isPrivate");
					macro.setBag(el, publicBag, options);
				}
			});
			window.setTimeout(function() {
				macro.setBag(el, defaultValue, options);
			}, 100);
			// annoyingly this is needed as customFields are added to end of EditTemplate so are not present yet
			// and don't seem to respect any existing customFields.
		}
	};

}(jQuery));
//}}}
!SpaceUnplugged
{{unpluggedSpaceTab{
{{wizard{
<<image unsyncedIcon width:48>> Sync is currently unavailable in ~TiddlyWiki due to security constraints in modern browsers. Research is being done to build a suitable alternative. In the meantime if you have changed content in an offline ~TiddlyWiki, you can get your content back into ~TiddlySpace by using the ''import'' functionality from the backstage of the online wiki.
}}}
}}}

!Menu
<<message messages.memberStatus>> <<homeLink>>
{{unsyncedList{<<message messages.syncListHeading>> <<list filter [is[unsynced]]>>}}}

running TiddlySpace@glossary version <<message extensions.tiddlyweb.status.tiddlyspace_version>>
{{autotable{
<<tiddler Backstage##Resources>>
}}}

!Resources
[[blog|@@blog]] [[documentation|@@docs]] [[featured spaces|@@featured]] 

!ImportExport
<<fileImport>>
You can download this TiddlySpace as an offline TiddlyWiki:

{{chunkyButton{<<exportSpace>>}}}

!BackstageTiddlers
|upload a <<message messages.privacySetting>> file: <<binaryUpload>>|<<closeAll>><<permaview>><<newTiddler>><<newJournal "DD MMM YYYY" "journal">><<saveChanges>>|
|>|<<search>>|
|>|<<tiddler Backstage##Tiddlers>>|

!Tiddlers
<<tabs
	txtMainTab
	"Recent" "Recently edited tiddlers" TabTimeline
	"All" "All tiddlers" TabAll
	"Public" "All public tiddlers" [[TiddlySpaceTabs##Public]]
	"Private" "All private tiddlers" [[TiddlySpaceTabs##Private]]
	"Tags" "All tags" TabTags
	"Spaces" "Tiddlers grouped by space" [[TiddlySpaceTabs##Spaces]]
	"Missing" "Missing tiddlers" TabMoreMissing
	"Orphans" "Orphaned tiddlers" TabMoreOrphans
	"Shadows" "Shadowed tiddlers" TabMoreShadowed
>>

!BatchOps
<<tabs
	txtPublisherTab
	"Private" "Move tiddlers from private to public" Backstage##BatchPrivate
	"Public" "Move tiddlers from public to private" Backstage##BatchPublic
>>

!BatchPrivate
<<TiddlySpacePublisher type:private>>

!BatchPublic
<<TiddlySpacePublisher type:public>>

!Plugins
''Note:'' Many of these plugins are core TiddlySpace plugins and cannot be changed unless first cloned.

<<tiddler PluginManager>>

!Tweaks
These options change behavior in TiddlyWiki //only// and may be ineffective in TiddlySpace.

<<tiddler AdvancedOptions>>
/***
|''Name''|TiddlySpaceRevertRevision|
|''Description''|Revert to a previous revision|
|''Author''|BenGillies|
|''Version''|0.1|
|''Status''|unstable|
|''Source''|http://github.com/TiddlySpace/tiddlyspace|
|''CodeRepository''|http://github.com/TiddlySpace/tiddlyspace|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''CoreVersion''|2.6.0|
|''Requires''|TiddlyWebAdaptor TiddlySpaceRevisionView|
!Usage
Add a control button to revert to a particular revision.

The button must be called from within a revision, as generated by TiddlySpaceRevisionView
!Code
***/
//{{{
(function($) {

config.commands.revert = {
	text: "revert",
	tooltip: "make this revision the current one",
	handler: function(ev, src, title) {
		var revElem = story.getTiddler(title);
		var tidToRevert = store.getTiddler($(revElem).attr("revName"));

		var revision = store.getTiddler(title);
		if ((revision) && (tidToRevert)) {
			tidToRevert.text = revision.text;
			var newFields = merge({}, revision.fields);
			for (var fieldName in newFields) {
				if (fieldName.substr(0, 7) === "server.") {
					delete newFields[fieldName];
				}
			}
			merge(tidToRevert.fields, newFields);
			tidToRevert.tags = merge([], revision.tags);
			tidToRevert.fields.changecount = 1;
			delete tidToRevert.fields.doNotSave;

			store.saveTiddler(tidToRevert.title, tidToRevert.title,
				tidToRevert.text, null, null, tidToRevert.tags,
				tidToRevert.fields, false, tidToRevert.created, tidToRevert.creator);

			autoSaveChanges(true);
		}
	}
};

})(jQuery);
//}}}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink" version="1.1" viewBox="2 724 68 55" 
width="30" height="30">
<g stroke="none" stroke-opacity="1" stroke-dasharray="none" fill="none" fill-opacity="1">
	<g>
		<path d="M 2.25 756 L 11.25 747 L 24.75 760.4994 L 60.750004 724.4994 L 69.75 733.49902 
		L 24.749977 778.49976 Z" fill="#101010" class="glyph"/>
	</g>
</g>
</svg>
|''Name''|SyntaxHighlighterPlugin3Info|
|''Description''|Documentation for [[SyntaxHighlighterPlugin3]]|
|''Author''|PMario|
|''Version''|0.3.0|
|''Source''|http://syntaxhighlighter.tiddlyspace.com/#SyntaxHighlighterPlugin3|
|''Documentation''|http://syntaxhighlighter.tiddlyspace.com/#SyntaxHighlighterPlugin3Info|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]], libraries used: see the according files: [[ShCore.js]] |
|''Keywords''|syntax highlighting color code|
!Usage
!!!!StyleSheet
<<<
*add this to your StyleSheet
{{{
[[ShCore.css]]
[[ShThemeDefault.css]]
}}}
<<<
!! Feedback / Support
Feedback is very welcome at [[TiddlyWiki group|http://groups.google.com/group/tiddlywiki]]
!!Examples
!!!!Code sample
<<<
<!--{{{-->
<code class="brush:js highlight:[1,3]">
// comment
var a = b = 0;
a = 17;
</code>
<!--}}}-->
will render like 
<code class="brush:js highlight:[1,3]">
// comment
var a = b = 0;
a = 17;
</code>
<<<
!!!!Text
<<<
{{{
 {{{
 this will be rendered as text!
 }}}
}}}
<<<
!!!!CSS
<<<
{{{
 /*{{{*/
 .cssClass {
	display: block; !important;
 }
 /*}}}*/
}}}
will render like:
/*{{{*/
	.cssClass {
		display: block; !important;
	}
/*}}}*/
<<<
!!!!XML
<<<
{{{
<!--{{{-->
<html>
	<div id='myId' class='dp50'>some text </div>
</html>
<!--}}}-->
}}}
will render like:
<!--{{{-->
<html>
	<div id='myId' class='dp50'>some text </div>
</html>
<!--}}}-->
<<<
!!!!Plugin
<<<
{{{
//{{{
(function($) {
	config.macros.highlightSyntax = {
		var a = b = 0;
		// your code here!
	}
})(jQuery);
//}}}
}}}
will render like:
//{{{
(function($) {
	config.macros.highlightSyntax = {
		var a = b = 0;
		// your code here!
	}
})(jQuery);
//}}}
<<<
!!! Macro highlightTiddlerText
<<<
{{{
<<highlightTiddlerText tiddlerName renderingParams>> or
<<highlightTiddlerText "tiddlerName::slice">>
<<highlightTiddlerText "##section" renderingParams>>
}}}
''tiddlerName''
>can be a {{{tiddlerName}}} or {{{tiddlerName::slice}}} or {{{tiddlerName##section}}} 
>if it is {{{::slice}}} or {{{##section}}} the containing tiddler name will be used
eg:
{{{
<<highlightTiddlerText "##thisCode" "javascript tab-size:3 highlight:[2]">>
}}}
will render as
<<highlightTiddlerText "##thisCode" "javascript tab-size:3 highlight:[2]">>
{{{
! thisCode
if (a >= 10) {
	b = a;
	// some comment
}
!
}}}
<<<
!!! Macro highlightSyntax
<<<
*The macro is only needed if you have inline html blocks, like shown below.
<!--{{{-->
<html>
	<pre class='brush:pascal tab-size:3'>
		// your code 
	<pre>
</html>

<<highlightSyntax>> .. will render the <pre> blocks shown above.
<!--}}}-->
<<<
!!!!ViewTemplate
<<<
*Same as macro, but will be executed automatically for every tiddler.
<!--{{{-->
<div class='tagging' macro='tagging'></div>
<div macro='highlightSyntax'></div>  <!-- insert this line -->
<div class='tagClear'></div>
<!--}}}-->
<<<
!!!!Parameters
<<<
{{{<<highlightSyntax [tagName]>>}}}
*will render all blocks, with any defined tag name. eg: tagName = code.
*[tagName] is optional. Default is "pre".
<<<
!!Advanced Options
<<<
Guess syntax: <<option chkGuessSyntax>> .. If activated, ~TiddlyWiky <pre> blocks will be rendered according to there block braces, like described obove.
Expert mode: <<option chkExpertSyntax>> .. If activated, additional values below will be used

{{{ {{{ }}} txtShText: <<option txtShText>> eg: 'brush:text tab-size:4 + options'
{{{ /*{{{*/ }}} txtShCss: <<option txtShCss>> eg: 'brush:css  + options'
{{{ //{{{ }}} txtShPlugin: <<option txtShPlugin>> 'brush:js  + options'
{{{ <!--{{{-->> }}} txtShXml: <<option txtShXml>> 'brush:xml  + options'

If you want to change the default values eg for C++, add the following to a [[zzConfig]] tiddler and tag it "systemConfig"
//{{{
config.options.chkGuessSyntax = true;
config.options.chkExpertSyntax = true;

config.options.txtShPlugin = 'brush:cpp tab-size:4';
//}}}
and use the following backets to cover your code
{{{
//{{{
   cpp code comes here.
//}}}
}}}

All possible SyntaxHighlighter options can be found at: [[SyntaxHighlighter homepage|http://alexgorbatchev.com/SyntaxHighlighter/manual/configuration/]]
<<<
!! You need a different brush?
* Go to [[syntaxhighlighter brushes page| http://alexgorbatchev.com/SyntaxHighlighter/manual/brushes/]] 
* Select your brush
* Copy paste it into a tiddler eg: ShBrushCpp.js
** Tag the new tiddler ''systemConfig''
** Save and reload
* Have a look at Advanced options or use the {{{<code class="brush: ... >}}} tag described above.

!!Needed: list tagged syntax
<<list filter [tag[syntax]]>>

!!!Revision History
*V 0.3.0 2012-05-07
** highlightTiddlerText macro added
*V 0.2.1 2011-08-01
**fix wrong error text
*V 0.2.0 2010-08-22
**New formatter for {{{<code class='brush:???'>}}} is available now
**expert mode uses config options now
*V 0.1.0 2010-08-17
**initial release
R0lGODlhPwAgAMQcAHp6eqqqqs7OzmFhYfPz89DQ0MLCwtvb221tbZ6enpycnFVVVYaGhra2tufn59bW1oeHh8/Pz76+vvr6+sHBwZKSkvn5+d/f383NzXJycklJSf///zMzMwAAAAAAAAAAACH5BAEAABwALAAAAAA/ACAAAAXfIMdtZGmeaKquLDq2cCzPdG3feK7vfO//wKBwSCwaj8igRsMwATSk53IJ2DA0gVJAU9lOpwIfuPSMYgPoxoYw0Bw2jsWAIFAoMhqI3SFuz82AKAIaVU9hWhqHP4RbCYFlKQlMGo4mW4piVQiJG5BPAKAAaiRsGn+WnECEGwemBJ6EoaOsY6iYPasbjbAqCAsHcgS2SlUkmwtQncknW1mNw6rFtEtmaNa0CCWbipfEqMlSXwTbJYOn3Unp6ukTEQXv8O8YF+stFhQG+fr5Eg/1/wADChxIsOCLgjBEIIQRAgA7
Once you have some content then you may choose to determine a tiddler, or set of tiddlers to display each time you load ~TiddlySpace. This is determined by the [[DefaultTiddlers]].
<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
	<title>This Space</title>
	<link href="/bags/common/tiddlers/profile.css" type='text/css' rel='stylesheet' >
	<link href="/bags/common/tiddlers/admin.css" type='text/css' rel='stylesheet' >
	<!--[if lte IE 8]>
	<script type="text/javascript" src="/bags/common/tiddlers/json2.js"></script>
	<script type="text/javascript" src="/bags/common/tiddlers/es5-shim.min.js"></script>
	<![endif]-->
</head>
<body>
<div id="container">
	<div id="text-html" class="main section">
		<a class="app" href="/">home</a>
		<div class="left">
		<h2>About this space <button class='toggleNext'></button></h2>
		<div id="siteinfo"></div>
		<h2>Site Icon</h2>
		<div>
			<img id="siteicon" class="siteicon">
			<form id="upload" method="POST" enctype="multipart/form-data">
				<input type="hidden" name="title" value="SiteIcon" />
				<input type="hidden" name="tags" value="excludeLists">
				<input type="hidden" name="csrf_token" class="csrf" />
				<input type="file" name="file" accept="image/*" />
				<input class="btn" type="submit" value="upload" />
			</form>
			<div id="dropzone">Drop file here
				<img class="notloading" src="/bags/common/tiddlers/ajax-loader.gif" alt="submitting SiteIcon" />
			</div>
		</div>
		<h2>Vital Statistics</h2>
		<div id="info">please wait while information is loaded about this space...</div>
		<button class="spacereset">Reset Space</button>
		<div class="reset-confirm-wrap messageArea">
			<button class="close-btn" title="cancel reset">×</button>
			<p>Are you sure you want to reset the space? You can't go back! This will remove all the content from the space!</p>
			<form class="cf">
				<label for="reset-confirm">Enter the space name to confirm.</label>
				<input type="text" name="reset-confirm" class="reset-confirm-input inputBox" />
				<button type="submit">Reset Now</button>
			</form>
			<div class="reset-message-area">
				<p class="performing">Resetting...</p>
				<p class="finished">Reset Done!</p>
				<p class="recipe-error-msg">Error removing includes. Please remove manually.</p>
			</div>
		</div>
		</div>
		<div class="right">
		<div class="ts-membership">
			<h2>
				Add Member
				<a href="http://docs.tiddlyspace.com/What%20is%20a%20member%3F" title="What is a Member?" class="help">What is a Member?</a>
			</h2>
			<div>
				<p>Add a new member to your space by entering their name below. Enter a space name instead and prefix with @ to add everyone who is already a member of that space.</p>
				<form class="ts-members">
					<input class="inputBox" type="text" name="username">
					<input type="submit" value="Add Member" class="btn" />
				</form>
			</div>
			<h2>
				Existing Members <button class='toggleNext'></button>
			</h2>
			<div>
				Your space currently has the following members: 
				<ul class="ts-members"></ul>
			</div>
			<h2>
				Include Space
				<a class="help" href="http://docs.tiddlyspace.com/What%20is%20space%20inclusion%3F" title="What is inclusion?">What is Inclusion?</a>
			</h2>
			<form class="ts-includes">
				<input class="inputBox" type="text" name="spacename">
				<input type="submit" value="Include Space" class="btn" />
			</form>
		</div>
		<div>
			<h2>Included Spaces <button class='toggleNext'></button></h2>
			<div>
			This space includes the following spaces:
			<ul class="ts-includes"></ul>
			</div>
		</div>
		</div>
		<div class="clear"></div>
	</div>
</div>
<script src='/bags/common/tiddlers/backstage.js'></script>
<script src='/bags/common/tiddlers/jquery.js'></script>
<script src='/bags/tiddlyspace/tiddlers/chrjs'></script>
<script src='/bags/common/tiddlers/chrjs.space'></script>
<script src='/bags/common/tiddlers/chrjs.users'></script>
<script src='/bags/common/tiddlers/chrjs.identities'></script>
<script src='/bags/tiddlyspace/tiddlers/TiddlySpaceCSRF'></script>
<script src='/bags/common/tiddlers/jquery-form.js'></script>
<script src="/bags/common/tiddlers/siteiconupload.js"></script>
<script src="/bags/common/tiddlers/ts.js"></script>
<script src="/status.js"></script>
<script src="/bags/common/tiddlers/space.js"></script>
</body>
</html>
//{{{
config.macros.tags2.handler = function(place,macroName,params,wikifier,paramString,tiddler)
{
	params = paramString.parseParams("anon",null,true,false,false);
	var ul = createTiddlyElement(place,"ul");
	var title = getParam(params,"anon","");
	if(title && store.tiddlerExists(title))
		tiddler = store.getTiddler(title);
	var sep = getParam(params,"sep"," ");
	var lingo = config.views.wikified.tag;
	var label = null;
	var t;
	for(t=0; t<tiddler.tags.length; t++) {
		var tag = store.getTiddler(tiddler.tags[t]);
		if(!tag || !tag.tags.contains("excludeLists")) {
			if(!label)
				label = createTiddlyElement(ul,"li",null,"listTitle",lingo.labelTags.format([tiddler.title]));
			createTagButton(createTiddlyElement(ul,"li"),tiddler.tags[t],tiddler.title);
			if(t<tiddler.tags.length-1)
				createTiddlyText(ul,sep);
		}
	}
	if(!label)
		createTiddlyElement(ul,"li",null,"listTitle",lingo.labelNoTags.format([tiddler.title]));
};
//}}}
User-agent: *
Disallow: /bags
Disallow: /recipes
/***
|''Name''|ErrorHandlerPlugin|
|''Version''|0.4.3|
|''Author''|Jon Robson|
|''Description''|Localised tiddler save errors including edit conflict resolution.|
|''CoreVersion''|2.6.1|
|''Requires''|TiddlySpaceConfig|
***/
//{{{
(function($) {

var tiddlyspace = config.extensions.tiddlyspace;
var currentSpace = tiddlyspace.currentSpace.name;
tiddlyspace.getLocalTitle = function(title, workspace, suffix) {
	var endsWith = config.extensions.BinaryTiddlersPlugin.endsWith;
	if(!suffix) {
		var isPublic = endsWith(workspace, "_public");
		suffix = tiddlyspace.resolveSpaceName(workspace);
		if(currentSpace == suffix) {
			suffix = isPublic ? "public" : "private";
		} else {
			suffix = "@%0".format(suffix);
		}
	}
	return "%0 *(%1)*".format(title, suffix);
};

var sssp = config.extensions.ServerSideSavingPlugin;

var msgs = config.messages.editConflict = {
	loading: "Loading..",
	resolve: "[[Edit Conflict]]@glossary: this tiddler may have been changed by someone else.",
	reviewDiff: "review (recommended)",
	reviewDiffTooltip: "review changes made to this tiddler",
	reviewDiffError: "error retrieving revision.",
	save: "overwrite",
	saveTooltip: "make this revision the top revision of this tiddler",
	discard: "cancel",
	discardTooltip: "undo changes to this tiddler and get most recent version",
	diffTitle: "%0",
	diffFieldTitle: "%0 - fields",
	diffTextTitle: "%0 - text",
	updating: "updating your version...",
	diffHeader: ["Review the changes that have been made whilst you were editing this tiddler. ",
		"Fold relevant changes back into your version.\n",
		"{{removed{Red}}} highlight shows content removed. ",
		"{{added{Green}}} highlight shows content added.\n"].join(""),
	diffTextHeader: "View changes in text",
	diffFieldsHeader: "View changes in fields"
};

var plugin = config.extensions.errorHandler = {
	diffTags: ["excludeLists", "excludeMissing", "excludeSearch"],
	displayMessage: function(message, tiddler, context) {
		var desc = context && context.httpStatus ? context.statusText :
			sssp.locale.connectionError;
		var reportArea = plugin.reportError(tiddler.title);
		var msg = $("<div />").appendTo(reportArea);
		if(message == "saveConflict") {
			wikify(msgs.resolve, msg[0]);
			var choiceArea = $("<div />").appendTo(reportArea)[0];
			plugin.editConflictHandler(choiceArea, tiddler);
		} else {
			msg.text(sssp.locale[message].format(tiddler.title, desc));
		}
	},
	editConflictHandler: function(container, tiddler) {
		var title = tiddler.title;
		var myrev = tiddler.fields["server.page.revision"];
		// note user now needs to edit, fix problem and save. 
		// TODO: make sure this gets reset in save callback
		store.getTiddler(title).fields["server.page.revision"] = "false";

		var diffBtn = createTiddlyButton(container, msgs.reviewDiff, msgs.reviewDiffTooltip, function(ev) {
			var title = $(ev.target).data("title");
			plugin.displayDiff(ev.target, store.getTiddler(title), myrev);
		});
		var saveBtn = createTiddlyButton(container, msgs.save, msgs.saveTooltip, function(ev) {
				var title = $(ev.target).data("title");
				var tid = store.saveTiddler(store.getTiddler(title));
				autoSaveChanges(null, [tid]);
			});
		var ignoreBtn = createTiddlyButton(container, msgs.discard, msgs.discardTooltip, function(ev) {
			var title = $(ev.target).text(msgs.updating).data("title");
			plugin.resetToServerVersion(store.getTiddler(title));
		});
		$([diffBtn, ignoreBtn, saveBtn]).data("title", title);
	},
	getDiffTiddlerTexts: function(diffText) {
		var chunks = diffText.split("\n  \n");
		if(chunks.length < 2) {
			return [chunks[0], ""];
		} else {
			var diffFieldsText = "{{diff{\n%0\n}}}".format(chunks[0]);
			diffText = '{{diff{\n%0\n}}}'.format(chunks.splice(1, chunks.length).join("\n"));
			return [diffText, diffFieldsText];
		}
	},
	makeDiffTiddler: function(title, diff) {
		var newTiddler = new Tiddler(title);
		var tags = plugin.diffTags;
		newTiddler.text = msgs.loading;
		newTiddler.fields.doNotSave = true;
		newTiddler.tags = diff ? tags.concat(["diff"]) : tags;
		newTiddler = store.saveTiddler(newTiddler);
		$.extend(store.getTiddler(title).fields,
			config.defaultCustomFields); // allow option to save it
		return newTiddler;
	},
	displayDiff: function(src, tiddler, latestRevision) {
		var adaptor = tiddler.getAdaptor();
		var title = tiddler.title;
		var ts = new Date().formatString("0hh:0mm:0ss");
		var suffix = "edit conflict %0".format(ts);
		var diffTitle = tiddlyspace.getLocalTitle(msgs.diffTitle.format(title), "", suffix);
		var diffTextTitle = tiddlyspace.getLocalTitle(msgs.diffTextTitle.format(title), "", suffix);
		var diffFieldsTitle = tiddlyspace.getLocalTitle(msgs.diffFieldTitle.format(title), "", suffix);
		plugin.makeDiffTiddler(diffTextTitle, true);
		plugin.makeDiffTiddler(diffFieldsTitle, true);
		var newTiddler = plugin.makeDiffTiddler(diffTitle, false);
		newTiddler.text = ['%0\n<<slider chkViewDiffText "%1" "%2">>\n',
			'<<slider chkViewDiffField "%3" "%4">>'].join("").
			format(msgs.diffHeader, diffTextTitle, msgs.diffTextHeader,
				diffFieldsTitle, msgs.diffFieldsHeader);
		store.saveTiddler(newTiddler);

		var callback = function(r) {
			var text = plugin.getDiffTiddlerTexts(r);
			store.getTiddler(diffTextTitle).text = text[0];
			store.getTiddler(diffFieldsTitle).text = text[1];
			story.refreshTiddler(diffTitle, null, true);
		};
		var workspace = "bags/%0".format(tiddler.fields["server.bag"]);
		ajaxReq({
			type: "get",
			dataType: "text",
			url: "/diff?format=unified&rev1=%0/%1/%2&rev2=%0/%1".format(workspace, title, latestRevision),
			success: callback,
			error: function() {
				displayMessage(msgs.reviewDiffError);
			}
		});
		story.displayTiddler(src, diffTitle);
	},
	resetToServerVersion: function(tiddler) {
		var adaptor = tiddler.getAdaptor();
		var ctx = { 
			host: tiddler.fields["server.host"],
			workspace: "bags/" + tiddler.fields["server.bag"]
		};
		adaptor.getTiddler(tiddler.title, ctx, null, function(context) {
			store.saveTiddler(context.tiddler);
			story.refreshTiddler(tiddler.title);
			store.setDirty(false);
		});
	},
	reportError: function(title) {
		var el = story.getTiddler(title);
		if(!el) {
			el = story.displayTiddler(null, title);
		}
		return $("<div />").addClass("error annotation").prependTo(el)[0];
	}
};

sssp.reportFailure = function(message, tiddler, context) {
	config.options.chkViewDiffText = config.options.chkViewDiffText === undefined ?
		true : config.options.chkViewDiffText;
	config.options.chkViewDiffFields = config.options.chkViewDiffFields || false;
	plugin.displayMessage(message, tiddler, context);
};

})(jQuery);
//}}}
The theme of this site is a modification of Mocha TiddlyWiki Theme created by Anthony and  ported to TiddlyWiki by Saq Imtiaz. 
And for writing [[LaTeX|http://en.wikipedia.org/wiki/LaTeX]] the @math-template is used.

Basic style sheets:
* [[StyleSheet]]
* [[SyntaxHighlighterStyleSheet]]
And basid templates:
* [[PageTemplate]]
* TiddlerTemplates
** [[ViewTemplate]]
** [[EditTemplate]]
** [[%articleViewTemplate]]
** [[%articleEditTemplate]]
** [[%postViewTemplate]]
** [[%postEditTemplate]]

List of available themes:
* [[MochaTheme]]
* [[TiddlyPediaTheme]]
Current theme:<<switchTheme width:auto>>
!Summary
This tiddler contains some basic $\LaTeX$ macros which are useful for writing Analytic Topology.  Documentation can be found [[here|BasicMacros Documentation]].

!Version
version: 1.0.4

1.0: (2011-04-15) Major release.
1.0.1: (2011-04-16) Bugfix. {{{#1}}} was added to the definition of {{{\closure}}}.
1.0.2: (2011-04-16) Command name change.  The command {{{\blackboard}}} was added (to the supplemental list).  {{{\blackBoard}}} is kept for backwards compatability.
1.0.3: (2011-04-17) Command name added.  The abbreviation {{{\fns}}} for {{{\functions}}} was added (to the supplemental list).
1.0.4: (2011-04-17) Comments changed.  Consistent capitalisation was applied to the section names.

!Code
$
\def\BasicMacros{

% Miscellaneous basics

\def\parentheses#1{{\left( {#1} \right)}}
\def\brackets#1{{\left[ {#1} \right]}}
\def\solidus#1/#2{{\left. {#1} \left/ \vphantom{#1} {#2} \right. \right.}}
\def\of{\parentheses}
\def\operator{\operatorname}

\def\script{\mathcal}
\def\gothic{\mathfrak}
\def\blackBoard{\mathbb}
\def\boldText{\mathbf}
\def\bold{\boldsymbol}


% Symbols

\def\epsilon{\varepsilon}
\def\infinity{\infty}
\def\continuum{\gothic{c}}

\def\naturals{\blackBoard{N}}
\def\integers{\blackBoard{Z}}
\def\rationals{\blackBoard{Q}}
\def\reals{\blackBoard{R}}
\def\complexNumbers{\blackBoard{C}}

\def\half{\frac{1}{2}}
\def\third{\frac{1}{3}}
\def\quarter{\frac{1}{4}}


% Sets and set operations

\def\Set#1{{\left\lbrace {#1} \right\rbrace}}
\def\set#1:#2{\Set{{#1} \colon {#2}}}
\def\singleton{\Set}
\def\emptySet{\emptyset}

\def\Sequence#1{{\left\langle {#1} \right\rangle}}
\def\sequence#1:#2{\Sequence{{#1} \colon {#2}}}
\def\tuple{\parentheses}
\def\emptyTuple{\tuple{}}

\def\family#1:#2{{\parentheses{#1}_{#2}}}

\def\subset{\subseteq}
\def\superset{\supseteq}
\def\union{\cup}
\def\Union{\bigcup}
\def\intersect{\cap}
\def\Intersection{\bigcap}
\def\setMinus{\setminus}
\def\cross{\times}
\def\product{\prod}

\def\powerSet#1{{\script{P}\of{#1}}}
\def\functionSpace#1#2{{{#2}^{#1}}}
\def\cardinality#1{{\left\lvert {#1} \right\rvert}}
\def\isEmpty{= \emptySet}
\def\isNonempty{\not= \emptySet}


% Functions and function operations

\def\function#1:#2->#3{{{#1} \colon {#2} \to {#3}}}
\def\mapsTo{\mapsto}
\def\map#1->#2{\parentheses{{#1} \mapsTo {#2}}}

\def\compose{\circ}
\def\inverse#1{{{#1}^{-1}}}
\def\restriction#1#2{{{\left. {#1} \right\lvert}_{#2}}}

\def\image#1#2{{{#2}\of{#1}}}
\def\preimage#1#2{{{#2}^{-1}\of{#1}}}
\def\fiber#1#2{\preimage{\singleton{#1}}{#2}}

\def\identity#1{{\operator{id}_{#1}}}


% Topology related notation

\def\homeomorphic{\cong}
\def\convergesTo{\to}

\def\closure#1{\overline{#1}}
\def\closureIn#1#2{{\closure{#2}^{#1}}}
\def\interior#1{{\operator{int}\of{#1}}}
\def\interiorIn#1#2{{\operator{int}_{#1}\of{#2}}}

\def\collection{\script}
\def\collections{\gothic}
\def\topology{\collection}
\def\cover{\collection}
\def\filter{\collection}
\def\ideal{\collection}

\def\interval#1#2,#3#4{{\left#1 {#2}, {#3} \right#4}}
\def\unitInterval{\interval[0, 1]}
\def\plane{{\functionSpace{2}{\reals}}}
\def\stoneCechCompactification#1{{\beta{#1}}}


% General notation

\def\modulus#1{{\left\lvert {#1} \right\rvert}}
\def\norm#1{{\left\Vert {#1} \right\Vert}}
\def\equivalent{\sim}
\def\quotient{\solidus}


% Aliases

\def\functions{\function}

}

\def\BasicMacroAbbreviations{

\def\p{\parentheses}
\def\b{\brackets}

\def\N{\naturals}
\def\Z{\integers}
\def\Q{\rationals}
\def\R{\reals}
\def\C{\complexNumbers}

\def\sng{\singleton}
\def\Seq{\Sequence}
\def\seq{\sequence}
\def\pSet{\powerSet}
\def\fnSpace{\functionSpace}
\def\card{\cardinality}

\def\fn{\function}
\def\id{\identity}

\def\homeo{\homeomorphic}
\def\sCC{\stoneCechCompactification}

}

% The following is a supplement to \BasicMacros  and \BasicMacroAbbreviations.  This macroset can be thought of as the list of changes that will be made for the next version.
\def\BasicMacrosSupplement
{

% Because 'blackboard' is one word the second 'b' should not be capitalised in the command name.
\def\blackboard{\blackBoard}

% Given the commands \function, \fn, and \functions, it is only natural that we have a command \fns.
\def\fns{\functions}

}
$
<<forEachTiddler
      where "tiddler.tags.contains('%article') && ! tiddler.tags.contains('#todo')"
      sortBy "store.getValue(tiddler,'written')" descending
      write " (index < 5) ? '* [[' + tiddler.title + '|' + tiddler.title + ']]\n' : '' ">>
!Summary
This tiddler is intended to be a central hub for all documentation on the mechanics, configuration, and use of $\LaTeX$ and ~MathJax on this site.  This is a first draft and will flesh out with time but hopefully there is enough here for people to get by for now.  If you have any questions please leave a comment at the bottom.

!Inputting $\LaTeX$ Script
Putting $\LaTeX$ script onto the site is easy.  Simply:
*Create a new tiddler (look for the 'new tiddler' link in the top-right).
*Change the title (highlighted by default) to something meaningful (just like a file name).
*Write some $\LaTeX$ script in the large text box (enclosed with {{{$...$}}} as usual).
*Click the tick (Save changes to this tiddler) which is above the edit-title box and to the right-hand side.
The mathematics you entered should be visible on the screen.  If you have problems then see the section on troubleshooting.

Beyond that things can get complicated.  If you prefer to learn by doing then [[Bare handed axiom checks work (Gareth)]] is probably the most thorough example of how to use $\LaTeX$ on the site.  [[Semantic Latex Example]] is also worth a look.  Be aware that there are some macros defined automatically when the site starts up.  They are in [[BasicMacros]].  Feel free to experiment with your own tiddlers but please don't change [[BasicMacros]].

If you want to know more about what is going on behind the scenes first you need to be aware that you are really using something called ~MathJax, not $\LaTeX$.

!Differences between $\LaTeX$ and ~MathJax
~MathJax tries hard to emulate $\LaTeX$ and bring you the most used functionality but it is NOT $\LaTeX$.  Some key differences are:
*Much of the lower-level $\TeX$ commands are not available.
*Most of the more powerful commands that are available can act quite differently to their $\LaTeX$ counterparts (for example, here, {{{\newcommand}}} allows you to overwrite any existing command).
*Few $\LaTeX$ packages are available, there is not even a version of "amsthm".
*In ~MathJax, //all// commands need to be enclosed in {{{$...$}}}, {{{\(...\)}}}, {{{\[...\]}}}, or {{{$$...$$}}}.  This includes environments like {{{\begin{align*}...\end{align*} }}} and macro definitions such as {{{\def\union{\cup} }}}.
*Basic large scale sectioning is not supported at all.  In particular, {{{\chapter}}}, {{{\section}}}, and {{{\ref}}} are not supported.
*Most text-formatting commands are unavailable, including {{{\emph}}} and {{{\begin{enumerate} }}}.

To see what is available in ~MathJax go [[here|http://www.mathjax.org/docs/1.1/tex.html#supported-latex-commands]].  Commands which are not labelled "non-standard" are $\TeX$ or $\LaTeX$ commands (I would avoid using non-standard commands so that you can easily export work later).

!Rendering
When you click a link to a tiddler it will be displayed in the main area (brought into the "story" and "rendered").  If it contains $\LaTeX$ script than the mathematics will be rendered and displayed automatically.  Right-click a mathematical expression for ~MathJax's context-sensitive menu for quick configuration.
\[
    \PopAll
    \GarethNotation

    \collection{U} = \set{\fiber{p}{\pi_i}}:{i \in I}

    \PopAll
\]

Some browsers don't display expressions on this site correctly (or at all).  It would be great if we could just make everything work but with our resources, it makes the most sense to support one or two browsers.  Firefox is recommended for both tiddlyspace and this site in particular but Chromium should work almost as well and I am interested in any problems you have with this browser.  You can find more [[here|Math Processing Error]].

There are two different rendering methods.  ~HTML-CSS and ~MathML.  You can find much more about these [[here|http://www.mathjax.org/docs/1.1/output.html]] but the important points are:
*~HTML-CSS is much slower (fonts and images are fetched online as they are required) but better quality.
*~MathML displays quite a lot better if you install the [[STIX|http://www.stixfonts.org/]] fonts.  Upgrading your browser can also make quite a big difference too.
*You can choose your favourite rendering method from the ~MathJax context sensitive menu by right-clicking any mathematial expression and selecting ''Settings > Math Renderer''.  You may well need to reload the site after doing this.
*We have configured ~MathJax to use ~MathML by default and ~HTML-CSS as a fallback option.

!Importing and Exporting $\LaTeX$
Because of the differences between $\LaTeX$ and ~MathJax (discussed above) copying work between the two (i.e. importing and exporting) is not a trivial task.

Firstly a note of caution.  If you make heavy use of features of one platform which are not available in another then you will have a tough time moving your work across.

The golden rule for this section is:
://Keep it simple//

It should be possible to import/export you mathematics by use of a small number of simple find/replace operations (0 counts as a small number).

The largescale structures you use on the two platforms is fundamentally different.  In $\LaTeX$ one uses commands like {{{\chapter}}}, {{{\section}}}, and {{{\ref}}} with the aim of creating a paper.  Online one creates tiddlers and links to tiddlers with the aim of building part of a website.  At this point you'll have to experiment with the tools available and see what works best but there's no getting around the fact that this aspect of importing and exporting will have to be done manually (at least for now).

Unfortunately, there are some small scale differences too.  ~MathJax does not support {{{\emph}}} or {{{\begin{enumerate} }}}.  The intension is that online you should use HTML for text markup.  On tiddlyspace.com, you can use basic HTML but it is highly recommended that you use standard [[TiddlyWiki markup syntax|Basic formatting]]@docs.  You can find more about how to drive ~TiddlyWikis in general from [[here|Contents]]@docs.

In short you have to realise that ~MathJax only takes responsibility for the mathematics.  Text and structure would be better handled by a $\LaTeX$ to HTML converter.  Try a web search if you're interested in this; I've not taken the time to do any research on it.

On both platforms you have the power to create your own macros and even keep a small collection of personal macros which you can //import// and use whenever you write $\LaTeX$ script (see the section below).  Of course, when importing and exporting mathematics, the supporting macros will have to be moved across too (note that ~MathJax requires definitions to be enclosed in {{{$...$}}} or similar whereas $\LaTeX$ requires that they are not).  There are globally available lists of macros on the site and if you use any of these commands you'll need to copy the various definitions when you export (again, see the section below).

To help keep things as simple as possible people please try to adopt the authors style of $\LaTeX$ code (within reason) when leaving comments on their work.  It will be much easier for them to understand and apply your suggestions and translation between ~MathJax and $\LaTeX$ will be easier.

I have created a $\LaTeX$ [[skeleton file|Convert site to Latex]] which can be used for working offline and for copying work from the site into $\LaTeX$.

!Macros
Both with $\LaTeX$ and ~MathJax you have the power to create your own macros.  However, because of the collaborative nature of the site, one should be careful/considerate when creating macros.

There are a number of ways of creating a new macro: {{{\newcommand}}}; {{{\renewcommand}}}; {{{\def}}}; and {{{\let}}}.  Given the underlying javascript I would urge you to avoid {{{\let}}} (it is quite powerful).   Currently, neither {{{\newcommand}}} nor {{{\renewcommand}}} check for existing macros so they effectively do the same thing as one another.  {{{\def}}} allows one to build macros with templates (see [[BasicMacros]] for examples like {{{\function}}} and {{{\set}}}).

The golden rule here is:
://Don't overwrite $\TeX$ or $\LaTeX$ commands//

The main reason for this is that other people may rely on these macros when leaving comments.  Richard and I have discussed some sort of automated warning for potentially harmful command name overwrites but for now don't worry too much and have at it.  If you break something due to a rogue definition I'll probably find it and fix it anyway.  If you get in trouble and things are acting weird then reload the site.  If you really want to know more about which command names to avoid then
+++[Read on (techincal information)][Hide]
The problem with {{{\newcommand}}} and {{{\renewcommand}}} here is that they give you into a false sense of security.  Unlike in $\LaTeX$, [[localTeX.js]] doesn't check to see if a definition exists before overwriting it with {{{\newcommand}}}.

The idea in $\LaTeX$ is that {{{\newcommand}}} won't overwrite an existing macro and thereby protects the user from themselves.  If you use {{{\def}}} then you can easily burn yourself.  For example:
{{{
\def\or{\vee}
}}}
This looks innocent enough but after making such a definition you'll find that {{{\begin{align}...\end{align} }}} stops working and $\LaTeX$ throws errors about counters doing weird things.  The reason is that {{{\or}}} is a basic $\TeX$ command for use with {{{\ifcase}}} and the $\LaTeX$ definition of the align environment makes heavy use of this.

I would suggest that when you do create a new macro that you check whether or not it exists in $\LaTeX$ by trying to define a macro with that name using {{{\newcommand}}}.  If $\LaTeX$ doesn't complain that the command already exists then you should be good to go on the site.  Be mindful that there exists a basic set of macros for discussing [[Analytic Topology|Basic Macros]] and another one for discussing [[Kunen|KunenMacros]] in particular; it is good practice to avoid changing the meanings of these macros because people may rely on them to make comments on your work.  Making notational tweaks to these macros is perfectly fine though.  Also, don't overwrite the commands {{{\Clean}}}, {{{\PushMacros}}}, {{{\PopMacros}}}, {{{\PopAll}}}, or any of the macrosets like {{{\BasicMacros}}} and {{{\LocalMacros}}} because you will cause chaos!

There is a short list of exceptions to the golden rule which are made for readability.  At the moment that list (stored in [[LatexNucleus]]) is
{{{
\let\LaTeXepsilon\epsilon
\let\LaTeXsubset\subset
\let\LaTeXrestriction\restriction
}}}
Translating: people are free to overwrite the commands {{{\epsilon}}}, {{{\subset}}}, and {{{\restriction}}}.  Consequently you should not rely on any of these three commands to be their original $\LaTeX$ selves when you are making a definition and you should use the backup commands {{{\LaTeXepsilon}}}, {{{\LaTeXsubset}}}, and {{{\LaTeXrestriction}}} instead.  For example:
{{{
\def\restriction#1#2{{{#1}\mathord{\LaTeXrestriction}\parentheses{#2}}}
}}}
If you think there are other commands which you would like to overwrite then create an appropriate tiddler for discussion.  The aim is, however, to keep the list as short as possible (so that it is easy to move definitions from $\LaTeX$ to ~MathJax.
===
----

If you want to make a new definition, for example:
{{{
\def\ball#1#2{{B_{#2}\of{#1}}}
}}}
in a tiddler then please make sure to tidy up when you are done by adding
{{{
$\PopAll$
}}}
at the end of your tiddler (or at the end of the section in which you write $\LaTeX$ script).  It's a good idea to start your tiddler with {{{\PopAll}}} too incase someone else forgot to tidy up.  Rarely, it may be that {{{\PopAll}}} is simply not powerful enough to do the job.  If you are experiencing macro weirdness even after {{{\PopAll}}} then you can try {{{\Clean}}} (slow but ''powerful'' - "occasionally more effective than reloading the site" powerful!).

There are also sets of macros which you may find useful.  If you wish to use one or more of these then begin your tiddler (or section of mathematics) with:
{{{
$
\PopAll
\<name of macroset 0>
\<name of macroset 1>
\<name of macroset 2>
...
$
}}}
and, as before, make sure to end the corresponding section with
{{{
$\PopAll$
}}}
Check out [[Errata: Chapter 3]] for an example.

The macrosets currently available (linked to in [[LatexNucleus]]) are:
|\BasicMacros|[[BasicMacros]]|Loaded automatically|
|\BasicMacroAbbreviations|~|Loaded automatically|
|\BasicMacrosSupplement|~|Loaded automatically|
|\KunenMacros|[[KunenMacros]]||
|\KunenMacroAbbreviations|~||
|\GarethNotation|[[GarethMacros||
|\GarethMacros|~||

If you want to make your own personal macro set then feel free to make a copy of [[mine|GarethMacros]] and change the relevant parts (don't forget the tags).  Feel free to dip into the other macrosets for ideas.  To make the command list globally accessible you'll have to add a line to [[LatexNucleus]].  If you have any problems then create an appropriate discussion tiddler and leave a comment.

You can get even fancier by use of {{{\LocalMacros}}}.  If you are writing a particularly long tiddler which should generate lots of embedded comments then it might be wise to create a macroset just for the local macros.  A special macroset name is reserved just for this purpose, {{{\LocalMacros}}} and the intended usage is as follows:
{{{
$
\PopAll
\<name of macroset 0>
\<name of macroset 1>
\<name of macroset 2>
...
\def\LocalMacros{
	\def\<name of local macro 0>{<definition of local macro 0}
	\def\<name of local macro 1>{<definition of local macro 1}
	\def\<name of local macro 2>{<definition of local macro 2}
	...
}
\LocalMacros
$
}}}

Now, If, for example, I want to leave a lengthy comment on one aspect of your proof and there are some macros in my personal macro set which would be useful to me then I can write:
{{{
+++[Gareth]
$\PushMacros\GarethMacros\LocalMacros$
<my comment>
$\PopMacros$
===
}}}
This way I'll have access to my macros but, in the event of a name clash, priority will be given to the local macros of the tiddler, followed by my personal macros, followed by the macrosets imported at the beginning, followed by basic macros, followed by plain $\LaTeX$.  (Like I said, fancy, but occasionally appropriate).  {{{\LocalMacros}}} is defined to be trivial by default so there should be no danger in using {{{\LocalMacros}}} for all of your comments.

!Semantic $\LaTeX$
We aim to promote the use of semantic style $\LaTeX$.

The heart of this idea is in the list of definitions in [[BasicMacros]] (these definitions are automatically loaded so you can easily try them out).  The primary goal of these macros is to make the underlying $\LaTeX$ code easier to read and understand.  There are some other benefits like reducing the chance of subtle formatting errors and giving people a way to make basic notational changes with practically no effort.

Of course you are free to only use standard $\LaTeX$ if that's what you prefer but we (Rolf and I) encourage you to give semantic $\LaTeX$ a go.

!Comments
+++[Add Comment][Hide]
<<comment here reverse>>
===


/%comment%/__''Thanks''__
^^posted by gareth on Thursday, April 14th, 2011 at 9:14:46 am^^
<<<
I just looked over this tiddler and I can imagine most people will be thinking "tl,dr".  Ah well, I'm not about to start improving this now.

As for {{{\Tidy}}}, I would be in favour but for the existence of {{{\PushMacros}}} and {{{\PopMacros}}}.  If people are going to know of and possibly use these commands then {{{\PopAll}}} needs no explanation and {{{\Tidy}}} would only serve to confuse.
<<<
__''{{{\PopAll}}} and {{{\Clean}}}''__
^^posted by richard on Wednesday, April 13th, 2011 at 10:58:43 pm^^
<<<
Sorry Gareth, I really should have gotten back to you quicker about {{{\PopAll}}} and {{{\Clean}}}. {{{\Clean}}} was intended as a save-your-tiddler-from-previous-local-macro-and-let-oblivion switch; {{{\PopAll}}} should deal with all things not {{{\let}}} in a far more efficient way, so I suggest this command is used for tidying up. You may want to alias it as {{{\Tidy}}} or something, since people are more likely to remember this for this purpose. I didn't want to make the changes myself in the above, but I shall start writing a local macro user guide [[here|Local macro user guide]].

Thanks for this Gareth, you've done a sterling job of setting this all in place!
<<<
/***
|''Name:''|SingleTiddlerPlugin|
|''Description:''|Display one tiddler at one time |
|''Author:''|PaulDowney (psd (at) osmosoft (dot) com) |
|''Source:''|http://whatfettle.com/2008/07/SingleTiddlerPlugin/ |
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/PaulDowney/plugins/SingleTiddlerPlugin/ |
|''Version:''|0.1|
|''License:''|[[BSD License|http://www.opensource.org/licenses/bsd-license.php]] |
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev |
|''~CoreVersion:''|2.4|
!!Documentation
This plugin closes all tiddlers and displays one tiddler at one time. 
The URL is updated to point to the current tiddler.
!!Code
***/
//{{{
/*jslint onevar: false nomen: false plusplus: false */
/*global jQuery window config Story story Tiddler */
(function ($) {
    version.extensions.SingleTiddlerPlugin = {installed: true};

	Story.prototype._displayTiddler = Story.prototype.displayTiddler;
	Story.prototype.displayTiddler = function (src, t) {
        var title = t instanceof Tiddler ? t.title : t;
		story.closeAllTiddlers();
		this._displayTiddler.apply(this, arguments);
        window.location.hash = encodeURIComponent(String.encodeTiddlyLink(title));
	};

}(jQuery));
//}}}
/***
|''Name''|TiddlySpaceTiddlerIconsPlugin|
|''Version''|0.8.10|
|''Status''|@@beta@@|
|''Author''|Jon Robson|
|''Description''|Provides ability to render SiteIcons and icons that correspond to the home location of given tiddlers|
|''Source''|http://github.com/TiddlySpace/tiddlyspace/raw/master/src/plugins/TiddlySpaceTiddlerIconsPlugin.js|
|''Requires''|TiddlySpaceConfig BinaryTiddlersPlugin ImageMacroPlugin TiddlySpacePublishingCommands|
!Notes
{{{<<tiddlerOrigin>>}}} shows the origin of the tiddler it is being run on.
In TiddlySpace terms this means it will determine whether the tiddler is external, public or private.
Where private it will analyse whether a public version exists and distinguish between the different scenarios.
If a tiddler is external, the SiteIcon of that external space will be shown

!Parameters
width / height : define a width or height of the outputted icon
label: if label parameter is set to yes, a label will accompany the icon.
!Code
***/
//{{{
(function($) {

if(!config.macros.image) {
	throw "Missing dependency: ImageMacroPlugin";
}

var imageMacro = config.macros.image;
var tiddlyspace = config.extensions.tiddlyspace;
var tweb = config.extensions.tiddlyweb;
var cmds = config.commands;
var cmd = cmds.publishTiddler;
tiddlyspace.resolveSpaceName = function(value) {
	var endsWith = config.extensions.BinaryTiddlersPlugin.endsWith;
	if(value) {
		value = value.indexOf("bags/") === 0 ? value.substr(5) : value;
		value = value.indexOf("recipes/") === 0 ? value.substr(8) : value;
		if(value.indexOf("@") === 0) {
			value = value.substr(1);
		}
		if(endsWith(value, "_public")) {
			value = value.substr(0, value.length - 7);
		} else if(endsWith(value, "_private")) {
			value = value.substr(0, value.length - 8);
		}
		value = value.toLowerCase();
	}
	return value;
};

tiddlyspace.renderAvatar = function(place, value, options) {
	options = options ? options : {};
	options.labelOptions = options.labelOptions ? options.labelOptions : { include: false, height: 48, width: 48 };
	options.imageOptions = options.imageOptions ? options.imageOptions : {};
	options.imageOptions.altImage = "/bags/common/tiddlers/defaultUserIcon";
	var container = $('<div class="siteIcon" />').appendTo(place);
	value = tiddlyspace.resolveSpaceName(value);

	tweb.getStatus(function(status) {
		var link, noLabel;
		if(!value || value == config.views.wikified.defaultModifier ||
			value == config.views.wikified.shadowModifier) {
			var icon = config.views.wikified.shadowModifier == value ? "shadowIcon" : "missingIcon";
			if(store.tiddlerExists(icon)) {
				imageMacro.renderImage(container, icon, options.imageOptions);
			} else {
				noLabel = true;
			}
		} else {
			var spaceURI;
			if(value != tiddlyspace.currentSpace.name) {
				spaceURI = options.notSpace ? tiddlyspace.getHost(status.server_host) :
					tiddlyspace.getHost(status.server_host, value);
			}
			link = spaceURI ? $("<a />").attr("href", spaceURI) : $("<span />");
			link.text(value);

			var imageOptions = options.imageOptions;
			if(options.spaceLink && !imageOptions.link) {
				imageOptions.link = spaceURI;
			}
			var avatar = options.notSpace ? false : value;
			var uri = tiddlyspace.getAvatar(status.server_host, avatar);
			imageMacro.renderImage(container, uri, options.imageOptions);
			if(!value) {
				value = "tiddlyspace";
			}
		}
		if(!noLabel && options.labelOptions.include) {
			var prefix = $("<span />").text(options.labelOptions.prefix || "")[0];
			var suffix = $("<span />").text(options.labelOptions.suffix || "")[0];
			$('<div class="label" />').append(prefix).append(link).
				append(suffix).appendTo(container);
		}
	});
	if(value) {
		var prefix = options.labelOptions.prefix || "";
		var suffix = options.labelOptions.suffix || "";
		var label = "%0%1%2".format(prefix, value, suffix);
		$(container).attr("title", label);
	}
};

var originMacro = config.macros.tiddlerOrigin = {
	locale: {
		"shadow": "shadow tiddler",
		"missing": "missing tiddler",
		"private": "private",
		"unknown": "unknown state",
		"public": "public",
		"unsyncedPrivate": "unsynced and private",
		"unsyncedPublic": "unsynced and public",
		externalPrefix: "from ",
		externalBagSuffix: " bag",
		externalSuffix: " space",
		publishPrivateDeletePrivate: "Are you sure you want to make this tiddler public?",
		moveToPrivate: "Are you sure you want to make this tiddler private? Only members will be able to see it.",
		pleaseWait: "please wait..",
		keepPublic: "keep public",
		cannotPublishDirtyTiddler: "The current tiddler is unsaved so cannot be published. Please save the tiddler first.",
		keepPrivate: "keep private",
		makePublic: "make public",
		makePrivate: "make private"
	},
	handler: function(place, macroName, params,wikifier, paramString, tiddler){
		var adaptor = tiddler.getAdaptor();
		var btn = $("<div />").addClass("originButton").attr("params", paramString).
			attr("refresh", "macro").attr("macroName", macroName).appendTo(place)[0];
		$(btn).data("tiddler", tiddler);
		originMacro.refresh(btn);
	},
	refresh: function(btn) {
		$(btn).empty();
		var paramString = $(btn).attr("params");
		var tiddler = $(btn).data("tiddler");
		var options = originMacro.getOptions(paramString);
		var type = tiddlyspace.getTiddlerStatusType(tiddler);
		originMacro.renderIcon(tiddler, type, btn, options);
	},
	getOptions: function(paramString) {
		paramString = "%0 label:no width:48 height:48 spaceLink:yes preserveAspectRatio:yes".format(paramString);
		var parsedParams = paramString.parseParams("name");
		var params = parsedParams[0].name;
		var options = {
			labelOptions: originMacro._getLabelOptions(parsedParams),
			imageOptions: imageMacro.getArguments(paramString, []),
			noclick: parsedParams[0].interactive &&
				parsedParams[0].interactive[0] == "no" ? true : false
		};
		if(!options.noclick) {
			var spaceLink = parsedParams[0].spaceLink;
			options.spaceLink = spaceLink && spaceLink[0] == "no" ? false : true;
		} else {
			options.spaceLink = false;
		}
		return options;
	},
	_getLabelOptions: function(parsedParams) {
		parsedParams = parsedParams[0];
		var includeLabel = !parsedParams.label || ( parsedParams.label && parsedParams.label[0] == "yes" );
		var prefix = parsedParams.labelPrefix ? parsedParams.labelPrefix[0] : false;
		var suffix = parsedParams.labelSuffix ? parsedParams.labelSuffix[0] : false;
		return { include: includeLabel, suffix: suffix, prefix: prefix };
	},
	_isSpace: function(value) {
		value = value ? value : "";
		var endsWith = config.extensions.BinaryTiddlersPlugin.endsWith;
		if(endsWith(value, "_private") || endsWith(value, "_public")) {
			return true;
		} else {
			return false;
		}
	},
	renderIcon: function(tiddler, type, button, options) {
		var locale = originMacro.locale;
		originMacro.annotateTiddler(button, type);
		if(type != "external") {
			originMacro.showPrivacyRoundel(tiddler, type, button,
				options);
		} else {
			var prefix = options.labelOptions.prefix, suffix = options.labelOptions.suffix;
			var space = tiddler.fields["server.bag"];
			options.notSpace = !originMacro._isSpace(space);
			options.labelOptions.prefix = prefix ? prefix : locale.externalPrefix;
			options.labelOptions.suffix = suffix ? suffix : (options.notSpace ? locale.externalBagSuffix : locale.externalSuffix);

			tiddlyspace.renderAvatar(button, space, options);
		}
	},
	showPrivacyRoundel: function(thisTiddler, privacyType, button, options) {
		// there is a public tiddler as well as the current tiddler!
		// TODO: not this is not enough.. we also need to check if the public tiddler is the same as..
		// .. the private tiddler to determine whether this is a draft
		// use of hashes would be useful here.
		$(button).empty();
		var icon = "%0Icon".format(privacyType);
		if(privacyType.indexOf("unsynced") === 0 && !store.tiddlerExists(icon)) {
			icon = "unsyncedIcon";
		}
		if(privacyType == "shadow") {
			if(!store.tiddlerExists(icon)) {
				icon = "bags/tiddlyspace/tiddlers/SiteIcon";
			}
		}
		if(privacyType == "missing" && !store.tiddlerExists(icon)) {
			return; // the user is not making use of the missingIcon
		} else {
			imageMacro.renderImage(button, icon, options.imageOptions);
			originMacro.showLabel(button, privacyType, options.labelOptions);
			var cmd = originMacro.iconCommands[privacyType];
			if(cmd && thisTiddler && !options.noclick) {
				$(button).click(function(ev) {
					cmd(ev, thisTiddler);
				});
			}
		}
	},
	annotateTiddler: function(place, type) {
		var tidEl = $(story.findContainingTiddler(place));
		tidEl.
			removeClass("private public external privateAndPublic privateNotPublic shadow").
			addClass(type);
	},
	showLabel: function(button, type, options) {
		var locale = originMacro.locale;
		var label = options.label ? options.label : locale[type];
		label = label ? label : locale.unknown;
		if(options && options.include) {
			$('<div class="roundelLabel" />').html(label).appendTo(button);
		}
		$(button).attr("title", label);
	},
	confirm: function(ev, msg, onYes, options) {
		options = options ? options : {};
		onYes = onYes ? onYes : function(ev) {};
		var btn = $(".originButton", $(ev.target).parents())[0];
		var popup = Popup.create(btn);
		$(popup).addClass("confirmationPopup");
		$("<div />").addClass("message").text(msg).appendTo(popup);
		$("<button />").addClass("button").text(options.yesLabel || "yes").appendTo(popup).click(onYes);
		$("<button />").addClass("button").text(options.noLabel || "no").click(function(ev) {
			Popup.remove();
		}).appendTo(popup);
		Popup.show();
		ev.stopPropagation();
		return false;
	},
	alert: function(ev, msg) {
		var popup = Popup.create(ev.target);
		$(popup).addClass("confirmationPopup alert");
		$("<div />").addClass("message").text(msg).appendTo(popup);
		Popup.show();
		ev.stopPropagation();
	},
	reportDirty: function(el) {
		originMacro.alert(el, originMacro.locale.cannotPublishDirtyTiddler);
	},
	iconCommands: {
		"public": function(ev, tiddler) {
			if(!readOnly) {
				var locale = originMacro.locale;
				var msg = locale.moveToPrivate;
				if(story.isDirty(tiddler.title)) {
					originMacro.reportDirty(ev);
				} else {
					originMacro.confirm(ev, msg, function(ev) {
						var target = $(ev.target);
						var onComplete = function(info) {};
						var privateBag = cmd.toggleBag(tiddler, "private");
						cmd.moveTiddler(tiddler, {
							title: tiddler.title,
							fields: { "server.bag": privateBag }
						}, onComplete);
					}, { yesLabel: locale.makePrivate, noLabel: locale.keepPublic });
				}
			}
		},
		"private": function(ev, tiddler) {
			if(!readOnly) {
				var locale = originMacro.locale;
				var adaptor = tiddler.getAdaptor();
				var publishTo = tiddler.fields["publish.name"] || tiddler.title;
				var workspace = "bags/%0".format(tiddler.fields["server.bag"]);
				tiddler.fields["server.workspace"] = workspace;
				var publicBag = cmd.toggleBag(tiddler, "public");
				var msg;
				msg = locale.publishPrivateDeletePrivate;
				var title = tiddler.title;
				var newTitle = publishTo || tiddler.title;
				tiddler.fields["server.page.revision"] = "false";
				store.addTiddler(tiddler);
				if(story.isDirty(tiddler.title)) {
					originMacro.reportDirty(ev);
				} else {
					originMacro.confirm(ev, msg, function(ev) {
						var onComplete = function(info) {};
						cmd.moveTiddler(tiddler, {
							title: newTitle,
							fields: { "server.bag": publicBag }
						}, onComplete);
					}, { yesLabel: locale.makePublic, noLabel: locale.keepPrivate });
				}
			}
		}
	}
};

})(jQuery);
//}}}
/*{{{*/
/* text alignments */
.left
{ display:block; text-align:left; }
.center
{ display:block; text-align:center; }
.right	
{ display:block; text-align:right; }

/* font sizes */
.big
{ font-size:14pt; line-height:120% }
.medium
{ font-size:12pt; line-height:120% }
.normal
{ font-size:9pt; line-height:120% }
.small
{ font-size:8pt; line-height:120% }
.fine
{ font-size:7pt; line-height:120% }
.tiny
{ font-size:6pt; line-height:120% }
.larger
{ font-size:120%; }
.smaller
{ font-size:80%; }

/* font styles */
.bold
{ font-weight:bold; }
.italic
{ font-style:italic; }
.underline
{ text-decoration:underline; }

/* important */
.important 
{ font-size:100%; font-family:arial,helvetica; font-weight:bold; color:red; }
/*}}}*/
<<forEachTiddler
      where 'tiddler.tags.contains("&siteSettings")'
      sortBy 'tiddler.title'
      write "'* [[' + tiddler.title + '|' + tiddler.title + ']]' + '\n'">>
|''Name''|TiddlyPediaTheme|

! Author Mode
|PageTemplate|TiddlyPediaPageTemplate|
|ViewTemplate|TiddlyPediaViewTemplate|
|EditTemplate|TiddlyPediaEditTemplate|
|StyleSheet|TiddlyPediaStyleSheet|
|ColorPalette|ColorPalette|

! Read-Only Mode
|PageTemplateReadOnly|TiddlyPediaPageTemplate|
|ViewTemplateReadOnly|TiddlyPediaViewTemplate|
|EditTemplateReadOnly|TiddlyPediaEditTemplate|
|StyleSheetReadOnly|TiddlyPediaStyleSheet|
|ColorPalette|ColorPalette|
/***
|''Name''|ServerSideSavingPlugin|
|''Description''|server-side saving|
|''Author''|FND|
|''Version''|0.6.5|
|''Status''|stable|
|''Source''|http://svn.tiddlywiki.org/Trunk/association/plugins/ServerSideSavingPlugin.js|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''CoreVersion''|2.5.3|
|''Keywords''|serverSide|
!Notes
This plugin relies on a dedicated adaptor to be present.
The specific nature of this plugin depends on the respective server.
!Revision History
!!v0.1 (2008-11-24)
* initial release
!!v0.2 (2008-12-01)
* added support for local saving
!!v0.3 (2008-12-03)
* added Save to Web macro for manual synchronization
!!v0.4 (2009-01-15)
* removed ServerConfig dependency by detecting server type from the respective tiddlers
!!v0.5 (2009-08-25)
* raised CoreVersion to 2.5.3 to take advantage of core fixes
!!v0.6 (2010-04-21)
* added notification about cross-domain restrictions to ImportTiddlers
!To Do
* conflict detection/resolution
* rename to ServerLinkPlugin?
* document deletion/renaming convention
!Code
***/
//{{{
(function($) {

readOnly = false; //# enable editing over HTTP

var plugin = config.extensions.ServerSideSavingPlugin = {};

plugin.locale = {
	saved: "%0 saved successfully",
	saveError: "Error saving %0: %1",
	saveConflict: "Error saving %0: edit conflict",
	deleted: "Removed %0",
	deleteError: "Error removing %0: %1",
	deleteLocalError: "Error removing %0 locally",
	removedNotice: "This tiddler has been deleted.",
	connectionError: "connection could not be established",
	hostError: "Unable to import from this location due to cross-domain restrictions."
};

plugin.sync = function(tiddlers) {
	tiddlers = tiddlers && tiddlers[0] ? tiddlers : store.getTiddlers();
	$.each(tiddlers, function(i, tiddler) {
		var changecount = parseInt(tiddler.fields.changecount, 10);
		if(tiddler.fields.deleted === "true" && changecount === 1) {
			plugin.removeTiddler(tiddler);
		} else if(tiddler.isTouched() && !tiddler.doNotSave() &&
				tiddler.getServerType() && tiddler.fields["server.host"]) { // XXX: server.host could be empty string
			delete tiddler.fields.deleted;
			plugin.saveTiddler(tiddler);
		}
	});
};

plugin.saveTiddler = function(tiddler) {
	try {
		var adaptor = this.getTiddlerServerAdaptor(tiddler);
	} catch(ex) {
		return false;
	}
	var context = {
		tiddler: tiddler,
		changecount: tiddler.fields.changecount,
		workspace: tiddler.fields["server.workspace"]
	};
	var serverTitle = tiddler.fields["server.title"]; // indicates renames
	if(!serverTitle) {
		tiddler.fields["server.title"] = tiddler.title;
	} else if(tiddler.title != serverTitle) {
		return adaptor.moveTiddler({ title: serverTitle },
			{ title: tiddler.title }, context, null, this.saveTiddlerCallback);
	}
	var req = adaptor.putTiddler(tiddler, context, {}, this.saveTiddlerCallback);
	return req ? tiddler : false;
};

plugin.saveTiddlerCallback = function(context, userParams) {
	var tiddler = context.tiddler;
	if(context.status) {
		if(tiddler.fields.changecount == context.changecount) { //# check for changes since save was triggered
			tiddler.clearChangeCount();
		} else if(tiddler.fields.changecount > 0) {
			tiddler.fields.changecount -= context.changecount;
		}
		plugin.reportSuccess("saved", tiddler);
		store.setDirty(false);
	} else {
		if(context.httpStatus == 412) {
			plugin.reportFailure("saveConflict", tiddler);
		} else {
			plugin.reportFailure("saveError", tiddler, context);
		}
	}
};

plugin.removeTiddler = function(tiddler) {
	try {
		var adaptor = this.getTiddlerServerAdaptor(tiddler);
	} catch(ex) {
		return false;
	}
	var context = {
		host: tiddler.fields["server.host"],
		workspace: tiddler.fields["server.workspace"],
		tiddler: tiddler
	};
	var req = adaptor.deleteTiddler(tiddler, context, {}, this.removeTiddlerCallback);
	return req ? tiddler : false;
};

plugin.removeTiddlerCallback = function(context, userParams) {
	var tiddler = context.tiddler;
	if(context.status) {
		if(tiddler.fields.deleted === "true") {
			store.deleteTiddler(tiddler.title);
		} else {
			plugin.reportFailure("deleteLocalError", tiddler);
		}
		plugin.reportSuccess("deleted", tiddler);
		store.setDirty(false);
	} else {
		plugin.reportFailure("deleteError", tiddler, context);
	}
};

plugin.getTiddlerServerAdaptor = function(tiddler) { // XXX: rename?
	var type = tiddler.fields["server.type"] || config.defaultCustomFields["server.type"];
	return new config.adaptors[type]();
};

plugin.reportSuccess = function(msg, tiddler) {
	displayMessage(plugin.locale[msg].format([tiddler.title]));
};

plugin.reportFailure = function(msg, tiddler, context) {
	var desc = (context && context.httpStatus) ? context.statusText :
		plugin.locale.connectionError;
	displayMessage(plugin.locale[msg].format([tiddler.title, desc]));
};

config.macros.saveToWeb = { // XXX: hijack existing sync macro?
	locale: { // TODO: merge with plugin.locale?
		btnLabel: "save to web",
		btnTooltip: "synchronize changes",
		btnAccessKey: null
	},

	handler: function(place, macroName, params, wikifier, paramString, tiddler) {
		createTiddlyButton(place, this.locale.btnLabel, this.locale.btnTooltip,
			plugin.sync, null, null, this.locale.btnAccessKey);
	}
};

// hijack saveChanges to trigger remote saving
var _saveChanges = saveChanges;
saveChanges = function(onlyIfDirty, tiddlers) {
	if(window.location.protocol == "file:") {
		_saveChanges.apply(this, arguments);
	} else {
		plugin.sync(tiddlers);
	}
};

// override removeTiddler to flag tiddler as deleted -- XXX: use hijack to preserve compatibility?
TiddlyWiki.prototype.removeTiddler = function(title) { // XXX: should override deleteTiddler instance method?
	var tiddler = this.fetchTiddler(title);
	if(tiddler) {
		tiddler.tags = ["excludeLists", "excludeSearch", "excludeMissing"];
		tiddler.text = plugin.locale.removedNotice;
		tiddler.fields.deleted = "true"; // XXX: rename to removed/tiddlerRemoved?
		tiddler.fields.changecount = "1";
		this.notify(title, true);
		this.setDirty(true);
	}
};

// hijack ImportTiddlers wizard to handle cross-domain restrictions
var _onOpen = config.macros.importTiddlers.onOpen;
config.macros.importTiddlers.onOpen = function(ev) {
	var btn = $(resolveTarget(ev));
	var url = btn.closest(".wizard").find("input[name=txtPath]").val();
	if(window.location.protocol != "file:" && url.indexOf("://") != -1) {
		var host = url.split("/")[2];
		var macro = config.macros.importTiddlers;
		if(host != window.location.host) {
			btn.text(macro.cancelLabel).attr("title", macro.cancelPrompt);
			btn[0].onclick = macro.onCancel;
			$('<span class="status" />').text(plugin.locale.hostError).insertAfter(btn);
			return false;
		}
	}
	return _onOpen.apply(this, arguments);
};

})(jQuery);
//}}}
/***
|''Name''|GroupByPlugin|
|''Description''|Mimics allTags macro to provide ways of creating lists grouping tiddlers by any field|
|''Version''|0.6.1|
|''Author''|Jon Robson|
|''Status''|beta|
!Usage
{{{<<groupBy tags>>}}}
mimics allTags macro

{{{<<groupBy server.bag>>}}}
groups by the server.bag field (this version contains TiddlySpace specific code for turning a bag into a space name)

{{{groupBy modified dateFormat:"YYYY"}}}
group tiddlers by year.

{{{<<groupBy tags exclude:excludeLists exclude:systemConfig>>}}}
group tiddlers by tag but exclude the tags with values excludeLists and systemConfig

Within that group you can also exclude things by filter
{{{groupBy modifier filter:[tag[film]]}}}
will group tiddlers tagged with film by modifier.
***/
//{{{
(function($) {
var taglocale = config.views.wikified.tag;
var macro = config.macros.groupBy = {
	locale: {
		tooltip: "all tiddlers in group %0",
		noTiddlers: "no tiddlers",
		openAllText: taglocale.openAllText,
		openAllTooltip: taglocale.openAllTooltip,
		openTiddler: "open tiddler with title %0"
	},
	morpher: {
		// TODO: note currently the following 2 morphers are TiddlySpace specific and probably should be in separate plugin
		"server.workspace": function(value, options) {
			return macro.morpher["server.bag"](value.replace("bags/", "").replace("recipes/", ""));
		},
		"server.bag": function(value, options) {
			if(typeof(value) !== "string") {
				return false;
			} else if(value.indexOf("_public") === -1 && value.indexOf("_private") === -1) {
				value = "*%0".format(value); // add star for non-space bags.
			}
			return value.replace("_public", "").replace("_private", "");
		},
		created: function(value, options) {
			return value.formatString(options.dateFormat || "DD MMM YYYY");
		},
		modified: function(value, options) {
			return macro.morpher.created(value, options);
		}
	},

	handler: function(place, macroName, params, wikifier, paramString) {
		var field = params[0] || "server.workspace";
		var dateFormat = params[1] || "DD MMM YYYY";
		var container = $("<div />").attr("macroName", macroName).addClass("groupBy").
			attr("refresh", "macro").attr("fieldName", field).
			attr("paramString", paramString).
			attr("dateFormat", dateFormat).appendTo(place)[0];
		macro.refresh(container);
	},
	isTypeArray: function(value) {
		var valueType = typeof value;
		if(valueType === "object" && typeof value.length === "number" &&
			!(value.propertyIsEnumerable("length")) &&
			typeof value.splice === "function") { //is Array
			return true;
		} else {
			return false;
		}
	},
	_onClickGroup: function(ev, options) {
		var i, target = ev.target, locale = macro.locale;
		var tiddlers = $(target).closest(".templateContainer").data("tiddlers");
		var popup = $(Popup.create(target)).addClass("taggedTiddlerList")[0];
		var value = $(target).attr("value");
		var openAll = createTiddlyButton($("<li />").appendTo(popup)[0],
			locale.openAllText.format(value), locale.openAllTooltip);
		$(openAll).click(function(ev) {
			story.displayTiddlers(ev.target, tiddlers);
			return false;
		});
		var listBreak = $("<li />").addClass("listBreak").html("<div />").appendTo(popup);
		for(i = 0; i < tiddlers.length; i++) {
			var item = $("<li />").appendTo(popup)[0];
			var template = store.getTiddlerText(options.template) || macro.template;
			wikify(template, item, null, tiddlers[i]);
		}
		listBreak.clone().appendTo(popup);
		$(createTiddlyLink($("<li />").appendTo(popup)[0], value, false)).
			text(locale.openTiddler.format(value));
		Popup.show();
		ev.stopPropagation();
		return false;
	},
	_refresh: function(container, tiddlers, options) {
		var totalGroups = 0, locale = macro.locale, i, j;
		var excludeValues = options.exclude;
		var values = {}, value_ids = [];
		var field = options.field;
		var morpher = macro.morpher[field] || function(value) {
			return value;
		};
		for(i = 0; i < tiddlers.length; i++) {
			var tiddler = tiddlers[i];
			var value = tiddler[field] || tiddler.fields[field];
			value = macro.isTypeArray(value) ? value : [ value ];
			for(j = 0; j < value.length; j++) {
				var v = morpher(value[j], options);
				if(v && $.inArray(v, excludeValues) === -1) {
					totalGroups += 1;
					if(!values[v]) {
						values[v] = [];
					}
					values[v].push(tiddler);
					value_ids.pushUnique(v);
				}
			}
		}
		var ul = $("<ul />").appendTo(container)[0];
		if(totalGroups === 0) {
			$("<li />").addClass("listTitle").text(locale.noTiddlers);
		}
		value_ids = value_ids.sort();
		var groupTemplate = store.getTiddlerText(options.groupTemplate);
		var onClick = function(ev) {
			macro._onClickGroup(ev, options);
		};
		for(i = 0; i < value_ids.length; i++) {
			var title = value_ids[i];
			var info = getTiddlyLinkInfo(title);
			tiddlers = values[title];
			var btn = createTiddlyButton($("<li />").appendTo(ul)[0],
				"%0 (%1)".format(title, tiddlers.length), locale.tooltip.format(title), null, info.classes);
			if(groupTemplate) {
				$(btn).empty();
				wikify(groupTemplate, btn, null, tiddlers[0]);
			}
			$(btn).click(onClick).attr("value", title).attr("refresh", "link").attr("tiddlyLink", title);
			$(btn).addClass("templateContainer").data("tiddlers", tiddlers);
		}
	},
	refresh: function(container) {
		container = $(container).empty();
		var paramString = container.attr("paramString");
		var args = paramString.parseParams("name", null, true, false, true)[0];
		var options = { field: container.attr("fieldName"), dateFormat: container.attr("dateFormat"), exclude: args.exclude || [],
			template: args.template ? args.template[0] : false, groupTemplate: args.groupTemplate ? args.groupTemplate[0] : "" };
		var tiddlers = args.filter ? store.filterTiddlers(args.filter[0]) : store.getTiddlers("title");
		macro._refresh(container, tiddlers, options);
	},
	template: "<<view title link>>"
};

}(jQuery));
//}}}
/***
|''Name''|TiddlySpaceViewTypes|
|''Version''|0.6.0|
|''Status''|@@beta@@|
|''Description''|Provides TiddlySpace specific view types|
|''Author''|Jon Robson|
|''Source''|http://github.com/TiddlySpace/tiddlyspace/raw/master/src/plugins/TiddlySpaceViewTypes.js|
|''Requires''|TiddlySpaceConfig TiddlySpaceTiddlerIconsPlugin|
!Usage
Provides replyLink, spaceLink and SiteIcon view types.
!!SiteIcon view parameters
* labelPrefix / labelSuffix : prefix or suffix the label with additional text. eg. labelPrefix:'modified by '
* spaceLink: if set to "yes" will make any avatars link to the corresponding space. {{{<<originMacro spaceLink:yes>>}}}

!Code
***/
//{{{
(function($) {

var tiddlyspace = config.extensions.tiddlyspace;
var originMacro = config.macros.tiddlerOrigin;
var tweb = config.extensions.tiddlyweb;

config.macros.view.replyLink = {
	locale: {
		label: "Reply to this tiddler"
	}
};

var _replyButtons = [];
var _replyInitialised, _replyScriptLoaded;
config.macros.view.views.replyLink = function(value, place, params, wikifier,
		paramString, tiddler) {
	var valueField = params[0];
	var imported;
	if(valueField == "title") { // special casing for imported tiddlers
		var localTitle = tiddler.title;
		var serverTitle = tiddler.fields["server.title"];
		if(serverTitle && localTitle != serverTitle) {
			value = serverTitle ? serverTitle : localTitle;
			imported = true;
		}
	} else {
		title = tiddler[valueField] ? tiddler[valueField] : tiddler.fields[valueField];
	}
	var args = paramString.parseParams("anon")[0];
	var label = (args.label) ? args.label : config.macros.view.replyLink.locale.label;
	var space;
	if(tiddler) {
		var bag = tiddler.fields["server.bag"];
		space = tiddlyspace.resolveSpaceName(bag);
	}
	var container = $('<span class="replyLink" />').appendTo(place)[0];

	tweb.getUserInfo(function(user) {
		if ((!user.anon) && ((space && user.name != space &&
				user.name != tiddlyspace.currentSpace.name) || imported)) {
			var link = $("<a />")
				.text(config.macros.view.replyLink.locale.label)
				.appendTo(container)[0];

			if(typeof(createReplyButton) === "undefined") {
				_replyButtons.push(link);
			}
			if(_replyInitialised) {
				createReplyButton(link);
			} else if(!_replyScriptLoaded) {
				_replyScriptLoaded = true;
				$.getScript("/bags/common/tiddlers/_reply-button.js",
					function() {
						_replyInitialised = true;
						for(var i = 0; i < _replyButtons.length; i++) {
							createReplyButton(_replyButtons[i]);
						}
						_replyButtons = [];
					});
			}
		}
	});

};

config.macros.view.views.spaceLink = function(value, place, params, wikifier,
		paramString, tiddler) {
		var spaceName = tiddlyspace.resolveSpaceName(value);
		var isBag = params[0] == "server.bag" && value === spaceName ? true : false;
		var args = paramString.parseParams("anon")[0];
		var titleField = args.anon[2];
		var labelField = args.labelField ? args.labelField[0] : false;
		var label;
		if(labelField) {
			label = tiddler[labelField] ? tiddler[labelField] : tiddler.fields[labelField];
		} else {
			label = args.label ? args.label[0] : false;
		}
		var title = tiddler[titleField] ? tiddler[titleField] : tiddler.fields[titleField];

		var link = createSpaceLink(place, spaceName, title, label, isBag);
		if(args.external && args.external[0] == "no") {
			$(link).click(function(ev) {
				var el = $(ev.target);
				var title = el.attr("tiddler");
				var bag = el.attr("bag");
				var space = el.attr("tiddlyspace");
				bag = space ? space + "_public" : bag;
				if(title && bag) {
					ev.preventDefault();
					tiddlyspace.displayServerTiddler(el[0], title,
						"bags/" + bag);
				}
				return false;
			});
		}
};

config.macros.view.views.SiteIcon = function(value, place, params, wikifier,
		paramString, tiddler) {
	var options = originMacro.getOptions(paramString);
	if(!tiddler || value == "None") { // some core tiddlers lack modifier
		value = false;
	}
	var field = params[0];
	if(field == "server.bag") {
		options.notSpace = !originMacro._isSpace(value);
	}
	tiddlyspace.renderAvatar(place, value, options);
};

})(jQuery);
//}}}
/***
|''Name''|DiffFormatter|
|''Description''|highlighting of text comparisons|
|''Author''|FND|
|''Version''|0.9.0|
|''Status''|beta|
|''Source''|http://svn.tiddlywiki.org/Trunk/contributors/FND/formatters/DiffFormatter.js|
|''CodeRepository''|http://svn.tiddlywiki.org/Trunk/contributors/FND/|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''Keywords''|formatting|
!Description
Highlights changes in a unified [[diff|http://en.wikipedia.org/wiki/Diff#Unified_format]].
!Notes
Based on Martin Budden's [[DiffFormatterPlugin|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/formatters/DiffFormatterPlugin.js]].
!Usage
The formatter is applied to blocks wrapped in <html><code>{{{diff{..}}}</code></html> within tiddlers tagged with "diff".
!Revision History
!!v0.9 (2010-04-07)
* initial release; fork of DiffFormatterPlugin
!StyleSheet
.diff { white-space: pre; font-family: monospace; }
.diff ins, .diff del { display: block; text-decoration: none; }
.diff ins { background-color: #dfd; }
.diff del { background-color: #fdd; }
.diff .highlight { background-color: [[ColorPalette::SecondaryPale]]; }
!Code
***/
//{{{
(function() {

config.shadowTiddlers.StyleSheetDiffFormatter = store.getTiddlerText(tiddler.title + "##StyleSheet");
store.addNotification("StyleSheetDiffFormatter", refreshStyles);

var formatters = [{
		name: "diffWrapper",
		match: "^\\{\\{diff\\{\n", // XXX: suboptimal
		termRegExp: /(.*\}\}\})$/mg,
		handler: function(w) {
			var el = createTiddlyElement(w.output, "div", null, "diff");
			w.subWikifyTerm(el, this.termRegExp);
		}
	}, {
		name: "diffRange",
		match: "^(?:@@|[+\\-]{3}) ",
		lookaheadRegExp: /^(?:@@|[+\-]{3}) .*\n/mg,
		handler: function(w) {
			createTiddlyElement(w.output, "div", null, "highlight").
				innerHTML = "&#8230;";
			this.lookaheadRegExp.lastIndex = w.matchStart;
			var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
			if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
				w.nextMatch = this.lookaheadRegExp.lastIndex;
			}
		}
	}, {
		name: "diffAdded",
		match: "^\\+",
		termRegExp: /(\n)/mg,
		handler: function(w) {
			var el = createTiddlyElement(w.output, "ins", null, "added");
			w.subWikifyTerm(el, this.termRegExp);
		}
	}, {
		name: "diffRemoved",
		match: "^-",
		termRegExp: /(\n)/mg,
		handler: function(w) {
			var el = createTiddlyElement(w.output, "del", null, "removed");
			w.subWikifyTerm(el, this.termRegExp);
		}
	}
];

config.parsers.diffFormatter = new Formatter(formatters);
config.parsers.diffFormatter.format = "diff";
config.parsers.diffFormatter.formatTag = "diff";

})();
//}}}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink" version="1.1" viewBox="364 157 64 51" width="30" height="30"><g stroke="none" stroke-opacity="1" stroke-dasharray="none" fill="none" fill-opacity="1"><g><path class="glyph" d="M 364.50006 184.50061 L 386.99985 207.00037 L 396 198.00002 L 373.50003 175.50066 Z M 403.02295 181.97704 C 400.38693 179.34099 396.11307 179.34099 393.47702 181.97704 C 390.841 184.61307 390.841 188.88695 393.47702 191.52298 C 396.11307 194.15903 400.38693 194.15903 403.02295 191.52298 C 405.65906 188.88695 405.65906 184.61307 403.02295 181.97704 M 414.27298 170.72704 C 411.63693 168.091 407.36307 168.091 404.72702 170.72704 C 402.091 173.36308 402.091 177.63693 404.72702 180.27296 C 407.36307 182.90901 411.63693 182.90901 414.27298 180.27296 C 416.90903 177.63693 416.90903 173.36308 414.27298 170.72704 M 425.523 159.47705 C 422.88696 156.841 418.6131 156.841 415.97705 159.47705 C 413.341 162.11308 413.341 166.38695 415.97705 169.02295 C 418.6131 171.65903 422.88696 171.65903 425.523 169.02295 C 428.15906 166.38695 428.15906 162.11308 425.523 159.47705" fill="#020202"/></g></g></svg>
/***
|''Name''|TiddlySpaceCloneCommand|
|''Version''|0.5.8|
|''Description''|provides a toolbar command for cloning external tiddlers|
|''Status''|stable|
|''Source''|http://github.com/TiddlySpace/tiddlyspace/raw/master/src/plugins/TiddlySpaceCloneCommand.js|
|''Requires''|TiddlySpaceConfig TiddlySpaceFilters|
!Code
***/
//{{{
(function($) {

var cmd = config.commands;
var tiddlyspace = config.extensions.tiddlyspace;

var fieldsCache = {};

cmd.cloneTiddler = {
	text: cmd.editTiddler.text,
	tooltip: "Create a copy of this tiddler in the current space",
	errorMsg: "Error publishing %0: %1",

	isEnabled: function(tiddler) {
		return !config.filterHelpers.is.local(tiddler) && !readOnly;
	},
	handler: function(ev, src, title) {
		var tiddler = store.getTiddler(title);
		if(tiddler) {
			fieldsCache[title] = $.extend({}, tiddler.fields);
			tiddler.fields["server.workspace"] = tiddlyspace.getCurrentWorkspace(config.options.chkPrivateMode ?
		"private" : "public");
			tiddler.fields["server.permissions"] = "read, write, create"; // no delete
			delete tiddler.fields["server.page.revision"];
			delete tiddler.fields["server.title"];
			delete tiddler.fields["server.etag"];
			// special handling for pseudo-shadow tiddlers
			if(tiddlyspace.coreBags.contains(tiddler.fields["server.bag"])) {
				tiddler.tags.remove("excludeLists");
			}
		} else { // ensure workspace is the current space
			var el = story.findContainingTiddler(src);
			el = $(el);
			var fields = el.attr("tiddlyfields");
			if(fields) { // inherited via TiddlyLink
				fields = fields.decodeHashMap();
				fields["server.workspace"] = config.
					defaultCustomFields["server.workspace"];
			} else {
				fields = config.defaultCustomFields;
			}
			fields = String.encodeHashMap(fields);
			el.attr("tiddlyfields", fields);
		}
		cmd.editTiddler.handler.apply(this, arguments);
		if(tiddler) {
			tiddler.fields["server.permissions"] += ", delete";
		}
		return false;
	}
};

cmd.editTiddler.isEnabled = function(tiddler) {
	return !cmd.cloneTiddler.isEnabled.apply(this, arguments);
};

// hijack cancelTiddler to restore original fields
var _cancelHandler = cmd.cancelTiddler.handler;
cmd.cancelTiddler.handler = function(ev, src, title) {
	var tiddler = store.getTiddler(title);
	if(tiddler) {
		tiddler.fields = fieldsCache[title] || tiddler.fields;
		delete fieldsCache[title];
	}
	return _cancelHandler.apply(this, arguments);
};

// hijack saveTiddler to clear unused fields stash
var _saveHandler = cmd.saveTiddler.handler;
cmd.saveTiddler.handler =  function(ev, src, title) {
	delete fieldsCache[title];
	return _saveHandler.apply(this, arguments);
};

})(jQuery);
//}}}
!!!!Definitions
{{{
\def\epsilon{\varepsilon}
\def\infinity{\infty}
\def\continuum{\gothic{c}}
}}}

!!!!Notes
The standard $\LaTeX$ {{{\epsilon}}} symbol can be access by {{{\LaTeXepsilon}}}.

!!!!Examples
{{{
\epsilon
\infinity
\continuum
}}}
\[
\epsilon\qquad
\infinity\qquad
\continuum
\]
----

!!!!Definitions
{{{
\def\naturals{\blackBoard{N}}
\def\integers{\blackBoard{Z}}
\def\rationals{\blackBoard{Q}}
\def\reals{\blackBoard{R}}
\def\complexNumbers{\blackBoard{C}}
}}}

!!!!Examples
{{{
\naturals
\integers
\rationals
\reals
\complexNumbers
}}}
\[
\naturals\qquad
\integers\qquad
\rationals\qquad
\reals\qquad
\complexNumbers
\]
----

!!!!Definitions
{{{
\def\half{\frac{1}{2}}
\def\third{\frac{1}{3}}
\def\quarter{\frac{1}{4}}
}}}

!!!!Examples
{{{
\half
\third
\quarter
}}}
\[
\half\qquad
\third\qquad
\quarter
\]
----

<<tabs txtMainTab "Timeline" "Timeline" TabTimeline "All" "All tiddlers" TabAll "Tags" "All tags" TabTags "More" "More lists" TabMore>>