<!--{{{-->
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml' />
<!--}}}-->
Background: #fff
Foreground: #000
PrimaryPale: #8cf
PrimaryLight: #18f
PrimaryMid: #04b
PrimaryDark: #014
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
/*{{{*/
body {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}

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

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

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

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

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

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

.wizard {background:[[ColorPalette::PrimaryPale]]; border:1px solid [[ColorPalette::PrimaryMid]];}
.wizard h1 {color:[[ColorPalette::PrimaryDark]]; border:none;}
.wizard h2 {color:[[ColorPalette::Foreground]]; border:none;}
.wizardStep {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];
	border:1px solid [[ColorPalette::PrimaryMid]];}
.wizardStep.wizardStepDone {background:[[ColorPalette::TertiaryLight]];}
.wizardFooter {background:[[ColorPalette::PrimaryPale]];}
.wizardFooter .status {background:[[ColorPalette::PrimaryDark]]; color:[[ColorPalette::Background]];}
.wizard .button {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryLight]]; border: 1px solid;
	border-color:[[ColorPalette::SecondaryPale]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryPale]];}
.wizard .button:hover {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Background]];}
.wizard .button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::Foreground]]; border: 1px solid;
	border-color:[[ColorPalette::PrimaryDark]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryDark]];}
	
