<!--{{{-->
<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 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>>
Man oh man, how time flies. I was at QCon yesterday and wanted to write down some notes. I've come back to update this lil' wiki - still the best place to put up random thoughts, like what's up with [[Blender]] and who's your favorite [[Server]].. Time's flown again, as they say, and I must leave this page alone.
My favorite Linux distro. From the website:

//Arch is lightweight, flexible and simple. Its design philosophy and implementation make it easy to extend and mold into whatever kind of system you're building- from a minimalist console machine to the most grandiose and feature rich desktop environments available. Rather than tearing out unneeded and unwanted packages, Arch offers the power user the ability to build up from a minimal foundation without any defaults chosen for them. It is the user who decides what Arch Linux will be.//
http://www.archlinux.org

It's easy and fun to contribute to the [[Arch Linux Wiki|http://wiki.archlinux.org]], which is the center for discussion about the system. 

Current machines on which I have Arch installed:
* Sony Vaio VGN-FE48E - Core 2 Duo - NVidia 7400
* Shuttle XPC SB83G5 - Pentium 4 HT - ATI X800 XL
* Compaq desktop - Pentium 4
* Various VMs for Virtual PC and VMWare
This is free and open source modelling and rendering software, which in the right hands can be used to create more detailed, organic or otherwise interesting 3D visualisations or animations than professional programs costing 1'000s if not 10'000s of dollars. Visit this site for all the details (and check out the galleries):
http://www.blender.org/

I've used Blender on a number of still images and animations, and right now I've got a spare-time (hah) project to help a model of a real-world factory become interactive, thanks to Blender's easy to use [[Python]] based game engine.

[[Yo Frankie!|http://www.yofrankie.org/]] is the first production quality Blender game - hot off the press!
Background: #ACC4C1
Foreground: #000
PrimaryPale: #FFD4AE
PrimaryLight: #DAD992
PrimaryMid: #87593E
PrimaryDark: #4F3424
SecondaryPale: #E8B8AC
SecondaryLight: #D1A69B
SecondaryMid: #8B6F67
SecondaryDark: #5C4944
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
Confluence was a simple, practical web application that made it easy for teammates to collaborate and manage knowledge. These days it can still do that (and do it well), but it has grown much and learned plenty of new tricks. If you are planning to use it, try to keep it simple, keep it light. ([[Why?|WikiPatterns]])
http://www.atlassian.com/software/confluence

There are many remarkable things about Confluence and the people who have created and contributed to it. The only thing here for now is a bit of code that sits between two open source communities - the Confluence plugin ecosystem and TiddlyWiki - see [[Confluence TiddlyWiki plugin]].
It is plugin allows downloading a TiddlyWiki pre-filled with content from Atlassian [[Confluence]], a popular wiki system. 

A TiddlyWiki is a single, self-contained HTML file that contains data organised in linked sections called tiddlers, which in this case correspond to Confluence pages. It also has script to allow easy viewing, editing, and saving - all on the desktop, no network connection required. This makes TiddlyWiki useful for people who need to go on the road with their wikis, or simply for the comfort and assurance of having a private copy to work with.

http://code.google.com/p/confluence-tiddlywiki-plugin/
!! How does it work?
The TiddlyWiki is generated on the server and sent back to the browser as an HTML page. The wiki includes a plugin which allows the Confluence formatting to be preserved, even while you edit the pages locally on your computer. 

You can then sync the content back up to your server using the included ConfluenceAdaptorPlugin. This is still experimental, and I cannot vouch for the safety of any of your data - however, it is a Wiki, so you should always be able to Undo.
!! Notes
* users still need to rename tiddlywiki.action to .html
* currently there is no way to select certain pages for the export - only the whole space can be reliably downloaded. Try creating a special space for pages you want to move out to a TiddlyWiki as an alternative. Extending Confluence's space export function is possible, but as it is not a standard approach making it stable enough for the rest of us is too much work for now.
* TiddlyWiki can update itself - in case you're worried that you're downloading an outdated version of the code (you probably are!). Click on the ''backstage'' link at the top and use the ''upgrade'' feature.
This plugin by MartinBudden allows TiddlyWiki to connect to Confluence servers via XML-RPC to exchange Wiki content. It's helpful to have the [[ConfluenceFormatterPlugin]] so that tiddler contents can be made in standard Confluence syntax.

This system works well, and is actually more reliable than my Confluence plugin. It's also a closed loop where your work is preserved. For more information, visit Martin's site: http://www.martinswiki.com/

* Note: it seems to have disappeared at time of writing.
This plugin by MartinBudden allows TiddlyWiki to seamlessly work with Confluence formatting in the tiddler contents. It uses some custom JavaScript magic and works superbly well. 

Of course, Confluence being a system that generates lots of dynamic code (and thus requires very beefy servers to run), this plugin will only handle the main formatting and not all of the dynamic markup. However, your macros and markup will be preserved for when you put the content back into Confluence.

For more info, please visit Martin's site:
http://www.martinswiki.com/#ConfluenceFormatterPlugin
HelloWorld
''Wiki'' (n) - A collaborative site where users can edit content and have fun. 
----
Welcome to my web scrapbook. It's a Wiki! Isn't all of this [[wikciting]]? If you're still bored, how about [[a little game|jsTetris]], just for fun! (send a msg if you beat the high score of 288933).

Notes from [[BarCampApacheOxford are here|http://oleg.utou.ch/wiki/BarCampOxfordTW.html]].

Areas of interest should be floating about in the cloud .. Questions? Comments? Missing tiddlers? Get in u[[touch|http://oleg.utou.ch]] :)
----
<<cloud limit:60 systemConfig excludeMissing script>>
Question: to look, but not touch? How to keep objectivity and stay original while being aware of all the progress and changes? How to avoid duplicating the established paradigms, and instead provoke, challenge and build on them?
The process is simple. Start with a pencil sketch on a rough piece of paper, and go from there.

My Wacom tablet found an excellent companion in the flawless [[ArtRage 2|http://www.artrage.com]] program.

[[Balsamiq Mockups|http://www.balsamiq.com/products/mockups]] is another one to try.
There are all kinds of interfaces in the programming business, but I'm even more interested in opportunities to envision, design, or develop ''user interfaces''. There are so many ways we reach out and connect as information users, that this becomes a completely boundless field for expression and experiment.

Concerning techniques: jQuery (for the root of this site), pure JavaScript (that runs this TiddlyWiki), CSS (that styles and envelops both), Adobe Flash / Flex / Air (the established name in RIA), Microsoft SilverLight (the nascent challenger), WebStandards and WAP for every platform and every device.

InterfaceInspiration

InterfaceProcess

PastInterfaces
<!--{{{-->
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml' />
<meta http-equiv="cache-control" content="no-cache" />

<META HTTP-EQUIV="Pragma" CONTENT="no-cache" />
<META HTTP-EQUIV="Expires" CONTENT="-1" />
<!--}}}-->
Martin Budden is one of the code wizards who lives in Osmosoft towers, a very nice guy who helps people survive and thrive in their encounters with various fire-breathing serverside wikis. Pay a visit to his online wardrobe to get a TiddlyWiki adaptor and take charge of your magical pest. He can be reached through any of these portals:
http://martinswiki.com
http://twitter.com/buddenisms
This wiki home catalogues random stuff, like [[Interfaces]]. For more random stuff check out the Delicious feed on my [[index.html|http://oleg.utou.ch]]. Oh, and once this wiki gets over, say, a MB in size, I'll bundle it up for joy and move it into the attic to start anew.
Go find [[Oleg]].
/***
|''Name:''|PasswordOptionPlugin|
|''Description:''|Extends TiddlyWiki options with non encrypted password option.|
|''Version:''|1.0.2|
|''Date:''|Apr 19, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#PasswordOptionPlugin|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0 (Beta 5)|
***/
//{{{
version.extensions.PasswordOptionPlugin = {
	major: 1, minor: 0, revision: 2, 
	date: new Date("Apr 19, 2007"),
	source: 'http://tiddlywiki.bidix.info/#PasswordOptionPlugin',
	author: 'BidiX (BidiX (at) bidix (dot) info',
	license: '[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D]]',
	coreVersion: '2.2.0 (Beta 5)'
};

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

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

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

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

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

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

merge(config.optionsDesc,{
		pasPassword: "Test password"
	});
*/
//}}}
I've pulled them off the main page, but they can land in here soon.
Apparently, when pythons lay eggs they tend to put them into a pile. I don't think this interesting fact from animal behavior has any relevance to the programming language, athough laying eggs and putting them into neat piles could be one poetic way to describe the pragmatic programmer.

''Python is a dynamic object-oriented programming language that can be used for many kinds of software development. It offers strong support for integration with other languages and tools, comes with extensive standard libraries, and can be learned in a few days. Many Python programmers report substantial productivity gains and feel the language encourages the development of higher quality, more maintainable code.''
http://www.python.org/

At the moment I tweak interactive physics in Blender and make runnable build scripts with Python. It could be a [[great|http://pylonshq.com]] [[way|http://www.twistedmatrix.com/]] to [[write|http://www.djangoproject.com]] Web apps, but I haven't really found the right host yet. [[Lousy|http://www.goeldi.com]] [[excuse|http://www.webfaction.com/]], I know.
QCon is an annual international software development conference that takes place in London (spring) and San Francisco (autumn). Move along to QConLondon2009.
On Thursday I went down to the fab-80's style Queen Elizabeth II conference hall where QCon took up two floors with a couple of hundred attendees going back and forth between the two bar areas and the ''seven'' parallel tracks. The sessions were all very high quality, the excitement level was high, and in a single day I could get to know at least a dozen other people and catch up with a couple of friends. During some of the sessions I was busy scribbling down on my pad, and in others there was a very active Twitter channel (#qcon) where I posted some feedback and interacted with folks sitting around through this new form of IRC.
!! Sessions of interest:
* [[Transforming Software Architecture with Web as Platform]] by [[Dion Hinchcliffe]]
* [[The evolving Guardian.co.uk architecture]] with [[Matthew Wall]]
* [[Open Standards Development: Opportunity or Constraint]] with a panel including [[Stephen Colebourne]], [[Patrick Curran]], [[Paul Downey]] and [[Rod Johnson]]
* [[OSGi and Java Modularization]] interviewing [[Neil Bartlett]]
* [[Spring Today and Tomorrow]] with [[Rod Johnson]]
* [[Adobe Flash Platform and SpringSource]] with [[Christophe Coenraets]]
!! Other notes
* [[Twist and Mingle]] from ThoughtWorks Studios
If one is wondering exactly what the difference is between this and REST and anything else is, it's probably because of the fact that it's already 2 AM by the time you can start to get any.

Representational state transfer (REST) is a style of software architecture ... The World Wide Web is the key example of a RESTful design.

http://java.sun.com/developer/technicalArticles/WebServices/restful
If I have to run a server, I try to be sure it's as familar and stable as possible. ArchLinux has been a favorite for the past few years, but there's also SlaxLinux and UbuntuLinux which can be great in a pitch.
because the server-side //c'est passe“//
Oleg's wiki
One of Stewarts popular presentations on how to grow an enterprise wiki is floating on YouTube:
http://www.youtube.com/watch?v=32cXcdXqS4A
/*{{{*/
#displayArea {
background:#FFFFFF none repeat scroll 0 0;
border:40px solid #DFFFFB;
margin:0em 16em 0em 1em; /* left 15em for mainMenu */
}
#tiddlerDisplay {
border-right:1px solid #eee;
border-bottom:1px solid #eee;
}
.button {
border:none !important
}
div.header {
display:none
}
div#mainMenu {
background-color:#F2B84B;
font-size:2em;
width:143px;
display:none; /* turn it off */
}
div#sidebar {
background-color:#565651;
}
div#sidebar .button, div#sidebar .searchButton {
color:#fff;
}
.tabUnselected {
background:none;
}

/* jsTetris Stylesheet */
#tetris	{
	position: relative;
	width: 300px;
	height:	309px;
	background:	#fff;
	border:	#BE9E7C	1px	solid;
}

#tetris	.left {
	background:	#F5EDE3;
	position: absolute;
	width: 131px;
	height:	100%;
	left: 0px;
	top: 0px;
}
.left-border { background: #E4BE95;	position: absolute;	z-index: 100; top: 0px;	left: 130px; width:	1px; height: 100%; }

#tetris-area {
	/* 168,308 +2px	borders	*/
	background:	#fff;
	position: absolute;
	width: 167px;
	height:	307px;
	left: 132px;
	top: 1px;
	overflow: hidden;
}

.grid1,	.grid2,	.grid3,	.grid4,	.grid5,	.grid6 { z-index: 10; position:	absolute; top: 0px;	width: 13px; height: 307px;	background:	#f4efe9; }
.grid1 { left: 14px; }
.grid2 { left: 42px; }
.grid3 { left: 70px; }
.grid4 { left: 98px; }
.grid5 { left: 126px; }
.grid6 { left: 154px; }

#tetris	.block0,
#tetris	.block1,
#tetris	.block2,
#tetris	.block3,
#tetris	.block4,
#tetris	.block5,
#tetris	.block6	{
	z-index: 1000;
	font-size: 10px;
	line-height: 1em;
	font-family: arial;
	position: absolute;
	width: 13px;
	height:	13px;
	border:	0.5px solid	#ffffff;
	/* with	margin 0.5px there were	problems with offsetLeft and offsetTop */
}

#tetris	.left h1 {
	font-size: 11px;
	font-family: "trebuchet	ms", arial;
	font-weight: bold;
	text-align:	center;
	margin-top:	10px;
	margin-bottom: 10px;
}
#tetris	.left h1 a {
	color: #3366CC;
	text-decoration: none;
}
#tetris	.left h1 a:hover {
	color: #FF6600;
	text-decoration: none;
}

/* menu	*/

#tetris	.left .menu	{
	margin-top:	1em;

}
#tetris	.menu a, #tetris .menu a:visited {
	display: block;
	text-decoration: none;
	color: #333333;
	background:	#EAE0D1;
	border-width: 1px;
	margin-bottom: -1px;
	border-style: solid;
	border-color: #BE9E7C;
	cursor:	pointer;
	text-align:	left;
	padding-left: 10px;
	height: 19px;
	line-height: 19px;
	width: 78px;
	padding-bottom: 1px;
	margin-left: 20px;
}
#tetris .menu a:hover { background: #EFE8DE; }

/* game	over */

#tetris-gameover {
	position: absolute;
	width: 100%;
	top: 50%;
	text-align:	center;
	font-weight: bold;
	display: none;
}

/* next	puzzle */
#tetris-nextpuzzle {
	position: absolute;
	top: 47%;
	left: 35%;
	background:	#ffffff;
	overflow: visible;
	display: none;
}
#tetris-keys {
	position: absolute;
	left: 25px;
	top: 135px;
}
#tetris div.h5 { margin-bottom: 0.5em; display: block; font-weight: bold; }
#tetris-keys td { padding-right: 1px; padding-bottom: 1px; }
#tetris-keys img { border-width: 0px; }

/* stats */

#tetris	.left .stats {
	position: absolute;
	left: 25px;
	bottom:	5px;
}
#tetris	.stats td {	padding-bottom:	1px; line-height: 1.25em; }

#tetris	.stats .level {	text-align:	left; padding-right: 5px; }
#tetris-stats-level	{ font-weight: bold; }

#tetris	.stats .time { text-align: left; padding-right:	5px; }
#tetris-stats-time { font-weight: bold;	}

#tetris	.stats .apm	{ text-align: left;	padding-right: 5px;	}
#tetris-stats-apm {	font-weight: bold; }

#tetris	.stats .lines {	text-align:	left; padding-right: 5px; }
#tetris-stats-lines	{ font-weight: bold; }

#tetris	.stats .score {	text-align:	left; padding-right: 5px; }
#tetris-stats-score	{ font-weight: bold; }


/*
	|
	---
*/
#tetris	.block1	{ background: #32a4fa; }

/*
	  |
	---
*/
#tetris	.block0	{ background: #38C44F; }



/*
	--
   --
*/
#tetris	.block2	{ background: #FFAC1C; }

/*
	--
	 --
*/
#tetris	.block3	{ background: #FF6600; }

/*
	|
   ---
*/
#tetris	.block4	{ background: #CC54C4; }

/*
	--
	--
*/
#tetris	.block5	{ background: #999;	}

/*
	----
*/
#tetris	.block6	{ background: #FF0000; }


/*** window	***/

#tetris	.window	{
	background:	#EFE8DE;
	position: absolute;
	width: 167px;
	height:	307px;
	left: 132px;
	top: 1px;
	z-index: 50000;
	display: none;
}
#tetris	.window	.top {
	position: relative;
	background:	#EAE0D1;
	color: #666666;
	letter-spacing:	+1px;
	height:	20px;
	line-height: 20px;
	vertical-align:	middle;
	border-bottom: 1px solid #ffffff;
	text-indent: 10px;
}
#tetris	.window	.top .close	{
	position: absolute;
	background:	#EAE0D1;
	font-family: verdana;
	font-weight: bold;
	right: 0px;
	top: 0px;
	height:	20px;
	line-height: 19px;
	text-indent: 7px;
	width: 21px;
	border-left: 1px solid #ffffff;
	cursor:	pointer;
}
#tetris	.window	.top .close:hover {
	background:	#EFE8DE;
}
#tetris	.window	.content {
	margin:	10px;
}
#tetris	.window	.content table {
}

