<!--{{{-->
<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]];}
.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='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
<div class='headerShadow'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
<div class='headerForeground'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>
<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 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>>
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>>
/***
|''Name:''|UploadTiddlerPlugin|
|''Description:''|Upload a tiddler and Update a remote TiddlyWiki |
|''Version:''|1.2.2|
|''Date:''|2008-09-13|
|''Source:''|http://tiddlywiki.bidix.info/#UploadTiddlerPlugin|
|''Usage:''|Uses {{{<<uploadOptions>>}}}<br>with those UploadTiddler Options : <br>chkUploadTiddler: <<option chkUploadTiddler>><br>txtUploadTiddlerStoreUrl: <<option txtUploadTiddlerStoreUrl>><br>chkUploadTiddlerFromFile: <<option chkUploadTiddlerFromFile>>|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''[[License]]:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''CoreVersion:''|2.3.0|
***/
//{{{
version.extensions.UploadTiddlerPlugin = {
major: 1, minor: 2, revision: 2,
date: new Date("2008-09-13"),
source: 'http://tiddlywiki.bidix.info/#UploadTiddlerPlugin',
author: 'BidiX (BidiX (at) bidix (dot) info',
coreVersion: '2.3.0'
};
if (!window.bidix) window.bidix = {}; // bidix namespace
bidix.debugMode = false;
bidix.uploadTiddler = {
messages: {
aboutToSaveTiddler: "About to update tiddler '%0'...",
aboutToRemotelySaveTiddler: "About to REMOTELY update tiddler '%0'...",
storeTiddlerNotFound: "Script store tiddler '%0' not found",
tiddlerSaved: "Tiddler '%0' updated in '%1'"
},
upload: function(title,tiddler,oldTitle) {
var done = function(data, textStatus, jqXHR) {
var responseText = data.join("");
if ((bidix.debugMode) || (responseText.indexOf("Debug mode") >= 0 )) {
alert("2"+responseText);
if (responseText.indexOf("Debug mode") >= 0 )
responseText = responseText.substring(responseText.indexOf("\n\n")+2);
} else if (responseText.charAt(0) != '0')
alert("3"+responseText);
else {
var filename = (config.options['txtUploadFilename']?config.options['txtUploadFilename']:'index.html');
displayMessage(bidix.uploadTiddler.messages.tiddlerSaved.format([title, filename]));
}
store.setDirty(false);
};
var failed = function(jqXHR, textStatus) {
if(textStatus == 'timeout') {
alert(bidix.uploadTiddler.messages.storeTiddlerNotFound.format([storeScript]));
}
};
if ((config.options['chkUploadTiddler']) &&
((document.location.toString().substr(0,4) == "http") || config.options['chkUploadTiddlerFromFile'])) {
clearMessage();
if (document.location.toString().substr(0,4) != "http")
displayMessage(bidix.uploadTiddler.messages.aboutToRemotelySaveTiddler.format([title]));
else
displayMessage(bidix.uploadTiddler.messages.aboutToSaveTiddler.format([title]));
var ExtTiddler = null;
var html = null;
if (tiddler) {
ExtTiddler = store.getSaver().externalizeTiddler(store,tiddler);
html = wikifyStatic(tiddler.text,null,tiddler).htmlEncode();
}
var form = "title="+encodeURIComponent(title);
form = form + "&tiddler="+(ExtTiddler?encodeURIComponent(ExtTiddler):'');
form = form + "&html="+(html?encodeURIComponent(html):'');
var filename = (config.options['txtUploadFilename']?config.options['txtUploadFilename']:'index.html');
form = form +"&oldTitle="+encodeURIComponent(oldTitle);
form = form +"&fileName="+encodeURIComponent(filename);
form = form +"&backupDir="+encodeURIComponent(config.options['txtUploadBackupDir']);
form = form +"&user="+encodeURIComponent(config.options['txtUploadUserName']);
form = form +"&password="+encodeURIComponent(config.options['pasUploadPassword']);
form = form +"&uploadir="+encodeURIComponent(config.options['txtUploadDir']);
form = form +"&debug="+encodeURIComponent(0);
var storeScript = (config.options.txtUploadTiddlerStoreUrl
? config.options.txtUploadTiddlerStoreUrl : 'storeTiddler.php');
jQuery.ajax({
url: storeScript ,
dataType: 'jsonp',
data: form,
timeout: 15000,
success: done,
complete: failed,
username: config.options['txtUploadUserName'],
password: config.options['pasUploadPassword']
});
}
}
}
TiddlyWiki.prototype.saveTiddler_bidix = TiddlyWiki.prototype.saveTiddler;
TiddlyWiki.prototype.saveTiddler = function(oldTitle,newTitle,newBody,modifier,modified,tags,fields,clearChangeCount,created) {
var tiddler = TiddlyWiki.prototype.saveTiddler_bidix.apply(this,arguments);
var title = (newTitle?newTitle:oldTitle);
if (oldTitle == title)
oldTitle = '';
bidix.uploadTiddler.upload(title, tiddler, oldTitle);
}
TiddlyWiki.prototype.removeTiddler_bidix =TiddlyWiki.prototype.removeTiddler;
TiddlyWiki.prototype.removeTiddler = function(title) {
TiddlyWiki.prototype.removeTiddler_bidix.apply(this,arguments);
bidix.uploadTiddler.upload(title, null);
}
//
// Initializations
//
bidix.initOption = function(name,value) {
if (!config.options[name])
config.options[name] = value;
};
// styleSheet
setStylesheet('.txtUploadTiddlerStoreUrl {width: 22em;}',"uploadTiddlerPluginStyles");
//optionsDesc
merge(config.optionsDesc,{
txtUploadTiddlerStoreUrl: "Url of the UploadTiddlerService script (default: storeTiddler.php)",
chkUploadTiddler: "Do per Tiddler upload using txtUploadTiddlerStoreUrl (default: false)",
chkUploadTiddlerFromFile: "Upload tiddler even if TiddlyWiki is located on local file (default: false)"
});
// Options Initializations
bidix.initOption('txtUploadTiddlerStoreUrl','');
bidix.initOption('chkUploadTiddler','');
bidix.initOption('chkUploadTiddlerFromFile','');
// add options in backstage UploadOptions
if (config.macros.uploadOptions) {
if (config.macros.uploadOptions.options) {
config.macros.uploadOptions.options.push("txtUploadTiddlerStoreUrl","chkUploadTiddler", "chkUploadTiddlerFromFile");
}
}
//}}}
//{{{
<?php
/***
! User settings
Edit these lines according to your need
***/
//{{{
$AUTHENTICATE_USER = true; // true | false
$USERS = array(
'PauloSoares'=>'*****'); // set usernames and strong passwords
$DEBUG = false; // true | false
$CLEAN_BACKUP = true; // during backuping a file, remove overmuch backups
error_reporting(E_ERROR | E_WARNING | E_PARSE);
//}}}
/***
!Code
No change needed under
***/
//{{{
/***
* storeTiddler.php - upload a tiddler to a TiddlyWiki file in this directory
* version: 1.2.1 - 2008-05-06 - BidiX@BidiX.info
*
* tiddler is POST as <FORM> with :
* FORM =
* title=<the title of the tiddler>
* tiddler=<result of externalizeTiddler() : the div in StoreArea format>
* [oldTitle=<the previous title of the tiddler>]
* [fileName=<tiddlyWiki filename>] (default: index.html)
* [backupDir=<backupdir>] (default: .)
* [user=<user>] (no default)
* [password=<password>] (no default)
* [uploadir=<uploaddir>] (default: .)
* [debug=1]] (default: false)
* see :
* http://tiddlywiki.bidi.info/#UploadTiddlerPlugin for usage
* http://tiddlywiki.bidi.info/#UploadPlugin for parameter descriptions
* usage :
* POST FORM
* Update <tiddler> in <fileName> TiddlyWiki
* GET
* Display a form for
*
* Revision history
* V1.2.1 - 2008-05-06
* bug correction : Filename is always 'index.html'. The fileName variable isn't used to initialize tiddlyWiki filename.
* V1.2.0 - 2008-03-23
* Exclusive lock to serialize rewrite of file
* V1.1.0 - 2008/03/05
* Delete tiddler with oldTitle
* V1.0.0 - 2008/02/24
* First public Version
* V0.3.0 - 2008/02/23
* minor adjustments
* V0.2.0 - 2008/02/23
* Correction bug on large regex
* V0.1.0 - 2008/02/09
* Initial: First working version
* V0.0.1 - 2008/02/02
* Initial: Proof Of Concept
*
* Copyright (c) BidiX@BidiX.info 2005-2008
***/
//}}}
//{{{
/*
* GET Request
*/
/*
* Functions included from store.php
*/
$msg = array();
// Recursive mkdir
function mkdirs($dir) {
if( is_null($dir) || $dir === "" ){
return false;
}
if( is_dir($dir) || $dir === "/" ){
return true;
}
if( mkdirs(dirname($dir)) ){
return mkdir($dir);
}
return false;
}
function toExit() {
global $DEBUG, $filename, $backupFilename, $options, $msg;
if ($DEBUG) {
echo ("\nHere is some debugging info : \n");
echo("\$filename : $filename \n");
echo("\$backupFilename : $backupFilename \n");
print ("\$_FILES : \n");
print_r($_FILES);
print ("\$options : \n");
print_r($options);
}
echo $_GET['callback'] . '('.json_encode($msg).')';
exit;
}
function ParseTWFileDate($s) {
// parse date element
preg_match ( '/^(\d\d\d\d)(\d\d)(\d\d)\.(\d\d)(\d\d)(\d\d)/', $s , $m );
// make a date object
$d = mktime($m[4], $m[5], $m[6], $m[2], $m[3], $m[1]);
// get the week number
$w = date("W",$d);
return array(
'year' => $m[1],
'mon' => $m[2],
'mday' => $m[3],
'hours' => $m[4],
'minutes' => $m[5],
'seconds' => $m[6],
'week' => $w);
}
function cleanFiles($dirname, $prefix) {
$now = getdate();
$now['week'] = date("W");
$hours = Array();
$mday = Array();
$year = Array();
$toDelete = Array();
// need files recent first
$files = Array();
($dir = opendir($dirname)) || die ("can't open dir '$dirname'");
while (false !== ($file = readdir($dir))) {
if (preg_match("/^$prefix/", $file))
array_push($files, $file);
}
$files = array_reverse($files);
// decides for each file
foreach ($files as $file) {
$fileTime = ParseTWFileDate(substr($file,strpos($file, '.')+1,strrpos($file,'.') - strpos($file, '.') -1));
if (($now['year'] == $fileTime['year']) &&
($now['mon'] == $fileTime['mon']) &&
($now['mday'] == $fileTime['mday']) &&
($now['hours'] == $fileTime['hours']))
continue;
elseif (($now['year'] == $fileTime['year']) &&
($now['mon'] == $fileTime['mon']) &&
($now['mday'] == $fileTime['mday'])) {
if (isset($hours[$fileTime['hours']]))
array_push($toDelete, $file);
else
$hours[$fileTime['hours']] = true;
}
elseif (($now['year'] == $fileTime['year']) &&
($now['mon'] == $fileTime['mon'])) {
if (isset($mday[$fileTime['mday']]))
array_push($toDelete, $file);
else
$mday[$fileTime['mday']] = true;
}
else {
if (isset($year[$fileTime['year']][$fileTime['mon']]))
array_push($toDelete, $file);
else
$year[$fileTime['year']][$fileTime['mon']] = true;
}
}
return $toDelete;
}
/*
* End Functions included from store.php
*/
/*
* parse and print a TiddlyWiki file
*/
Function readTiddlyWiki($tw) {
if (preg_match ("/(.*?<div id=\"storeArea\">.*?)(<div.*)/ms", $tw,$matches)) {
$head = $matches[1];
$h = $matches[2];
$tiddlers = array();
while (preg_match ("/(.*?)(<div title=\"(.*?)\".*?<\/div>)(.*)/ms", $h,$matches)) {
$h=$matches[4];
$tiddlers[$matches[3]] = $matches[2];
}
$tail = ltrim($h);
}
else {
$msg[] = "The file '$file' isn't a valid TiddlyWiki";
toExit();
}
return array($head, $tiddlers ,$tail);
}
Function writeTiddlyWiki($head,$tiddlers,$tail) {
$content = $head;
sort($tiddlers);
foreach ($tiddlers as $t => $c) {
$content .= $c . "\n";
}
$content .= $tail;
return $content;
}
// var definitions
$uploadDir = './';
$uploadDirError = false;
$backupError = false;
$backupFilename = '';
$filename = "index.html";
$destfile = $filename;
$options = $_GET; // for store.php name compatibility
// debug activated by client
if ($options['debug'] == 1) {
$DEBUG = true;
}
// authenticate User
if (($AUTHENTICATE_USER)
&& ((!$options['user']) || (!$options['password']) || ($USERS[$options['user']] != $options['password']))) {
$msg[] = "Error: UserName or Password do not match \n";
$msg[] = "UserName: [".$options['user']. "] Password: [". $options['password'] . "]\n";
toExit();
}
if ($options['fileName'])
$filename = $options['fileName'];
// make uploadDir
if ($options['uploaddir']) {
$uploadDir = $options['uploaddir'];
// path control for uploadDir
if (!(strpos($uploadDir, "../") === false)) {
$msg[] = "Error: directory to upload specifies a parent folder";
toExit();
}
if (! is_dir($uploadDir)) {
mkdirs($uploadDir);
}
if (! is_dir($uploadDir)) {
$msg[] = "UploadDirError: $uploadDirError - File NOT uploaded !\n";
toExit();
}
if ($uploadDir{strlen($uploadDir)-1} != '/') {
$uploadDir = $uploadDir . '/';
}
}
$destfile = $uploadDir . $filename;
// backup existing file
if (file_exists($destfile) && ($options['backupDir'])) {
if (! is_dir($options['backupDir'])) {
mkdirs($options['backupDir']);
if (! is_dir($options['backupDir'])) {
$backupError = "backup mkdir error";
}
}
$backupFilename = $options['backupDir'].'/'.substr($filename, 0, strrpos($filename, '.'))
.date('.Ymd.His').substr($filename,strrpos($filename,'.'));
copy($destfile, $backupFilename) or ($backupError = "rename error");
// remove overmuch backup
if ($CLEAN_BACKUP) {
$toDelete = cleanFiles($options['backupDir'], substr($filename, 0, strrpos($filename, '.')));
foreach ($toDelete as $file) {
$f = $options['backupDir'].'/'.$file;
if($DEBUG) {
$msg[] = "Delete: ".$options['backupDir'].'/'.$file."\n";
}
unlink($options['backupDir'].'/'.$file);
}
}
}
if (file_exists($destfile)) {
$f = fopen($destfile,'r+');
if (flock($f, LOCK_EX)) {
while (!feof($f)) {
$contents .= fread($f, 8192);
}
list($head,$tiddlers,$tail) = readTiddlyWiki($contents);
$title = $_GET['title'];
$oldTitle = $_GET['oldTitle'];
if ($oldTitle && ($title != $oldTitle)) {
unset($tiddlers[$oldTitle]);
}
$tiddlers[$title] = stripslashes($_GET['tiddler']);
$contents = writeTiddlyWiki($head,$tiddlers,$tail);
if (!rewind($f)) {
$msg[] = "rewind error";
toExit();
}
if (!ftruncate($f, 0)) {
$msg[] = "ftruncate error";
toExit();
};
if (!fwrite($f, $contents)) {
$msg[] = "fwrite error";
toExit();
}
fclose($f); // fclose also unlock the file
if($DEBUG) {
echo "Debug mode \n\n";
}
if (!$backupError) {
$msg[] = "0 - Tiddler successfully updated in " .$destfile. "\n";
} else {
$msg[] = "BackupError: $backupError - Tiddler successfully updated in " .$destfile. "\n";
}
$msg[] = "destfile:$destfile \n";
if (($backupFilename) && (!$backupError)) {
$msg[] = "backupfile:$backupFilename\n";
}
$mtime = filemtime($destfile);
$msg[] = "mtime:$mtime";
}
else {
$msg[] = "Error: '" . $filename . "' couldn't be locked - File NOT updated !\n";
}
}
else {
$msg[] = "Error: '" . $filename . "' doesn't exist - File NOT updated !\n";
}
toExit();
?>
//}}}