.wizard .notChanged {background:transparent;}
.wizard .changedLocally {background:#80ff80;}
.wizard .changedServer {background:#8080ff;}
.wizard .changedBoth {background:#ff8080;}
.wizard .notFound {background:#ffff80;}
.wizard .putToServer {background:#ff80ff;}
.wizard .gotFromServer {background:#80ffff;}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

hr {height:1px;}

a {text-decoration:none;}

dt {font-weight:bold;}

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

.txtOptionInput {width:11em;}

#contentWrapper .chkOptionInput {border:0;}

.externalLink {text-decoration:underline;}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

----
Also see AdvancedOptions
<<importTiddlers>>
//{{{
config.options.txtTheme = "WritableTheme";
//}}}
/***
|''Name''|HTTPSavingPlugin|
|''Description''|<...>|
|''Author''|Zooko|
|''Contributors''|FND|
|''Version''|0.2.1|
|''Status''|@@experimental@@|
|''Source''|http://allmydata.org/trac/tiddly_on_tahoe|
|''CodeRepository''|http://allmydata.org/source/tiddly_on_tahoe/trunk/|
|''License''|GPLv2+ or TGPPLv1.0+|
|''Keywords''|<...>|
!Description
<...>
!Notes
This plugin is being developed for [[Tiddly on Tahoe|http://allmydata.org/trac/tiddly_on_tahoe]].
***/
/* The following comment is to let jslint know which variables are supposed to be global. */
/*global clearMessage, config, getPath, readOnly, saveChanges, saveTest, showBackstage, store, story, version, convertUriToUTF8, convertUnicodeToFileFormat, getLocalPath, loadRemoteFile, locateStoreArea, saveBackup, saveEmpty, saveFile, saveMain, saveRss, unescape, displayMessage, httpReq */
//{{{
if (!version.extensions.HTTPSavingPlugin) { //# ensure that the plugin is only installed once
	version.extensions.HTTPSavingPlugin = { installed: true };

	(function () { //# wrapper
		readOnly = false;
		config.options.chkHttpReadOnly = false;
		showBackstage = true;

		saveTest = function () {
			var s = document.getElementById("saveTest");
			/*if (s.hasChildNodes()) {
			  alert(config.messages.savedSnapshotError);
			  }*/
			s.appendChild(document.createTextNode("savetest"));
		};

		// Save this TiddlyWiki with the pending changes
		saveChanges = function (onlyIfDirty, tiddlers) {
			var originalPath, localCallback, result;
			if (onlyIfDirty && !store.isDirty()) {
				return;
			}
			clearMessage();
			// Get the URL of the document
			originalPath = getPath(document.location.toString());
			// Load the original file
			localCallback = function (status, context, original, url, xhr) {
				//log("loaded remote file from ", originalPath);
				/*log("got callback status ", status, "\n", context: ", context, "\n",
				  URL: ", url, "\n", XHR: ", xhr);*/
				if (original === null) {
					alert(config.messages.cantSaveError);
					if (store.tiddlerExists(config.messages.saveInstructions)) {
						story.displayTiddler(null, config.messages.saveInstructions);
					}
					return;
				}
				// Locate the storeArea div's
				var posDiv = locateStoreArea(original);
				if (!posDiv) {
					alert(config.messages.invalidFileError.format([originalPath]));
					return;
				}
				saveRss(originalPath);
				saveEmpty(originalPath, original, posDiv);
				saveMain(originalPath, original, posDiv);
			};
			result = loadRemoteFile(originalPath, localCallback);
			//log("result from loadRemoteFile: ", result);
			return true;
		};

		// override and disable saveBackup()
		saveBackup = function (localPath, original) {};

		// override and disable getLocalPath()
		getLocalPath = function (origPath) {};

		// override getPath()
		getPath = function (origPath) {
			var originalPath, argPos, hashPos, resultPath;
			originalPath = convertUriToUTF8(origPath, config.options.txtFileSystemCharSet);
			// Remove any location or query part of the URL
			argPos = originalPath.indexOf("?");
			if (argPos !== -1) {
				originalPath = originalPath.substr(0, argPos);
			}
			hashPos = originalPath.indexOf("#");
			if (hashPos !== -1) {
				originalPath = originalPath.substr(0, hashPos);
			}
			// Convert file://localhost/ to file:///
			if (originalPath.indexOf("file://localhost/") === 0) {
				originalPath = "file://" + originalPath.substr(16);
			}
			// Convert to a native file format
			if (originalPath.indexOf("http://") === 0) { // HTTP file
				resultPath = originalPath;
			} else if (originalPath.charAt(9) === ":") { // PC local file
				resultPath = unescape(originalPath.substr(8)).replace(new RegExp("/", "g"), "\\");
			} else if (originalPath.indexOf("file://///") === 0) { // Firefox PC network file
				resultPath = "\\\\" + unescape(originalPath.substr(10)).replace(new RegExp("/", "g"), "\\");
			} else if (originalPath.indexOf("file:///") === 0) { // *nix local file
				resultPath = unescape(originalPath.substr(7));
			} else if (originalPath.indexOf("file:/") === 0) { // *nix local file
				resultPath = unescape(originalPath.substr(5));
			} else { // PC local file
				resultPath = "\\\\" + unescape(originalPath.substr(7)).replace(new RegExp("/", "g"), "\\");
			}
			return resultPath;
		};

		// override saveFile()
		saveFile = function (fileUrl, content, callb) {
			displayMessage("saving... please wait"); // XXX: belongs into command handler -- TODO: i18n
			//alert("whee! about to save to " + fileUrl);
			var localCallback = function (status, params, responseText, url, xhr) {
				if (!status) {
					displayMessage("saving failed: " + responseText);
				}
			};
			return httpReq("PUT", fileUrl, localCallback, null, null, content, "text/html;charset=utf-8");
		};

		// override convertUnicodeToFileFormat()
		convertUnicodeToFileFormat = function (s)
		{
			return s;
		};

	})(); //# end of wrapper
} //# end of "install only once"
//}}}
<!--{{{-->
<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
<div class='headerShadow'>
<div id='accessControlExplanationDivId' macro='accessControlExplanation'></div>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
<div class='headerForeground'>
<div id='accessControlExplanationDivId' macro='accessControlExplanation'></div>
<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>
<!--}}}-->
/***
|''Name''|HTTPSavingPlugin|
|''Description''|<...>|
|''Author''|Zooko|
|''Contributors''|FND|
|''Version''|0.2.1|
|''Status''|@@experimental@@|
|''Source''|http://allmydata.org/trac/tiddly_on_tahoe|
|''CodeRepository''|http://allmydata.org/source/tiddly_on_tahoe/trunk/|
|''License''|GPLv2+ or TGPPLv1.0+|
|''Keywords''|<...>|
!Description
<...>
!Notes
This plugin is being developed for [[Tiddly on Tahoe|http://allmydata.org/trac/tiddly_on_tahoe]].
***/
/* The following comment is to let jslint know which variables are supposed to be global. */
/*global clearMessage, config, getPath, readOnly, saveChanges, saveTest, showBackstage, store, story, version, convertUriToUTF8, convertUnicodeToFileFormat, getLocalPath, loadRemoteFile, locateStoreArea, saveBackup, saveEmpty, saveFile, saveMain, saveRss, unescape, displayMessage, httpReq */
//{{{
if (!version.extensions.HTTPSavingPlugin) { //# ensure that the plugin is only installed once
	version.extensions.HTTPSavingPlugin = { installed: true };

	(function () { //# wrapper
		readOnly = false;
		config.options.chkHttpReadOnly = false;
		showBackstage = true;

		saveTest = function () {
			var s = document.getElementById("saveTest");
			/*if (s.hasChildNodes()) {
			  alert(config.messages.savedSnapshotError);
			  }*/
			s.appendChild(document.createTextNode("savetest"));
		};

		// Save this TiddlyWiki with the pending changes
		saveChanges = function (onlyIfDirty, tiddlers) {
			var originalPath, localCallback, result;
			if (onlyIfDirty && !store.isDirty()) {
				return;
			}
			clearMessage();
			// Get the URL of the document
			originalPath = getPath(document.location.toString());
			// Load the original file
			localCallback = function (status, context, original, url, xhr) {
				//log("loaded remote file from ", originalPath);
				/*log("got callback status ", status, "\n", context: ", context, "\n",
				  URL: ", url, "\n", XHR: ", xhr);*/
				if (original === null) {
					alert(config.messages.cantSaveError);
					if (store.tiddlerExists(config.messages.saveInstructions)) {
						story.displayTiddler(null, config.messages.saveInstructions);
					}
					return;
				}
				// Locate the storeArea div's
				var posDiv = locateStoreArea(original);
				if (!posDiv) {
					alert(config.messages.invalidFileError.format([originalPath]));
					return;
				}
				saveRss(originalPath);
				saveEmpty(originalPath, original, posDiv);
				saveMain(originalPath, original, posDiv);
			};
			result = loadRemoteFile(originalPath, localCallback);
			//log("result from loadRemoteFile: ", result);
			return true;
		};

		// override and disable saveBackup()
		saveBackup = function (localPath, original) {};

		// override and disable getLocalPath()
		getLocalPath = function (origPath) {};

		// override getPath()
		getPath = function (origPath) {
			var originalPath, argPos, hashPos, resultPath;
			originalPath = convertUriToUTF8(origPath, config.options.txtFileSystemCharSet);
			// Remove any location or query part of the URL
			argPos = originalPath.indexOf("?");
			if (argPos !== -1) {
				originalPath = originalPath.substr(0, argPos);
			}
			hashPos = originalPath.indexOf("#");
			if (hashPos !== -1) {
				originalPath = originalPath.substr(0, hashPos);
			}
			// Convert file://localhost/ to file:///
			if (originalPath.indexOf("file://localhost/") === 0) {
				originalPath = "file://" + originalPath.substr(16);
			}
			// Convert to a native file format
			if (originalPath.indexOf("http://") === 0) { // HTTP file
				resultPath = originalPath;
			} else if (originalPath.charAt(9) === ":") { // PC local file
				resultPath = unescape(originalPath.substr(8)).replace(new RegExp("/", "g"), "\\");
			} else if (originalPath.indexOf("file://///") === 0) { // Firefox PC network file
				resultPath = "\\\\" + unescape(originalPath.substr(10)).replace(new RegExp("/", "g"), "\\");
			} else if (originalPath.indexOf("file:///") === 0) { // *nix local file
				resultPath = unescape(originalPath.substr(7));
			} else if (originalPath.indexOf("file:/") === 0) { // *nix local file
				resultPath = unescape(originalPath.substr(5));
			} else { // PC local file
				resultPath = "\\\\" + unescape(originalPath.substr(7)).replace(new RegExp("/", "g"), "\\");
			}
			return resultPath;
		};

		// override saveFile()
		saveFile = function (fileUrl, content, callb) {
			displayMessage("saving... please wait"); // XXX: belongs into command handler -- TODO: i18n
			//alert("whee! about to save to " + fileUrl);
			var localCallback = function (status, params, responseText, url, xhr) {
				if (!status) {
					displayMessage("saving failed: " + responseText);
				}
			};
			return httpReq("PUT", fileUrl, localCallback, null, null, content, "text/html;charset=utf-8");
		};

		// override convertUnicodeToFileFormat()
		convertUnicodeToFileFormat = function (s)
		{
			return s;
		};

	})(); //# end of wrapper
} //# end of "install only once"
//}}}
/***
|''Name''|TahoePlugin|
|''Description''|<...>|
|''Author''|Zooko|
|''Contributors''|FND, EricShulman|
|''Version''|0.2.0|
|''Requires''|HTTPSavingPlugin| 
|''Status''|@@experimental@@|
|''Source''|http://allmydata.org/trac/tiddly_on_tahoe|
|''CodeRepository''|http://allmydata.org/source/tiddly_on_tahoe/trunk/|
|''License''|GPLv2+ or TGPPLv1.0+|
|''Keywords''|<...>|
!Description
<...>
!Notes
This plugin is being developed for [[Tiddly on Tahoe|http://allmydata.org/trac/tiddly_on_tahoe]].
***/
//{{{
/* The following comment is to let jslint know which variables are supposed to be global. */
/*global version, readOnly, showBackstage, config, loadRemoteFile, wikify */
if (!version.extensions.TahoePlugin) { //# ensure that the plugin is only installed once
	version.extensions.TahoePlugin = { installed: true };

	(function () { //# wrapper
		var BASE32CHAR, BASE32CHAR_3bits, BASE32CHAR_1bits, SEP, NUMBER, HTTPLEAD, BASE32STR_128bits, BASE32STR_256bits, ALPHANUMERIC_STRING, TAHOE_FUTURE_IMMUTABLE_CAP_RE_STR, TAHOE_FUTURE_READONLY_CAP_RE_STR, TAHOE_FUTURE_WRITABLE_CAP_RE_STR, TAHOE_IMMUTABLE_CAP_RE_STR, TAHOE_READONLY_FILE_CAP_RE_STR, TAHOE_READONLY_DIR_CAP_RE_STR, TAHOE_WRITABLE_FILE_CAP_RE_STR, TAHOE_WRITABLE_DIR_CAP_RE_STR, TAHOE_NONWRITABLE_THING_CAP_RE_STR, TAHOE_WRITABLE_THING_CAP_RE_STR, TAHOE_ANY_CAP_RE_STR, splitTahoeURL, scrapeOutReadonlyCap, diminishToReadonlyCap, getReadonlyURLToThisPage;

		BASE32CHAR = '[abcdefghijklmnopqrstuvwxyz234567]';
		BASE32CHAR_3bits = '[aqiyemu4]';
		BASE32CHAR_1bits = '[aq]';
		SEP = '(?::|%3A)';
		NUMBER = '[0-9]+';
		HTTPLEAD = 'https?://(?:[^:/]+)(?::' + NUMBER + ')?/(uri|file|cap)/?';

		BASE32STR_128bits = '(' + BASE32CHAR + '{25}' + BASE32CHAR_3bits + ')';
		BASE32STR_256bits = '(' + BASE32CHAR + '{51}' + BASE32CHAR_1bits + ')';

		ALPHANUMERIC_STRING = '[A-Za-z0-9]+';

		// This is speculative: maybe in the future there will be a version of Tahoe where caps 
		// start with these symbols, and if so then this JavaScript code will magically work with 
		// that version of Tahoe.
		TAHOE_FUTURE_IMMUTABLE_CAP_RE_STR = "i_" + ALPHANUMERIC_STRING;
		TAHOE_FUTURE_READONLY_CAP_RE_STR = "r_" + ALPHANUMERIC_STRING;
		TAHOE_FUTURE_WRITABLE_CAP_RE_STR = "W_" + ALPHANUMERIC_STRING;

		TAHOE_IMMUTABLE_CAP_RE_STR = "(?:URI" + SEP + "CHK" + SEP + BASE32STR_128bits + SEP + BASE32STR_256bits + SEP + NUMBER + SEP + NUMBER + SEP + NUMBER + '|' + TAHOE_FUTURE_IMMUTABLE_CAP_RE_STR + ')';
		TAHOE_READONLY_FILE_CAP_RE_STR = "URI" + SEP + "SSK-RO" + SEP + BASE32STR_128bits + SEP + BASE32STR_256bits;
		TAHOE_READONLY_DIR_CAP_RE_STR = "URI" + SEP + "DIR2-RO" + SEP + BASE32STR_128bits + SEP + BASE32STR_256bits;
		TAHOE_WRITABLE_FILE_CAP_RE_STR = "URI" + SEP + "SSK" + SEP + BASE32STR_128bits + SEP + BASE32STR_256bits;
		TAHOE_WRITABLE_DIR_CAP_RE_STR = "URI" + SEP + "DIR2" + SEP + BASE32STR_128bits + SEP + BASE32STR_256bits;

		TAHOE_NONWRITABLE_THING_CAP_RE_STR = '(' + TAHOE_READONLY_FILE_CAP_RE_STR + '|' + TAHOE_READONLY_DIR_CAP_RE_STR + '|' + TAHOE_IMMUTABLE_CAP_RE_STR + '|' + TAHOE_FUTURE_IMMUTABLE_CAP_RE_STR + '|' + TAHOE_FUTURE_READONLY_CAP_RE_STR + ')';
		TAHOE_WRITABLE_THING_CAP_RE_STR = '(' + TAHOE_WRITABLE_DIR_CAP_RE_STR + '|' + TAHOE_WRITABLE_FILE_CAP_RE_STR + '|' + TAHOE_FUTURE_WRITABLE_CAP_RE_STR + ')';

		TAHOE_ANY_CAP_RE_STR = '(' + TAHOE_NONWRITABLE_THING_CAP_RE_STR + '|' + TAHOE_WRITABLE_THING_CAP_RE_STR + ')';

		readOnly = document.location.toString().match(new RegExp(HTTPLEAD + TAHOE_NONWRITABLE_THING_CAP_RE_STR));
		showBackstage = !readOnly;
		config.options.chkHttpReadOnly = false;
		
		/* Returns server (which is "http://$HOST:$PORT/uri"), cap, and suffix, which can be a 
		   path from the cap through the tahoe filesystem and/or trailing extra arguments. */
		splitTahoeURL = function (someURL) {
			var u, urlSuffix, candidate_cap, urlPrefix;

			u = someURL.split('/');
			urlSuffix = [];
			candidate_cap = u.pop();
			urlPrefix = u.join('/');
			while ((u.length > 0) && (!urlPrefix.match(new RegExp("^" + HTTPLEAD + "$")))) {
				urlSuffix.unshift(candidate_cap);
				candidate_cap = u.pop();
				urlPrefix = u.join('/');
			}
			// Okay we've found the HTTPLEAD.  Is the following thing shaped like a Tahoe capability?
			if (candidate_cap.match(new RegExp(TAHOE_ANY_CAP_RE_STR))) {
				// Yes!
				return {'urlPrefix': urlPrefix, 'cap': candidate_cap, 'urlSuffix': urlSuffix};
			} else {
				// No!
				return;
			}
		};

		scrapeOutReadonlyCap = function (metadata) {
			// example of tahoe-lafs json-encoded metadata:
			// [
			// "dirnode", 
			// {
			//  "rw_uri": "URI:DIR2:ouojn4oj2fa7fphdf54hz5bfaq:rf56nzb6klj3ctvssqghy2ugalp6wundystbysxujodttrhxbqwa", 
			//  "ro_uri": "URI:DIR2-RO:sznrgoyz7lbjorhe4ipzcnmluy:rf56nzb6klj3ctvssqghy2ugalp6wundystbysxujodttrhxbqwa", 
			//  "children": {
			//   "tw_empty.html": [
			//    "filenode", 
			//    {
			//     "mutable": false, 
			//     "metadata": {
			//      "ctime": 1229263396.69, 
			//      "mtime": 1229263396.69
			//     }, 
			//     "ro_uri": "URI:CHK:cofm2lm3ywu4r4efeqwjzuzyeq:dfw7oi65smf7dhtcx6wvr4ouazswprhwkvc3uopqtmvn3e7cactq:3:10:295520", 
			//     "size": 295520
			//    }
			//   ]
			//  }, 
			//  "mutable": true
			// }
			//]

			// another example:
			// [
			//  "filenode", 
			//  {
			//   "rw_uri": "URI:SSK:ouojn4oj2fa7fphdf54hz5bfaq:rf56nzb6klj3ctvssqghy2ugalp6wundystbysxujodttrhxbqwa", 
			//   "mutable": true, 
			//   "ro_uri": "URI:SSK-RO:sznrgoyz7lbjorhe4ipzcnmluy:rf56nzb6klj3ctvssqghy2ugalp6wundystbysxujodttrhxbqwa", 
			//   "size": "?"
			//  }
			// ]
			var matchobj = metadata.match(new RegExp("^\\s*\\[[^\\[]*\"ro_uri\"\\s*:\\s*\"([^\"]*)\""));
			if (matchobj) {
				return matchobj[1];
			}
		};

		diminishToReadonlyCap = function (urlPrefix, writableCap, callback) {
			var queryURL = [urlPrefix, writableCap, "?t=json"].join("/");

			loadRemoteFile(queryURL, function (success, param, txt, src, xhr) {
				if (success) {
					callback(scrapeOutReadonlyCap(txt));
				}
			}); 
		};
    
		getReadonlyURLToThisPage = function (callback) {
			if (document.location.tahoeDiminishedCapabilityURL) {
				return callback(document.location.tahoeDiminishedCapabilityURL);
			} else {
				var pieces = splitTahoeURL(document.location.toString());
				diminishToReadonlyCap(pieces.urlPrefix, pieces.cap, function (diminishedCap) {
					var diminishedURL = pieces.urlPrefix + "/" + diminishedCap + "/" + pieces.urlSuffix;
					document.location.tahoeDiminishedCapabilityURL = diminishedURL;
					callback(diminishedURL);
				});
			}
		};

		config.macros.accessControlExplanation = {
	
			handler: function (place, macroName, params, wikifier, paramString, tiddler) {
				if (document.location.toString().match(new RegExp(HTTPLEAD + TAHOE_IMMUTABLE_CAP_RE_STR))) {
					wikify("This is an immutable view of this page.  Using this link will always give this exact same page, even if a newer version has been uploaded.", place);
				} else if (document.location.toString().match(new RegExp(HTTPLEAD + TAHOE_NONWRITABLE_THING_CAP_RE_STR))) {
					wikify("This is a read-only view of this page.  Using this link will give the most recent version of this page, but doesn't allow the user to change the page.", place);
				} else if (document.location.toString().match(new RegExp(HTTPLEAD + TAHOE_WRITABLE_THING_CAP_RE_STR))) {
					getReadonlyURLToThisPage(function (readonlyCap) {
						wikify("You are accessing this page with a writable link.  If you share this link with someone else, they will gain the ability to write to this page.  Click here for a [[read-only link to this page|" + readonlyCap + "]].", place);
					});
				} else {
					wikify("You are accessing this page not through the Tahoe-LAFS secure, distributed filesystem.", place);
				}
			}
		};
	})(); //# end of wrapper
} //# end of "install only once"
//}}}
|StyleSheet|##AuthorStyles|
|StyleSheetReadOnly|##ReaderStyles|

!AuthorStyles
/*{{{*/
[[StyleSheet]]
body {
	background: #eee;
}
/*}}}*/

!ReaderStyles
/*{{{*/
[[StyleSheet]]
body {
}
/*}}}*/