/*}}}*/
/***
|Name|TagCloudPlugin|
|Source|http://www.TiddlyTools.com/#TagCloudPlugin|
|Version|1.6.0|
|Author|Eric Shulman|
|Original Author|Clint Checketts|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|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:... =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>shows tags/links 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>>}}}
//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.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: 6 , revision: 0, date: new Date(2009,2,26)};
//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));
		if (params.length) {
			if (params[0].substr(0,1)=='+') { // get tag list from tiddler
				var inc=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=params; // exclude params
		}
		// 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;
			}
		}
	}
};
//}}}
[[Osmosoft|http://www.osmosoft.com]]'s innovative open source Wiki runs in almost any Web browser with servers optional. You're looking at one now! 

For more info and to get your own, visit http://www.tiddlywiki.com

If you happen to run Confluence, check out my [[Confluence TiddlyWiki plugin]].
I sat down with [[Andy Yates]] from ThoughtWorks (one of the main sponsors of QCon) who was kind enough to give me an in-depth tour of their latest products for collaboration in development projects. This being the company that defines Agile and creates universally acclaimed software like CruiseControl, their sleek new apps drew my attention and I was not disappointed.

Twist is "//the// next generation of software test automation tools" (my emphasis). It allows business members of the project to add user stories and functional documentation directly into the project through an Eclipse plugin which packages a surprisingly intuitive UI with a powerful Domain Specific Language (DSL) processor. By integrating this with Selenium's testing framework, they're demonstrating a fast, interactive process whereby product testing can be developed and refactored in a very powerful way.

DSL's have already become a sturdy bridge between design and development on big projects, but this brings test driven analysis and development very close together that may just "twist" projects in a whole new way.

Twist is still in beta and can be trialled here: http://studios.thoughtworks.com/twist

Since I haven't seen Mingle 2 yet, Andy also gave me a tour of this project management app for software teams. It is incredibly flexible and can be tailored not only to any kind of project, but to almost any kind of project management style. It seemed like a powerful, slick, and mature product, but for me it just wasn't of that much interest since I simply don't have that much interest in project management. He couldn't show me the Subversion integration, so maybe I'll have to come back to this later and check out the developer tools: http://studios.thoughtworks.com/mingle-project-intelligence
| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |
| 05/04/2009 11:41:54 | Oleg | [[index.html|file:///C:/TEMP/tiddlywiki/index.html]] | [[store.php|http://oleg.utou.ch/wiki/store.php]] | . | [[index.html | http://oleg.utou.ch/wiki/index.html]] | backup |
| 06/04/2009 14:22:55 | Oleg | [[index.html|file:///C:/TEMP/tiddlywiki/index.html]] | [[store.php|http://oleg.utou.ch/wiki/store.php]] | . | [[index.html | http://oleg.utou.ch/wiki/index.html]] | backup |
| 09/05/2009 15:35:54 | Zusi | [[index.html|file:///C:/dl/wiki/index.html]] | [[|http://oleg.utou.ch/wiki/]] | . | [[index.html | http://oleg.utou.ch/wiki/index.html]] | backup | failed |
| 09/05/2009 15:36:24 | Zusi | [[index.html|file:///C:/dl/wiki/index.html]] | [[store.php|http://oleg.utou.ch/wiki/store.php]] | . | [[index.html | http://oleg.utou.ch/wiki/index.html]] | backup |
/***
|''Name:''|UploadPlugin|
|''Description:''|Save to web a TiddlyWiki|
|''Version:''|4.1.4|
|''Date:''|2008-08-11|
|''Source:''|http://tiddlywiki.bidix.info/#UploadPlugin|
|''Documentation:''|http://tiddlywiki.bidix.info/#UploadPluginDoc|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0|
|''Requires:''|PasswordOptionPlugin|
***/
//{{{
version.extensions.UploadPlugin = {
	major: 4, minor: 1, revision: 4,
	date: new Date("2008-08-11"),
	source: 'http://tiddlywiki.bidix.info/#UploadPlugin',
	author: 'BidiX (BidiX (at) bidix (dot) info',
	coreVersion: '2.2.0'
};

