Background: #fff
Foreground: #000
PrimaryPale: #8cf
PrimaryLight: #18f
PrimaryMid: #04b
PrimaryDark: #014
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
/*{{{*/
body {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}

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

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

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

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

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

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

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

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

.tiddlerPopupButton {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::PrimaryPale]]; border: 1px solid [[ColorPalette::PrimaryLight]];}
.tiddlerPopupButton:hover {color:[[ColorPalette::Background]]; background:[[ColorPalette::PrimaryMid]];}
.tiddlerPopupButton:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::Foreground]];}
.tiddlerPopupButton.highlight {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Background]];}
.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]];}

table {border:2px solid [[ColorPalette::TertiaryDark]];}
th, thead td {background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::Background]];}
td, 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:absolute; top:2em; right:0em; margin:0.5em; padding:0.5em; z-index:200;}
*[id='messageArea'] {position:fixed !important; z-index:200;}
.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;}

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

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

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

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

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

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

* html #backstage {width:99%;}
* html #backstageArea {width:99%;}
#backstageArea {display:none; position:relative; overflow: hidden; z-index:150; padding:0.3em 0.5em 0.3em 0.5em;}
#backstageToolbar {position:relative;}
#backstageArea a {font-weight:bold; margin-left:0.5em; padding:0.3em 0.5em 0.3em 0.5em;}
#backstageButton {display:none; position:absolute; z-index:175; top:0em; right:0em;}
#backstageButton a {padding:0.1em 0.4em 0.1em 0.4em; margin:0.1em 0.1em 0.1em 0.1em;}
#backstage {position:relative; width:100%; z-index:50;}
#backstagePanel {display:none; z-index:100; position:absolute; margin:0em 3em 0em 3em; padding:1em 1em 1em 1em;}
.backstagePanelFooter {padding-top:0.2em; float:right;}
.backstagePanelFooter a {padding:0.2em 0.4em 0.2em 0.4em;}
#backstageCloak {display:none; z-index:50; 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 use a logographic writing system and 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;}

.htmlarea .toolbarHA table {border:1px solid ButtonFace; margin:0em 0em;}
/*}}}*/
/*{{{*/
@media print {
#mainMenu, #sidebar, #messageArea, .toolbar {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='storyDisplay'></div>
</div>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar closeTiddler closeOthers +editTiddler > fields syncing permalink references jump'></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 +saveTiddler -cancelTiddler deleteTiddler'></div>
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div macro='annotations'></div>
<div class='editor' macro='edit text'></div>
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser'></span></div>
<!--}}}-->
To get started with this blank TiddlyWiki, you'll need to modify the following tiddlers:
* SiteTitle & SiteSubtitle: The title and subtitle of the site, as shown above (after saving, they will also appear in the browser title bar)
* MainMenu: The menu (usually on the left)
* DefaultTiddlers: Contains the names of the tiddlers that you want to appear when the TiddlyWiki is opened
You'll also need to enter your username for signing your edits: <<option txtUserName>>
These InterfaceOptions for customising TiddlyWiki are saved in your browser

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

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

----
Also see AdvancedOptions
Background: #fff
Foreground: #000
PrimaryPale: #679DC2
PrimaryLight: #1A2E78
PrimaryMid: #003
PrimaryDark: #1A2E78
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #E22882
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
/***
|''Name:''|ContactMacroPlugin|
|''Description:''|Manipulate contact information held as tiddlers|
|''Version:''|1.0.0|
|''Date:''|Jun 11, 2007|
|''Source:''|http://www.tiddlywiki.com/#ContactMacroPlugin|
|''Author:''|PaulDowney (paul.downey (at) whatfettle (dot) com)|
|''License:''|[[BSD open source license]]|
|''CoreVersion:''|2.2|
***/