//
// Environment
//

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

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

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

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

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

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

//
// uploadOptions Macro
//

config.macros.uploadOptions = {
	handler: function(place,macroName,params) {
		var wizard = new Wizard();
		wizard.createWizard(place,this.wizardTitle);
		wizard.addStep(this.step1Title,this.step1Html);
		var markList = wizard.getElement("markList");
		var listWrapper = document.createElement("div");
		markList.parentNode.insertBefore(listWrapper,markList);
		wizard.setValue("listWrapper",listWrapper);
		this.refreshOptions(listWrapper,false);
		var uploadCaption;
		if (document.location.toString().substr(0,4) == "http") 
			uploadCaption = config.macros.upload.label.saveLabel;
		else
			uploadCaption = config.macros.upload.label.uploadLabel;
		
		wizard.setButtons([
				{caption: uploadCaption, tooltip: config.macros.upload.label.promptOption, 
					onClick: config.macros.upload.action},
				{caption: this.cancelButton, tooltip: this.cancelButtonPrompt, onClick: this.onCancel}
				
			]);
	},
	options: [
		"txtUploadUserName",
		"pasUploadPassword",
		"txtUploadStoreUrl",
		"txtUploadDir",
		"txtUploadFilename",
		"txtUploadBackupDir",
		"chkUploadLog",
		"txtUploadLogMaxLine"		
	],
	refreshOptions: function(listWrapper) {
		var opts = [];
		for(i=0; i<this.options.length; i++) {
			var opt = {};
			opts.push();
			opt.option = "";
			n = this.options[i];
			opt.name = n;
			opt.lowlight = !config.optionsDesc[n];
			opt.description = opt.lowlight ? this.unknownDescription : config.optionsDesc[n];
			opts.push(opt);
		}
		var listview = ListView.create(listWrapper,opts,this.listViewTemplate);
		for(n=0; n<opts.length; n++) {
			var type = opts[n].name.substr(0,3);
			var h = config.macros.option.types[type];
			if (h && h.create) {
				h.create(opts[n].colElements['option'],type,opts[n].name,opts[n].name,"no");
			}
		}
		
	},
	onCancel: function(e)
	{
		backstage.switchTab(null);
		return false;
	},
	
	wizardTitle: "Upload with options",
	step1Title: "These options are saved in cookies in your browser",
	step1Html: "<input type='hidden' name='markList'></input><br>",
	cancelButton: "Cancel",
	cancelButtonPrompt: "Cancel prompt",
	listViewTemplate: {
		columns: [
			{name: 'Description', field: 'description', title: "Description", type: 'WikiText'},
			{name: 'Option', field: 'option', title: "Option", type: 'String'},
			{name: 'Name', field: 'name', title: "Name", type: 'String'}
			],
		rowClasses: [
			{className: 'lowlight', field: 'lowlight'} 
			]}
};

//
// upload functions
//

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

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

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

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

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

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

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

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

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

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

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

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

//
// Utilities
// 

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

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

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

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

//
// Initializations
//

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

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

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

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


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


//}}}
Some think that grassroots is best - especially when it comes to such a flexible and addictive tool as the wiki. Started by StewartMader as a collection of patterns and anti-patterns (borrowed from software design), it has grown into a community of adopters, and was recently published as a book.

Visit their site if you are using wikis in any way, and still wish to keep your sanity for years to come.
http://www.wikipatterns.com

The Wiki Patterns book:
http://www.amazon.com/Wikipatterns-Stewart-Mader/dp/0470223626/ref=bxgy_cc_b_img_b
This is a standard for data exchange. It's somewhat inferior to SOAP, or so [[they|http://weblog.masukomi.org/writings/xml-rpc_vs_soap.htm]] [[claim|http://effbot.org/zone/rest-vs-rpc.htm]]. Many wish to delight in RESTful abandon. Others proclaim JSON as the new King.

Frankly, it's all just packages of data sent to-and-fro, and I don't expect to have to spend too much time worrying about the wrapping. If you want to take it to a whole new level and call it an art? Please do. Go get inspired: http://furoshiki.com/
Very wikiable name. 

Now where is my built-in spell checker to tell me off?
<html>
<!-- 
	Author: Cezary Tomczak

	Adapted as TiddlyWiki plugin by Oleg Lavrovsky

	Installation: 
        - copy this tiddler, jsTetris, and the bottom
	  part of the StyleSheet into your TiddlyWiki