//{{{
// Ensure that the ContactMacroPlugin Plugin is only installed once.
if(!version.extensions.ContactMacroPlugin) {
version.extensions.ContactMacroPlugin = {installed:true};

config.macros.contact = {

	debug: false,
	offline: false,

	hCardFields: [
		{hcard: 'org', names: ['Company','company','Organization','Organization','Org']},
		{hcard: 'fn', names: ['FullName', 'Fullname', 'fullName', 'fullname', 'name']},
		{hcard: 'fn.given-name', names: ['FirstName','First','Given','Firstname','GivenName']},
		{hcard: 'fn.additional-name', names: ['AdditionalName','MiddleName','Middlename','Middle','Additional','AdditionalName']},
		{hcard: 'fn.family-name', names: ['LastName','Lastname','Last','FamilyName','Surname']},

		{hcard: 'adr.street-address', names: ['Street','Street Address']},
		{hcard: 'adr.locality', names: ['Locality','City']},
		{hcard: 'adr.region', names: ['Region','State','County','Province']},
		{hcard: 'adr.postal-code', names: ['PostalCode','PostCode','Zip'],uri: 'http://maps.google.com/maps?q='},
		{hcard: 'adr.country-name', names: ['CountryName','Country']},

		{hcard: 'tel', names: ['tel','TEL','Tel','Telephone','Phone']},
		{hcard: 'tel.work', names: ['WorkTel','TelWork','WorkPhone','workPhone']},
		{hcard: 'tel.home', names: ['HomeTel','HomeTel','HomePhone','homePhone']},
		{hcard: 'tel.mobile', names: ['Mobile','MobileTel','Cell','CellNumber','CellNo']},

		{hcard: 'email', names: ['Email','email']},
		{hcard: 'email.work', names: ['EmailWork','WorkEmail']},
		{hcard: 'email.home', names: ['EmailHome','HomeEmail']},

		{hcard: 'im.AIM', names: ['AIM'], uri: 'aim:goim?screenname=',className: 'url'},
		{hcard: 'im.MSN', names: ['MSN','WindowsLive','MicrosoftMessenger'],uri: 'msn:',className: 'url'},
		{hcard: 'im.Jabber', names: ['Jabber','XMPP'],uri: 'xmpp:',className: 'url'},
		{hcard: 'im.YIM', names: ['YIM','Yahoo','Yahoo!'],uri: 'ymsgr:sendIM?',className: 'url'},
	],

	fieldDictionary: {},

	squash: function (str) {
		return str.toLowerCase().replace(/[\s(),.\-!\?:\[\]]/g,'');
	},

	init: function () {
		if(this.initialised) 
			return;

	s= "/* content macro plugin style */"
        +".contact {background-color: #666; padding: 1em; margin: 2em 5em 2em 5em;}"
        +".vcard {margin: -3em 0 0 -3em; border: thin solid #999; padding: 2em; left: -1px; top: -1px; background-color: #eee; color: black;}"
        +".org {float: right; font-weight: bold; font-size: 1em;}"
        +".fn {font-weight: bold; font-size: 3em;}"
        +".phone {margin-top:1em;}"
        +".type:after {content: ': ';}"
        +".adr {float:right;margin: 1em 1em 1em 1em;font-size: 1.5em;}"
        +".im {margin-top:1em;}"
        +".emails {margin-top:1em;}"
        +".vcardEnd {clear:right;}"
        +".url {display: block;}";
		setStylesheet(s,"contact");


		for(var i=0;i<this.hCardFields.length;i++) {
			var item = this.hCardFields[i];
			var fieldName = this.squash(item.hcard);
			if(!item.element) 
				item.element = 'span';
			if(!item.className) 
				item.className = item.hcard.split('.').pop();
			this.fieldDictionary[fieldName] = this.hCardFields[i];
		}
		this.initialised = true;
	},

	getCardField: function (tiddlerName,fieldName,item) {
		fieldName = this.squash(fieldName);
		if(!item) {
			item = this.fieldDictionary[fieldName];
		}
		if(!item) {
			displayMessage("We didn't expect the '"+fieldName+"' field");
			return "";
		}
		for(var i=0;i<item.names.length;i++) {
			var value = store.getTiddlerSlice(tiddlerName,item.names[i]);
			if(value) return value;
		}
		return "";
	},

	getElementByClass:  function (node,className) {
		var re = new RegExp('\\b'+className+'\\b');
		var element = node.getElementsByTagName('*');
		for(var i = 0; i < element.length; i++) {
			var classes = element[i].className;
			if(re.test(classes)) return element[i];
		}
		return 0;
	},
	
	vCardHolder: function (vcard,element,name) {
		node = this.getElementByClass(vcard,name);
		if(!node) 
			node = createTiddlyElement(vcard,element,null,name);
		return node;
	},

	addItem_element: function (place,item,value) {
		return createTiddlyElement(place,item.element,null,item.className,value);
	},

	addItem_a: function (place,item,value) {
		node = createTiddlyElement(place,'a',null,item.className,value);
		node.setAttribute('href',item.uri+encodeURI(value));
		var type = item.hcard.split('.').pop();
		node.setAttribute('title',type);
		return node;
	},

	addItem_im: function (place,item,value) {
		var holder = this.vCardHolder(place,'div','im');
		holder = createTiddlyElement(holder,'div',null,'line');
		var node = this.addItem_a(holder,item,value);
		return node;
	},

	addItem_email: function (place,item,value) {
		holder = this.vCardHolder(place,'div','emails');
		holder = createTiddlyElement(holder,'div',null,'line');
		if (!item.uri) 
			item.uri = 'mailto:';
		node = this.addItem_a(holder,item,value);
		return node;
	},

	addItem_fn: function (place,item,value) {
		if(item.hcard=='fn') 
			return this.addItem_element(place,item,value);
		node = this.vCardHolder(place,'div','fn');
		return createTiddlyElement(node,'span',null,item.className,value);
	},

	addItem_adr: function (place,item,value) {
		holder = this.vCardHolder(place,'div','adr');
		holder = createTiddlyElement(holder,'div',null,'line');
		return createTiddlyElement(holder,'span',null,item.className,value);
	},

	addItem_adr_postalcode: function (place,item,value) {
		holder = this.vCardHolder(place,'div','adr');
		holder = createTiddlyElement(holder,'div',null,'line');
		return this.addItem_a(holder,item,value);
	},

	addItem_tel: function (place,item,value) {
		holder = this.vCardHolder(place,'div','phone');
		holder = createTiddlyElement(holder,'div',null,'line');
		node = createTiddlyElement(holder,'span',null,'tel');
		var type = item.hcard.split('.').pop();
		if (type=='tel') 
			type='other';
		createTiddlyElement(node,'span',null,'type',type);
		createTiddlyElement(node,'span',null,'value',value);
		createTiddlyButton(holder,'☏','Click here to dial this number',this.onClickDial);
	},

	addItem: function (place,item,value) {
		if(!value) return;
		path = item.hcard.split('.');
		while (path.length) {
			adder = 'addItem_'+this.squash(path.join('_'));
			if(this[adder]) 
				return this[adder](place,item,value);
			path.pop();
		}
		return this.addItem_element(place,item,value);
	},

	createTiddlyhCard: function (place,tiddlerName) {
		this.init();
		var contact = createTiddlyElement(place,'div',null,'contact',null);
		var container = createTiddlyElement(contact,'div',null,'vcardContainer',null);
		var vcard = createTiddlyElement(container,'div',null,'vcard',null);

		for(var i=0;i<this.hCardFields.length;i++) {
			var item = this.hCardFields[i];
			this.addItem(vcard,item,this.getCardField(tiddlerName,item.hcard,item));
		}

		// TBD: editing a tiddler should cause the vcard to update?
		createTiddlyLink(vcard,tiddlerName,tiddlerName,'editVcard');

		// TBD: ideally split WikiName and set as first child node ..
		if(!this.getElementByClass(vcard,'fn'))
			this.addItem_element(vcard,this.fieldDictionary['fn'],tiddlerName);

		createTiddlyElement(vcard,'div',null,'vcardEnd',null);

		return contact;
	},

	handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		params = paramString.parseParams('name',null,true,false,false);
		var tiddlerName = getParam(params,'name',null);

		// Name beginning with '+' is a group name, for conference calling

		if(tiddlerName.substr(0,1)=='+') {
			var tiddlers = store.getTaggedTiddlers(tiddlerName.substr(1));
			for(var n=0;n<tiddlers.length;n++) {
			    this.createTiddlyhCard(place,tiddlers[n].title);
			}
		} else {
			if(!store.tiddlerExists(tiddlerName)) {
				createTiddlyError(place,'The tiddler \'' + tiddlerName + '\' does not yet exist after all even after looking for it twice');
				return;
			}
			this.createTiddlyhCard(place,tiddlerName);
		}
	},

	telURI: function (no) {
		return encodeURIComponent('tel:'+no);
	},

	onClickDial: function (e) {
	        var macro = config.macros.contact;
	        var callingParty = macro.getCardField(config.options.txtUserName,'tel.mobile');
	        var calledParty = macro.getElementByClass(this.previousSibling,'value').firstChild.data;
		macro.makeCall(callingParty, calledParty);
	},

	makeCall: function (callingParty, calledParty) {

	        var macro = config.macros.contact;

		var body = 'callingParty=' + macro.telURI(callingParty) + '&calledParty=' + macro.telURI(calledParty);

		if(macro.debug)
			displayMessage('call info:' + body );

		var callback = function(status,params,responseText,url,xhr) {
			displayMessage(status?'call made':'call failed');
			if(config.macros.contact.debug)
				displayMessage(responseText);
		};

		// BT Web21C SDK http://sdk.bt.com
		// exposed as a web form at http://whatfetttle.com for demonstration purposes
		// you need authentication to use this!
		if(!macro.offline) {
			var req = doHttp('POST', 'http://web21c.whatfettle.com/calls/new', body, null, null,null, callback);
			if(macro.debug)
				displayMessage(req);
		}
	}

},