-->
<div id="tetris">
		<div class="left">
			<h1><a href="http://www.gosu.pl/tetris/">Js	Tetris 1.17</a></h1>
			<div class="menu">
				<div><a href="javascript:void(0)" id="tetris-menu-start">New Game</a></div>
				<div><a href="javascript:void(0)" id="tetris-menu-reset">Reset</a></div>
				<div><a href="javascript:void(0)" id="tetris-menu-highscores">Highscores</a></div>
				<div><a href="javascript:void(0)" id="tetris-menu-help">About</a></div>
			</div>
			<div id="tetris-keys"></div>
			<div id="tetris-nextpuzzle"></div>
			<div id="tetris-gameover">Game Over</div>
			<div class="stats">
				<table cellspacing="0" cellpadding="0">
				<tr>
					<td	class="level">Level:</td>
					<td><span id="tetris-stats-level">1</span></td>
				</tr>
				<tr>
					<td	class="score">Score:</td>
					<td><span id="tetris-stats-score">0</span></td>
				</tr>
				<tr>
					<td	class="lines">Lines:</td>
					<td><span id="tetris-stats-lines">0</span></td>
				</tr>
				<tr>
					<td	class="apm">APM:</td>
					<td><span id="tetris-stats-apm">0</span></td>
				</tr>
				<tr>
					<td	class="time">Time:</td>
					<td><span id="tetris-stats-time">0</span></td>
				</tr>

				</table>
			</div>
		</div>
		<div class="left-border"></div>
		<div id="tetris-area">
			<div class="grid1"></div>
			<div class="grid2"></div>
			<div class="grid3"></div>
			<div class="grid4"></div>
			<div class="grid5"></div>
			<div class="grid6"></div>
		</div>
		<div id="tetris-help" class="window">
			<div class="top">
				About <span id="tetris-help-close" class="close">x</span>
			</div>
			<div class="content" style="margin-top:	1em;">
				<div style="margin-top:	1em;">
				<div>JsTetris is a highly customizable tetris game written in javascript,
				full sources available, it is free to modify.
				</div>
				<br>
				<div>Author: Cezary Tomczak</div>
				<div>Site: <a href="http://www.gosu.pl/tetris/">www.gosu.pl/tetris/</a></div>
				<br>
				<div>License: BSD revised (free for any use)</div>
				</div>
			</div>
		</div>
		<div id="tetris-highscores"	class="window">
			<div class="top">
				Highscores <span id="tetris-highscores-close" class="close">x</span>
			</div>
			<div class="content">
				<div id="tetris-highscores-content"></div>
				<br>
				Note: these scores are kept in cookies, they are only visible to your computer.
			</div>
		</div>
	</div>