//TBD - wizard to load CSV file into a tidler, then explode them into tiddlers?

config.macros.contactLoadCSV = {
	handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		params = paramString.parseParams('name',null,true,false,false);
		tags = "fromCSV";
		var tiddlerName = getParam(params,'name',null);

		text = store.getTiddlerText(tiddlerName);
		// TBD - has to be a better way?
		text = text.replace(/^{{{/, "").replace(/}}}$/, "");
		var csv = new CSV(text);

		for (var n=0; n < csv.nlines(); n++) {
			line = csv.getLine(n);

			//TBD use _fn to construct title
			title = line['firstName']+line['lastName'];
			//csv.line[n].['fn'] = title;

			body = csv.getTiddlerText(n);

			if (title && body) 
				tiddler = store.saveTiddler(title,title,body,config.options.txtUserName);
		}
	}
};


/*
 *  Parse CSV into array of hashes
 */
{
	/*
	 *  parse CSV 
	 */
	function CSV(stringData,columns)
	{
		this.setColumns(columns);
		this.line = [];
		if (stringData) this.parse(stringData);
	}

	CSV.prototype.forceQuotes = true;

	CSV.prototype.parse = function(s) {
		s.replace("\r","");
		var lines = s.split("\n");
		if (!this.columns) {
			line = lines.shift();
			this.setColumns(this.parseLine(line));
		}
		for(var n = 0; n < lines.length; n++) {
			this.line.push(this.parseLine(lines[n]));
		}
	};

	CSV.prototype.parseLine = function(line) {
		data = line.split(/,(?=(?:[^"]*"[^"]*")*(?![^"]*"))/);
		for(var n = 0; n < data.length; n++) {
			if (!data[n]['substr']) continue;
			d = data[n].substr(0,1);
			if (d == '"' || d == "'") {
				data[n] = data[n].substr(1,data[n].length-2);
			}
		}
		return data;
	};

	CSV.prototype.writeLine = function(a) {
		return a.join(",");
	};

	CSV.prototype.setColumns = function(columns) {
		this.columns = columns;
	};

	CSV.prototype.getColumns = function() {
		return this.columns;
	};

	CSV.prototype.nlines = function() {
		return this.line.length;
	};

	CSV.prototype.getLineArray = function(n) {
		return this.line[n];
	};

	CSV.prototype.getLine = function(n) {
		line = this.line[n];
		if (!line) return line;
		a = {}
		for(var c = 0; c < line.length; c++) {
			if (line[c]) {
				a[this.columns[c]] = line[c];
			}
		}
		return a;
	};

	CSV.prototype.getTiddlerText = function(n) {
		line = this.line[n];
		if (!line) return line;
		text = "";
		for(var c = 0; c < line.length; c++) {
			if (line[c])
				text = text.concat("|"+this.columns[c]+"|"+line[c]+"|\n");
		}
		return text;
	};
}



} //# end of "install only once"
//}}}
<<contact "+geek" 3>>
|''Fullname:''|James Shi|
|''Mobile:''|+44779...|
|''Fullname:''|Jeremy Ruston|
|''Company:''|BT Osmosoft|
|''Mobile:''|+4478.....|
|''HomeEmail:''|jeremy.ruston@gmail.com|
|''WorkEmail:''|jeremy.ruston@bt.com|
|''Jabber:''|jeremy.ruston@gmail.com|
|''url:''|http://osmosoft.com/|
|''Street''|Tiddly Towers|
|''City''|Ashwell|
|''PostCode''|SG7|
|''Country:''|UK|
|''Fullname:''|Jon Lister|
|''Mobile:''|+44791.....|
[[Geeks]]
[[SpeedDate]]
[[Web21C]]
|''Fullname:''|Martin Budden|
|''Mobile:''|+4477....|
|''Fullname:''|Paul Downey|
|''Company:''|BT|
|''Mobile:''|+447918.....|
|''WorkTel:''|+44144.....|
|''HomeEmail:''|paul.downey@whatfettle.com|
|''WorkEmail:''|paul.downey@bt.com|
|''Jabber:''|paul.s.downey@gmail.com|
|''url:''|http://blog.whatfettle.com|
|''Street:''|101, London Road|
|''City:''|Hemel Hempstead|
|''PostCode:''|HP3 9YF|
|''State:''|Hertfordshire|
|''Country:''|UK|
|''Fullname:''|Phil Hawksworth|
|''Mobile:''|+4479...|
|''Fullname:''|Simon McManus|
|''Mobile:''|+44791.....|
<<speedDate geek 3>>
<<speedDateDial geek>>
|MartinBudden|SimonMcManus|
|JonLister|PaulDowney|
|PhilHawksworth|JamesShi|
/***
|''Name:''|SpeedDatingPlugin|
|''Description:''|Shuffle and pair-up contact information held as tiddlers|
|''Version:''|1.0.0|
|''Date:''|Jul 2, 2007|
|''Source:''|http://www.tiddlywiki.com/#SpeedDatingMacroPlugin|
|''Author:''|PaulDowney (paul.downey (at) whatfettle (dot) com)|
|''License:''|[[BSD open source license]]|
|''CoreVersion:''|2.2|
***/

//{{{
// Ensure that this Plugin is only installed once.
if(!version.extensions.SpeedDatingPlugin) {
version.extensions.SpeedDatingPlugin = {installed:true};

config.macros.speedDateDial = {

	handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		params = paramString.parseParams('tag',null,true,false,false);
		var tag = getParam(params,'tag',null);
	        var button = createTiddlyButton(place,'RING!','Click here to make these calls!',this.onClickDail);
		button.setAttribute("tiddlerName",tiddler.title);
	},

	onClickDail: function (e) {
		var macro = config.macros.speedDateDial;
		var pairs = macro.getPairs(this);

		for(var n=0;n<pairs.length;n++) {
			var callingParty = store.getTiddlerSlice(pairs[n][0],"Mobile");
			var calledParty = store.getTiddlerSlice(pairs[n][1],"Mobile");
			config.macros.contact.makeCall(callingParty, calledParty);
		}
        },

	getPairs: function (button) {
		title = button.getAttribute('tiddlerName');
		text = store.getTiddlerText(title);
		lines = text.split("|\n");
		pairs = [];
		for(var n=0;n<lines.length;n++) {
			var parts = lines[n].split("|");
			if (parts[2]) {
				pairs.push([parts[1],parts[2]]);
			}
		}
		return pairs;
	}
},

config.macros.speedDate = {

	round: 0,

	handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		params = paramString.parseParams('tag',null,true,false,false);
		var tag = getParam(params,'tag',null);
		var limit = params[2].value;

	        var button = createTiddlyButton(place,'ROUND!','Click here to pair up tiddlers tagged with \''+tag+'\'',this.onClickDeal);
		button.setAttribute("limit",limit);
	},

	onClickDeal: function (e) {
	        var macro = config.macros.speedDate;
		macro.round++;

		var tag = "geek";
		var title = "SpeedDateRound" + macro.round;
		var tiddlers = macro.shuffle(store.getTaggedTiddlers(tag));

		var body = '<<speedDateDial '+tag+'>>\n';

		var limit = this.getAttribute('limit')*2;
		if (limit > tiddlers.length) { limit = tiddlers.length; }

		for(var n=0;n<limit;n+=2) {
			body = body + '|' + tiddlers[n].title + '|' + (tiddlers[n+1]?tiddlers[n+1].title : "") + '|\n'
		}

		tiddler = store.saveTiddler(title,title,body,config.options.txtUserName);
		story.displayTiddlers(this,[title]);
	},

	shuffle: function(list) {
		var i = list.length;
		if (i == 0) return false;
		while (--i) {
			var j = Math.floor(Math.random() * (i + 1));
			var ti = list[i];
			var tj = list[j];
			list[i] = tj;
			list[j] = ti;
		}
		return list;
	}

}
} //# end of "install only once"
//}}}
/*{{{*/

body { font-size:10px; }
#sidebar { width:18em; margin:0; padding:0;}
#storyDisplay { margin-right:50px; }
div.header { border-bottom:solid 3px [[ColorPalette::SecondaryDark]];}
div.contact { margin:10px 80px 20px 0; padding:0; border:solid 1px #ccc; border-bottom:solid 1px #999; border-right:solid 1px #999; background-color:#fff; }
div.contact div.vcardContainer {margin:2px 0 0 0; background-color:#eee;}
div.contact div.vcardContainer div.vcard {margin:0; background-color:#eee; color:#000; border-width:0;}
div.viewer pre { margin-right:30px; }

/*}}}*/
Phone calls made using the Web21C SDK. 

http://web21c.bt.com
Person up for a spot of speed-geek-dating