</html>
<<jsTetris>>
//{{{
config.macros.jsTetris = {
  handler: function (place, macroName, params, wikifier, paramString, tiddler)
  {

var	tetris = new Tetris();
	tetris.unit	= 14;
	tetris.areaX = 12;
	tetris.areaY = 22;

// minified with Rhino shrinksafe (from 60 KB to 15 KB)
function Tetris() {
var self=this;
this.stats=new Stats();
this.puzzle=null;
this.area=null;
this.unit=20;
this.areaX=20;
this.areaY=20;
this.highscores=new Highscores(10);
this.start=function(){
self.reset();
self.stats.start();
document.getElementById("tetris-nextpuzzle").style.display="block";
document.getElementById("tetris-keys").style.display="none";
self.area=new Area(self.unit,self.areaX,self.areaY,"tetris-area");
self.puzzle=new Puzzle(self,self.area);
if(self.puzzle.mayPlace()){
self.puzzle.place();
}else{
self.gameOver();
}
};
this.reset=function(){
if(self.puzzle){
self.puzzle.destroy();
self.puzzle=null;
}
if(self.area){
self.area.destroy();
self.area=null;
}
document.getElementById("tetris-gameover").style.display="none";
document.getElementById("tetris-nextpuzzle").style.display="none";
document.getElementById("tetris-keys").style.display="block";
self.stats.reset();
};
this.gameOver=function(){
self.stats.stop();
self.puzzle.stop();
document.getElementById("tetris-nextpuzzle").style.display="none";
document.getElementById("tetris-gameover").style.display="block";
if(this.highscores.mayAdd(this.stats.getScore())){
var _1=prompt("Game Over !\nEnter your name:","");
if(_1&&_1.trim().length){
this.highscores.add(_1,this.stats.getScore());
}
}
};
this.up=function(){
if(self.puzzle&&self.puzzle.isRunning()&&!self.puzzle.isStopped()){
if(self.puzzle.mayRotate()){
self.puzzle.rotate();
self.stats.setActions(self.stats.getActions()+1);
}
}
};
this.down=function(){
if(self.puzzle&&self.puzzle.isRunning()&&!self.puzzle.isStopped()){
if(self.puzzle.mayMoveDown()){
self.stats.setScore(self.stats.getScore()+5+self.stats.getLevel());
self.puzzle.moveDown();
self.stats.setActions(self.stats.getActions()+1);
}
}
};
this.left=function(){
if(self.puzzle&&self.puzzle.isRunning()&&!self.puzzle.isStopped()){
if(self.puzzle.mayMoveLeft()){
self.puzzle.moveLeft();
self.stats.setActions(self.stats.getActions()+1);
}
}
};
this.right=function(){
if(self.puzzle&&self.puzzle.isRunning()&&!self.puzzle.isStopped()){
if(self.puzzle.mayMoveRight()){
self.puzzle.moveRight();
self.stats.setActions(self.stats.getActions()+1);
}
}
};
this.space=function(){
if(self.puzzle&&self.puzzle.isRunning()&&!self.puzzle.isStopped()){
self.puzzle.stop();
self.puzzle.forceMoveDown();
}
};
var helpwindow=new Window("tetris-help");
var highscores=new Window("tetris-highscores");
document.getElementById("tetris-menu-start").onclick=function(){
helpwindow.close();
highscores.close();
self.start();
this.blur();
};
document.getElementById("tetris-menu-reset").onclick=function(){
helpwindow.close();
highscores.close();
self.reset();
this.blur();
};
document.getElementById("tetris-menu-help").onclick=function(){
highscores.close();
helpwindow.activate();
this.blur();
};
document.getElementById("tetris-help-close").onclick=helpwindow.close;
document.getElementById("tetris-menu-highscores").onclick=function(){
helpwindow.close();
document.getElementById("tetris-highscores-content").innerHTML=self.highscores.toHtml();
highscores.activate();
this.blur();
};
document.getElementById("tetris-highscores-close").onclick=highscores.close;
var keyboard=new Keyboard();
keyboard.set(keyboard.n,this.start);
keyboard.set(keyboard.r,this.reset);
keyboard.set(keyboard.up,this.up);
keyboard.set(keyboard.down,this.down);
keyboard.set(keyboard.left,this.left);
keyboard.set(keyboard.right,this.right);
keyboard.set(keyboard.space,this.space);
document.onkeydown=keyboard.event;
function Window(id){
this.id=id;
this.el=document.getElementById(this.id);
var _3=this;
this.activate=function(){
_3.el.style.display=(_3.el.style.display=="block"?"none":"block");
};
this.close=function(){
_3.el.style.display="none";
};
this.isActive=function(){
return (_3.el.style.display=="block");
};
};
function Keyboard(){
this.up=38;
this.down=40;
this.left=37;
this.right=39;
this.n=78;
this.r=82;
this.space=32;
this.f12=123;
this.escape=27;
this.keys=[];
this.funcs=[];
var _4=this;
this.set=function(_5,_6){
this.keys.push(_5);
this.funcs.push(_6);
};
this.event=function(e){
if(!e){
e=window.event;
}
for(var i=0;i<_4.keys.length;i++){
if(e.keyCode==_4.keys[i]){
_4.funcs[i]();
}
}
};
};
function Stats(){
this.level;
this.time;
this.apm;
this.lines;
this.score;
this.puzzles;
this.actions;
this.el={"level":document.getElementById("tetris-stats-level"),"time":document.getElementById("tetris-stats-time"),"apm":document.getElementById("tetris-stats-apm"),"lines":document.getElementById("tetris-stats-lines"),"score":document.getElementById("tetris-stats-score")};
this.timerId=null;
var _9=this;
this.start=function(){
this.reset();
this.timerId=setInterval(this.incTime,1000);
};
this.stop=function(){
if(this.timerId){
clearInterval(this.timerId);
}
};
this.reset=function(){
this.stop();
this.level=1;
this.time=0;
this.apm=0;
this.lines=0;
this.score=0;
this.puzzles=0;
this.actions=0;
this.el.level.innerHTML=this.level;
this.el.time.innerHTML=this.time;
this.el.apm.innerHTML=this.apm;
this.el.lines.innerHTML=this.lines;
this.el.score.innerHTML=this.score;
};
this.incTime=function(){
_9.time++;
_9.el.time.innerHTML=_9.time;
_9.apm=parseInt((_9.actions/_9.time)*60);
_9.el.apm.innerHTML=_9.apm;
};
this.setScore=function(i){
this.score=i;
this.el.score.innerHTML=this.score;
};
this.setLevel=function(i){
this.level=i;
this.el.level.innerHTML=this.level;
};
this.setLines=function(i){
this.lines=i;
this.el.lines.innerHTML=this.lines;
};
this.setPuzzles=function(i){
this.puzzles=i;
};
this.setActions=function(i){
this.actions=i;
};
this.getScore=function(){
return this.score;
};
this.getLevel=function(){
return this.level;
};
this.getLines=function(){
return this.lines;
};
this.getPuzzles=function(){
return this.puzzles;
};
this.getActions=function(){
return this.actions;
};
};
function Area(_f,x,y,id){
this.unit=_f;
this.x=x;
this.y=y;
this.el=document.getElementById(id);
this.board=[];
for(var y=0;y<this.y;y++){
this.board.push(new Array());
for(var x=0;x<this.x;x++){
this.board[y].push(0);
}
}
this.destroy=function(){
for(var y=0;y<this.board.length;y++){
for(var x=0;x<this.board[y].length;x++){
if(this.board[y][x]){
this.el.removeChild(this.board[y][x]);
this.board[y][x]=0;
}
}
}
};
this.removeFullLines=function(){
var _15=0;
for(var y=this.y-1;y>0;y--){
if(this.isLineFull(y)){
this.removeLine(y);
_15++;
y++;
}
}
return _15;
};
this.isLineFull=function(y){
for(var x=0;x<this.x;x++){
if(!this.board[y][x]){
return false;
}
}
return true;
};
this.removeLine=function(y){
for(var x=0;x<this.x;x++){
this.el.removeChild(this.board[y][x]);
this.board[y][x]=0;
}
y--;
for(;y>0;y--){
for(var x=0;x<this.x;x++){
if(this.board[y][x]){
var el=this.board[y][x];
el.style.top=el.offsetTop+this.unit+"px";
this.board[y+1][x]=el;
this.board[y][x]=0;
}
}
}
};
this.getBlock=function(y,x){
if(y<0){
return 0;
}
if(y<this.y&&x<this.x){
return this.board[y][x];
}else{
throw "Area.getBlock("+y+",\t"+x+") failed";
}
};
this.addElement=function(el){
var x=parseInt(el.offsetLeft/this.unit);
var y=parseInt(el.offsetTop/this.unit);
if(y>=0&&y<this.y&&x>=0&&x<this.x){
this.board[y][x]=el;
}else{
}
};
};
function Puzzle(_21,_22){
var _23=this;
this.tetris=_21;
this.area=_22;
this.fallDownID=null;
this.forceMoveDownID=null;
this.type=null;
this.nextType=null;
this.position=null;
this.speed=null;
this.running=null;
this.stopped=null;
this.board=[];
this.elements=[];
this.nextElements=[];
this.x=null;
this.y=null;
this.puzzles=[[[0,0,1],[1,1,1],[0,0,0]],[[1,0,0],[1,1,1],[0,0,0]],[[0,1,1],[1,1,0],[0,0,0]],[[1,1,0],[0,1,1],[0,0,0]],[[0,1,0],[1,1,1],[0,0,0]],[[1,1],[1,1]],[[0,0,0,0],[1,1,1,1],[0,0,0,0],[0,0,0,0]]];
this.reset=function(){
if(this.fallDownID){
clearTimeout(this.fallDownID);
}
if(this.forceMoveDownID){
clearTimeout(this.forceMoveDownID);
}
this.type=this.nextType;
this.nextType=random(this.puzzles.length);
this.position=0;
this.speed=80+(700/this.tetris.stats.getLevel());
this.running=false;
this.stopped=false;
this.board=[];
this.elements=[];
for(var i=0;i<this.nextElements.length;i++){
document.getElementById("tetris-nextpuzzle").removeChild(this.nextElements[i]);
}
this.nextElements=[];
this.x=null;
this.y=null;
};
this.nextType=random(this.puzzles.length);
this.reset();
this.isRunning=function(){
return this.running;
};
this.isStopped=function(){
return this.stopped;
};
this.getX=function(){
return this.x;
};
this.getY=function(){
return this.y;
};
this.mayPlace=function(){
var _25=this.puzzles[this.type];
var _26=parseInt((this.area.x-_25[0].length)/2);
var _27=1;
var _28=false;
var _29=0;
for(var y=_25.length-1;y>=0;y--){
for(var x=0;x<_25[y].length;x++){
if(_25[y][x]){
_28=true;
if(this.area.getBlock(_27,_26+x)){
return false;
}
}
}
if(_28){
_29++;
}
if(_27-_29<0){
break;
}
}
return true;
};
this.place=function(){
this.tetris.stats.setPuzzles(this.tetris.stats.getPuzzles()+1);
if(this.tetris.stats.getPuzzles()>=(10+this.tetris.stats.getLevel()*2)){
this.tetris.stats.setLevel(this.tetris.stats.getLevel()+1);
this.tetris.stats.setPuzzles(0);
}
var _2c=this.puzzles[this.type];
var _2d=parseInt((this.area.x-_2c[0].length)/2);
var _2e=1;
var _2f=false;
var _30=0;
this.x=_2d;
this.y=1;
this.board=this.createEmptyPuzzle(_2c.length,_2c[0].length);
for(var y=_2c.length-1;y>=0;y--){
for(var x=0;x<_2c[y].length;x++){
if(_2c[y][x]){
_2f=true;
var el=document.createElement("div");
el.className="block"+this.type;
el.style.left=(_2d+x)*this.area.unit+"px";
el.style.top=(_2e-_30)*this.area.unit+"px";
this.area.el.appendChild(el);
this.board[y][x]=el;
this.elements.push(el);
}
}
if(_30){
this.y--;
}
if(_2f){
_30++;
}
}
this.running=true;
this.fallDownID=setTimeout(this.fallDown,this.speed);
var _34=this.puzzles[this.nextType];
for(var y=0;y<_34.length;y++){
for(var x=0;x<_34[y].length;x++){
if(_34[y][x]){
var el=document.createElement("div");
el.className="block"+this.nextType;
el.style.left=(x*this.area.unit)+"px";
el.style.top=(y*this.area.unit)+"px";
document.getElementById("tetris-nextpuzzle").appendChild(el);
this.nextElements.push(el);
}
}
}
};
this.destroy=function(){
for(var i=0;i<this.elements.length;i++){
this.area.el.removeChild(this.elements[i]);
}
this.elements=[];
this.board=[];
this.reset();
};
this.createEmptyPuzzle=function(y,x){
var _38=[];
for(var y2=0;y2<y;y2++){
_38.push(new Array());
for(var x2=0;x2<x;x2++){
_38[y2].push(0);
}
}
return _38;
};
this.fallDown=function(){
if(_23.isRunning()){
if(_23.mayMoveDown()){
_23.moveDown();
_23.fallDownID=setTimeout(_23.fallDown,_23.speed);
}else{
for(var i=0;i<_23.elements.length;i++){
_23.area.addElement(_23.elements[i]);
}
var _3c=_23.area.removeFullLines();
if(_3c){
_23.tetris.stats.setLines(_23.tetris.stats.getLines()+_3c);
_23.tetris.stats.setScore(_23.tetris.stats.getScore()+(1000*_23.tetris.stats.getLevel()*_3c));
}
_23.reset();
if(_23.mayPlace()){
_23.place();
}else{
_23.tetris.gameOver();
}
}
}
};
this.forceMoveDown=function(){
if(!_23.isRunning()&&!_23.isStopped()){
if(_23.mayMoveDown()){
_23.tetris.stats.setScore(_23.tetris.stats.getScore()+5+_23.tetris.stats.getLevel());
_23.tetris.stats.setActions(_23.tetris.stats.getActions()+1);
_23.moveDown();
_23.forceMoveDownID=setTimeout(_23.forceMoveDown,30);
}else{
for(var i=0;i<_23.elements.length;i++){
_23.area.addElement(_23.elements[i]);
}
var _3e=_23.area.removeFullLines();
if(_3e){
_23.tetris.stats.setLines(_23.tetris.stats.getLines()+_3e);
_23.tetris.stats.setScore(_23.tetris.stats.getScore()+(1000*_23.tetris.stats.getLevel()*_3e));
}
_23.reset();
if(_23.mayPlace()){
_23.place();
}else{
_23.tetris.gameOver();
}
}
}
};
this.stop=function(){
this.running=false;
};
this.mayRotate=function(){
for(var y=0;y<this.board.length;y++){
for(var x=0;x<this.board[y].length;x++){
if(this.board[y][x]){
var _41=this.getY()+this.board.length-1-x;
var _42=this.getX()+y;
if(_41>=this.area.y){
return false;
}
if(_42<0){
return false;
}
if(_42>=this.area.x){
return false;
}
if(this.area.getBlock(_41,_42)){
return false;
}
}
}
}
return true;
};
this.rotate=function(){
var _43=this.createEmptyPuzzle(this.board.length,this.board[0].length);
for(var y=0;y<this.board.length;y++){
for(var x=0;x<this.board[y].length;x++){
if(this.board[y][x]){
var _46=_43.length-1-x;
var _47=y;
var el=this.board[y][x];
var _49=_46-y;
var _4a=_47-x;
el.style.left=el.offsetLeft+(_4a*this.area.unit)+"px";
el.style.top=el.offsetTop+(_49*this.area.unit)+"px";
_43[_46][_47]=el;
}
}
}
this.board=_43;
};
this.mayMoveDown=function(){
for(var y=0;y<this.board.length;y++){
for(var x=0;x<this.board[y].length;x++){
if(this.board[y][x]){
if(this.getY()+y+1>=this.area.y){
this.stopped=true;
return false;
}
if(this.area.getBlock(this.getY()+y+1,this.getX()+x)){
this.stopped=true;
return false;
}
}
}
}
return true;
};
this.moveDown=function(){
for(var i=0;i<this.elements.length;i++){
this.elements[i].style.top=this.elements[i].offsetTop+this.area.unit+"px";
}
this.y++;
};
this.mayMoveLeft=function(){
for(var y=0;y<this.board.length;y++){
for(var x=0;x<this.board[y].length;x++){
if(this.board[y][x]){
if(this.getX()+x-1<0){
return false;
}
if(this.area.getBlock(this.getY()+y,this.getX()+x-1)){
return false;
}
}
}
}
return true;
};
this.moveLeft=function(){
for(var i=0;i<this.elements.length;i++){
this.elements[i].style.left=this.elements[i].offsetLeft-this.area.unit+"px";
}
this.x--;
};
this.mayMoveRight=function(){
for(var y=0;y<this.board.length;y++){
for(var x=0;x<this.board[y].length;x++){
if(this.board[y][x]){
if(this.getX()+x+1>=this.area.x){
return false;
}
if(this.area.getBlock(this.getY()+y,this.getX()+x+1)){
return false;
}
}
}
}
return true;
};
this.moveRight=function(){
for(var i=0;i<this.elements.length;i++){
this.elements[i].style.left=this.elements[i].offsetLeft+this.area.unit+"px";
}
this.x++;
};
};
function random(i){
return Math.floor(Math.random()*i);
};
function Highscores(_55){
this.maxscores=_55;
this.scores=[];
this.load=function(){
var _56=new Cookie();
var s=_56.get("tetris-highscores");
this.scores=[];
if(s.length){
var _58=s.split("|");
for(var i=0;i<_58.length;++i){
var a=_58[i].split(":");
this.scores.push(new _5b(a[0],Number(a[1])));
}
}
};
this.save=function(){
var _5c=new Cookie();
var a=[];
for(var i=0;i<this.scores.length;++i){
a.push(this.scores[i].name+":"+this.scores[i].score);
}
var s=a.join("|");
_5c.set("tetris-highscores",s,3600*24*1000);
};
this.mayAdd=function(_60){
if(this.scores.length<this.maxscores){
return true;
}
for(var i=this.scores.length-1;i>=0;--i){
if(this.scores[i].score<_60){
return true;
}
}
return false;
};
this.add=function(_62,_63){
_62=_62.replace(/[;=:|]/g,"?");
_62=_62.replace(/</g,"&lt;").replace(/>/g,"&gt;");
if(this.scores.length<this.maxscores){
this.scores.push(new _5b(_62,_63));
}else{
for(var i=this.scores.length-1;i>=0;--i){
if(this.scores[i].score<_63){
this.scores.removeByIndex(i);
this.scores.push(new _5b(_62,_63));
break;
}
}
}
this.sort();
this.save();
};
this.getScores=function(){
return this.scores;
};
this.toHtml=function(){
var s="<table\tcellspacing=\"0\"\tcellpadding=\"2\"><tr><th></th><th>Name</th><th>Score</th></tr>";
for(var i=0;i<this.scores.length;++i){
s+="<tr><td>?.</td><td>?</td><td>?</td></tr>".format(i+1,this.scores[i].name,this.scores[i].score);
}
s+="</table>";
return s;
};
this.sort=function(){
var _67=this.scores;
var len=_67.length;
this.scores=[];
for(var i=0;i<len;++i){
var el=null,_6b=null;
for(var j=0;j<_67.length;++j){
if(!el||(_67[j].score>el.score)){
el=_67[j];
_6b=j;
}
}
_67.removeByIndex(_6b);
this.scores.push(el);
}
};
function _5b(_6d,_6e){
this.name=_6d;
this.score=_6e;
};
this.load();
};
function Cookie(){
this.get=function(_6f){
var _70=document.cookie.split(";");
for(var i=0;i<_70.length;++i){
var a=_70[i].split("=");
if(a.length==2){
a[0]=a[0].trim();
a[1]=a[1].trim();
if(a[0]==_6f){
return unescape(a[1]);
}
}
}
return "";
};
this.set=function(_73,_74,_75,_76,_77,_78){
this.del(_73);
if(!_76){
_76="/";
}
var _79=(_73+"="+escape(_74));
if(_75){
var _7a=new Date(new Date().getTime()+_75*1000);
_79+=("; expires="+_7a.toGMTString());
}
_79+=(_76?";\tpath="+_76:"");
_79+=(_77?";\tdomain="+_77:"");
_79+=(_78?";\tsecure":"");
document.cookie=_79;
};
this.del=function(_7b){
document.cookie=_7b+"=; expires=Thu, 01-Jan-70\t00:00:01 GMT";
};
};
}
// end function Tetris()

if (!String.prototype.trim)	{
	String.prototype.trim =	function() {
		return this.replace(/^\s*|\s*$/g, "");
	};
}

if (!Array.prototype.removeByIndex)	{
	Array.prototype.removeByIndex =	function(index)	{
		this.splice(index, 1);
	};
}

if (!String.prototype.format) {
	String.prototype.format	= function() {
		if (!arguments.length) { throw "String.format()	failed,	no arguments passed, this =	"+this;	}
		var	tokens = this.split("?");
		if (arguments.length !=	(tokens.length - 1)) { throw "String.format() failed, tokens !=	arguments, this	= "+this; }
		var	s =	tokens[0];
		for	(var i = 0;	i <	arguments.length; ++i) {
			s += (arguments[i] + tokens[i +	1]);
		}
		return s;
	};
}

  }
};
//}}}