<!--{{{-->
<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 0 1em 1em; left:-1px; top:-1px;}
.headerForeground {position:absolute; padding:4.5em 0 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:0 0.2em; padding:0.2em 0.3em; display:block;}
#sidebarOptions input {margin:0.4em 0.5em;}
#sidebarOptions .sliderPanel {margin-left:1em; padding:0.5em; font-size:.85em;}
#sidebarOptions .sliderPanel a {font-weight:bold; display:inline; padding:0;}
#sidebarOptions .sliderPanel input {margin:0 0 0.3em 0;}
#sidebarTabs .tabContents {width:15em; overflow:hidden;}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

.viewer table, table.twtable {border-collapse:collapse; margin:0.8em 1.0em;}
.viewer th, .viewer td, .viewer tr,.viewer caption,.twtable th, .twtable td, .twtable tr,.twtable caption {padding:3px;}
table.listView {font-size:0.85em; margin:0.8em 1.0em;}
table.listView th, table.listView td, table.listView tr {padding: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 0; font-size:.9em;}
.editorFooter .button {padding-top:0px; padding-bottom:0px;}

.fieldsetFix {border:0; padding:0; margin: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;}
#backstageToolbar {position:relative;}
#backstageArea a {font-weight:bold; margin-left:0.5em; padding:0.3em 0.5em;}
#backstageButton {display:none; position:absolute; z-index:175; top:0; right:0;}
#backstageButton a {padding:0.1em 0.4em; margin:0.1em;}
#backstage {position:relative; width:100%; z-index:50;}
#backstagePanel {display:none; z-index:100; position:absolute; width:90%; margin-left:3em; padding:1em;}
.backstagePanelFooter {padding-top:0.2em; float:right;}
.backstagePanelFooter a {padding:0.2em 0.4em;}
#backstageCloak {display:none; z-index:20; position:absolute; width:100%; height:100px;}

.whenBackstage {display:none;}
.backstageVisible .whenBackstage {display:block;}
/*}}}*/
/***
StyleSheet for use when a translation requires any css style changes.
This StyleSheet can be used directly by languages such as Chinese, Japanese and Korean which need larger font sizes.
***/
/*{{{*/
body {font-size:0.8em;}
#sidebarOptions {font-size:1.05em;}
#sidebarOptions a {font-style:normal;}
#sidebarOptions .sliderPanel {font-size:0.95em;}
.subtitle {font-size:0.8em;}
.viewer table.listView {font-size:0.95em;}
/*}}}*/
/*{{{*/
@media print {
#mainMenu, #sidebar, #messageArea, .toolbar, #backstageButton, #backstageArea {display: none !important;}
#displayArea {margin: 1em 1em 0em;}
noscript {display:none;} /* Fixes a feature in Firefox 1.5.0.2 where print preview displays the noscript content */
}
/*}}}*/
<!--{{{-->
<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
<div class='headerShadow'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&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>>
Det var det jeg skulle gøre
A quick start guide is provided in the [[Kom i gang med Lektier & opgaver]] tiddler.

This application has been built using TiddlyWiki and requires several plugins to function.  For an up-to-date list of the plugins used, and other building blocks required to build TeamTasks, take a look at the [[Release Notes]].

TeamTasks also require some definitions, which you can modify and add to as required:
[[BrugerDefinitioner|UserDefinitions]]
PriorityDefinitions
ScopeDefinitions
StatusDefinitions
<html>
<div class='vcard'>
<a class='url fn n' href='undefined'><span class='given-name'>Anne</span><span class='family-name'>Other</span></a>
<div class='email'><span><a href='mailto:anneother@nowhere.com'>anneother@nowhere.com</a></span></div>
</div></html>
/***
|Name|CalendarPlugin|
|Source|http://www.TiddlyTools.com/#CalendarPlugin|
|Version|2008.06.17|
|Author|Eric Shulman|
|Original Author|SteveRumsby|
|License|unknown|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Options|##Configuration|
|Description|display monthly and yearly calendars|

NOTE: For enhanced date display (including popups), you must also install [[DatePlugin]]
!!!!!Usage:
<<<
|{{{<<calendar>>}}}|Produce a full-year calendar for the current year|
|{{{<<calendar year>>}}}|Produce a full-year calendar for the given year|
|{{{<<calendar year month>>}}}|Produce a one-month calendar for the given month and year|
|{{{<<calendar thismonth>>}}}|Produce a one-month calendar for the current month|
|{{{<<calendar lastmonth>>}}}|Produce a one-month calendar for last month|
|{{{<<calendar nextmonth>>}}}|Produce a one-month calendar for next month|
<<<
!!!!!Configuration:
<<<
|''First day of week:''<br>{{{config.options.txtCalFirstDay}}}|<<option txtCalFirstDay>>|(Monday = 0, Sunday = 6)|
|''First day of weekend:''<br>{{{config.options.txtCalStartOfWeekend}}}|<<option txtCalStartOfWeekend>>|(Monday = 0, Sunday = 6)|

<<option chkDisplayWeekNumbers>> Display week numbers //(note: Monday will be used as the start of the week)//
|''Week number display format:''<br>{{{config.options.txtWeekNumberDisplayFormat }}}|<<option txtWeekNumberDisplayFormat >>|
|''Week number link format:''<br>{{{config.options.txtWeekNumberLinkFormat }}}|<<option txtWeekNumberLinkFormat >>|
<<<
!!!!!Revisions
<<<
2008.06.17: added support for config.macros.calendar.todaybg
2008.02.27: in handler(), DON'T set hard-coded default date format, so that *customized* value (pre-defined in config.macros.calendar.journalDateFmt is used.
2008.02.17: in createCalendarYear(), fix next/previous year calculation (use parseInt() to convert to numeric value).  Also, use journalDateFmt for date linking when NOT using [[DatePlugin]].
2008.02.16: in createCalendarDay(), week numbers now created as TiddlyLinks, allowing quick creation/navigation to 'weekly' journals (based on request from Kashgarinn)
2008.01.08: in createCalendarMonthHeader(), "month year" heading is now created as TiddlyLink, allowing quick creation/navigation to 'month-at-a-time' journals
2007.11.30: added "return false" to onclick handlers (prevent IE from opening blank pages)
2006.08.23: added handling for weeknumbers (code supplied by Martin Budden (see "wn**" comment marks).  Also, incorporated updated by Jeremy Sheeley to add caching for reminders (see [[ReminderMacros]], if installed)
2005.10.30: in config.macros.calendar.handler(), use "tbody" element for IE compatibility.  Also, fix year calculation for IE's getYear() function (which returns '2005' instead of '105'). Also, in createCalendarDays(), use showDate() function (see [[DatePlugin]], if installed) to render autostyled date with linked popup.  Updated calendar stylesheet definition: use .calendar class-specific selectors, add text centering and margin settings
2006.05.29: added journalDateFmt handling
<<<
***/
/***
!!!!!Code section:
***/
//{{{
version.extensions.calendar = { major: 0, minor: 7, revision: 0, date: new Date(2008, 6, 17)};

if(config.options.txtCalFirstDay == undefined)
  config.options.txtCalFirstDay = 0;
if(config.options.txtCalStartOfWeekend == undefined)
  config.options.txtCalStartOfWeekend = 5;
if(config.options.chkDisplayWeekNumbers == undefined)//wn**
  config.options.chkDisplayWeekNumbers = false;
if(config.options.chkDisplayWeekNumbers)
  config.options.txtCalFirstDay = 0;
if(config.options.txtWeekNumberDisplayFormat == undefined)//wn**
  config.options.txtWeekNumberDisplayFormat = "w0WW";
if(config.options.txtWeekNumberLinkFormat == undefined)//wn**
  config.options.txtWeekNumberLinkFormat = "YYYY-w0WW";

config.macros.calendar = {};
config.macros.calendar.monthnames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
config.macros.calendar.daynames = ["M", "T", "W", "T", "F", "S", "S"];
config.macros.calendar.todaybg = "#ccccff";
config.macros.calendar.weekendbg = "#c0c0c0";
config.macros.calendar.monthbg = "#e0e0e0";
config.macros.calendar.holidaybg = "#ffc0c0";
config.macros.calendar.journalDateFmt = "DD MMM YYYY";
config.macros.calendar.monthdays = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
config.macros.calendar.holidays = [ ]; // Not sure this is required anymore - use reminders instead
//}}}
//{{{
function calendarIsHoliday(date) // Is the given date a holiday?
{
	var longHoliday = date.formatString("0DD/0MM/YYYY");
	var shortHoliday = date.formatString("0DD/0MM");
	for(var i = 0; i < config.macros.calendar.holidays.length; i++) {
		if(config.macros.calendar.holidays[i] == longHoliday || config.macros.calendar.holidays[i] == shortHoliday)
			return true;
	}
	return false;
}
//}}}
//{{{
config.macros.calendar.handler = function(place,macroName,params) {
	var calendar = createTiddlyElement(place, "table", null, "calendar", null);
	var tbody = createTiddlyElement(calendar, "tbody", null, null, null);
	var today = new Date();
	var year = today.getYear();
	if (year<1900) year+=1900;

 	// get format for journal link by reading from SideBarOptions (ELS 5/29/06 - based on suggestion by Martin Budden)
	var text = store.getTiddlerText("SideBarOptions");
	var re = new RegExp("<<(?:newJournal)([^>]*)>>","mg"); var fm = re.exec(text);
	if (fm && fm[1]!=null) { var pa=fm[1].readMacroParams(); if (pa[0]) this.journalDateFmt = pa[0]; }

	if (params[0] == "thismonth") {
		cacheReminders(new Date(year, today.getMonth(), 1, 0, 0), 31);
		createCalendarOneMonth(tbody, year, today.getMonth());
	} 
	else if (params[0] == "lastmonth") {
		var month = today.getMonth()-1; if (month==-1) { month=11; year--; }
		cacheReminders(new Date(year, month, 1, 0, 0), 31);
		createCalendarOneMonth(tbody, year, month);
	}
	else if (params[0] == "nextmonth") {
		var month = today.getMonth()+1; if (month>11) { month=0; year++; }
		cacheReminders(new Date(year, month, 1, 0, 0), 31);
		createCalendarOneMonth(tbody, year, month);
	} else {
		if (params[0]) year = params[0];
		if(params[1]) {
			cacheReminders(new Date(year, params[1]-1, 1, 0, 0), 31);
			createCalendarOneMonth(tbody, year, params[1]-1);
		} else {
			cacheReminders(new Date(year, 0, 1, 0, 0), 366);
			createCalendarYear(tbody, year);
		}
	}
	window.reminderCacheForCalendar = null;
}
//}}}
//{{{
//This global variable is used to store reminders that have been cached
//while the calendar is being rendered.  It will be renulled after the calendar is fully rendered.
window.reminderCacheForCalendar = null;
//}}}
//{{{
function cacheReminders(date, leadtime)
{
	if (window.findTiddlersWithReminders == null) return;
	window.reminderCacheForCalendar = {};
	var leadtimeHash = [];
	leadtimeHash [0] = 0;
	leadtimeHash [1] = leadtime;
	var t = findTiddlersWithReminders(date, leadtimeHash, null, 1);
	for(var i = 0; i < t.length; i++) {
		//just tag it in the cache, so that when we're drawing days, we can bold this one.
		window.reminderCacheForCalendar[t[i]["matchedDate"]] = "reminder:" + t[i]["params"]["title"]; 
	}
}
//}}}
//{{{
function createCalendarOneMonth(calendar, year, mon)
{
	var row = createTiddlyElement(calendar, "tr", null, null, null);
	createCalendarMonthHeader(calendar, row, config.macros.calendar.monthnames[mon] + " " + year, true, year, mon);
	row = createTiddlyElement(calendar, "tr", null, null, null);
	createCalendarDayHeader(row, 1);
	createCalendarDayRowsSingle(calendar, year, mon);
}
//}}}
//{{{
function createCalendarMonth(calendar, year, mon)
{
	var row = createTiddlyElement(calendar, "tr", null, null, null);
	createCalendarMonthHeader(calendar, row, config.macros.calendar.monthnames[mon] + " " + year, false, year, mon);
	row = createTiddlyElement(calendar, "tr", null, null, null);
	createCalendarDayHeader(row, 1);
	createCalendarDayRowsSingle(calendar, year, mon);
}
//}}}
//{{{
function createCalendarYear(calendar, year)
{
	var row;
	row = createTiddlyElement(calendar, "tr", null, null, null);
	var back = createTiddlyElement(row, "td", null, null, null);
	var backHandler = function() {
		removeChildren(calendar);
		createCalendarYear(calendar, parseInt(year)-1);
		return false; // consume click
	};
	createTiddlyButton(back, "<", "Previous year", backHandler);
	back.align = "center";
	var yearHeader = createTiddlyElement(row, "td", null, "calendarYear", year);
	yearHeader.align = "center";
	yearHeader.setAttribute("colSpan",config.options.chkDisplayWeekNumbers?22:19);//wn**
	var fwd = createTiddlyElement(row, "td", null, null, null);
	var fwdHandler = function() {
		removeChildren(calendar);
		createCalendarYear(calendar, parseInt(year)+1);
		return false; // consume click
	};
	createTiddlyButton(fwd, ">", "Next year", fwdHandler);
	fwd.align = "center";
	createCalendarMonthRow(calendar, year, 0);
	createCalendarMonthRow(calendar, year, 3);
	createCalendarMonthRow(calendar, year, 6);
	createCalendarMonthRow(calendar, year, 9);
}
//}}}
//{{{
function createCalendarMonthRow(cal, year, mon)
{
	var row = createTiddlyElement(cal, "tr", null, null, null);
	createCalendarMonthHeader(cal, row, config.macros.calendar.monthnames[mon], false, year, mon);
	createCalendarMonthHeader(cal, row, config.macros.calendar.monthnames[mon+1], false, year, mon);
	createCalendarMonthHeader(cal, row, config.macros.calendar.monthnames[mon+2], false, year, mon);
	row = createTiddlyElement(cal, "tr", null, null, null);
	createCalendarDayHeader(row, 3);
	createCalendarDayRows(cal, year, mon);
}
//}}}
//{{{
function createCalendarMonthHeader(cal, row, name, nav, year, mon)
{
	var month;
	if (nav) {
		var back = createTiddlyElement(row, "td", null, null, null);
		back.align = "center";
		back.style.background = config.macros.calendar.monthbg;

		var backMonHandler = function() {
			var newyear = year;
			var newmon = mon-1;
			if(newmon == -1) { newmon = 11; newyear = newyear-1;}
			removeChildren(cal);
			cacheReminders(new Date(newyear, newmon , 1, 0, 0), 31);
			createCalendarOneMonth(cal, newyear, newmon);
			return false; // consume click
		};
		createTiddlyButton(back, "<", "Previous month", backMonHandler);
		month = createTiddlyElement(row, "td", null, "calendarMonthname")
		createTiddlyLink(month,name,true);
		month.setAttribute("colSpan", config.options.chkDisplayWeekNumbers?6:5);//wn**
		var fwd = createTiddlyElement(row, "td", null, null, null);
		fwd.align = "center";
		fwd.style.background = config.macros.calendar.monthbg; 

		var fwdMonHandler = function() {
			var newyear = year;
			var newmon = mon+1;
			if(newmon == 12) { newmon = 0; newyear = newyear+1;}
			removeChildren(cal);
			cacheReminders(new Date(newyear, newmon , 1, 0, 0), 31);
			createCalendarOneMonth(cal, newyear, newmon);
			return false; // consume click
		};
		createTiddlyButton(fwd, ">", "Next month", fwdMonHandler);
	} else {
		month = createTiddlyElement(row, "td", null, "calendarMonthname", name)
		month.setAttribute("colSpan",config.options.chkDisplayWeekNumbers?8:7);//wn**
	}
	month.align = "center";
	month.style.background = config.macros.calendar.monthbg;
}
//}}}
//{{{
function createCalendarDayHeader(row, num)
{
	var cell;
	for(var i = 0; i < num; i++) {
		if (config.options.chkDisplayWeekNumbers) createTiddlyElement(row, "td");//wn**
		for(var j = 0; j < 7; j++) {
			var d = j + (config.options.txtCalFirstDay - 0);
			if(d > 6) d = d - 7;
			cell = createTiddlyElement(row, "td", null, null, config.macros.calendar.daynames[d]);
			if(d == (config.options.txtCalStartOfWeekend-0) || d == (config.options.txtCalStartOfWeekend-0+1))
				cell.style.background = config.macros.calendar.weekendbg;
		}
	}
}
//}}}
//{{{
function createCalendarDays(row, col, first, max, year, mon) {
	var i;
	if (config.options.chkDisplayWeekNumbers){
		if (first<=max) {
			var ww = new Date(year,mon,first);
			var td=createTiddlyElement(row, "td");//wn**
			var link=createTiddlyLink(td,ww.formatString(config.options.txtWeekNumberLinkFormat),false);
			link.appendChild(document.createTextNode(ww.formatString(config.options.txtWeekNumberDisplayFormat)));
		}
		else createTiddlyElement(row, "td", null, null, null);//wn**
	}
	for(i = 0; i < col; i++)
		createTiddlyElement(row, "td", null, null, null);
	var day = first;
	for(i = col; i < 7; i++) {
		var d = i + (config.options.txtCalFirstDay - 0);
		if(d > 6) d = d - 7;
		var daycell = createTiddlyElement(row, "td", null, null, null);
		var isaWeekend = ((d == (config.options.txtCalStartOfWeekend-0) || d == (config.options.txtCalStartOfWeekend-0+1))? true:false);
		if(day > 0 && day <= max) {
			var celldate = new Date(year, mon, day);
			// ELS 2005.10.30: use <<date>> macro's showDate() function to create popup
			// ELS 5/29/06 - use journalDateFmt 
			if (window.showDate)
				showDate(daycell,celldate,"popup","DD",config.macros.calendar.journalDateFmt,true, isaWeekend);
			else {
				if(isaWeekend) daycell.style.background = config.macros.calendar.weekendbg;
				var title = celldate.formatString(config.macros.calendar.journalDateFmt);
				if(calendarIsHoliday(celldate))
					daycell.style.background = config.macros.calendar.holidaybg;
				var now=new Date();
				if ((now-celldate>=0) && (now-celldate<86400000)) // is today?
					daycell.style.background = config.macros.calendar.todaybg;
				if(window.findTiddlersWithReminders == null) {
					var link = createTiddlyLink(daycell, title, false);
					link.appendChild(document.createTextNode(day));
				} else
					var button = createTiddlyButton(daycell, day, title, onClickCalendarDate);
			}
		}
		day++;
	}
}
//}}}
//{{{
// We've clicked on a day in a calendar - create a suitable pop-up of options.
// The pop-up should contain:
//  * a link to create a new entry for that date
//  * a link to create a new reminder for that date
//  * an <hr>
//  * the list of reminders for that date
// NOTE: The following code is only used when [[DatePlugin]] is not present
function onClickCalendarDate(e)
{
	var button = this;
	var date = button.getAttribute("title");
	var dat = new Date(date.substr(6,4), date.substr(3,2)-1, date.substr(0, 2));

	date = dat.formatString(config.macros.calendar.journalDateFmt);
	var popup = createTiddlerPopup(this);
	popup.appendChild(document.createTextNode(date));
	var newReminder = function() {
		var t = store.getTiddlers(date);
		displayTiddler(null, date, 2, null, null, false, false);
		if(t) {
			document.getElementById("editorBody" + date).value += "\n<<reminder day:" + dat.getDate() +
				" month:" + (dat.getMonth()+1) + " year:" + (dat.getYear()+1900) + " title: >>";
		} else {
			document.getElementById("editorBody" + date).value = "<<reminder day:" + dat.getDate() +
				" month:" + (dat.getMonth()+1) +" year:" + (dat.getYear()+1900) + " title: >>";
		}
		return false; // consume click
	};
	var link = createTiddlyButton(popup, "New reminder", null, newReminder); 
	popup.appendChild(document.createElement("hr"));
	var t = findTiddlersWithReminders(dat, [0,14], null, 1);
	for(var i = 0; i < t.length; i++) {
		link = createTiddlyLink(popup, t[i].tiddler, false);
		link.appendChild(document.createTextNode(t[i].tiddler));
	}
	return false; // consume click
}
//}}}
//{{{
function calendarMaxDays(year, mon)
{
	var max = config.macros.calendar.monthdays[mon];
	if(mon == 1 && (year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0)) max++;
	return max;
}
//}}}
//{{{
function createCalendarDayRows(cal, year, mon)
{
	var row = createTiddlyElement(cal, "tr", null, null, null);
	var first1 = (new Date(year, mon, 1)).getDay() -1 - (config.options.txtCalFirstDay-0);
	if(first1 < 0) first1 = first1 + 7;
	var day1 = -first1 + 1;
	var first2 = (new Date(year, mon+1, 1)).getDay() -1 - (config.options.txtCalFirstDay-0);
	if(first2 < 0) first2 = first2 + 7;
	var day2 = -first2 + 1;
	var first3 = (new Date(year, mon+2, 1)).getDay() -1 - (config.options.txtCalFirstDay-0);
	if(first3 < 0) first3 = first3 + 7;
	var day3 = -first3 + 1;

	var max1 = calendarMaxDays(year, mon);
	var max2 = calendarMaxDays(year, mon+1);
	var max3 = calendarMaxDays(year, mon+2);

	while(day1 <= max1 || day2 <= max2 || day3 <= max3) {
		row = createTiddlyElement(cal, "tr", null, null, null);
		createCalendarDays(row, 0, day1, max1, year, mon); day1 += 7;
		createCalendarDays(row, 0, day2, max2, year, mon+1); day2 += 7;
		createCalendarDays(row, 0, day3, max3, year, mon+2); day3 += 7;
	}
}
//}}}
//{{{
function createCalendarDayRowsSingle(cal, year, mon)
{
	var row = createTiddlyElement(cal, "tr", null, null, null);
	var first1 = (new Date(year, mon, 1)).getDay() -1 - (config.options.txtCalFirstDay-0);
	if(first1 < 0) first1 = first1+ 7;
	var day1 = -first1 + 1;
	var max1 = calendarMaxDays(year, mon);
	while(day1 <= max1) {
		row = createTiddlyElement(cal, "tr", null, null, null);
		createCalendarDays(row, 0, day1, max1, year, mon); day1 += 7;
	}
}
//}}}
//{{{
setStylesheet(".calendar, .calendar table, .calendar th, .calendar tr, .calendar td { text-align:center; } .calendar, .calendar a { margin:0px !important; padding:0px !important; }", "calendarStyles");
//}}}
// // override cookie settings for CalendarPlugin:
//{{{
config.options.txtCalFirstDay=6;
config.options.txtCalStartOfWeekend=5;
//}}}

// // override internal default settings for CalendarPlugin:
//{{{
config.macros.calendar.journalDateFmt="DDD MMM 0DD YYYY";
//}}}
You can create your own custom views of the tasks using the ~TeamTask Report View Plugin (TTReportViewPlugin).


The general form for calling the plugin is like this:
{{{
<<TTReportView>>
}}}


You can also specify which fields to display in your report like this:
{{{
<<TTReportView DisplayFields:"fieldName,fieldName,fieldName">>
}}}
for example:
{{{
<<TTReportView DisplayFields:"Title,Priority,Status">>
}}}


In addition, you can choose to order your results by a given field like this:
{{{
<<TTReportView OrderBy:"fieldName,[asc|desc]">>
}}}
for example:
{{{
<<TTReportView DisplayFields:"Title,Priority,Status" OrderBy:"Status,asc">>
}}}


You can also specify field values to include and exclude tasks and create filtered reports:
{{{
<<TTReportView FieldName:"value">>
}}}
{{{
<<TTReportView FieldName:"!value">>
}}}

for example:
{{{
<<TTReportView DisplayFields:"Title,Priority,Status" OrderBy:"Status,asc" Priority:"high" Status:"!closed">>
}}}
Det er nemt at oprette opgaver. Alle tiddlers mærket med 'task' vil blive til en "opgavetiddler". Når du går ud af edit mode vil du kunne se at det er en opgavetiddler (gul baggrund) og den har rullemenuer med [[opgavedefinitioner|TaskDefinitions]].

Du kan også oprette nye opgaver ved at klikke på <<newTiddler label:'Ny opgave' title:NewTask tag:task text:'Skriv noget tekst og klik på DONE for at se rullemenuerne'>> knappen i menuen øverst th. på siden.
[[Modificer opgavekontrol områder|TaskTiddlerControls]][[Tidsrammer|ScopeDefinitions]][[BrugerDefinitioner|UserDefinitions]][[Prioriteringer|PriorityDefinitions]][[Status|StatusDefinitions]][[Modificer denne menu|MainMenu]][[Muligheder|OptionsPanel]]
/***
|''Navn:''|DanishTranslationPlugin|
|''Beskrivelse:''|Translation of TiddlyWiki into Danish|
|''Forfatter:''|MartinBudden (mjbudden (at) gmail (dot) com)|
|''Kilde:''|www.example.com |
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/association/locales/core/en/locale.en.js |
|''Version:''|0.3.7|
|''Dato:''|Jul 6, 2007|
|''Kommentarer:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev |
|''Licens:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]] |
|''~CoreVersion:''|2.4|
***/

//{{{
//--
//-- Translateable strings
//--

// Strings in "double quotes" should be translated; strings in 'single quotes' should be left alone

config.locale = "da"; // W3C language tag

if (config.options.txtUserName == 'YourName') // do not translate this line, but do translate the next line
	merge(config.options,{txtUserName: "DitNavn"});

merge(config.tasks,{
	save: {text: "gem", tooltip: "Gem dine ændringer til denne TiddlyWiki", action: saveChanges},
	sync: {text: "synk", tooltip: "Synkronisér ændringer med andre TiddlyWiki filer og servere", content: '<<sync>>'},
	importTask: {text: "importér", tooltip: "Importér tiddlers og plugins fra andre TiddlyWiki filer og servere", content: '<<importTiddlers>>'},
	tweak: {text: "Tilpas", tooltip: "Tilpas TiddlyWikis udseende og opførsel", content: '<<options>>'},
	upgrade: {text: "upgradér", tooltip: "Upgrader TiddlyWikis kerne kode", content: '<<upgrade>>'},
	plugins: {text: "udvidelser", tooltip: "Administrér installerede udvidelser", content: '<<plugins>>'}
});

// Options that can be set in the options panel and/or cookies
merge(config.optionsDesc,{
	txtUserName: "Brugernavn til signering af dine ændringer",
	chkRegExpSearch: "Avend almindelige udtryk til søgninger",
	chkCaseSensitiveSearch: "Forskel på store og små bogstaver",
	chkIncrementalSearch: "Bogstav for bogstav-søgning",
	chkAnimate: "Anvend animationer",
	chkSaveBackups: "Gem en backupfil når der gemmes ændringer",
	chkAutoSave: "Gem automatisk ændringer",
	chkGenerateAnRssFeed: "Lav et RSS feed når der gemmes ændringer",
	chkSaveEmptyTemplate: "Lav en tom skabelon når der gemmes ændringer",
	chkOpenInNewWindow: "Åben internet links i et nyt vindue",
	chkToggleLinks: "Når man klikker på et link i åbne tiddlers lukkes de",
	chkHttpReadOnly: "Skjul redigeringsværktøjer når den vises over HTTP",
	chkForceMinorUpdate: "Opdatér ikke brugernavn og dato når tiddlers bliver ændrede",
	chkConfirmDelete: "Bed om bekræftelse før tiddlers slettes",
	chkInsertTabs: "Brug tab tasten til at indsætte tab tegn istedet for at hoppe imellem felter",
	txtBackupFolder: "Navn på mappe til brug for backups",
	txtMaxEditRows: "Maximum antal af rækker i edit bokse",
	txtFileSystemCharSet: "Default tegnsæt til at gemme ændringer (Kun i Firefox/Mozilla)"});

merge(config.messages,{
	customConfigError: "Der opstod problemer ved loading af udvidelser. Se PluginManager for detaljer",
	pluginError: "Fejl: %0",
	pluginDisabled: "Ikke udført fordi det er slået fra via 'systemConfigDisable' tag",
	pluginForced: "Udført fordi det er tvunget via 'systemConfigForce' tag",
	pluginVersionError: "Ikke udført fordi denne udvidelse kræver en nyere udgave af TiddlyWiki",
	nothingSelected: "Intet er valgt. Du er nødt til at vælge en eller flere ting først",
	savedSnapshotError: "Det ser ud som om denne TiddlyWiki er blevet gemt forkert. Se venligst http://www.tiddlywiki.com/#DownloadSoftware for details",
	subtitleUnknown: "(ukendt)",
	undefinedTiddlerToolTip: "Tiddleren '%0' findes ikke endnu",
	shadowedTiddlerToolTip: "Tiddleren '%0' findes ikke endnu, men har en foruddefineret skygge værdi",
	tiddlerLinkTooltip: "%0 - %1, %2",
	externalLinkTooltip: "Internet link til %0",
	noTags: "Der er ingen taggede tiddlere",
	notFileUrlError: "Du er nødt til at gemme denne TiddlyWiki til en fil før du kan gemme ændringer",
	cantSaveError: "Det er ikke muligt at gemme ændringer. Mulige grunde indbefatter:\n- din browser understøtter det ikke (Firefox, Internet Explorer, Safari og Opera virker alle fint hvis de er konfigurerede korrekt)\n- stien til din TiddlyWiki fil indeholder ulovlige tegn\n- TiddlyWiki HTML filen er blevet flyttet eller omdøbt",
	invalidFileError: "Den originale fil '%0' lader ikke til at være en rigtig TiddlyWiki",
	backupSaved: "Backup gemt",
	backupFailed: "Det lykkedes IKKE at gemme en backup fil",
	rssSaved: "RSS feed gemt",
	rssFailed: "Det lykkedes IKKE at gemme et RSS feed",
	emptySaved: "Tom skabelon gemt",
	emptyFailed: "Det lykkedes IKKE at gemme en tom skabelon",
	mainSaved: "Hoved TiddlyWiki fil gemt",
	mainFailed: "Det lykkedes IKKE at gemme hoved TiddlyWiki filen. Dine ændringer er IKKE blevet gemt",
	macroError: "Fejl i makro <<\%0>>",
	macroErrorDetails: "Fejl ved udførsel af makro <<\%0>>:\n%1",
	missingMacro: "Ingen sådan makro",
	overwriteWarning: "En tiddler med navnet '%0' findes allerede. Vælg OK for at overskrive den",
	unsavedChangesWarning: "ADVARSEL! Der er ugemte æmdringer i TiddlyWikien\n\nVælg OK for at gemme\nVælg FORTRYD for at afvise",
	confirmExit: "--------------------------------\n\nDer er ugemte ændringer i TiddlyWikien. Hvis du fortsætter vil du miste disse ændringer\n\n--------------------------------",
	saveInstructions: "GemÆndringer",
	unsupportedTWFormat: "Ikke understøttet TiddlyWiki format '%0'",
	tiddlerSaveError: "Fejl ved forsøg på at gemme tiddler '%0'",
	tiddlerLoadError: "Fejl ved load af tiddler '%0'",
	wrongSaveFormat: "Kan ikke gemme med formatet '%0'. Bruger standard format til at gemme.",
	invalidFieldName: "Ikke tilladt feltnavn %0",
	fieldCannotBeChanged: "Felt '%0' kan ikke ændres",
	loadingMissingTiddler: "Forsøger at hente tiddleren '%0' fra '%1' serveren ved:\n\n'%2' i arbejdsområdet '%3'",
	upgradeDone: "Opgradering til version %0 er nu fuldført\n\nKlik 'OK' for at genopfriske den nyligt opgraderede TiddlyWiki"});

merge(config.messages.messageClose,{
	text: "luk",
	tooltip: "luk dette meddelelsesområde"});

config.messages.backstage = {
	open: {text: "bagscenen", tooltip: "Åben bagsceneområdet for at ændre på nogle grundlæggende indstillinger"},
	close: {text: "luk", tooltip: "Luk bagsceneområdet"},
	prompt: "bagscenen: ",
	decal: {
		edit: {text: "edit", tooltip: "Redigér tiddleren '%0'"}
	}
};

config.messages.listView = {
	tiddlerTooltip: "Klik for at se hele denne tiddlers tekst",
	previewUnavailable: "(forhåndsvisning er ikke tilgængelig)"
};

config.messages.dates.months = ["Januar", "Februar", "Marts", "April", "Maj", "Juni", "Juli", "August", "September", "Oktober", "November","December"];
config.messages.dates.days = ["Søndag", "Mandag", "Tirsdag", "Onsdag", "Torsdag", "Fredag", "Lørdag"];
config.messages.dates.shortMonths = ["Jan", "Feb", "Mar", "Apr", "Maj", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec"];
config.messages.dates.shortDays = ["Søn", "Man", "Tir", "Ons", "Tor", "Fre", "Lør"];
// suffixes for dates, eg "1ste","2den","3die"..."30te","31te"
config.messages.dates.daySuffixes = ["ste","den","die","te","te","te","te","te","te","te",
		"te","te","te","te","te","te","te","te","te","te",
		"ste","den","die","te","te","te","te","te","te","te",
		"te"];
config.messages.dates.am = "formiddag";
config.messages.dates.pm = "eftermiddag";

merge(config.messages.tiddlerPopup,{
	});

merge(config.views.wikified.tag,{
	labelNoTags: "ingen tags",
	labelTags: "tags: ",
	openTag: "Åben tag '%0'",
	tooltip: "Vis tiddlere der er taggede med '%0'",
	openAllText: "Åben alle",
	openAllTooltip: "Åben alle disse tiddlere",
	popupNone: "Ingen andre tiddlere er taggede med '%0'"});

merge(config.views.wikified,{
	defaultText: "Tiddleren '%0' findes ikke endnu. Dobbelt-klik for at lave den",
	defaultModifier: "(mangler)",
	shadowModifier: "(indbygget skygge tiddler)",
	dateFormat: "DD MMM YYYY", // use this to change the date format for your locale, eg "YYYY MMM DD", do not translate the Y, M or D
	createdPrompt: "lavet"});

merge(config.views.editor,{
	tagPrompt: "Skriv tags delt med mellemrum, [[brug 2 dobbelte firkantede klammer]] om nødvendigt, eller tilføj allerede eksisterende",
	defaultText: "Skriv teksten til '%0'"});

merge(config.views.editor.tagChooser,{
	text: "tags",
	tooltip: "Vælg eksisterende tags som tilføjelse til denne tiddler",
	popupNone: "Der er ikke defineret nogen tags",
	tagTooltip: "Tilføj tagget '%0'"});

merge(config.messages,{
	sizeTemplates:
		[
		{unit: 1024*1024*1024, template: "%0\u00a0GB"},
		{unit: 1024*1024, template: "%0\u00a0MB"},
		{unit: 1024, template: "%0\u00a0KB"},
		{unit: 1, template: "%0\u00a0B"}
		]});

merge(config.macros.search,{
	label: "søg",
	prompt: "Søg i denne TiddlyWiki",
	accessKey: "F",
	successMsg: "Der er fundet %0 tiddlere som matcher %1",
	failureMsg: "Der er ikke fundet nogen tiddlere som matcher %0"});

merge(config.macros.tagging,{
	label: "tagger: ",
	labelNotTag: "tagger ikke",
	tooltip: "Liste over tiddlere der er taggede med '%0'"});

merge(config.macros.timeline,{
	dateFormat: "DD MMM YYYY"});// use this to change the date format for your locale, eg "YYYY MMM DD", do not translate the Y, M or D

merge(config.macros.allTags,{
	tooltip: "Vis tiddlere der er taggede med '%0'",
	noTags: "Der er ingen taggede tiddlere"});

config.macros.list.all.prompt = "Alle tiddlere i alfabetisk orden";
config.macros.list.missing.prompt = "Tiddlere der linkes til men som ikke er definerede";
config.macros.list.orphans.prompt = "Tiddlere som der ikke linkes til fra nogen andre tiddlere";
config.macros.list.shadowed.prompt = "Tiddlere som er skyggede med grundlæggende indhold";
config.macros.list.touched.prompt = "Tiddlere som er blevet ændret lokalt ";

merge(config.macros.closeAll,{
	label: "luk alle",
	prompt: "Luk alle viste tiddlere (bortset fra dem, der er ved at blive redigeret)"});

merge(config.macros.permaview,{
	label: "vis permalink",
	prompt: "Lav et link til en URL som henter alle de netop nu synlige tiddlere"});

merge(config.macros.saveChanges,{
	label: "gem ændringer",
	prompt: "Gem alle tiddlere for at lave en ny TiddlyWiki",
	accessKey: "S"});

merge(config.macros.newTiddler,{
	label: "ny tiddler",
	prompt: "Lav en ny tiddler",
	title: "Ny Tiddler",
	accessKey: "N"});

merge(config.macros.newJournal,{
	label: "ny journal",
	prompt: "Lav en ny tiddler ud fra nuværende dato og tid",
	accessKey: "J"});

merge(config.macros.options,{
	wizardTitle: "Tilpas avancerede muligheder",
	step1Title: "Disse muligheder gemmes i cookies i din browser",
	step1Html: "<input type='hidden' name='markList'></input><br><input type='checkbox' checked='false' name='chkUnknown'>Show unknown options</input>",
	unknownDescription: "//(ukendt)//",
	listViewTemplate: {
		columns: [
			{name: 'Option', field: 'option', title: "Option", type: 'String'},
			{name: 'Description', field: 'description', title: "Description", type: 'WikiText'},
			{name: 'Name', field: 'name', title: "Name", type: 'String'}
			],
		rowClasses: [
			{className: 'lowlight', field: 'lowlight'}
			]}
	});

merge(config.macros.plugins,{
	wizardTitle: "Administrer udvidelser",
	step1Title: "Aktive udvidelser",
	step1Html: "<input type='hidden' name='markList'></input>", // DO NOT TRANSLATE
	skippedText: "(Denne udvidelse er ikke blevet aktiveret fordi den først er blevet tilføjet efter start)",
	noPluginText: "Der er ikke installeret nogen udvidelser",
	confirmDeleteText: "Er du sikker på at du vil slette disse udvidelser:\n\n%0",
	removeLabel: "Fjern systemConfig tag",
	removePrompt: "Fjern systemConfig tag",
	deleteLabel: "slet",
	deletePrompt: "Slet disse tiddlere permanent",
	listViewTemplate: {
		columns: [
			{name: 'Selected', field: 'Selected', rowName: 'title', type: 'Selector'},
			{name: 'Tiddler', field: 'tiddler', title: "Tiddler", type: 'Tiddler'},
			{name: 'Size', field: 'size', tiddlerLink: 'size', title: "Size", type: 'Size'},
			{name: 'Forced', field: 'forced', title: "Forced", tag: 'systemConfigForce', type: 'TagCheckbox'},
			{name: 'Disabled', field: 'disabled', title: "Disabled", tag: 'systemConfigDisable', type: 'TagCheckbox'},
			{name: 'Executed', field: 'executed', title: "Loaded", type: 'Boolean', trueText: "Yes", falseText: "No"},
			{name: 'Startup Time', field: 'startupTime', title: "Startup Time", type: 'String'},
			{name: 'Error', field: 'error', title: "Status", type: 'Boolean', trueText: "Error", falseText: "OK"},
			{name: 'Log', field: 'log', title: "Log", type: 'StringList'}
			],
		rowClasses: [
			{className: 'error', field: 'error'},
			{className: 'warning', field: 'warning'}
			]}
	});

merge(config.macros.toolbar,{
	moreLabel: "mere",
	morePrompt: "Vis flere muligheder"
	});

merge(config.macros.refreshDisplay,{
	label: "genopfrisk",
	prompt: "Genopfrisk hele TiddlyWikiens udseende"
	});

merge(config.macros.importTiddlers,{
	readOnlyWarning: "Du kan ikke importere til en låst TiddlyWiki fil. Prøv at åbne den fra en fil:// URL",
	wizardTitle: "Importer tiddlere fra en anden fil eller server",
	step1Title: "Trin 1: Find serveren eller TiddlyWiki filen",
	step1Html: "Vælg servertypen: <select name='selTypes'><option value=''>Choose...</option></select><br>Indskriv webadresse eller sti her: <input type='text' size=50 name='txtPath'><br>...eller søg efter en fil: <input type='file' size=50 name='txtBrowse'><br><hr>...eller vælg et forudbestemt feed: <select name='selFeeds'><option value=''>Vælg...</option></select>",
	openLabel: "åbn",
	openPrompt: "Åbn forbindelsen til denne fil eller server",
	openError: "Der var problemer med at hente tiddlywiki filen",
	statusOpenHost: "Forbinder til hosten",
	statusGetWorkspaceList: "Henter en liste over tilgængelige arbejdsområder",
	step2Title: "Trin 2: Vælg arbejdsområde",
	step2Html: "Indskriv et navn på arbejdsområdet: <input type='text' size=50 name='txtWorkspace'><br>...eller vælg et der allerede er der: <select name='selWorkspace'><option value=''>Choose...</option></select>",
	cancelLabel: "fortryd",
	cancelPrompt: "Fortryd denne import",
	statusOpenWorkspace: "Åben arbejdsområdet",
	statusGetTiddlerList: "Henter listen over tilgængelige tiddlere",
	errorGettingTiddlerList: "Fejl ved hentning af liste over tiddlere, klik Fortryd for at prøve igen",
	step3Title: "Trin 3: Vælg hvilke tiddlere der skal importeres",
	step3Html: "<input type='hidden' name='markList'></input><br><input type='checkbox' checked='true' name='chkSync'>Keep these tiddlers linked to this server so that you can synchronise subsequent changes</input><br><input type='checkbox' name='chkSave'>Save the details of this server in a 'systemServer' tiddler called:</input> <input type='text' size=25 name='txtSaveTiddler'>",
	importLabel: "importer",
	importPrompt: "Importer disse tiddlere",
	confirmOverwriteText: "Er du sikker på at du vil overskrive disse tiddlere:\n\n%0",
	step4Title: "Trin 4: Importerer %0 tiddler(e)",
	step4Html: "<input type='hidden' name='markReport'></input>", // DO NOT TRANSLATE
	doneLabel: "udført",
	donePrompt: "Luk denne wizard",
	statusDoingImport: "Importerer tiddlere",
	statusDoneImport: "Alle tiddlere er importede",
	systemServerNamePattern: "%2 on %1",
	systemServerNamePatternNoWorkspace: "%1",
	confirmOverwriteSaveTiddler: "Tiddleren '%0' findes allerede. Klik 'OK' for at overskrive den med detaljerne fra denne server, eller 'Fortryd' for at efterlade uændret",
	serverSaveTemplate: "|''Type:''|%0|\n|''URL:''|%1|\n|''Workspace:''|%2|\n\nDenne tiddler blev lavet automatisk for at skrive denne servers detaljer",
	serverSaveModifier: "(System)",
	listViewTemplate: {
		columns: [
			{name: 'Selected', field: 'Selected', rowName: 'title', type: 'Selector'},
			{name: 'Tiddler', field: 'tiddler', title: "Tiddler", type: 'Tiddler'},
			{name: 'Size', field: 'size', tiddlerLink: 'size', title: "Size", type: 'Size'},
			{name: 'Tags', field: 'tags', title: "Tags", type: 'Tags'}
			],
		rowClasses: [
			]}
	});

merge(config.macros.upgrade,{
	wizardTitle: "Opgrader TiddlyWikis kerne kode",
	step1Title: "Opdater eller reparer denne TiddlyWiki til sidste nye udgivelse",
	step1Html: "Du er ved at opgradere til sidste nye udgave af TiddlyWikis kerne kode (from <a href='%0' class='externalLink' target='_blank'>%1</a>). Dit indhold vil blive bibeholdt under opgraderinen.<br><br>Bemærk at opgraderinger kan konfikte med gamle udvidelser. Hvis du får problemer med den opgraderede fil se her <a href='http://www.tiddlywiki.org/wiki/CoreUpgrades' class='externalLink' target='_blank'>http://www.tiddlywiki.org/wiki/CoreUpgrades</a>",
	errorCantUpgrade: "Kan ikke opgradere denne TiddlyWiki. Du kan kun opgradere en TiddlyWiki fil som er gemt lokalt på en pc",
	errorNotSaved: "Du skal gemme ændringer før du kan gennemføre en opgradering",
	step2Title: "Bekræft opgraderingsdetaljer",
	step2Html_downgrade: "Du er ved at nedgradere til TiddlyWiki version %0 fra %1.<br><br>Nedgradering til en ældre udgave af kerne koden er IKKE tilrådeligt",
	step2Html_restore: "Denne tiddlyWike bruger allerede den sidste nye kerne kode (%0).<br><br>Du kan fortsætte med opgraderingen for at sikre dig at koden ikke er blevet ødelagt",
	step2Html_upgrade: "Du er ved at opgradere til TiddlyWiki version %0 fra %1",
	upgradeLabel: "opgrader",
	upgradePrompt: "Forbered opgraderingsprocessen",
	statusPreparingBackup: "Forbereder backup",
	statusSavingBackup: "Gemmer backup fil",
	errorSavingBackup: "Der var problemer med at gemme backup filen",
	statusLoadingCore: "Loader kernekoden",
	errorLoadingCore: "Fejl ved load af kernekoden",
	errorCoreFormat: "Fejl ved den nye kernekode",
	statusSavingCore: "Gemmer den nye kernekode",
	statusReloadingCore: "Genloader den nye kernekode",
	startLabel: "start",
	startPrompt: "Start opgraderingsprocessen",
	cancelLabel: "fortryd",
	cancelPrompt: "Fortryd opgraderingsprocessen",
	step3Title: "Opgradering afbrudt",
	step3Html: "Du har afbrudt opgraderingsprocessen"
	});

merge(config.macros.sync,{
	listViewTemplate: {
		columns: [
			{name: 'Selected', field: 'selected', rowName: 'title', type: 'Selector'},
			{name: 'Tiddler', field: 'tiddler', title: "Tiddler", type: 'Tiddler'},
			{name: 'Server Type', field: 'serverType', title: "Server type", type: 'String'},
			{name: 'Server Host', field: 'serverHost', title: "Server host", type: 'String'},
			{name: 'Server Workspace', field: 'serverWorkspace', title: "Server workspace", type: 'String'},
			{name: 'Status', field: 'status', title: "Synchronisation status", type: 'String'},
			{name: 'Server URL', field: 'serverUrl', title: "Server URL", text: "View", type: 'Link'}
			],
		rowClasses: [
			],
		buttons: [
			{caption: "Synkronisér disse tiddlere", name: 'sync'}
			]},
	wizardTitle: "Synkroniser med internet servere og filer",
	step1Title: "Vælg hvilke tiddlere du vil synkronisere",
	step1Html: "<input type='hidden' name='markList'></input>", // DO NOT TRANSLATE
	syncLabel: "synk",
	syncPrompt: "Synkronisér disse tiddlere",
	hasChanged: "Ændret imens den var koblet fra",
	hasNotChanged: "Uændret imens den var koblet fra",
	syncStatusList: {
		none: {text: "...", color: "gennemsigtig", display:null},
		changedServer: {text: "Ændret på serveren", color: '#8080ff', display:null},
		changedLocally: {text: "Ændret imens den var koblet fra", color: '#80ff80', display:null},
		changedBoth: {text: "ændret imens den var koblet fra også på serveren", color: '#ff8080', display:null},
		notFound: {text: "Ikke fundet på serveren", color: '#ffff80', display:null},
		putToServer: {text: "Gemt update på serveren", color: '#ff80ff', display:null},
		gotFromServer: {text: "Hentet update fra serveren", color: '#80ffff', display:null}
		}
	});

merge(config.commands.closeTiddler,{
	text: "luk",
	tooltip: "Luk denne tiddler"});

merge(config.commands.closeOthers,{
	text: "luk andre",
	tooltip: "Luk alle andre tiddlere"});

merge(config.commands.editTiddler,{
	text: "redigér",
	tooltip: "Redigér denne tiddler",
	readOnlyText: "se",
	readOnlyTooltip: "Se denne tiddlers kilde"});

merge(config.commands.saveTiddler,{
	text: "færdig",
	tooltip: "Gem ændringer til denne tiddler"});

merge(config.commands.cancelTiddler,{
	text: "fortryd",
	tooltip: "Fortryd ændringer til denne tiddler",
	warning: "Er du sikker på at du vil fortryde dine ændringer til  '%0'?",
	readOnlyText: "færdig",
	readOnlyTooltip: "Se tiddlere normalt"});

merge(config.commands.deleteTiddler,{
	text: "slet",
	tooltip: "Slet denne tiddler",
	warning: "Er du sikker på at du vil slette '%0'?"});

merge(config.commands.permalink,{
	text: "permalink",
	tooltip: "Permalink til denne tiddler"});

merge(config.commands.references,{
	text: "referencer",
	tooltip: "Vis tiddlere som linker til denne tiddler",
	popupNone: "Ingen referencer"});

merge(config.commands.jump,{
	text: "spring",
	tooltip: "Spring til en anden tiddler"});

merge(config.commands.syncing,{
	text: "synkroniserer",
	tooltip: "Kontroller synkronisering af denne tiddler med en server eller en fil",
	currentlySyncing: "<div>Currently syncing via <span class='popupHighlight'>'%0'</span> to:</"+"div><div>host: <span class='popupHighlight'>%1</span></"+"div><div>workspace: <span class='popupHighlight'>%2</span></"+"div>", // Note escaping of closing <div> tag
	notCurrentlySyncing: "Sykroniserer ikke lige nu",
	captionUnSync: "Stop synkronisering af denne tiddler",
	chooseServer: "Synkronisér denne tiddler med en anden server:",
	currServerMarker: "\u25cf ",
	notCurrServerMarker: "  "});

merge(config.commands.fields,{
	text: "felter",
	tooltip: "Vis denne tiddlers udvidede felter",
	emptyText: "Der er ingen udvidede felter til rådighed for denne tiddler",
	listViewTemplate: {
		columns: [
			{name: 'Field', field: 'field', title: "Field", type: 'String'},
			{name: 'Value', field: 'value', title: "Value", type: 'String'}
			],
		rowClasses: [
			],
		buttons: [
			]}});

merge(config.shadowTiddlers,{
	DefaultTiddlers: "[[TranslatedGettingStarted]]",
	MainMenu: "[[TranslatedGettingStarted]]\n\n\n^^~TiddlyWiki version <<version>>\n© 2007 [[UnaMesa|http://www.unamesa.org/]]^^",
	TranslatedGettingStarted: "For at komme i gang med denne tomme tiddlywiki, skal du ændre på de følgende tiddlere:\n* SiteTitle & SiteSubtitle: Sidens titel og undertitel, som vist øverst (efter de er gemt, vil de også vise sig i browserens titelmenu)\n* MainMenu: er hovedmenuen (er oftest placeret til venstre)\n* DefaultTiddlers: Indeholder navnene på de tiddlere du vilhave skal starte op når du åbner TiddlyWiki\nDu skal også skrive dit brugernavn for at signere dine redigeringer: <<option txtUserName>>",
	SiteTitle: "Min TiddlyWiki",
	SiteSubtitle: "en genbrugelig ikke-liniær personlig web notesbog",
	SiteUrl: "http://www.tiddlywiki.com/",
	OptionsPanel: "Disse muligheder for at ændre på TiddlyWiki bliver gemt i din browser\n\nDit brugernavn til at signere dine ændringer. Skriv det som et WikiOrd (f.eks. PerPoulsen)\n<<option txtUserName>>\n\n<<option chkSaveBackups>> Save backups\n<<option chkAutoSave>> Auto save\n<<option chkRegExpSearch>> Regexp search\n<<option chkCaseSensitiveSearch>> Case sensitive search\n<<option chkAnimate>> Enable animations\n\n----\nAlso see [[TranslatedAdvancedOptions|AdvancedOptions]]",
	SideBarOptions: '<<search>><<closeAll>><<permaview>><<newTiddler>><<newJournal "DD MMM YYYY" "journal">><<saveChanges>><<slider chkSliderOptionsPanel OptionsPanel "muligheder \u00bb" "Ændre på TiddlyWikis avancerede muligheder">>',
	SideBarTabs: '<<tabs txtMainTab "Tidslinie" "Tidslinie" TabTimeline "Alle" "Alle tiddlere" TabAll "Tags" "Alle tags" TabTags "Flere" "Flere lister" TabMore>>',
	TabMore: '<<tabs txtMoreTab "Manglende" "Manglende tiddlere" TabMoreMissing "Uden tilknytning" "Tiddlere" TabMoreOrphans "Skyggede" "Skyggede tiddlere" TabMoreShadowed>>'
	});

merge(config.annotations,{
	AdvancedOptions: "Denne skygge tiddler giver adgang til flere avancerede muligheder",
	ColorPalette: "Disse værdier i denne skyggetiddler bestemmer hvilket farveskema, der bliver brugt til ~TiddlyWikis brugerflade",
	DefaultTiddlers: "Tiddlere som er listede i denne skyggetiddler vil automatisk blive vist når ~TiddlyWiki starter op",
	EditTemplate: "HTML skabelonen i denne skyggetiddler bestemmer hvordan tiddlere ser ud når de bliver redigerede",
	GettingStarted: "Denne skyggetiddler giver instruktioner om grundlæggende anvendelse",
	ImportTiddlers: "Denne skyggetiddler giver mulighed for at importere tiddlere",
	MainMenu: "Denne tiddler bliver brugt til at definere indholdet af hoved menuen i venstre side af skærmen",
	MarkupPreHead: "Denne tiddler bliver indsat i toppen af <head> sektionen på TiddlyWiki HTML filen",
	MarkupPostHead: "Denne tiddler bliver indsat i bunden af <head> sektionen på TiddlyWiki HTML filen",
	MarkupPreBody: "Denne tiddler bliver indsat i toppen af<body> sektionen på TiddlyWiki HTML filen",
	MarkupPostBody: "Denne tiddler bliver indsat i slutningen af  <body> sektionen på TiddlyWiki HTML filen umiddelbart efter script blokken",
	OptionsPanel: "Denne skyggetiddler bliver brugt til indholdet af muligheder skydepanelet i højre side",
	PageTemplate: "HTML skabelonen i denne skyggetiddler bestemmer det overordnede ~TiddlyWiki layout",
	PluginManager: "Denne skyggetiddler giver adgang til udvidelsesadministrationen",
	SideBarOptions: "Denne skyggetiddler bruges til indholdet af muligheder panelet i højre sidemenu",
	SideBarTabs: "Denne skyggetiddler bruges til indholdet af fanebladspanelet i højre sidemenu",
	SiteSubtitle: "Denne skyggetiddler bruges som anden del af sidens titel",
	SiteTitle: "Denne skyggetiddler bruges som første del af sidens titel",
	SiteUrl: "Denne skyggetiddler bør sættes til den fulde mål-URL til publikation",
	StyleSheetColors: "Denne skyggetiddler indeholder CSS definitionerne der bestemmer farverne på side elementerne. ''REDIGÉR IKKE DENNE TIDDLER'', lav i stedet dine ændringer i StyleSheet skyggetiddleren",
	StyleSheet: "Denne tiddler kan indeholde specialle CSS definitioner",
	StyleSheetLayout: "Denne skyggetiddler indeholder CSS definitioner der bestemmer layoutet på side elementer. ''REDIGÉR IKKE DENNE TIDDLER'', lav i stedet dine ændringer i StyleSheet skyggetiddleren",
	StyleSheetLocale: "Denne skyggetiddler indeholder CSS definitioner relateret til lokale oversættelser",
	StyleSheetPrint: "Denne skyggetiddler indeholder CSS definitioner til print",
	TabAll: "Denne skyggetiddler indeholder hvad der er i 'Alle' fanen i højre sidemenu",
	TabMore: "Denne skyggetiddler indeholder  hvad der er i 'Flere' fanen i højre sidemenu",
	TabMoreMissing: "Denne skyggetiddler indeholder  hvad der er i 'Mangler' fanen i højre sidemenu",
	TabMoreOrphans: "Denne skyggetiddler indeholder  hvad der er i  'Mangler tilknytning' fanen i højre sidemenu",
	TabMoreShadowed: "Denne skyggetiddler indeholder  hvad der er i 'Skyggede' fanen i højre sidemenu",
	TabTags: "Denne skyggetiddler indeholder  hvad der er i 'Tags' fanen i højre sidemenu",
	TabTimeline: "Denne skyggetiddler indeholder hvad der er i 'Tidslinie' fanen i højre sidemenu",
	ToolbarCommands: "Denne skyggetiddler bestemmer hvilke værktøjer der vises i tiddleres værktøjslinier",
	ViewTemplate: "HTML skabelonen i denne skyggetiddler bestemmer hvordan tiddlere ser ud"
	});

//}}}
/***
|Name|DatePlugin|
|Source|http://www.TiddlyTools.com/#DatePlugin|
|Documentation|http://www.TiddlyTools.com/#DatePluginInfo|
|Version|2.7.0|
|Author|Eric Shulman - ELS Design Studios|
|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||
|Options|##Configuration|
|Description|formatted dates plus popup menu with 'journal' link, changes and (optional) reminders|
There are quite a few calendar generators, reminders, to-do lists, 'dated tiddlers' journals, blog-makers and GTD-like schedule managers that have been built around TW.  While they all have different purposes, and vary in format, interaction, and style, in one way or another each of these plugins displays and/or uses date-based information to make finding, accessing and managing relevant tiddlers easier.  This plugin provides a general approach to embedding dates and date-based links/menus within tiddler content.
!!!!!Documentation
>see [[DatePluginInfo]]
!!!!!Configuration
<<<
<<option chkDatePopupHideCreated>> omit 'created' section from date popups
<<option chkDatePopupHideChanged>> omit 'changed' section from date popups
<<option chkDatePopupHideTagged>> omit 'tagged' section from date popups
<<option chkDatePopupHideReminders>> omit 'reminders' section from date popups
<<option chkShowJulianDate>> display Julian day number (1-365) below current date

see [[DatePluginConfig]] for additional configuration settings, for use in calendar displays, including:
*date formats
*color-coded backgrounds
*annual fixed-date holidays
*weekends
<<<
!!!!!Revisions
<<<
2008.03.08 [2.7.0] in addModifiedsToPopup(), if a tiddler was created on the specified date, don't list it in the 'changed' section of the popup.  Based on a request from Kashgarinn.
|please see [[DatePluginInfo]] for additional revision details|
2005.10.30 [0.9.0] pre-release
<<<
!!!!!Code
***/
//{{{
version.extensions.date = {major: 2, minor: 7, revision: 0, date: new Date(2008,3,8)};

config.macros.date = {
	format: "YYYY.0MM.0DD", // default date display format
	linkformat: "YYYY.0MM.0DD", // 'dated tiddler' link format
	linkedbg: "#babb1e", // "babble"
	todaybg: "#ffab1e", // "fable"
	weekendbg: "#c0c0c0", // "cocoa"
	holidaybg: "#ffaace", // "face"
	createdbg: "#bbeeff", // "beef"
	modifiedsbg: "#bbeeff", // "beef"
	remindersbg: "#c0ffee", // "coffee"
	holidays: [ "01/01", "07/04", "07/24", "11/24" ], // NewYearsDay, IndependenceDay(US), Eric's Birthday (hooray!), Thanksgiving(US)
	weekend: [ 1,0,0,0,0,0,1 ] // [ day index values: sun=0, mon=1, tue=2, wed=3, thu=4, fri=5, sat=6 ]
};

config.macros.date.handler = function(place,macroName,params)
{
	// do we want to see a link, a popup, or just a formatted date?
	var mode="display";
	if (params[0]=="display") { mode=params[0]; params.shift(); }
	if (params[0]=="popup") { mode=params[0]; params.shift(); }
	if (params[0]=="link") { mode=params[0]; params.shift(); }
	// get the date
	var now = new Date();
	var date = now;
	if (!params[0] || params[0]=="today")
		{ params.shift(); }
	else if (params[0]=="filedate")
		{ date=new Date(document.lastModified); params.shift(); }
	else if (params[0]=="tiddler")
		{ date=store.getTiddler(story.findContainingTiddler(place).id.substr(7)).modified; params.shift(); }
	else if (params[0].substr(0,8)=="tiddler:")
		{ var t; if ((t=store.getTiddler(params[0].substr(8)))) date=t.modified; params.shift(); }
	else {
		var y = eval(params.shift().replace(/Y/ig,(now.getYear()<1900)?now.getYear()+1900:now.getYear()));
		var m = eval(params.shift().replace(/M/ig,now.getMonth()+1));
		var d = eval(params.shift().replace(/D/ig,now.getDate()+0));
		date = new Date(y,m-1,d);
	}
	// date format with optional custom override
	var format=this.format; if (params[0]) format=params.shift();
	var linkformat=this.linkformat; if (params[0]) linkformat=params.shift();
	showDate(place,date,mode,format,linkformat);
}

window.showDate=showDate;
function showDate(place,date,mode,format,linkformat,autostyle,weekend)
{
	if (!mode) mode="display";
	if (!format) format=config.macros.date.format;
	if (!linkformat) linkformat=config.macros.date.linkformat;
	if (!autostyle) autostyle=false;

	// format the date output
	var title = date.formatString(format);
	var linkto = date.formatString(linkformat);

	// just show the formatted output
	if (mode=="display") { place.appendChild(document.createTextNode(title)); return; }

	// link to a 'dated tiddler'
	var link = createTiddlyLink(place, linkto, false);
	link.appendChild(document.createTextNode(title));
	link.title = linkto;
	link.date = date;
	link.format = format;
	link.linkformat = linkformat;

	// if using a popup menu, replace click handler for dated tiddler link
	// with handler for popup and make link text non-italic (i.e., an 'existing link' look)
	if (mode=="popup") {
		link.onclick = onClickDatePopup;
		link.style.fontStyle="normal";
	}
	// format the popup link to show what kind of info it contains (for use with calendar generators)
	if (autostyle) setDateStyle(place,link,weekend);
}
//}}}

//{{{
// NOTE: This function provides default logic for setting the date style when displayed in a calendar
// To customize the date style logic, please see[[DatePluginConfig]]
function setDateStyle(place,link,weekend) {
	// alias variable names for code readability
	var date=link.date;
	var fmt=link.linkformat;
	var linkto=date.formatString(fmt);
	var cmd=config.macros.date;

	if ((weekend!==undefined?weekend:isWeekend(date))&&(cmd.weekendbg!=""))
		{ place.style.background = cmd.weekendbg; }
	if (hasModifieds(date)||hasCreateds(date)||hasTagged(date,fmt))
		{ link.style.fontStyle="normal"; link.style.fontWeight="bold"; }
	if (hasReminders(date))
		{ link.style.textDecoration="underline"; }
	if (isToday(date))
		{ link.style.border="1px solid black"; }
	if (isHoliday(date)&&(cmd.holidaybg!=""))
		{ place.style.background = cmd.holidaybg; }
	if (hasCreateds(date)&&(cmd.createdbg!=""))
		{ place.style.background = cmd.createdbg; }
	if (hasModifieds(date)&&(cmd.modifiedsbg!=""))
		{ place.style.background = cmd.modifiedsbg; }
	if ((hasTagged(date,fmt)||store.tiddlerExists(linkto))&&(cmd.linkedbg!=""))
		{ place.style.background = cmd.linkedbg; }
	if (hasReminders(date)&&(cmd.remindersbg!=""))
		{ place.style.background = cmd.remindersbg; }
	if (isToday(date)&&(cmd.todaybg!=""))
		{ place.style.background = cmd.todaybg; }
	if (config.options.chkShowJulianDate) { // optional display of Julian date numbers
		var m=[0,31,59,90,120,151,181,212,243,273,304,334];
		var d=date.getDate()+m[date.getMonth()];
		var y=date.getFullYear();
		if (date.getMonth()>1 && (y%4==0 && y%100!=0) || y%400==0)
			d++; // after February in a leap year
		wikify("@@font-size:80%;<br>"+d+"@@",place);
	}

}
//}}}

//{{{
function isToday(date) // returns true if date is today
	{ var now=new Date(); return ((now-date>=0) && (now-date<86400000)); }

function isWeekend(date) // returns true if date is a weekend
	{ return (config.macros.date.weekend[date.getDay()]); }

function isHoliday(date) // returns true if date is a holiday
{
	var longHoliday = date.formatString("0MM/0DD/YYYY");
	var shortHoliday = date.formatString("0MM/0DD");
	for(var i = 0; i < config.macros.date.holidays.length; i++) {
		var holiday=config.macros.date.holidays[i];
		if (holiday==longHoliday||holiday==shortHoliday) return true;
	}
	return false;
}
//}}}

//{{{
// Event handler for clicking on a day popup
function onClickDatePopup(e)
{
	if (!e) var e = window.event;
	var theTarget = resolveTarget(e);
	var popup = Popup.create(this);
	if(popup) {
		// always show dated tiddler link (or just date, if readOnly) at the top...
		if (!readOnly || store.tiddlerExists(this.date.formatString(this.linkformat)))
			createTiddlyLink(popup,this.date.formatString(this.linkformat),true);
		else
			createTiddlyText(popup,this.date.formatString(this.linkformat));
		if (!config.options.chkDatePopupHideCreated)
			addCreatedsToPopup(popup,this.date,this.format);
		if (!config.options.chkDatePopupHideChanged)
			addModifiedsToPopup(popup,this.date,this.format);
		if (!config.options.chkDatePopupHideTagged)
			addTaggedToPopup(popup,this.date,this.linkformat);
		if (!config.options.chkDatePopupHideReminders)
			addRemindersToPopup(popup,this.date,this.linkformat);
	}
	Popup.show(popup,false);
	e.cancelBubble = true;
	if (e.stopPropagation) e.stopPropagation();
	return(false);
}
//}}}

//{{{
function indexCreateds() // build list of tiddlers, hash indexed by creation date
{
	var createds= { };
	var tiddlers = store.getTiddlers("title","excludeLists");
	for (var t = 0; t < tiddlers.length; t++) {
		var date = tiddlers[t].created.formatString("YYYY0MM0DD")
		if (!createds[date])
			createds[date]=new Array();
		createds[date].push(tiddlers[t].title);
	}
	return createds;
}
function hasCreateds(date) // returns true if date has created tiddlers
{
	if (!config.macros.date.createds) config.macros.date.createds=indexCreateds();
	return (config.macros.date.createds[date.formatString("YYYY0MM0DD")]!=undefined);
}

function addCreatedsToPopup(popup,when,format)
{
	var force=(store.isDirty() && when.formatString("YYYY0MM0DD")==new Date().formatString("YYYY0MM0DD"));
	if (force || !config.macros.date.createds) config.macros.date.createds=indexCreateds();
	var indent=String.fromCharCode(160)+String.fromCharCode(160);
	var createds = config.macros.date.createds[when.formatString("YYYY0MM0DD")];
	if (createds) {
		createds.sort();
		var e=createTiddlyElement(popup,"div",null,null,"created ("+createds.length+")");
		for(var t=0; t<createds.length; t++) {
			var link=createTiddlyLink(popup,createds[t],false);
			link.appendChild(document.createTextNode(indent+createds[t]));
			createTiddlyElement(popup,"br",null,null,null);
		}
	}
}
//}}}

//{{{
function indexModifieds() // build list of tiddlers, hash indexed by modification date
{
	var modifieds= { };
	var tiddlers = store.getTiddlers("title","excludeLists");
	for (var t = 0; t < tiddlers.length; t++) {
		var date = tiddlers[t].modified.formatString("YYYY0MM0DD")
		if (!modifieds[date])
			modifieds[date]=new Array();
		modifieds[date].push(tiddlers[t].title);
	}
	return modifieds;
}
function hasModifieds(date) // returns true if date has modified tiddlers
{
	if (!config.macros.date.modifieds) config.macros.date.modifieds = indexModifieds();
	return (config.macros.date.modifieds[date.formatString("YYYY0MM0DD")]!=undefined);
}

function addModifiedsToPopup(popup,when,format)
{
	var date=when.formatString("YYYY0MM0DD");
	var force=(store.isDirty() && date==new Date().formatString("YYYY0MM0DD"));
	if (force || !config.macros.date.modifieds) config.macros.date.modifieds=indexModifieds();
	var indent=String.fromCharCode(160)+String.fromCharCode(160);
	var mods = config.macros.date.modifieds[date];
	if (mods) {
		// if a tiddler was created on this date, don't list it in the 'changed' section
		if (config.macros.date.createds && config.macros.date.createds[date]) {
			var temp=[];
			for(var t=0; t<mods.length; t++)
				if (!config.macros.date.createds[date].contains(mods[t]))
					temp.push(mods[t]);
			mods=temp;
		}
		mods.sort();
		var e=createTiddlyElement(popup,"div",null,null,"changed ("+mods.length+")");
		for(var t=0; t<mods.length; t++) {
			var link=createTiddlyLink(popup,mods[t],false);
			link.appendChild(document.createTextNode(indent+mods[t]));
			createTiddlyElement(popup,"br",null,null,null);
		}
	}
}
//}}}

//{{{
function hasTagged(date,format) // returns true if date is tagging other tiddlers
{
	return store.getTaggedTiddlers(date.formatString(format)).length>0;
}

function addTaggedToPopup(popup,when,format)
{
	var indent=String.fromCharCode(160)+String.fromCharCode(160);
	var tagged=store.getTaggedTiddlers(when.formatString(format));
	if (tagged.length) var e=createTiddlyElement(popup,"div",null,null,"tagged ("+tagged.length+")");
	for(var t=0; t<tagged.length; t++) {
		var link=createTiddlyLink(popup,tagged[t].title,false);
		link.appendChild(document.createTextNode(indent+tagged[t].title));
		createTiddlyElement(popup,"br",null,null,null);
	}
}
//}}}

//{{{
function indexReminders(date,leadtime) // build list of tiddlers with reminders, hash indexed by reminder date
{
	var reminders = { };
	if(window.findTiddlersWithReminders!=undefined) { // reminder plugin is installed
		// DEBUG var starttime=new Date();
		var t = findTiddlersWithReminders(date, [0,leadtime], null, null, 1);
		for(var i=0; i<t.length; i++) reminders[t[i].matchedDate]=true;
		// DEBUG var out="Found "+t.length+" reminders in "+((new Date())-starttime+1)+"ms\n";
		// DEBUG out+="startdate: "+date.toLocaleDateString()+"\n"+"leadtime: "+leadtime+" days\n\n";
		// DEBUG for(var i=0; i<t.length; i++) { out+=t[i].matchedDate.toLocaleDateString()+" "+t[i].params.title+"\n"; }
		// DEBUG alert(out);
	}
	return reminders;
}

function hasReminders(date) // returns true if date has reminders
{
	if (window.reminderCacheForCalendar)
		return window.reminderCacheForCalendar[date]; // use calendar cache
	if (!config.macros.date.reminders)
		config.macros.date.reminders = indexReminders(date,90); // create a 90-day leadtime reminder cache
	return (config.macros.date.reminders[date]);
}

function addRemindersToPopup(popup,when,format)
{
	if(window.findTiddlersWithReminders==undefined) return; // reminder plugin not installed

	var indent = String.fromCharCode(160)+String.fromCharCode(160);
	var reminders=findTiddlersWithReminders(when, [0,31],null,null,1);
	createTiddlyElement(popup,"div",null,null,"reminders ("+(reminders.length||"none")+")");
	for(var t=0; t<reminders.length; t++) {
		link = createTiddlyLink(popup,reminders[t].tiddler,false);
		var diff=reminders[t].diff;
		diff=(diff<1)?"Today":((diff==1)?"Tomorrow":diff+" days");
		var txt=(reminders[t].params["title"])?reminders[t].params["title"]:reminders[t].tiddler;
		link.appendChild(document.createTextNode(indent+diff+" - "+txt));
		createTiddlyElement(popup,"br",null,null,null);
	}
	if (readOnly) return;	// omit "new reminder..." link
	var link = createTiddlyLink(popup,indent+"new reminder...",true); createTiddlyElement(popup,"br");
	var title = when.formatString(format);
	link.title="add a reminder to '"+title+"'";
	link.onclick = function() {
		// show tiddler editor
		story.displayTiddler(null, title, 2, null, null, false, false);
		// find body 'textarea'
		var c =document.getElementById("tiddler" + title).getElementsByTagName("*");
		for (var i=0; i<c.length; i++) if ((c[i].tagName.toLowerCase()=="textarea") && (c[i].getAttribute("edit")=="text")) break;
		// append reminder macro to tiddler content
		if (i<c.length) {
			if (store.tiddlerExists(title)) c[i].value+="\n"; else c[i].value="";
			c[i].value += "<<reminder";
			c[i].value += " day:"+when.getDate();
			c[i].value += " month:"+(when.getMonth()+1);
			c[i].value += " year:"+when.getFullYear();
			c[i].value += ' title:"Enter a title" >>';
		}
	};
}
//}}}
/***
|Name|DatePluginConfig|
|Source|http://www.TiddlyTools.com/#DatePluginConfig|
|Documentation|http://www.TiddlyTools.com/#DatePluginInfo|
|Version|2.6.0|
|Author|Eric Shulman - ELS Design Studios|
|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|formats, background colors and other optional settings for DatePlugin|
***/
// // Default popup content display options (can be overridden by cookies)
//{{{
if (config.options.chkDatePopupHideCreated===undefined)
	config.options.chkDatePopupHideCreated=false;
if (config.options.chkDatePopupHideChanged===undefined)
	config.options.chkDatePopupHideChanged=false;
if (config.options.chkDatePopupHideTagged===undefined)
	config.options.chkDatePopupHideTagged=false;
if (config.options.chkDatePopupHideReminders===undefined)
	config.options.chkDatePopupHideReminders=false;
//}}}

// // show Julian date number below regular date
//{{{
if (config.options.chkShowJulianDate===undefined)
	config.options.chkShowJulianDate=false;
//}}}

// // fixed-date annual holidays
//{{{
config.macros.date.holidays=[
	"01/01", // NewYearsDay, 
	"07/04", // US Independence Day
	"07/24"  // Eric's Birthday (hooray!)
];
//}}}

// // weekend map (1=weekend, 0=weekday)
//{{{
config.macros.date.weekend=[ 1,0,0,0,0,0,1 ]; // day index values: sun=0, mon=1, tue=2, wed=3, thu=4, fri=5, sat=6
//}}}

// // date display/link formats
//{{{
config.macros.date.format="YYYY.0MM.0DD"; // default date display format
config.macros.date.linkformat="YYYY.0MM.0DD"; // 'dated tiddler' link format
//}}}

// // When displaying a calendar (see [[CalendarPlugin]]), you can customize the colors/styles that are applied to the calendar dates by modifying the values and/or functions below:
//{{{
// default calendar colors
config.macros.date.weekendbg="#c0c0c0";
config.macros.date.holidaybg="#ffaace";
config.macros.date.createdbg="#bbeeff";
config.macros.date.modifiedsbg="#bbeeff";
config.macros.date.linkedbg="#babb1e";
config.macros.date.remindersbg="#c0ffee";

// apply calendar styles
function setDateStyle(place,link,weekend) {
	// alias variable names for code readability
	var date=link.date;
	var fmt=link.linkformat;
	var linkto=date.formatString(fmt);
	var cmd=config.macros.date;

	if ((weekend!==undefined?weekend:isWeekend(date))&&(cmd.weekendbg!=""))
		{ place.style.background = cmd.weekendbg; }
	if (hasModifieds(date)||hasCreateds(date)||hasTagged(date,fmt))
		{ link.style.fontStyle="normal"; link.style.fontWeight="bold"; }
	if (hasReminders(date))
		{ link.style.textDecoration="underline"; }
	if (isToday(date))
		{ link.style.border="1px solid black"; }
	if (isHoliday(date)&&(cmd.holidaybg!=""))
		{ place.style.background = cmd.holidaybg; }
	if (hasCreateds(date)&&(cmd.createdbg!=""))
		{ place.style.background = cmd.createdbg; }
	if (hasModifieds(date)&&(cmd.modifiedsbg!=""))
		{ place.style.background = cmd.modifiedsbg; }
	if ((hasTagged(date,fmt)||store.tiddlerExists(linkto))&&(cmd.linkedbg!=""))
		{ place.style.background = cmd.linkedbg; }
	if (hasReminders(date)&&(cmd.remindersbg!=""))
		{ place.style.background = cmd.remindersbg; }
	if (isToday(date)&&(cmd.todaybg!=""))
		{ place.style.background = cmd.todaybg; }
	if (config.options.chkShowJulianDate) {
		var m=[0,31,59,90,120,151,181,212,243,273,304,334];
		var d=date.getDate()+m[date.getMonth()];
		var y=date.getFullYear();
		if (date.getMonth()>1 && (y%4==0 && y%100!=0) || y%400==0) d++; // after February in a leap year
		wikify("@@font-size:80%;<br>"+d+"@@",place);
	}
}
//}}}
|Name|DatePluginInfo|
|Source|http://www.TiddlyTools.com/#DatePlugin|
|Documentation|http://www.TiddlyTools.com/#DatePluginInfo|
|Version|2.7.0|
|Author|Eric Shulman - ELS Design Studios|
|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|documentation|
|Requires||
|Overrides||
|Description|documentation for DatePlugin|
There are quite a few calendar generators, reminders, to-do lists, 'dated tiddlers' journals, blog-makers and GTD-like schedule managers that have been built around TW.  While they all have different purposes, and vary in format, interaction, and style, in one way or another each of these plugins displays and/or uses date-based information to make finding, accessing and managing relevant tiddlers easier.  This plugin provides a general approach to embedding dates and date-based links/menus within tiddler content.
!!!!!Usage
<<<
This plugin display formatted dates, for the specified year, month, day using number values or mathematical expressions such as (Y+1) or (D+30).  Optionally, you can create a link from the formatted output to a 'dated tiddler' for quick blogging or create a popup menu that includes the dated tiddler link plus links to tiddlers that were created/changed on that date, or are tagged with that date, as well as links to any pending reminders for the coming 31 days (if the RemindersPlugin is installed).  This plugin also provides a public API for easily incorporating formatted date output (with or without the links/popups) into other plugins, such as calendar generators, etc.

This plugin defines a macro: {{{<<date [mode] [date] [format] [linkformat]>>}}}.  All of the macro parameters are optional and, in it's simplest form, {{{<<date>>}}}, it is equivalent to the ~TiddlyWiki core macro, {{{<<today>>}}}.

However, where {{{<<today>>}}} simply inserts the current date/time in a predefined format (or custom format, using {{{<<today [format]>>}}}), the {{{<<date>>}}} macro's parameters take it much further than that:
* [mode] is either ''display'', ''link'' or ''popup''.  If omitted, it defaults to ''display''.  This param let's you select between simply displaying a formatted date, or creating a link to a specific 'date titled' tiddler or a popup menu containing a dated tiddler link, plus links to changes and reminders.
* [date] lets you enter ANY date (not just today) as ''year, month, and day values or simple mathematical expressions'' using pre-defined variables, Y, M, and D for the current year, month and day, repectively.  You can display the modification date of the current tiddler by using the keyword: ''tiddler'' in place of the year, month and day parameters.  Use ''tiddler://name-of-tiddler//'' to display the modification date of a specific tiddler.  You can also use keywords ''today'' or ''filedate'' to refer to these //dynamically changing// date/time values.  
* [format] and [linkformat] uses standard ~TiddlyWiki date formatting syntax.  The default is "YYYY.0MM.0DD"
>^^''DDD'' - day of week in full (eg, "Monday"), ''DD'' - day of month, ''0DD'' - adds leading zero^^
>^^''MMM'' - month in full (eg, "July"), ''MM'' - month number, ''0MM'' - adds leading zero^^
>^^''YYYY'' - full year, ''YY'' - two digit year, ''hh'' - hours, ''mm'' - minutes, ''ss'' - seconds^^
>^^//note: use of hh, mm or ss format codes is only supported with ''tiddler'', ''today'' or ''filedate'' values//^^
* [linkformat] - specify an alternative date format so that the title of a 'dated tiddler' link can have a format that differs from the date's displayed format

In addition to the macro syntax, DatePlugin also provides a public javascript API so that other plugins that work with dates (such as calendar generators, etc.) can quickly incorporate date formatted links or popups into their output:

''{{{showDate(place, date, mode, format, linkformat, autostyle, weekend)}}}'' 

Note that in addition to the parameters provided by the macro interface, the javascript API also supports two optional true/false parameters:
* [autostyle] - when true, the font/background styles of formatted dates are automatically adjusted to show the date's status:  'today' is boxed, 'changes' are bold, 'reminders' are underlined, while weekends and holidays (as well as changes and reminders) can each have a different background color to make them more visibly distinct from each other.
* [weekend] - true indicates a weekend, false indicates a weekday.  When this parameter is omitted, the plugin uses internal defaults to automatically determine when a given date falls on a weekend.
<<<
!!!!!Examples
<<<
The current date: <<date>>
The current time: <<date today "0hh:0mm:0ss">>
Today's blog: <<date link today "DDD, MMM DDth, YYYY">>
Recent blogs/changes/reminders: <<date popup Y M D-1 "yesterday">> <<date popup today "today">> <<date popup Y M D+1 "tomorrow">>
The first day of next month will be a <<date Y M+1 1 "DDD">>
This tiddler (DatePlugin) was last updated on: <<date tiddler "DDD, MMM DDth, YYYY">>
The SiteUrl was last updated on: <<date tiddler:SiteUrl "DDD, MMM DDth, YYYY">>
This document was last saved on <<date filedate "DDD, MMM DDth, YYYY at 0hh:0mm:0ss">>
<<date 2006 07 24 "MMM DDth, YYYY">> will be a <<date 2006 07 24 "DDD">>
<<<
!!!!!Revisions
<<<
2008.03.08 [2.7.0] in addModifiedsToPopup(), if a tiddler was created on the specified date, don't list it in the 'changed' section of the popup.  Based on a request from Kashgarinn
2008.01.31 [2.6.0] refactored date style logic into separate setDateStyle() function so it can be overridden by a custom definition.  See [[DatePluginConfig]].
2008.01.11 [2.5.0] added options to selectively suppress created/changes/tagged/reminders popup content 
2008.01.08 [*.*.*] plugin size reduction: documentation moved to DatePluginInfo
2007.11.21 [2.4.0] added hasTagged() and addTaggedToPopup() to list any tiddlers that has been tagged using the title of the dated journal tiddler asa tag value (i.e., the tiddlers that will be listed in the standard "tagging" display when viewing the journal tiddler itself).  Based on a request from Coby.
2007.06.20 [2.3.1] in onClickDatePopup(), use Popup.show() instead of deprecated ScrollToTiddlerPopup().  Fixes fatal error that prevents popups from being properly displayed
2007.05.31 [2.3.0] list "created" tiddlers in date popup.  Also, force re-cache of created/modified indices when displaying current date and store.isDirty(), so that popup is kept in sync with tiddler changes.
2006.05.09 [2.2.1] added "todaybg" handling to set background color of current date.  Also, honor excludeLists tag when getting lists of tiddlers.  Based on suggestions by Mark Hulme.
2006.05.05 [2.2.0] added "linkedbg" handling to set background color when a 'dated tiddler' exists.  Based on a suggestion by Mark Hulme.
2006.03.08 [2.1.2] add 'override leadtime' flag param in call to findTiddlersWithReminders(), and add "Enter a title" default text to new reminder handler.  Thanks to Jeremy Sheeley for these additional tweaks.
2006.03.06 [2.1.0] hasReminders() nows uses window.reminderCacheForCalendar[] when present.  If calendar cache is not present, indexReminders() now uses findTiddlersWithReminders() with a 90-day look ahead to check for reminders.  Also, switched default background colors for autostyled dates: reminders are now greenish ("c0ffee") and holidays are now reddish ("ffaace").
2006.02.14 [2.0.5] when readOnly is set (by TW core), omit "new reminders..." popup menu item and, if a "dated tiddler" does not already exist, display the date as simple text instead of a link.
2006.02.05 [2.0.4] added var to variables that were unintentionally global.  Avoids FireFox 1.5.0.1 crash bug when referencing global variables
2006.01.18 [2.0.3] In 1.2.x the tiddler editor's text area control was given an element ID=("tiddlerBody"+title), so that it was easy to locate this field and programmatically modify its content.  With the addition of configuration templates in 2.x, the textarea no longer has an ID assigned.  To find this control we now look through all the child nodes of the tiddler editor to locate a "textarea" control where attribute("edit") equals "text", and then append the new reminder to the contents of that control.
2006.01.11 [2.0.2] correct 'weekend' override detection logic in showDate()
2006.01.10 [2.0.1] allow custom-defined weekend days (default defined in config.macros.date.weekend[] array)
added flag param to showDate() API to override internal weekend[] array
2005.12.27 [2.0.0] Update for TW2.0
Added parameter handling for 'linkformat'
2005.12.21 [1.2.2] FF's date.getYear() function returns 105 (for the current year, 2005).  When calculating a date value from Y M and D expressions, the plugin adds 1900 to the returned year value get the current year number.  But IE's date.getYear() already returns 2005.  As a result, plugin calculated date values on IE were incorrect (e.g., 3905 instead of 2005).  Adding +1900 is now conditional so the values will be correct on both browsers.
2005.11.07 [1.2.1] added support for "tiddler" dynamic date parameter
2005.11.06 [1.2.0] added support for "tiddler:title" dynamic date parameter
2005.11.03 [1.1.2] when a reminder doesn't have a specified title parameter, use the title of the tiddler that contains the reminder as "fallback" text in the popup menu.  Based on a suggestion from BenjaminKudria.
2005.11.03 [1.1.1] Temporarily bypass hasReminders() logic to avoid excessive overhead from generating the indexReminders() cache.  While reminders can still appear in the popup menu, they just won't be indicated by auto-styling the date number that is displayed.  This single change saves approx. 60% overhead (5 second delay reduced to under 2 seconds).
2005.11.01 [1.1.0] corrected logic in hasModifieds() and hasReminders() so caching of indexed modifieds and reminders is done just once, as intended.  This should hopefully speed up calendar generators and other plugins that render multiple dates...
2005.10.31 [1.0.1] documentation and code cleanup
2005.10.31 [1.0.0] initial public release
2005.10.30 [0.9.0] pre-release
<<<
[[Kom i gang med Lektier & opgaver]]
To make it easy to organise tasks by the appropriate projects, products or whatever sensible unit best fits your needs, you can define a set of 'Scopes' in the ScopeDefinitions tiddler. This works in the same way as [[defining users|DefinerBrugere]].
I [[Lektier & opgaver|TeamTasks]], kan du knytte opgaver til flere brugere. Hvis du kun bruger det til dig selv kan du nemt fjerne funktionen.

Det er enkelt at oprette en bruger. Du skal blot tilføje navnene til [[BrugerDefinitioner|UserDefinitions]].  Hvert navn skal have sin egen linie.  Alle navne [[her|BrugerDefinitioner]] kan få tildelt opgaver.
/%
|Name|DigitalClock|
|Source|http://www.TiddlyTools.com/#DigitalClock|
|Version|1.0.0|
|Author|Eric Shulman - ELS Design Studios|
|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|script|
|Requires|InlineJavascriptPlugin|
|Overrides||
|Description|display current time with automatic LIVE update|

Usage: <<tiddler DigitalClock with: format tick>>

where 'format' is any TiddlyWiki date/time formatting string
and 'tick' is the time in seconds between display updates (default=1sec)

For example, use:
   << ... "0hh:0mm" 60>>
to show hours and minutes only, updated once per minute

%/<script>
	window.DigitalClock_tick=function(id){
		var e=document.getElementById(id); if (!e) return;
		e.title='click to '+(e.paused?'RESUME':'PAUSE')+' clock display';
		if (e.paused) return;
		e.innerHTML=new Date().formatString(e.fmt);
		setTimeout('window.DigitalClock_tick('+id+')',e.tick*1000);
	}
	var e=createTiddlyElement(place,'a',new Date().getTime()+Math.random());
	e.onclick=function(){this.paused=!this.paused;window.DigitalClock_tick(this.id);}
	e.style.cursor='pointer';
	e.fmt=('$1'=='$'+'1')?'hh12:0mm:0ss am':'$1';
	e.tick=('$2'=='$'+'2')?'1':'$2';
	window.DigitalClock_tick(e.id);
</script>
Jeg skal øve mig i at bruge Lektier og opgaver...
The following macro call exports all tiddlers to a text file "c:/MyTiddlyWikiExport.txt", using a customized format.
{{{
<<forEachTiddler
 script 'function getSortedTagsText(tiddler) {var tags = tiddler.tags; if (!tags) return ""; tags.sort(); var result = ""; for (var i = 0; i < tags.length;i++) {result += tags[i]+ " ";} return result;} function writeTiddler(tiddler) {return "==== "+tiddler.title+"=========================\nTags: "+ getSortedTagsText(tiddler)+"\nModified: "+tiddler.modified.convertToYYYYMMDDHHMM()+"\nModifier: "+tiddler.modifier+"\n--------------------------------------------------\n"+tiddler.text+"\n--------------------------------------------------\n(End of "+tiddler.title+")\n\n\n\n"}'
 write 
 'writeTiddler(tiddler)' 
 toFile 'file:///c:/MyTiddlyWikiExport.txt' withLineSeparator '\r\n'
>>
}}}
For better readablility here the script text in a nicer layout:
{{{
function getSortedTagsText(tiddler) {
 var tags = tiddler.tags; 
 if (!tags) 
 return ""; 
 tags.sort(); 
 var result = ""; 
 for (var i = 0; i < tags.length;i++) {
 result += tags[i]+ " ";
 } 
 return result;
} 

function writeTiddler(tiddler) {
 return "==== "+tiddler.title+"=========================\n"+
 "Tags: "+ getSortedTagsText(tiddler)+"\n"+
 "Modified: "+tiddler.modified.convertToYYYYMMDDHHMM()+"\n"+
 "Modifier: "+tiddler.modifier+"\n"+
 "--------------------------------------------------\n"+
 tiddler.text+"\n"+
 "--------------------------------------------------\n"
 "(End of "+tiddler.title+")\n\n\n\n"
}
}}}

<<forEachTiddler
 script 'function getSortedTagsText(tiddler) {var tags = tiddler.tags; if (!tags) return ""; tags.sort(); var result = ""; for (var i = 0; i < tags.length;i++) {result += tags[i]+ " ";} return result;} function writeTiddler(tiddler) {return "==== "+tiddler.title+"=========================\nTags: "+ getSortedTagsText(tiddler)+"\nModified: "+tiddler.modified.convertToYYYYMMDDHHMM()+"\nModifier: "+tiddler.modifier+"\n--------------------------------------------------\n"+tiddler.text+"\n--------------------------------------------------\n(End of "+tiddler.title+")\n\n\n\n"}'
 write 
 'writeTiddler(tiddler)' 
 toFile 'file:///c:/MyTiddlyWikiExport.txt' withLineSeparator '\r\n'
>>

Here are some examples that show the usage of the write action in the ForEachTiddlerMacro.

//''Select and Sort Examples''//
* InClauseExamples
* WhereClauseExamples
* SortClauseExamples
* ScriptClauseExamples
//''Action Examples''//
* AddToListActionExamples
* WriteActionExamples


Of cause you may also combine the examples, e.g. taking the whereClause of one example, the sortClause of a second and the action of a third.
//~~(Part of the [[ForEachTiddlerPlugin]])~~//

Create customizable lists, tables etc. for your selections of tiddlers. Specify the tiddlers to include and their order through a powerful language.

''Syntax:'' 
|>|{{{<<}}}''forEachTiddler'' [''in'' //tiddlyWikiPath//] [''where'' //whereCondition//] [''sortBy'' //sortExpression// [''ascending'' //or// ''descending'']] [''script'' //scriptText//] [//action// [//actionParameters//]]{{{>>}}}|
|//tiddlyWikiPath//|The filepath to the TiddlyWiki the macro should work on. When missing the current TiddlyWiki is used.|
|//whereCondition//|(quoted) JavaScript boolean expression. May refer to the build-in variables {{{tiddler}}} and {{{context}}}.|
|//sortExpression//|(quoted) JavaScript expression returning "comparable" objects (using '{{{<}}}','{{{>}}}','{{{==}}}'. May refer to the build-in variables {{{tiddler}}} and {{{context}}}.|
|//scriptText//|(quoted) JavaScript text. Typically defines JavaScript functions that are called by the various JavaScript expressions (whereClause, sortClause, action arguments,...)|
|//action//|The action that should be performed on every selected tiddler, in the given order. By default the actions [[addToList|AddToListAction]] and [[write|WriteAction]] are supported. When no action is specified [[addToList|AddToListAction]] is used.|
|//actionParameters//|(action specific) parameters the action may refer while processing the tiddlers (see action descriptions for details). <<tiddler [[JavaScript in actionParameters]]>>|
|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|


''Using JavaScript''

To give you a lot of flexibility the [[ForEachTiddlerMacro]] uses JavaScript in its arguments. Even if you are not that familiar with JavaScript you may find forEachTiddler useful. Just have a look at the various ready-to-use [[ForEachTiddlerExamples]] and adapt them to your needs.

''The Elements of the Macro''

The arguments of the ForEachTiddlerMacro consist of multiple parts, each of them being optional.

<<slider chkFETInClause [[inClause]] "inClause" "inClause">>
<<slider chkFETWhereClause [[whereClause]] "whereClause" "whereClause">>
<<slider chkFETSortClause [[sortClause]] "sortClause" "sortClause">>
<<slider chkFETScriptClause [[scriptClause]] "scriptClause" "scriptClause">>
<<slider chkFETActions [[Action Specification]] "Action Specification" "Action Specification">>

''Using Macros and ">" inside the forEachTiddler Macro''

You may use other macro calls into the expression, especially in the actionParameters. To avoid that the {{{>>}}} of such a macro call is misinterpreted as the end of the {{{<<forEachTiddler...>>}}} macro you must escape the {{{>>}}} of the inner macro with {{{$))}}} E.g. if you want to use {{{<<tiddler ...>>}}} inside the {{{forEachTiddler}}} macro you have to write {{{<<tiddler ...$))}}}.

In addition it is necessary to escape single {{{>}}} with the text {{{$)}}}.

''Using {{{<<tiddler ... with: ...>>}}} to re-use ForEachTiddler definitions''

Sometimes you may want to use a certain ForEachTiddler definition in slight variations. E.g. you may want to list either the tiddlers tagged with "ToDo" and in the other case with "Done". To do so you may use "Tiddler parameters". Here an example:

Replace the variable part of the ForEachTiddler definition with $1 ($2,... $9 are supported). E.g. you may create the tiddler "ListTaggedTiddlers" like this
{{{
<<forEachTiddler 
 where 
 'tiddler.tags.contains("$1")'
>>
}}}

Now you can use the ListTaggedTiddlers for various specific tags, using the {{{<<tiddler ...>>}}} macro:
{{{
<<tiddler ListTaggedTiddlers with: "systemConfig">>
}}}
{{{
<<tiddler ListTaggedTiddlers with: "Plugin">>
}}}


See also [[ForEachTiddlerExamples]].
/***
|''Name:''|ForEachTiddlerPlugin|
|''Version:''|1.0.8 (2007-04-12)|
|''Source:''|http://tiddlywiki.abego-software.de/#ForEachTiddlerPlugin|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]|
|''Copyright:''|&copy; 2005-2007 [[abego Software|http://www.abego-software.de]]|
|''TiddlyWiki:''|1.2.38+, 2.0|
|''Browser:''|Firefox 1.0.4+; Firefox 1.5; InternetExplorer 6.0|
!Description

Create customizable lists, tables etc. for your selections of tiddlers. Specify the tiddlers to include and their order through a powerful language.

''Syntax:'' 
|>|{{{<<}}}''forEachTiddler'' [''in'' //tiddlyWikiPath//] [''where'' //whereCondition//] [''sortBy'' //sortExpression// [''ascending'' //or// ''descending'']] [''script'' //scriptText//] [//action// [//actionParameters//]]{{{>>}}}|
|//tiddlyWikiPath//|The filepath to the TiddlyWiki the macro should work on. When missing the current TiddlyWiki is used.|
|//whereCondition//|(quoted) JavaScript boolean expression. May refer to the build-in variables {{{tiddler}}} and  {{{context}}}.|
|//sortExpression//|(quoted) JavaScript expression returning "comparable" objects (using '{{{<}}}','{{{>}}}','{{{==}}}'. May refer to the build-in variables {{{tiddler}}} and  {{{context}}}.|
|//scriptText//|(quoted) JavaScript text. Typically defines JavaScript functions that are called by the various JavaScript expressions (whereClause, sortClause, action arguments,...)|
|//action//|The action that should be performed on every selected tiddler, in the given order. By default the actions [[addToList|AddToListAction]] and [[write|WriteAction]] are supported. When no action is specified [[addToList|AddToListAction]]  is used.|
|//actionParameters//|(action specific) parameters the action may refer while processing the tiddlers (see action descriptions for details). <<tiddler [[JavaScript in actionParameters]]>>|
|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|

See details see [[ForEachTiddlerMacro]] and [[ForEachTiddlerExamples]].

!Revision history
* v1.0.8 (2007-04-12)
** Adapted to latest TiddlyWiki 2.2 Beta importTiddlyWiki API (introduced with changeset 2004). TiddlyWiki 2.2 Beta builds prior to changeset 2004 are no longer supported (but TiddlyWiki 2.1 and earlier, of cause)
* v1.0.7 (2007-03-28)
** Also support "pre" formatted TiddlyWikis (introduced with TW 2.2) (when using "in" clause to work on external tiddlers)
* v1.0.6 (2006-09-16)
** Context provides "viewerTiddler", i.e. the tiddler used to view the macro. Most times this is equal to the "inTiddler", but when using the "tiddler" macro both may be different.
** Support "begin", "end" and "none" expressions in "write" action
* v1.0.5 (2006-02-05)
** Pass tiddler containing the macro with wikify, context object also holds reference to tiddler containing the macro ("inTiddler"). Thanks to SimonBaird.
** Support Firefox 1.5.0.1
** Internal
*** Make "JSLint" conform
*** "Only install once"
* v1.0.4 (2006-01-06)
** Support TiddlyWiki 2.0
* v1.0.3 (2005-12-22)
** Features: 
*** Write output to a file supports multi-byte environments (Thanks to Bram Chen) 
*** Provide API to access the forEachTiddler functionality directly through JavaScript (see getTiddlers and performMacro)
** Enhancements:
*** Improved error messages on InternetExplorer.
* v1.0.2 (2005-12-10)
** Features: 
*** context object also holds reference to store (TiddlyWiki)
** Fixed Bugs: 
*** ForEachTiddler 1.0.1 has broken support on win32 Opera 8.51 (Thanks to BrunoSabin for reporting)
* v1.0.1 (2005-12-08)
** Features: 
*** Access tiddlers stored in separated TiddlyWikis through the "in" option. I.e. you are no longer limited to only work on the "current TiddlyWiki".
*** Write output to an external file using the "toFile" option of the "write" action. With this option you may write your customized tiddler exports.
*** Use the "script" section to define "helper" JavaScript functions etc. to be used in the various JavaScript expressions (whereClause, sortClause, action arguments,...).
*** Access and store context information for the current forEachTiddler invocation (through the build-in "context" object) .
*** Improved script evaluation (for where/sort clause and write scripts).
* v1.0.0 (2005-11-20)
** initial version

!Code
***/
//{{{

	
//============================================================================
//============================================================================
//		   ForEachTiddlerPlugin
//============================================================================
//============================================================================

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

if (!window.abego) window.abego = {};

version.extensions.ForEachTiddlerPlugin = {
	major: 1, minor: 0, revision: 8, 
	date: new Date(2007,3,12), 
	source: "http://tiddlywiki.abego-software.de/#ForEachTiddlerPlugin",
	licence: "[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]",
	copyright: "Copyright (c) abego Software GmbH, 2005-2007 (www.abego-software.de)"
};

// For backward compatibility with TW 1.2.x
//
if (!TiddlyWiki.prototype.forEachTiddler) {
	TiddlyWiki.prototype.forEachTiddler = function(callback) {
		for(var t in this.tiddlers) {
			callback.call(this,t,this.tiddlers[t]);
		}
	};
}

//============================================================================
// forEachTiddler Macro
//============================================================================

version.extensions.forEachTiddler = {
	major: 1, minor: 0, revision: 8, date: new Date(2007,3,12), provider: "http://tiddlywiki.abego-software.de"};

// ---------------------------------------------------------------------------
// Configurations and constants 
// ---------------------------------------------------------------------------

config.macros.forEachTiddler = {
	 // Standard Properties
	 label: "forEachTiddler",
	 prompt: "Perform actions on a (sorted) selection of tiddlers",

	 // actions
	 actions: {
		 addToList: {},
		 write: {}
	 }
};

// ---------------------------------------------------------------------------
//  The forEachTiddler Macro Handler 
// ---------------------------------------------------------------------------

config.macros.forEachTiddler.getContainingTiddler = function(e) {
	while(e && !hasClass(e,"tiddler"))
		e = e.parentNode;
	var title = e ? e.getAttribute("tiddler") : null; 
	return title ? store.getTiddler(title) : null;
};

config.macros.forEachTiddler.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
	// config.macros.forEachTiddler.traceMacroCall(place,macroName,params,wikifier,paramString,tiddler);

	if (!tiddler) tiddler = config.macros.forEachTiddler.getContainingTiddler(place);
	// --- Parsing ------------------------------------------

	var i = 0; // index running over the params
	// Parse the "in" clause
	var tiddlyWikiPath = undefined;
	if ((i < params.length) && params[i] == "in") {
		i++;
		if (i >= params.length) {
			this.handleError(place, "TiddlyWiki path expected behind 'in'.");
			return;
		}
		tiddlyWikiPath = this.paramEncode((i < params.length) ? params[i] : "");
		i++;
	}

	// Parse the where clause
	var whereClause ="true";
	if ((i < params.length) && params[i] == "where") {
		i++;
		whereClause = this.paramEncode((i < params.length) ? params[i] : "");
		i++;
	}

	// Parse the sort stuff
	var sortClause = null;
	var sortAscending = true; 
	if ((i < params.length) && params[i] == "sortBy") {
		i++;
		if (i >= params.length) {
			this.handleError(place, "sortClause missing behind 'sortBy'.");
			return;
		}
		sortClause = this.paramEncode(params[i]);
		i++;

		if ((i < params.length) && (params[i] == "ascending" || params[i] == "descending")) {
			 sortAscending = params[i] == "ascending";
			 i++;
		}
	}

	// Parse the script
	var scriptText = null;
	if ((i < params.length) && params[i] == "script") {
		i++;
		scriptText = this.paramEncode((i < params.length) ? params[i] : "");
		i++;
	}

	// Parse the action. 
	// When we are already at the end use the default action
	var actionName = "addToList";
	if (i < params.length) {
	   if (!config.macros.forEachTiddler.actions[params[i]]) {
			this.handleError(place, "Unknown action '"+params[i]+"'.");
			return;
		} else {
			actionName = params[i]; 
			i++;
		}
	} 
	
	// Get the action parameter
	// (the parsing is done inside the individual action implementation.)
	var actionParameter = params.slice(i);


	// --- Processing ------------------------------------------
	try {
		this.performMacro({
				place: place, 
				inTiddler: tiddler,
				whereClause: whereClause, 
				sortClause: sortClause, 
				sortAscending: sortAscending, 
				actionName: actionName, 
				actionParameter: actionParameter, 
				scriptText: scriptText, 
				tiddlyWikiPath: tiddlyWikiPath});

	} catch (e) {
		this.handleError(place, e);
	}
};

// Returns an object with properties "tiddlers" and "context".
// tiddlers holds the (sorted) tiddlers selected by the parameter,
// context the context of the execution of the macro.
//
// The action is not yet performed.
//
// @parameter see performMacro
//
config.macros.forEachTiddler.getTiddlersAndContext = function(parameter) {

	var context = config.macros.forEachTiddler.createContext(parameter.place, parameter.whereClause, parameter.sortClause, parameter.sortAscending, parameter.actionName, parameter.actionParameter, parameter.scriptText, parameter.tiddlyWikiPath, parameter.inTiddler);

	var tiddlyWiki = parameter.tiddlyWikiPath ? this.loadTiddlyWiki(parameter.tiddlyWikiPath) : store;
	context["tiddlyWiki"] = tiddlyWiki;
	
	// Get the tiddlers, as defined by the whereClause
	var tiddlers = this.findTiddlers(parameter.whereClause, context, tiddlyWiki);
	context["tiddlers"] = tiddlers;

	// Sort the tiddlers, when sorting is required.
	if (parameter.sortClause) {
		this.sortTiddlers(tiddlers, parameter.sortClause, parameter.sortAscending, context);
	}

	return {tiddlers: tiddlers, context: context};
};

// Returns the (sorted) tiddlers selected by the parameter.
//
// The action is not yet performed.
//
// @parameter see performMacro
//
config.macros.forEachTiddler.getTiddlers = function(parameter) {
	return this.getTiddlersAndContext(parameter).tiddlers;
};

// Performs the macros with the given parameter.
//
// @param parameter holds the parameter of the macro as separate properties.
//				  The following properties are supported:
//
//						place
//						whereClause
//						sortClause
//						sortAscending
//						actionName
//						actionParameter
//						scriptText
//						tiddlyWikiPath
//
//					All properties are optional. 
//					For most actions the place property must be defined.
//
config.macros.forEachTiddler.performMacro = function(parameter) {
	var tiddlersAndContext = this.getTiddlersAndContext(parameter);

	// Perform the action
	var actionName = parameter.actionName ? parameter.actionName : "addToList";
	var action = config.macros.forEachTiddler.actions[actionName];
	if (!action) {
		this.handleError(parameter.place, "Unknown action '"+actionName+"'.");
		return;
	}

	var actionHandler = action.handler;
	actionHandler(parameter.place, tiddlersAndContext.tiddlers, parameter.actionParameter, tiddlersAndContext.context);
};

// ---------------------------------------------------------------------------
//  The actions 
// ---------------------------------------------------------------------------

// Internal.
//
// --- The addToList Action -----------------------------------------------
//
config.macros.forEachTiddler.actions.addToList.handler = function(place, tiddlers, parameter, context) {
	// Parse the parameter
	var p = 0;

	// Check for extra parameters
	if (parameter.length > p) {
		config.macros.forEachTiddler.createExtraParameterErrorElement(place, "addToList", parameter, p);
		return;
	}

	// Perform the action.
	var list = document.createElement("ul");
	place.appendChild(list);
	for (var i = 0; i < tiddlers.length; i++) {
		var tiddler = tiddlers[i];
		var listItem = document.createElement("li");
		list.appendChild(listItem);
		createTiddlyLink(listItem, tiddler.title, true);
	}
};

abego.parseNamedParameter = function(name, parameter, i) {
	var beginExpression = null;
	if ((i < parameter.length) && parameter[i] == name) {
		i++;
		if (i >= parameter.length) {
			throw "Missing text behind '%0'".format([name]);
		}
		
		return config.macros.forEachTiddler.paramEncode(parameter[i]);
	}
	return null;
}

// Internal.
//
// --- The write Action ---------------------------------------------------
//
config.macros.forEachTiddler.actions.write.handler = function(place, tiddlers, parameter, context) {
	// Parse the parameter
	var p = 0;
	if (p >= parameter.length) {
		this.handleError(place, "Missing expression behind 'write'.");
		return;
	}

	var textExpression = config.macros.forEachTiddler.paramEncode(parameter[p]);
	p++;

	// Parse the "begin" option
	var beginExpression = abego.parseNamedParameter("begin", parameter, p);
	if (beginExpression !== null) 
		p += 2;
	var endExpression = abego.parseNamedParameter("end", parameter, p);
	if (endExpression !== null) 
		p += 2;
	var noneExpression = abego.parseNamedParameter("none", parameter, p);
	if (noneExpression !== null) 
		p += 2;

	// Parse the "toFile" option
	var filename = null;
	var lineSeparator = undefined;
	if ((p < parameter.length) && parameter[p] == "toFile") {
		p++;
		if (p >= parameter.length) {
			this.handleError(place, "Filename expected behind 'toFile' of 'write' action.");
			return;
		}
		
		filename = config.macros.forEachTiddler.getLocalPath(config.macros.forEachTiddler.paramEncode(parameter[p]));
		p++;
		if ((p < parameter.length) && parameter[p] == "withLineSeparator") {
			p++;
			if (p >= parameter.length) {
				this.handleError(place, "Line separator text expected behind 'withLineSeparator' of 'write' action.");
				return;
			}
			lineSeparator = config.macros.forEachTiddler.paramEncode(parameter[p]);
			p++;
		}
	}
	
	// Check for extra parameters
	if (parameter.length > p) {
		config.macros.forEachTiddler.createExtraParameterErrorElement(place, "write", parameter, p);
		return;
	}

	// Perform the action.
	var func = config.macros.forEachTiddler.getEvalTiddlerFunction(textExpression, context);
	var count = tiddlers.length;
	var text = "";
	if (count > 0 && beginExpression)
		text += config.macros.forEachTiddler.getEvalTiddlerFunction(beginExpression, context)(undefined, context, count, undefined);
	
	for (var i = 0; i < count; i++) {
		var tiddler = tiddlers[i];
		text += func(tiddler, context, count, i);
	}
	
	if (count > 0 && endExpression)
		text += config.macros.forEachTiddler.getEvalTiddlerFunction(endExpression, context)(undefined, context, count, undefined);

	if (count == 0 && noneExpression) 
		text += config.macros.forEachTiddler.getEvalTiddlerFunction(noneExpression, context)(undefined, context, count, undefined);
		

	if (filename) {
		if (lineSeparator !== undefined) {
			lineSeparator = lineSeparator.replace(/\\n/mg, "\n").replace(/\\r/mg, "\r");
			text = text.replace(/\n/mg,lineSeparator);
		}
		saveFile(filename, convertUnicodeToUTF8(text));
	} else {
		var wrapper = createTiddlyElement(place, "span");
		wikify(text, wrapper, null/* highlightRegExp */, context.inTiddler);
	}
};


// ---------------------------------------------------------------------------
//  Helpers
// ---------------------------------------------------------------------------

// Internal.
//
config.macros.forEachTiddler.createContext = function(placeParam, whereClauseParam, sortClauseParam, sortAscendingParam, actionNameParam, actionParameterParam, scriptText, tiddlyWikiPathParam, inTiddlerParam) {
	return {
		place : placeParam, 
		whereClause : whereClauseParam, 
		sortClause : sortClauseParam, 
		sortAscending : sortAscendingParam, 
		script : scriptText,
		actionName : actionNameParam, 
		actionParameter : actionParameterParam,
		tiddlyWikiPath : tiddlyWikiPathParam,
		inTiddler : inTiddlerParam, // the tiddler containing the <<forEachTiddler ...>> macro call.
		viewerTiddler : config.macros.forEachTiddler.getContainingTiddler(placeParam) // the tiddler showing the forEachTiddler result
	};
};

// Internal.
//
// Returns a TiddlyWiki with the tiddlers loaded from the TiddlyWiki of 
// the given path.
//
config.macros.forEachTiddler.loadTiddlyWiki = function(path, idPrefix) {
	if (!idPrefix) {
		idPrefix = "store";
	}
	var lenPrefix = idPrefix.length;
	
	// Read the content of the given file
	var content = loadFile(this.getLocalPath(path));
	if(content === null) {
		throw "TiddlyWiki '"+path+"' not found.";
	}
	
	var tiddlyWiki = new TiddlyWiki();

	// Starting with TW 2.2 there is a helper function to import the tiddlers
	if (tiddlyWiki.importTiddlyWiki) {
		if (!tiddlyWiki.importTiddlyWiki(content))
			throw "File '"+path+"' is not a TiddlyWiki.";
		tiddlyWiki.dirty = false;
		return tiddlyWiki;
	}
	
	// The legacy code, for TW < 2.2
	
	// Locate the storeArea div's
	var posOpeningDiv = content.indexOf(startSaveArea);
	var posClosingDiv = content.lastIndexOf(endSaveArea);
	if((posOpeningDiv == -1) || (posClosingDiv == -1)) {
		throw "File '"+path+"' is not a TiddlyWiki.";
	}
	var storageText = content.substr(posOpeningDiv + startSaveArea.length, posClosingDiv);
	
	// Create a "div" element that contains the storage text
	var myStorageDiv = document.createElement("div");
	myStorageDiv.innerHTML = storageText;
	myStorageDiv.normalize();
	
	// Create all tiddlers in a new TiddlyWiki
	// (following code is modified copy of TiddlyWiki.prototype.loadFromDiv)
	var store = myStorageDiv.childNodes;
	for(var t = 0; t < store.length; t++) {
		var e = store[t];
		var title = null;
		if(e.getAttribute)
			title = e.getAttribute("tiddler");
		if(!title && e.id && e.id.substr(0,lenPrefix) == idPrefix)
			title = e.id.substr(lenPrefix);
		if(title && title !== "") {
			var tiddler = tiddlyWiki.createTiddler(title);
			tiddler.loadFromDiv(e,title);
		}
	}
	tiddlyWiki.dirty = false;

	return tiddlyWiki;
};


	
// Internal.
//
// Returns a function that has a function body returning the given javaScriptExpression.
// The function has the parameters:
// 
//	 (tiddler, context, count, index)
//
config.macros.forEachTiddler.getEvalTiddlerFunction = function (javaScriptExpression, context) {
	var script = context["script"];
	var functionText = "var theFunction = function(tiddler, context, count, index) { return "+javaScriptExpression+"}";
	var fullText = (script ? script+";" : "")+functionText+";theFunction;";
	return eval(fullText);
};

// Internal.
//
config.macros.forEachTiddler.findTiddlers = function(whereClause, context, tiddlyWiki) {
	var result = [];
	var func = config.macros.forEachTiddler.getEvalTiddlerFunction(whereClause, context);
	tiddlyWiki.forEachTiddler(function(title,tiddler) {
		if (func(tiddler, context, undefined, undefined)) {
			result.push(tiddler);
		}
	});
	return result;
};

// Internal.
//
config.macros.forEachTiddler.createExtraParameterErrorElement = function(place, actionName, parameter, firstUnusedIndex) {
	var message = "Extra parameter behind '"+actionName+"':";
	for (var i = firstUnusedIndex; i < parameter.length; i++) {
		message += " "+parameter[i];
	}
	this.handleError(place, message);
};

// Internal.
//
config.macros.forEachTiddler.sortAscending = function(tiddlerA, tiddlerB) {
	var result = 
		(tiddlerA.forEachTiddlerSortValue == tiddlerB.forEachTiddlerSortValue) 
			? 0
			: (tiddlerA.forEachTiddlerSortValue < tiddlerB.forEachTiddlerSortValue)
			   ? -1 
			   : +1; 
	return result;
};

// Internal.
//
config.macros.forEachTiddler.sortDescending = function(tiddlerA, tiddlerB) {
	var result = 
		(tiddlerA.forEachTiddlerSortValue == tiddlerB.forEachTiddlerSortValue) 
			? 0
			: (tiddlerA.forEachTiddlerSortValue < tiddlerB.forEachTiddlerSortValue)
			   ? +1 
			   : -1; 
	return result;
};

// Internal.
//
config.macros.forEachTiddler.sortTiddlers = function(tiddlers, sortClause, ascending, context) {
	// To avoid evaluating the sortClause whenever two items are compared 
	// we pre-calculate the sortValue for every item in the array and store it in a 
	// temporary property ("forEachTiddlerSortValue") of the tiddlers.
	var func = config.macros.forEachTiddler.getEvalTiddlerFunction(sortClause, context);
	var count = tiddlers.length;
	var i;
	for (i = 0; i < count; i++) {
		var tiddler = tiddlers[i];
		tiddler.forEachTiddlerSortValue = func(tiddler,context, undefined, undefined);
	}

	// Do the sorting
	tiddlers.sort(ascending ? this.sortAscending : this.sortDescending);

	// Delete the temporary property that holds the sortValue.	
	for (i = 0; i < tiddlers.length; i++) {
		delete tiddlers[i].forEachTiddlerSortValue;
	}
};


// Internal.
//
config.macros.forEachTiddler.trace = function(message) {
	displayMessage(message);
};

// Internal.
//
config.macros.forEachTiddler.traceMacroCall = function(place,macroName,params) {
	var message ="<<"+macroName;
	for (var i = 0; i < params.length; i++) {
		message += " "+params[i];
	}
	message += ">>";
	displayMessage(message);
};


// Internal.
//
// Creates an element that holds an error message
// 
config.macros.forEachTiddler.createErrorElement = function(place, exception) {
	var message = (exception.description) ? exception.description : exception.toString();
	return createTiddlyElement(place,"span",null,"forEachTiddlerError","<<forEachTiddler ...>>: "+message);
};

// Internal.
//
// @param place [may be null]
//
config.macros.forEachTiddler.handleError = function(place, exception) {
	if (place) {
		this.createErrorElement(place, exception);
	} else {
		throw exception;
	}
};

// Internal.
//
// Encodes the given string.
//
// Replaces 
//	 "$))" to ">>"
//	 "$)" to ">"
//
config.macros.forEachTiddler.paramEncode = function(s) {
	var reGTGT = new RegExp("\\$\\)\\)","mg");
	var reGT = new RegExp("\\$\\)","mg");
	return s.replace(reGTGT, ">>").replace(reGT, ">");
};

// Internal.
//
// Returns the given original path (that is a file path, starting with "file:")
// as a path to a local file, in the systems native file format.
//
// Location information in the originalPath (i.e. the "#" and stuff following)
// is stripped.
// 
config.macros.forEachTiddler.getLocalPath = function(originalPath) {
	// Remove any location part of the URL
	var hashPos = originalPath.indexOf("#");
	if(hashPos != -1)
		originalPath = originalPath.substr(0,hashPos);
	// Convert to a native file format assuming
	// "file:///x:/path/path/path..." - pc local file --> "x:\path\path\path..."
	// "file://///server/share/path/path/path..." - FireFox pc network file --> "\\server\share\path\path\path..."
	// "file:///path/path/path..." - mac/unix local file --> "/path/path/path..."
	// "file://server/share/path/path/path..." - pc network file --> "\\server\share\path\path\path..."
	var localPath;
	if(originalPath.charAt(9) == ":") // pc local file
		localPath = unescape(originalPath.substr(8)).replace(new RegExp("/","g"),"\\");
	else if(originalPath.indexOf("file://///") === 0) // FireFox pc network file
		localPath = "\\\\" + unescape(originalPath.substr(10)).replace(new RegExp("/","g"),"\\");
	else if(originalPath.indexOf("file:///") === 0) // mac/unix local file
		localPath = unescape(originalPath.substr(7));
	else if(originalPath.indexOf("file:/") === 0) // mac/unix local file
		localPath = unescape(originalPath.substr(5));
	else // pc network file
		localPath = "\\\\" + unescape(originalPath.substr(7)).replace(new RegExp("/","g"),"\\");	
	return localPath;
};

// ---------------------------------------------------------------------------
// Stylesheet Extensions (may be overridden by local StyleSheet)
// ---------------------------------------------------------------------------
//
setStylesheet(
	".forEachTiddlerError{color: #ffffff;background-color: #880000;}",
	"forEachTiddler");

//============================================================================
// End of forEachTiddler Macro
//============================================================================


//============================================================================
// String.startsWith Function
//============================================================================
//
// Returns true if the string starts with the given prefix, false otherwise.
//
version.extensions["String.startsWith"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
String.prototype.startsWith = function(prefix) {
	var n =  prefix.length;
	return (this.length >= n) && (this.slice(0, n) == prefix);
};



//============================================================================
// String.endsWith Function
//============================================================================
//
// Returns true if the string ends with the given suffix, false otherwise.
//
version.extensions["String.endsWith"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
String.prototype.endsWith = function(suffix) {
	var n = suffix.length;
	return (this.length >= n) && (this.right(n) == suffix);
};


//============================================================================
// String.contains Function
//============================================================================
//
// Returns true when the string contains the given substring, false otherwise.
//
version.extensions["String.contains"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
String.prototype.contains = function(substring) {
	return this.indexOf(substring) >= 0;
};

//============================================================================
// Array.indexOf Function
//============================================================================
//
// Returns the index of the first occurance of the given item in the array or 
// -1 when no such item exists.
//
// @param item [may be null]
//
version.extensions["Array.indexOf"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
Array.prototype.indexOf = function(item) {
	for (var i = 0; i < this.length; i++) {
		if (this[i] == item) {
			return i;
		}
	}
	return -1;
};

//============================================================================
// Array.contains Function
//============================================================================
//
// Returns true when the array contains the given item, otherwise false. 
//
// @param item [may be null]
//
version.extensions["Array.contains"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
Array.prototype.contains = function(item) {
	return (this.indexOf(item) >= 0);
};

//============================================================================
// Array.containsAny Function
//============================================================================
//
// Returns true when the array contains at least one of the elements 
// of the item. Otherwise (or when items contains no elements) false is returned.
//
version.extensions["Array.containsAny"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
Array.prototype.containsAny = function(items) {
	for(var i = 0; i < items.length; i++) {
		if (this.contains(items[i])) {
			return true;
		}
	}
	return false;
};


//============================================================================
// Array.containsAll Function
//============================================================================
//
// Returns true when the array contains all the items, otherwise false.
// 
// When items is null false is returned (even if the array contains a null).
//
// @param items [may be null] 
//
version.extensions["Array.containsAll"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
Array.prototype.containsAll = function(items) {
	for(var i = 0; i < items.length; i++) {
		if (!this.contains(items[i])) {
			return false;
		}
	}
	return true;
};


} // of "install only once"

// Used Globals (for JSLint) ==============
// ... DOM
/*global 	document */
// ... TiddlyWiki Core
/*global 	convertUnicodeToUTF8, createTiddlyElement, createTiddlyLink, 
			displayMessage, endSaveArea, hasClass, loadFile, saveFile, 
			startSaveArea, store, wikify */
//}}}


/***
!Licence and Copyright
Copyright (c) abego Software ~GmbH, 2005 ([[www.abego-software.de|http://www.abego-software.de]])

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.

Neither the name of abego Software nor the names of its contributors may be
used to endorse or promote products derived from this software without specific
prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
***/

[[Lektier & opgaver|TeamTasks]] hjælper dig med at holde styr på dine projekter.  Det hele kan ændres meget, men jeg tror at de fleste vil hurtigt i gang med at:
*[[Definere nogle brugere|UserDefinitions]]         -        [[Hvordan og hvorfor|DefinerBrugere]]
*[[Definere nogle tidsrammer|ScopeDefinitions]] - [[Forklaring|DefineScopes]]
*[[Oprette nogle arbejdsopgaver|CreatingTasks]] <<newTiddler label:'Ny opgave' title:NewTask tag:task text:'Skriv noget tekst og klik på DONE for at se rullemenuerne'>> 
*[[Oprette prioriteter|PriorityDefinitions]]
*[[Lave opgave-rapporter|CreatingTaskReportViews]]

flere ændringer kan laves i [[OpgaveDefinition|TaskDefinitions]].

[[Mere information|About TeamTasks]] om hvilke komponenter der udgør [[Lektier & opgaver|TeamTasks]]. 
<<slideShow>>
-s-
[[Lav et slideshow]]
-s-
Klik på "edit" og se hvad der skal skrives for at lave et slide show
-s-
Tryk Esc for at lukke slide show igen
-s-
Det var da ikke så svært - vel?
-s-
[[En lektie]]
<<calendar thismonth>>
<<tabs txtMainTab "Timeline" "Timeline" TabTimeline "A - Z" "All tiddlers in alphabetical order" TabAll "Tags" "All tags" TabTags "Missing" "Missing tiddlers" TabMoreMissing "Shadowed" "Shadowed tiddlers" TabMoreShadowed>>
/***
|''Name:''|LoadRemoteFileThroughProxy (previous LoadRemoteFileHijack)|
|''Description:''|When the TiddlyWiki file is located on the web (view over http) the content of [[SiteProxy]] tiddler is added in front of the file url. If [[SiteProxy]] does not exist "/proxy/" is added. |
|''Version:''|1.1.0|
|''Date:''|mar 17, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#LoadRemoteFileHijack|
|''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|
***/
//{{{
version.extensions.LoadRemoteFileThroughProxy = {
 major: 1, minor: 1, revision: 0, 
 date: new Date("mar 17, 2007"), 
 source: "http://tiddlywiki.bidix.info/#LoadRemoteFileThroughProxy"};

if (!window.bidix) window.bidix = {}; // bidix namespace
if (!bidix.core) bidix.core = {};

bidix.core.loadRemoteFile = loadRemoteFile;
loadRemoteFile = function(url,callback,params)
{
 if ((document.location.toString().substr(0,4) == "http") && (url.substr(0,4) == "http")){ 
 url = store.getTiddlerText("SiteProxy", "/proxy/") + url;
 }
 return bidix.core.loadRemoteFile(url,callback,params);
}
//}}}
/***
|''Name:''|LoadRemoteFileThroughProxy (previous LoadRemoteFileHijack)|
|''Description:''|When the TiddlyWiki file is located on the web (view over http) the content of [[SiteProxy]] tiddler is added in front of the file url. If [[SiteProxy]] does not exist "/proxy/" is added. |
|''Version:''|1.1.0|
|''Date:''|mar 17, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#LoadRemoteFileHijack|
|''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|
***/
//{{{
version.extensions.LoadRemoteFileThroughProxy = {
 major: 1, minor: 1, revision: 0, 
 date: new Date("mar 17, 2007"), 
 source: "http://tiddlywiki.bidix.info/#LoadRemoteFileThroughProxy"};

if (!window.bidix) window.bidix = {}; // bidix namespace
if (!bidix.core) bidix.core = {};

bidix.core.loadRemoteFile = loadRemoteFile;
loadRemoteFile = function(url,callback,params)
{
 if ((document.location.toString().substr(0,4) == "http") && (url.substr(0,4) == "http")){ 
  url = store.getTiddlerText("SiteProxy", "/proxy/") + url;
 }
 return bidix.core.loadRemoteFile(url,callback,params);
}
//}}}
{{search{<<search søg>>}}}
[[Kom i gang med Lektier & opgaver]]
<<slider chkSliderOptionsPanel UserDefinitions 'Brugere »' 'En liste over hvem der gør det'>>
<<slider chkSliderOptionsPanel TaskViews 'Opgave overblik »' 'Et udvalg af opgave lister'>>
[[Lister|Listings]]
<<slider chkSliderOptionsPanel Customise 'Lav ændringer »' 'lav de ændringer der skal til for at det virker bedst for dig'>>
<<tag kalendere>>
[[Upload]]
[[download|http://lektier.tiddlyspot.com/download]]
[[Om|About TeamTasks]] 
[[UdgivelsesNoter|Release Notes]]
[[Migrering til sidste nye udgave|Migrating to the latest version]]
{{meta{
	<<tiddler TeamTasksMetaData>>
}}}
Since TeamTasks is built using TiddlyWiki, it contains all of the application logic, the styling, the content, and all of your tasks in a single file. This means that upgrading your instance of TeamTasks might seem like a fiddly task. Don't panic. It's simple when you know how!
	
!Downloading an empty copy of the latest ~TeamTasks version and then importing your tasks and views.
The process of upgrading a TiddlyWiki is well documented at [[www.tiddlywiki.com/#HowToUpgrade|http://www.tiddlywiki.com/#HowToUpgrade]]. Refer to that documentation to help you upgrade, but rather then downloading a fresh version of Tiddlywiki as your starting point, you should download a fresh version of TeamTasks by right-clicking on [[this link|http://www.hawksworx.com/playground/TeamTasks/index.html]], selecting 'Save target' or 'Save link' and saving it in a convenient location. You can then import your tasks into that file.
	
!Perhaps you would prefer to import the updated and new plugins into your existing ~TeamTasks file.
If this is the case, you should refer to the [[HowToUpgrade|www.tiddlywiki.com/#HowToUpgrade]] documentation as above, but rather than importing your tasks and views into a fresh teamTasks file, you should import into your exisiting TeamTasks file. You will need to import the following tiddlers from http://www.hawksworx.com/playground/TeamTasks in order to upgrade to version 0.4 of TeamTasks:
*[[FullScreenPlugin|http://www.hawksworx.com/playground/TeamTasks/#FullScreenPlugin]]
*[[NewUserWizardPlugin|http://www.hawksworx.com/playground/TeamTasks/#NewUserWizardPlugin]]
*[[TableSortingPlugin|http://www.hawksworx.com/playground/TeamTasks/#TableSortingPlugin]]
*[[TaggedTemplateTweak|http://www.hawksworx.com/playground/TeamTasks/#TaggedTemplateTweak]]
*[[TTReportViewPlugin|http://www.hawksworx.com/playground/TeamTasks/#TTReportViewPlugin]]
*[[TTMigrateTasks0304Plugin|http://www.hawksworx.com/playground/TeamTasks/#TTMigrateTasks0304Plugin]]
*[[ValueSwitcherPlugin|http://www.hawksworx.com/playground/TeamTasks/#ValueSwitcherPlugin]]

!Incompatible task tiddlers.
Version 0.4 employs a slightly different format for storing information on the task tiddlers to previous versions. A macro to upgrade all of your task tiddlers to adopt this new format is available in this plugin: [[TTMigrateTasks0304Plugin|http://www.hawksworx.com/playground/TeamTasks/#TTMigrateTasks0304Plugin]]

!!!Using the macro.
Using the macro is simple. 
#Import the [[TTMigrateTasks0304Plugin|http://www.hawksworx.com/playground/TeamTasks/#TTMigrateTasks0304Plugin]] as described above.
#Save your file and reload it to make sure that the macro is available to run.
#Create a new tiddler in your document and edit it to include a call to the migration macro like this {{{<<TTMigrateTasks0304>>}}}
#Click {{{done}}} to finish editing your new tiddler. The macro will run, converting all of your existing tasks to the latest version.
#Save your TeamTasks document in the usual way.
#Reload and if you wish, delete the TTMigrateTasks0304Plugin tiddler and the new tiddler you created to run the macro - you won't need them again.
	
	
/***
|''Name:''|NewUserWizardPlugin|
|''Description:''|Create a new user for the TeamTasks system |
|''Version:''|0.1|
|''Date:''|22 Oct, 2007|
|''Source:''|http://www.hawksworx.com/playground/TeamTasks/#NewUserWizardPlugin|
|''Author:''|PhilHawksworth (phawksworth (at) gmail (dot) com)|
|''License:''|[[BSD open source license]]|
|''CoreVersion:''|2.2|
***/

//{{{
// Ensure that this Plugin is only installed once.
if(!version.extensions.newUserWizard) 
{
	version.extensions.newUserWizard = {installed:true};
	config.macros.newUserWizard = {
	
		handler: function(place,macroName,params,wikifier,paramString,tiddler) {
			createTiddlyButton(place, 'Create user', false, this.onClickNewUser);
		},
		
		onClickNewUser : function(e) {
			
			//get data from the form
			var form = document.getElementById('createTeamTaskUserForm');
			var inputs = form.getElementsByTagName('input');
			var userData = [];
			var mandatoryFields = [];
			var f;
			for (var i=0; i < inputs.length; i++) {
				f = inputs[i];
				if(f.getAttribute('mandatory') && f.getAttribute('mandatory') =='true') mandatoryFields.push(f);
				if(f.value.length > 0) userData[f.name] = f.value;
			};
			
			// stop if we are missing anything mandatory
			var missingValues = false;
 			missingValues = config.macros.newUserWizard.checkMandatory(mandatoryFields);
			if(missingValues) return false;
		
			//build a properly formatted username
			userData['fname'] = userData['fname'].toLowerCase().substring(0,1).toUpperCase() + userData['fname'].substring(1);
			userData['lname'] = userData['lname'].toLowerCase().substring(0,1).toUpperCase() + userData['lname'].substring(1);
			userData['username'] = userData['fname'] + userData['lname'];
			
			//Check for dupes
			var existingTiddler = store.getTiddler(userData['username']);
			if(existingTiddler != null) {
				displayMessage('A user called '+ userData['username'] +' already exists');
				return false;
			}
			
			//add user to UserDefinitions
			var body = store.getTiddlerText('UserDefinitions') + '\n' + userData['username'];
			store.saveTiddler('UserDefinitions','UserDefinitions',body,config.options.txtUserName);
			
			//TODO: Replace the vCard creation from HTML insertion to nice TW DOM methods.
			//create a tiddler for the user with an hCard for the contact details.
			var homeTiddlerBody = [];
			homeTiddlerBody.push('<html>');
			homeTiddlerBody.push('<div class="vcard">');
			homeTiddlerBody.push('<a class="url fn n" href="'+ userData['blog'] +'"><span class="given-name">'+ userData['fname'] +'</span><span class="family-name">'+ userData['lname'] +'</span></a>');
			if(userData['company'])homeTiddlerBody.push('<div class="org"><span class="organization-name">'+ userData['company']  +'</span></div>');
			if(userData['email'])homeTiddlerBody.push('<div class="email"><span><a href="mailto:'+ userData['email']  +'">'+ userData['email']  +'</a></span></div>');
			if(userData['blog'])homeTiddlerBody.push('<div class="blog"><span><a href="'+ userData['blog']  +'">'+ userData['blog']  +'</a></span></div>');
			if(userData['photos'])homeTiddlerBody.push('<div class="photos"><span><a href="'+ userData['photos']  +'">'+ userData['photos']  +'</a></span></div>');
			if(userData['twitter'])homeTiddlerBody.push('<div class="twitter"><span><a href="'+ userData['twitter']  +'">'+ userData['twitter']  +'</a></span></div>');
			homeTiddlerBody.push('</div></html>');
			
			//Create some simple TaskListViews.
			//Task list index template.
			var body;
			body = store.getTiddlerText('SampleTaskListTemplate');
			homeTiddlerBody.push(body.replace(/UserName/g,userData['username']));
			
			store.saveTiddler(userData['username'],userData['username'],homeTiddlerBody.join('\n'),config.options.txtUserName);
			
			//TODO: automate the generation of these views from some templates and the index
			//create the task views
			var body_array = [];
			body_array.push('<<TaskViewBuilder UserDefinitions='+ userData['username'] +' PriorityDefinitions='+ userData['username'] +' !StatusDefinitions=Complete>>');
			store.saveTiddler(userData['username'] +'OpenTasks', userData['username'] +'OpenTasks',body_array.join('\n'),config.options.txtUserName);
			body = '<<TaskViewBuilder UserDefinitions='+ userData['username'] +' StatusDefinitions=InProgress>>';
			store.saveTiddler(userData['username'] +'InProgressTasks', userData['username'] +'InProgressTasks',body,config.options.txtUserName);
			body = '<<TaskViewBuilder UserDefinitions='+ userData['username'] +' StatusDefinitions=Next>>';
			store.saveTiddler(userData['username'] +'NextTasks', userData['username'] +'NextTasks',body,config.options.txtUserName);
			body = '<<TaskViewBuilder UserDefinitions='+ userData['username'] +' StatusDefinitions=Complete>>';
			store.saveTiddler(userData['username'] +'CompletedTasks', userData['username'] +'CompletedTasks',body,config.options.txtUserName);
			
			//open the new user tiddler
			story.displayTiddlers(this,[userData['username']]);
		},
		
		checkMandatory : function(things) {
			var flag = false;
			var v = "";
			var ele;
			for (var i=0; i < things.length; i++) {
				if(typeof(things[i])=='string') {
					ele = document.getElementById(things[i]);
				}
				else if(typeof(things[i]) == 'object') {
					ele = things[i];
				}
				else return false;
				v = ele.value;
				removeClass(ele, 'flaggedMandatory');
				if(v.length == 0){
					addClass(ele, 'flaggedMandatory');
					flag = true;
				}	
			};
			if(flag == true) return true;
			else return false;
		}
	};
}
//}}}
<<list filter [tag[subtask]]>> 
<<TTReportView>>
/***
|''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"
	});
*/
//}}}
<html>
<div class="vcard">
<a class="url fn n" href=""><span class="given-name">Phil</span><span class="family-name">Hawksworth</span></a>
<div class="org"><span class="organization-name">Osmosoft</span></div>
<div><span><a href="http://www.hawksworx.com">www.hawksworx.com</a></span></div>
<div class="email"><span><a href="mailto:ph@osmosoft.com">ph@osmosoft.com</a></span></div>
<div class="photos"><span><a href="http://flickr/photos/philhawksworth">flickr/photos/philhawksworth</a></span></div>
<div class="twitter"><span><a href="http://twitter.com/philhawksworth">twitter.com/philhawksworth</a></span></div>
</div></html>
Staun:
*Vævestuen 
*Ida  
*De 3 på Dorthes kontor.
 - evt. også digitale kameraer?
*Ullas
<<TTReportView DisplayFields:"Title,Priority,Status,User">>
Akut
Er i gang
Det er jeg i tvivl om
Færdig
<<TTReportView DisplayFields:"Upload,AssignedTo,TargetDate">>
!Version 0.4
!!!Comments
*The macro for producing task list views has been replaced with the TTReportViewPlugin which uses named prameters and outputs sortable table views of your data.
*Task metadata is now stored on the task tiddlers in a much more friendly way. All TeamTasks fields on a tiddler are of the form {{{tt_fieldName='value'}}}
*For those wishing to upgrade their previous tasks to make use of the new structure, there is a [[Task Migration Tool|TTMigrateTasks0304Plugin]] to ease the pain.
*There is now [[documentation to assist in upgrading TeamTasks|Migrating to the latest version]]
*Task Reports now refresh automatically as Tasks are updated.
*The new theme is defined by just two tiddlers: TeamTasksSkin and TeamTasksColors
!!!Comprehensive Plugin List
|TableSortingPlugin |by SaqImtiaz |http://tw.lewcid.org/#TableSortingPlugin |
|TaggedTemplateTweak |by EricShulman |http://www.TiddlyTools.com/#TaggedTemplateTweak |
|TTReportViewPlugin |by PhilHawksworth |http://www.getteamtasks.com/teamtasks.html#TTReportViewPlugin |
|TTMigrateTasks0304Plugin |by PhilHawksworth |http://www.getteamtasks.com/teamtasks.html#TTMigrateTasks0304Plugin |
|ValueSwitcherPlugin |by PhilHawksworth |http://www.getteamtasks.com/teamtasks.html#ValueSwitcherPlugin |

!Version 0.3
!!!Comments
*Lots more documentation and help is evolving
*Introduction of UserSetupWizard which speeds up the setting up of users and automates some associated tasks.
!!!Plugins
|FullScreenPlugin |by SaqImtiaz |http://tw.lewcid.org/#FullScreenPlugin |
|TaggedTemplateTweak |by EricShulman |http://www.TiddlyTools.com/#TaggedTemplateTweak |
|TaskViewBuilderPlugin |by PhilHawksworth |http://www.hawksworx.com/playground/TeamTasks/#TaskViewBuilderPlugin |
|ValueSwitcherPlugin |by PhilHawksworth |http://www.hawksworx.com/playground/TeamTasks/#ValueSwitcherPlugin |
|NewUserWizardPlugin|by PhilHawksworth |http://www.hawksworx.com/playground/TeamTasks/#NewUserWizardPlugin |
!!Tiddlers providing UI styling
PageTemplate
StyleSheet
ColorPalette
ViewTemplate
TaskViewTemplate
!!Tiddlers providing other functionality
ControlsContainer
[[Listings]]
TaskTiddlerControls
SampleTaskListTemplate
UserDetailsTemplate
UserSetupWizard
!!Tiddlers providing documentation
[[About TeamTasks]]
CreatingTaskListViews
CreatingTasks
DefineScopes
DefinerBrugere
[[Getting Started with TeamTasks]]
[[Release Notes]]
TaskListView
TeamTasks
!Version 0.2
!!!Comments
*Task visualisation improved
*TaskViewBuilderPlugin syntax employs {{{ = }}} rather than {{{ _ }}}
!!!Plugins
|FullScreenPlugin |by SaqImtiaz |http://tw.lewcid.org/#FullScreenPlugin |
|TaggedTemplateTweak |by EricShulman |http://www.TiddlyTools.com/#TaggedTemplateTweak |
|TaskViewBuilderPlugin |by PhilHawksworth |http://www.hawksworx.com/playground/TeamTasks/#TaskViewBuilderPlugin |
|ValueSwitcherPlugin |by PhilHawksworth |http://www.hawksworx.com/playground/TeamTasks/#ValueSwitcherPlugin |
!!Tiddlers providing UI styling
PageTemplate
StyleSheet
ColorPalette
ViewTemplate
TaskViewTemplate
!!Tiddlers providing other functionality
ControlsContainer
[[Listings]]
TaskTiddlerControls

!Version 0.1
!!!Comments
*Basic UI structure established
*Task generation using tagging mechanism
*Basic task list views.
!!!Plugins
|FullScreenPlugin |by SaqImtiaz |http://tw.lewcid.org/#FullScreenPlugin |
|TaskViewBuilderPlugin |by PhilHawksworth |http://www.hawksworx.com/playground/TeamTasks/#TaskViewBuilderPlugin |
|ValueSwitcherPlugin |by PhilHawksworth |http://www.hawksworx.com/playground/TeamTasks/#ValueSwitcherPlugin |
!!Tiddlers providing UI styling
PageTemplate
StyleSheet
ColorPalette
ViewTemplate
!!Tiddlers providing other functionality
ControlsContainer
[[Listings]]
Akut
Et par dage
En uge
14 dage
1 måned
Hele året
Til næste år
Fremtidsplan
Januar
Februar
Marts
April
Maj
Juni
Juli
August
September
Oktober
November
December
Snart
I arbejdstiden
I fritiden
digital management
//''Lektier'' & opgaver//
!!Example:
|sortable|k
|Name |Salary |Extension |Performance |File Size |Start date |h
|ZBloggs, Fred |$12000.00 |1353 |+1.2 |74.2Kb |Aug 19, 2003 21:34:00 |
|ABloggs, Fred |$12000.00 |1353 |1.2 |3350b |09/18/2003 |
|CBloggs, Fred |$12000 |1353 |1.200 |55.2Kb |August 18, 2003 |
|DBloggs, Fred |$12000.00 |1353 |1.2 |2100b |07/18/2003 |
|Bloggs, Fred |$12000.00 |1353 |01.20 |6.156Mb |08/17/2003 05:43 |
|Turvey, Kevin |$191200.00 |2342 |-33 |1b |02/05/1979 |
|Mbogo, Arnold |$32010.12 |2755 |-21.673 |1.2Gb |09/08/1998 |
|Shakespeare, Bill |�122000.00|3211 |6 |33.22Gb |12/11/1961 |
|Shakespeare, Hamlet |�9000 |9005 |-8 |3Gb |01/01/2002 |
|Fitz, Marvin |�3300.30 |5554 |+5 |4Kb |05/22/1995 |

***/
// /%
//!BEGIN-PLUGIN-CODE
config.tableSorting = {
	
	darrow: "\u2193",
	
	uarrow: "\u2191",
	
	getText : function (o) {
		var p = o.cells[SORT_INDEX];
		return p.innerText || p.textContent || '';
	},
	
	sortTable : function (o,rev) {
		SORT_INDEX = o.getAttribute("index");
		var c = config.tableSorting;
		var T = findRelated(o.parentNode,"TABLE");
		if(T.tBodies[0].rows.length<=1) 
			return;
		var itm = "";
		var i = 0;
		while (itm == "" && i < T.tBodies[0].rows.length) {
			itm = c.getText(T.tBodies[0].rows[i]).trim();
			i++;
		}
		if (itm == "") 
			return; 	
		var r = [];
		var S = o.getElementsByTagName("span")[0];		
		c.fn = c.sortAlpha; 
		if(!isNaN(Date.parse(itm)))
			c.fn = c.sortDate; 
		else if(itm.match(/^[$|�|�|\+|\-]{0,1}\d*\.{0,1}\d+$/)) 
			c.fn = c.sortNumber; 
		else if(itm.match(/^\d*\.{0,1}\d+[K|M|G]{0,1}b$/)) 
			c.fn = c.sortFile; 
		for(i=0; i<T.tBodies[0].rows.length; i++) {
			 r[i]=T.tBodies[0].rows[i]; 
		} 
		r.sort(c.reSort);
		if(S.firstChild.nodeValue==c.darrow || rev) {
			r.reverse();
			S.firstChild.nodeValue=c.uarrow;
		} 
		else 
			S.firstChild.nodeValue=c.darrow;
		var thead = T.getElementsByTagName('thead')[0]; 
		var headers = thead.rows[thead.rows.length-1].cells;
		for(var k=0; k<headers.length; k++) {
			if(!hasClass(headers[k],"nosort"))
				addClass(headers[k].getElementsByTagName("span")[0],"hidden");
		}
		removeClass(S,"hidden");
		for(i=0; i<r.length; i++) { 
			T.tBodies[0].appendChild(r[i]);
			c.stripe(r[i],i);
			for(var j=0; j<r[i].cells.length;j++){
				removeClass(r[i].cells[j],"sortedCol");
			}
			addClass(r[i].cells[SORT_INDEX],"sortedCol");
		}
	},
	
	stripe : function (e,i){
		var cl = ["oddRow","evenRow"];
		i&1? cl.reverse() : cl;
		removeClass(e,cl[1]);
		addClass(e,cl[0]);
	},
	
	sortNumber : function(v) {
		var x = parseFloat(this.getText(v).replace(/[^0-9.-]/g,''));
		return isNaN(x)? 0: x;
	},
	
	sortDate : function(v) {
		return Date.parse(this.getText(v));
	},

	sortAlpha : function(v) {
		return this.getText(v).toLowerCase();
	},
	
	sortFile : function(v) { 		
		var j, q = config.messages.sizeTemplates, s = this.getText(v);
		for (var i=0; i<q.length; i++) {
			if ((j = s.toLowerCase().indexOf(q[i].template.replace("%0\u00a0","").toLowerCase())) != -1)
				return q[i].unit * s.substr(0,j);
		}
		return parseFloat(s);
	},
	
	reSort : function(a,b){
		var c = config.tableSorting;
		var aa = c.fn(a);
		var bb = c.fn(b);
		return ((aa==bb)? 0 : ((aa<bb)? -1:1));
	}
};

Story.prototype.tSort_refreshTiddler = Story.prototype.refreshTiddler;
Story.prototype.refreshTiddler = function(title,template,force,customFields,defaultText){
	var elem = this.tSort_refreshTiddler.apply(this,arguments);
	if(elem){
		var tables = elem.getElementsByTagName("TABLE");
		var c = config.tableSorting;
		for(var i=0; i<tables.length; i++){
			if(hasClass(tables[i],"sortable")){
				var x = null, rev, table = tables[i], thead = table.getElementsByTagName('thead')[0], headers = thead.rows[thead.rows.length-1].cells;
				for (var j=0; j<headers.length; j++){
					var h = headers[j];
					if (hasClass(h,"nosort"))
						continue;
					h.setAttribute("index",j);
					h.onclick = function(){c.sortTable(this); return false;};
					h.ondblclick = stopEvent;
					if(h.getElementsByTagName("span").length == 0)
						createTiddlyElement(h,"span",null,"hidden",c.uarrow); 
					if(!x && hasClass(h,"autosort")) {
						x = j;
						rev = hasClass(h,"reverse");
					}
				}
				if(x)
					c.sortTable(headers[x],rev);		
			}
		}
	}
	return elem; 
};

setStylesheet("table.sortable span.hidden {visibility:hidden;}\n"+
	"table.sortable thead {cursor:pointer;}\n"+
	"table.sortable .nosort {cursor:default;}\n"+
	"table.sortable td.sortedCol {background:#ffc;}","TableSortingPluginStyles");

function stopEvent(e){
	var ev = e? e : window.event;
	ev.cancelBubble = true;
	if (ev.stopPropagation) ev.stopPropagation();
	return false;	
}	

config.macros.nosort={
	handler : function(place){
		addClass(place,"nosort");
	}	
};

config.macros.autosort={
	handler : function(place,m,p,w,pS){
		addClass(place,"autosort"+" "+pS);		
	}	
};
//!END-PLUGIN-CODE
// %/
<!--{{{-->
<div id='displayArea'>
<div id='tiddlerDisplay'></div>
</div>
<!--}}}-->
/***
|''Name:''|SlideShowPlugin|
|''Description:''|Creates a simple slide show type display|
|''Version:''|1.6|
|''Date:''|Feb 12, 2008|
|''Source:''|http://www.math.ist.utl.pt/~psoares/addons.html|
|''Documentation:''|[[SlideShowPlugin Documentation|SlideShowPluginDoc]]|
|''Author:''|Paulo Soares and [[Clint Checketts|http://www.checkettsweb.com]]|
|''License:''|[[Creative Commons Attribution-Share Alike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion:''|2.1.0|
***/
//{{{
config.macros.slideShow = {label: "slide show", maxTOCLength: 30};
config.macros.slideShow.messages = {gotoLabel: "Go to slide:"};
config.views.wikified.slideShow = {text: "slide show", tooltip: "Start slide show"};
config.views.wikified.slideShow.quit = {text: "end", tooltip: "Quit the slide show"};
config.views.wikified.slideShow.firstSlide = {text: "<<", tooltip: "first slide"};
config.views.wikified.slideShow.previousSlide = {text: "<", tooltip: "previous slide"};
config.views.wikified.slideShow.nextSlide = {text: ">", tooltip: "next slide"};
config.views.wikified.slideShow.lastSlide = {text: ">>", tooltip: "last slide"};
config.views.wikified.slideShow.resetClock = {text: " ", tooltip: "reset"};

config.formatters.push( {
	name: "SlideSeparator",
	match: "^-s-+$\\n?",
	handler: function(w) {
		createTiddlyElement(w.output,"hr",null,'slideSeparator');
	}
});

function changeStyleSheet(tiddlerName) {
	setStylesheet(store.getRecursiveTiddlerText("StyleSheetColors"),"StyleSheetColors");
	setStylesheet(store.getRecursiveTiddlerText("StyleSheetLayout"),"StyleSheetLayout");
	setStylesheet(store.getRecursiveTiddlerText(tiddlerName == null ? "StyleSheet" : tiddlerName,""),"StyleSheet");
}

//Excellent (and versatile) reparser created by Paul Petterson for parsing the paramString in a macro
function reparse( params ) {
	var re = /([^:\s]+)(?:\:((?:\d+)|(?:["'](?:[^"']+)["']))|\s|$)/g;
	var ret = new Array();
	var m;
	while( (m = re.exec( params )) != null ) ret[ m[1] ] = m[2]?m[2]:true;
	return ret;
}

function getElementsByClass(searchClass,node,tag) {
	var classElements = new Array();
	if ( node == null ) node = document;
	if ( tag == null ) tag = '*';
	var els = node.getElementsByTagName(tag);
	var elsLen = els.length;
	var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
	var j=0;
	for (var i = 0; i < elsLen; i++) {
		if ( pattern.test(els[i].className) ) {
			classElements[j] = els[i];
			j++;
		}
	}
	return classElements;
}

// 'keys' code adapted from S5 which in turn was adapted from MozPoint (http://mozpoint.mozdev.org/)
function keys(key) {
with(config.macros.slideShow){
	if (document.getElementById('contentWrapper').className == "slideShowMode"){
		if (!key) {
			key = event;
			key.which = key.keyCode;
		}
 		switch (key.which) {
			case 32: // spacebar
				if(time>0){
					if(autoAdvance){
						clearInterval(autoAdvance);
						autoAdvance = null;
					} else {
						autoAdvance=setInterval("GoToSlide(1)", time);
					}
				}
				break;
			case 34: // page down
			case 39: // rightkey
				GoToSlide("n");
				break;
			case 40: // downkey
				GoToSlide(-1);
				break;
			case 33: // page up
			case 37: // leftkey
				GoToSlide("p");
				break;
			case 38: // upkey
				GoToSlide(1);
				break;
			case 36: // home
				GoToSlide("f");
				break;
			case 35: // end
				GoToSlide("l");
				break;
			case 27: // escape
				endSlideShow();
				break;
			case 66: // B
				blankScreen();
				break;
		}
	}
	return false;
}
}

function blankScreen(){
	var blanker = document.getElementById('slideBlanker');
	if (blanker.style.display == 'block'){
		blanker.style.display = 'none';
	} else {
		blanker.style.display = 'block';
	}
}

function clicker(e) {
	if (!e) var e = window.event;
	var target = resolveTarget(e);
	//Whenever something is clicked that won't advance the slide make sure that the table of contents gets hidden
	if (target.getAttribute('href') != null || isParentOrSelf(target, 'toc') || isParentOrSelf(target,'embed') || isParentOrSelf(target,'object') || isParentOrSelf(target, 'slideFooter') || isParentOrSelf(target, 'navigator')){
		 //Don't hide the TOC if the indexNumbers (which trigger the index) is clicked
		if(isParentOrSelf(target,'indexNumbers') || isParentOrSelf(target,'jumpInput')){
 			return true;
		}
		showHideTOC('none');
		return true;
	}
	//Advance a slide if the TOC is visible otherwise make sure that the TOC gets hidden
	if ((!e.which && e.button == 1) || e.which == 1) {
		if (document.getElementById('toc').style.display != 'block'){
			GoToSlide("n");
		} else {
			showHideTOC('none');
		}
	}
	if ((!e.which && e.button == 2) || e.which == 3) {
		if (document.getElementById('toc').style.display != 'block'){
			GoToSlide("p");
		} else {
			showHideTOC('none');
		}
		return false;
	}
}

function isParentOrSelf(element, id) {
	if (element == null || element.nodeName=='BODY') return false;
	else if (element.id == id) return true;
	else return isParentOrSelf(element.parentNode, id);
}

GoToSlide = function(step) {
	var new_pos;
	var slideHolder = document.getElementById('slideContainer');
	//The parse float ensures that the attribute is returned as a number and not a string.
	var cur_pos = parseFloat(slideHolder.getAttribute('currentslide'));
	var numberSlides = parseFloat(slideHolder.getAttribute('numberSlides'));
	switch (step) {
		case "f":
			new_pos=0;
			break;
		case "l":
			new_pos=numberSlides-1;
			break;
		case "n":
			var numberOverlays = parseFloat(slideHolder.childNodes[cur_pos].getAttribute('numberOverlays'));
			var currentOverlay = parseFloat(slideHolder.getAttribute('currentOverlay'));
			if(numberOverlays==0 || currentOverlay==numberOverlays){
				if(noClicks==false) new_pos=cur_pos+1;
			} else {
				var className="Overlay"+currentOverlay;
				var overlay=getElementsByClass(className,slideHolder.childNodes[cur_pos]);
				for(var i=0; i<overlay.length; i++) {overlay[i].className=className+' previousOverlay';}
				currentOverlay++;
				slideHolder.setAttribute('currentOverlay',currentOverlay);
				className="Overlay"+currentOverlay;
				overlay=getElementsByClass(className,slideHolder.childNodes[cur_pos]);
				for(i=0; i<overlay.length; i++) {overlay[i].className=className+' currentOverlay';}
				return false;
			}
			break;
		case "p":
			var numberOverlays = parseFloat(slideHolder.childNodes[cur_pos].getAttribute('numberOverlays'));
			var currentOverlay = parseFloat(slideHolder.getAttribute('currentOverlay'));
			if(numberOverlays==0 || currentOverlay==0){
				if(noClicks==false) new_pos=cur_pos-1;
			} else {
				var className="Overlay"+currentOverlay;
				var overlays=getElementsByClass(className,slideHolder.childNodes[cur_pos]);
				for(var i=0; i<overlays.length; i++) {overlays[i].className=className+' nextOverlay';}
				currentOverlay--;
				className="Overlay"+currentOverlay;
				overlays=getElementsByClass(className,slideHolder.childNodes[cur_pos]);
				for(i=0; i<overlays.length; i++) {overlays[i].className=className+' currentOverlay';}
				slideHolder.setAttribute('currentOverlay',currentOverlay);
				return false;
			}
			break;
		default:
			new_pos=cur_pos+step;
	}
	if(slideShowCircularMode && new_pos == numberSlides) new_pos=0;
	if(slideShowCircularMode && new_pos<0) new_pos=(numberSlides - 1);
	if(step!=0 && new_pos>=0 && new_pos<numberSlides) {
		slideHolder.childNodes[cur_pos].style.display='none';
		slideHolder.childNodes[new_pos].style.display='block';
		slideHolder.setAttribute('currentslide',new_pos);
		var numberOverlays = parseFloat(slideHolder.childNodes[new_pos].getAttribute('numberOverlays'));
		if(step=="p"){
			var currentOverlay=numberOverlays;
			var state=' previousOverlay';
		} else {
			var currentOverlay=0;
			var state=' nextOverlay';
		}
		slideHolder.setAttribute('currentOverlay',currentOverlay);
		if(numberOverlays>0) {
			for(var i=1; i<=numberOverlays; i++){
				var className="Overlay"+i;
				var overlays=getElementsByClass(className,slideHolder.childNodes[new_pos]);
				for(var j=0; j<overlays.length; j++) {overlays[j].className=className+state;}
			}
			if(step=="p"){
				var className="Overlay"+numberOverlays;
				var overlays=getElementsByClass(className,slideHolder.childNodes[new_pos]);
				for(var j=0; j<overlays.length; j++) {overlays[j].className=className+' currentOverlay';}
			}
		}
		new_pos++;
		var indexNumbers = document.getElementById('indexNumbers');
		indexNumbers.firstChild.data = new_pos+'/'+numberSlides;
		if((new_pos==numberSlides) && !slideShowCircularMode && autoAdvance) clearInterval(autoAdvance);
		return true;
	}
	return false;
}

function tocShowSlide(e) {
	if (!e) var e = window.event;
	var target = resolveTarget(e);
	var slide = target.getAttribute('slideNumber');
	var cur_pos = document.getElementById('slideContainer').getAttribute('currentslide');
	var step = slide-cur_pos;
	if(step!=0) GoToSlide(step);
	showHideTOC('none');
	return;
}

//Toggle the display of the table of contents
function showHideTOC(display){
	var toc = document.getElementById('toc');
	//Reset the input box
	document.getElementById('jumpInput').value = "";
	if (display == null || display.length == null){
		if (toc.style.display == 'none' || toc.style.display == ''){
			toc.style.display = 'block';
			document.getElementById('jumpInput').focus();
		} else {
			toc.style.display = 'none';
		}
	} else {
		toc.style.display = display;
		if (display == 'block')
			document.getElementById('jumpInput').focus();
	}
}

function padZero(x){return (x>=10 || x<0 ? "" : "0")+x;}

setClock = function(){
	var actualTime = new Date();
	var newTime = actualTime.getTime() - clockStartTime;
	newTime = clockMultiplier*newTime+clockInterval+clockCorrection;
	actualTime.setTime(newTime);
	newTime = padZero(actualTime.getHours()) + ":" + padZero(actualTime.getMinutes());
//+ ":" + padZero(actualTime.getSeconds());
	var clock = document.getElementById('slideClock');
	clock.firstChild.nodeValue = newTime;
}

function resetClock(){
	var time = new Date(0);
	if(clockStartTime>time){
		var startTime = new Date();
		clockStartTime=startTime.getTime();
	}
}

var title;
var place;
var autoAdvance=null;
var slideClock=null;
var noOverlays=false;
var noClicks=false;
var forceRefresh=false;
var time = 0;
var slideShowCircularMode;
var slideShowStyleSheet;
var slideShowParams;
var clockMultiplier;
var clockInterval;
var clockCorrection=0;
var clockStartTime;
var openTiddlers;

config.macros.slideShow.handler = function(aPlace,macroName,params,wikifier,paramString,tiddler){
	if(tiddler instanceof Tiddler){
		var lingo = config.views.wikified.slideShow;
		if (!e) var e = window.event;
 		place = aPlace;
		title = tiddler.title;
		params = reparse(paramString);
		var onclick = function(){config.macros.slideShow.onClickSlideShow(params);};
		createTiddlyButton(aPlace,lingo.text,lingo.tooltip,onclick);
	}
}

config.macros.slideShow.onClickSlideShow = function(newParams) {
//	if(typeof(newParams)=="number") newParams=slideShowParams;
	openTiddlers = new Array;
	var viewer=document.getElementById('tiddlerDisplay');
	for(var i=0; i<viewer.childNodes.length; i++){
		var name = viewer.childNodes[i].getAttribute('tiddler');
		openTiddlers.push(name);
	}
	document.oncontextmenu = function(e){return false;}
	clockMultiplier = 1;
	clockInterval = 0;
	var startTime = new Date(0);
	slideShowCircularMode = false;
	time = 0;
	slideShowStyleSheet = null;
	if(newParams['style']){
		slideShowStyleSheet = eval(newParams['style']);
	} 
	if(newParams['repeat']){
		slideShowCircularMode = true;
	}
	if(newParams['noClicks']){
		noClicks = true;
	}
	if(newParams['forceRefresh']){
		forceRefresh = true;
	}
	if(newParams['slidePause'] > 0){
		time = newParams['slidePause'];
	}
	if(newParams['clock']){
		clockCorrection=startTime.getTimezoneOffset()*60000;
		startTime = new Date();
		var clockType= eval(newParams['clock']);
		if(clockType != '+') {
			clockMultiplier = -1;
			clockInterval = -clockType*60000;
		}
	}
	clockStartTime=startTime.getTime();
	if(newParams['noOverlays']){
		noOverlays = true;
	}
	clearMessage();
	//Attach the key and mouse listeners
	document.onkeyup = keys;
	document.onmouseup = clicker;
	story.refreshTiddler(title,"SlideShowViewTemplate",true);
	createSlides(newParams);
	slideClock=setInterval('setClock()', 1000); 
	if(time>0) autoAdvance=setInterval("GoToSlide(1)", time); 
	story.closeAllTiddlers(title);
	toggleSlideStyles();
	return;
}

config.macros.slideShow.endSlideShow=function(){
	var showHolder = document.getElementById('slideShowWrapper');
	showHolder.parentNode.removeChild(showHolder);
	document.oncontextmenu =  function(e){};
	if(autoAdvance) clearInterval(autoAdvance);
	if(slideClock) clearInterval(slideClock);
	noClicks=false;
	story.refreshTiddler(title,null,true);
	story.closeAllTiddlers();
	toggleSlideStyles();
	story.displayTiddlers(null,openTiddlers,DEFAULT_VIEW_TEMPLATE);
	document.onmouseup = function(){};
}

function isInteger(s){
	var i;
	for (i = 0; i < s.length; i++){
		// Check that current character is number.
		var c = s.charAt(i);
		if (((c < "0") || (c > "9"))) return false;
	}
	// All characters are numbers.
	return true;
}

function jumpInputToSlide(e){
	if (!e) {
		e = window.event;
		e.which = e.keyCode;
	}
	if(e.which==13){
		var jumpInput= document.getElementById("jumpInput").value;
		if(isInteger(jumpInput)){
			var step=jumpInput-document.getElementById('slideContainer').getAttribute('currentslide')-1;
			if (GoToSlide(step)){
				showHideTOC('none'); 
			}
		}
	}
	return;
}

//Used to shorten the TOC fields
function abbreviateLabel(label){
	var maxTOCLength = config.macros.slideShow.maxTOCLength;
	if(label.length>maxTOCLength) {
		var temp = new Array();
		temp = label.split(' ');
		label = temp[0];
		for(var j=1; j<temp.length; j++){
			if((label.length+temp[j].length)<=maxTOCLength){
				label += " " + temp[j];
			} else {
				label += " ...";
				break;
			}
		}
	}
	return label;
}

function createSlides(newParams){
	var lingo = config.views.wikified.slideShow;
	//Remove dblClick on edit function
	var theTiddler = document.getElementById("tiddler"+title);
	theTiddler.ondblclick = function() {};
	// Grab the 'viewer' element and give it a signature so the show can be resumed if stopped
	var tiddlerElements = theTiddler.childNodes;
	var viewer;
	for (var i = 0; i < tiddlerElements.length; i++){
		if (tiddlerElements[i].className == "viewer") viewer = tiddlerElements[i];
	}
	viewer.id = 'slideShowWrapper';
	//Hide the text that comes before the first H1 element (I think I may put this into a cover page type thing)
	while(viewer.childNodes.length > 0 && viewer.firstChild.nodeName.toUpperCase() != "HR" && viewer.firstChild.className!="slideSeparator") {
		viewer.removeChild(viewer.firstChild);
	}
	//Cycle through the content and each time you hit an H1 begin a new slide div
	var slideNumber = 0;
	var slideHolder = document.createElement('DIV');
	slideHolder.id = "slideContainer";
	slideHolder.setAttribute('currentslide',0);

	while(viewer.childNodes.length > 0){
		//Create a new slide a append it to the slide holder
		if (viewer.firstChild.nodeName.toUpperCase() == "HR" && viewer.firstChild.className=="slideSeparator"){
			slideNumber++;
			var slide = document.createElement('DIV');
			slide.id = "slideNumber"+slideNumber;
			slide.className = "slide";
			if (slideNumber > 1) {
				//slideHolder.setAttribute('currentslide',0);
				slide.style.display='none';
			} else {
				slide.style.display='block';
			}
			slideHolder.appendChild(slide); 
			viewer.removeChild(viewer.firstChild);
		} else {
			if(viewer.firstChild.nodeName=="SPAN" && viewer.firstChild.className=="" && viewer.firstChild.hasChildNodes()) {
				var anchor=viewer.firstChild.nextSibling;
				for (var ii=0;ii<viewer.firstChild.childNodes.length;ii++) {
					var clone=viewer.firstChild.childNodes[ii].cloneNode(true);
					viewer.insertBefore(clone,anchor);
				}
				viewer.removeChild(viewer.firstChild);
			} else {
				slide.appendChild(viewer.firstChild);
			}
		}
	} 
	//Stick the slides back into the viewer

	var blanker= createTiddlyElement(viewer,"DIV","slideBlanker");
	blanker.style.display="none";

	viewer.appendChild(slideHolder);
	slideHolder.setAttribute('numberSlides',slideNumber);
	//Create the navigation bar
	var slidefooter = createTiddlyElement(viewer,"DIV","slideFooter","slideFooterOff");
	var navigator = createTiddlyElement(slidefooter,"SPAN","navigator");
	//Make it so that when the footer is hovered over the class will change to make it visible
	slidefooter.onmouseover = function () {slidefooter.className = "slideFooterOn"};
	slidefooter.onmouseout = function () {slidefooter.className = "slideFooterOff"};
	//Create the control button for the navigation 
	var onClickQuit = function(){config.macros.slideShow.endSlideShow();};
	createTiddlyButton(navigator,lingo.quit.text,lingo.quit.tooltip,onClickQuit);
	createTiddlyButton(navigator,lingo.firstSlide.text,lingo.firstSlide.tooltip,first_slide);
	createTiddlyButton(navigator,lingo.previousSlide.text,lingo.previousSlide.tooltip,previous_slide);
	createTiddlyButton(navigator,lingo.nextSlide.text,lingo.nextSlide.tooltip,next_slide);
	createTiddlyButton(navigator,lingo.lastSlide.text,lingo.lastSlide.tooltip,last_slide); 
	createTiddlyButton(navigator,lingo.resetClock.text,lingo.resetClock.tooltip,resetClock,"button","slideClock");
	var indexNumbers = createTiddlyElement(slidefooter,"SPAN","indexNumbers","indexNumbers","1/"+slideNumber)
	indexNumbers.onclick = showHideTOC;
	var toc = createTiddlyElement(slidefooter,"UL","toc");
	var ovl=1;
	for (var i=0;i<slideHolder.childNodes.length;i++) {
		if(!noOverlays) {
			var ovl=1;
			while(1){
				var className="Overlay"+ovl;
				var overlays=getElementsByClass(className,slideHolder.childNodes[i]);
				if(overlays.length>0){
					for(var j=0; j<overlays.length; j++) {overlays[j].className+=' nextOverlay';}
					ovl++;
				} else {break;}
			}
		}
		slideHolder.childNodes[i].setAttribute("numberOverlays",ovl-1);
		slideHolder.setAttribute("currentOverlay",0);
		//Loop through each slide and check the header's content
		var tocLabel = null; 
		for (var j=0;j<slideHolder.childNodes[i].childNodes.length;j++) {
			var node = slideHolder.childNodes[i].childNodes[j];
			if(node.nodeName=="H1" || node.nodeName=="H2" || node.nodeName=="H3" || node.nodeName=="H4") {
				var htstring = node.innerHTML;
				var stripped = htstring.replace(/(<([^>]+)>)/ig,"");
				tocLabel = abbreviateLabel(stripped);
				var tocLevel="tocLevel"+node.nodeName.charAt(1);
				var tocItem = createTiddlyElement(toc,"LI",null,tocLevel);
				var tocLink = createTiddlyElement(tocItem,"A",null,"tocItem",tocLabel);
				tocLink.setAttribute("slideNumber",i);
				tocLink.onclick=tocShowSlide;
			}
		}
	}
	//Input box to jump to s specific slide
	var tocItem = createTiddlyElement(toc,"LI",null,"tocJumpItem",config.macros.slideShow.messages.gotoLabel);
	var tocJumpInput = createTiddlyElement(tocItem,"INPUT","jumpInput");
	tocJumpInput.type="text";
	tocJumpInput.onkeyup=jumpInputToSlide;
}

var next_slide= function(e){GoToSlide(1);}
var first_slide= function(e){GoToSlide("f");}
var previous_slide= function(e){GoToSlide(-1);}
var last_slide= function(e){GoToSlide("l");}

function toggleSlideStyles(){
	var contentWrapper = document.getElementById('contentWrapper');
	if (contentWrapper.className == "slideShowMode"){
		contentWrapper.className = "";
		refreshPageTemplate();
		setStylesheet("#backstageShow{display: block;}","SlideShowStyleSheet"); 
		changeStyleSheet();
	} else{
		contentWrapper.className = "slideShowMode";
		refreshPageTemplate("SlideShowPageTemplate");
		setStylesheet(store.getRecursiveTiddlerText("SlideShowStyleSheet"),"SlideShowStyleSheet");
		if(slideShowStyleSheet) changeStyleSheet(slideShowStyleSheet);
	}
}

config.shadowTiddlers.SlideShowPageTemplate="<!--{{{-->\n<div id='displayArea'>\n<div id='tiddlerDisplay'></div>\n</div>\n<!--}}}-->";

config.shadowTiddlers.SlideShowViewTemplate="<!--{{{-->\n<div class='title' macro='view title'></div>\n<div class='viewer' macro='view text wikified'></div>\n<!--}}}-->";

config.shadowTiddlers.SlideShowStyleSheet = "/***\n!Slide Mode Styles\n***/\n/*{{{*/\n#slideBlanker {\n position:absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 90; \n background-color: #000;\n}\n#backstageShow{\n display: none !important;\n}\n\n#contentWrapper.slideShowMode #slideContainer{\n display: block;\n}\n\n#contentWrapper.slideShowMode .Comment{\n display: none;\n}\n\n#contentWrapper.slideShowMode .nextOverlay{\n visibility: hidden;\n}\n\n#contentWrapper.slideShowMode .currentOverlay{\n visibility: visible;\n}\n\n#contentWrapper.slideShowMode .previousOverlay{\n visibility: visible;\n}\n\n#jump{\n text-align: right;\n}\n\n.slideFooterOff #navigator{\n visibility: hidden;\n}\n\n.slideFooterOn #navigator{\n visibility: visible;\n}\n\n#contentWrapper.slideShowMode #slideClock{\n cursor: pointer; margin: 0 5px 0 5px; border: 1px solid #db4\n}\n\n#contentWrapper.slideShowMode,\n #contentWrapper.slideShowMode #displayArea{\n width: 100%;\n font-size: 1.5em;\n margin: 0 !important;\n padding: 0;\n}\n\n#slideContainer{\n display: none;\n}\n\n.indexNumbers{\n cursor: pointer;\n}\n\n#navigator{\n visibility: hidden;\n bottom: 0;\n}\n\n#toc{\n display: none;\n position: absolute;\n font-size: .75em;\n bottom: 2em;\n right: 0;\n background: #fff;\n border: 1px solid #000;\n text-align: left;\n}\n\nul#toc, #toc li{\n margin: 0;\n padding: 0;\n list-style: none;\n line-height: 1em;\n}\n\n.tocJumpItem{\n margin-right: 2em;\n}\n\n.tocJumpItem input{\nmargin-right: 1em;\n border: 0;\n}\n\n#toc a,\n#toc a.button{\n display: block;\n padding: .1em;\n}\n\n#toc .tocLevel1{\nfont-size: .8em;\n}\n\n#toc .tocLevel2{\n margin-left: 1em;\n font-size: .75em;\n}\n\n#toc .tocLevel3{\n margin-left: 2em;\nfont-size: .75em;\n}\n\n#toc .tocLevel4{\n margin-left: 3em;\nfont-size: .65em;\n}\n\n#toc a{\n cursor: pointer;\n}\n\nh1{\n min-height: 1em;\n}\n\n.slide h1{\n min-height: 0;\n}\n\n/* The '>' selector is ignored by IE6 and earlier so the proper rules are given */\n#slideFooter{\n position: fixed;\n bottom: 2px;\n right: 2px;\n width: 100%;\n text-align: right;\n}\n\n/* This is a hack to trick IE6 and earlier to put the navbar on the bottom of the page */\n* html #slideFooter {\n position: absolute;\n width: 100%;\n text-align: right;\n right: auto; bottom: auto;\n left: expression( ( -20 - slideFooter.offsetWidth + ( document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.clientWidth ) + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px' );\n top: expression( ( -10 - slideFooter.offsetHeight + ( document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight ) + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) ) + 'px' );\n}\n\n\n\n/*}}}*/";

config.shadowTiddlers.SlideShowPluginDoc="The documentation is missing. It is available [[here|http://www.math.ist.utl.pt/~psoares/addons.html#SlideShowPluginDoc]].";
//}}}
<!--{{{-->
<div class='title' macro='view title'></div>
<div class='viewer' macro='view text wikified'></div>
<!--}}}-->
Venter
Iværksat
Pauset
Færdig
[[StyleSheetShortcuts]]
/***
|Name|StyleSheetShortcuts|
|Source|http://www.TiddlyTools.com/#StyleSheetShortcuts|
|Version||
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|CSS|
|Requires||
|Description|'convenience' classes for common formatting, alignment, boxes, tables, etc.|

These 'style tweaks' can be easily included in other stylesheet tiddler so they can share a baseline look-and-feel that can then be customized to create a wide variety of 'flavors'.
***/
/*{{{*/

/* text alignments */
.left
	{ display:block;text-align:left; }
.center
	{ display:block;text-align:center; }
.center table
	{ margin:auto !important; }
.right	
	{ display:block;text-align:right; }
.justify
	{ display:block;text-align:justify; }
.indent
	{ display:block;margin:0;padding:0;border:0;margin-left:2em; }
.floatleft
	{ float:left; }
.floatright
	{ float:right; }
.valignTop, .valignTop table, .valignTop tbody, .valignTop th, .valignTop tr, .valignTop td
	{ vertical-align:top; }
.valignBottom, .valignBottom table, .valignBottom tbody, .valignBottom th, .valignBottom tr, .valignBottom td
	{ vertical-align:bottom; }
.clear
	{ clear:both; }
.wrap
	{ white-space:normal; }
.nowrap
	{ white-space:nowrap; }
.hidden
	{ display:none; }
.show
	{ display:inline !important; }
.span
	{ display:span; }
.block
	{ display:block; }
.relative
	{ position:relative; }
.absolute
	{ position:absolute; }

/* font sizes */
.big
	{ font-size:14pt;line-height:120% }
.medium
	{ font-size:12pt;line-height:120% }
.normal
	{ font-size:9pt;line-height:120% }
.small
	{ font-size:8pt;line-height:120% }
.fine
	{ font-size:7pt;line-height:120% }
.tiny
	{ font-size:6pt;line-height:120% }
.larger
	{ font-size:120%; }
.smaller
	{ font-size:80%; }

/* font styles */
.bold
	{ font-weight:bold; }
.italic
	{ font-style:italic; }
.underline
	{ text-decoration:underline; }

/* plain list items (no bullets or indent) */
.nobullets li { list-style-type: none; margin-left:-2em; }

/* multi-column tiddler content (not supported in Internet Explorer) */
.twocolumns { display:block;
	-moz-column-count:2; -moz-column-gap:1em; -moz-column-width:50%; /* FireFox */
	-webkit-column-count:2; -webkit-column-gap:1em; -webkit-column-width:50%; /* Safari */
	column-count:2; column-gap:1em; column-width:50%; /* Opera */
}
.threecolumns { display:block;
	-moz-column-count:3; -moz-column-gap:1em; -moz-column-width:33%; /* FireFox */
	-webkit-column-count:3; -webkit-column-gap:1em; -webkit-column-width:33%; /* Safari */
	column-count:3; column-gap:1em; column-width:33%; /* Opera */
}
.fourcolumns { display:block;
	-moz-column-count:4; -moz-column-gap:1em; -moz-column-width:25%; /* FireFox */
	-webkit-column-count:4; -webkit-column-gap:1em; -webkit-column-width:25%; /* Safari */
	column-count:4; column-gap:1em; column-width:25%; /* Opera */
}

/* page breaks */
.breakbefore { page-break-before:always; }
.breakafter { page-break-before:always; } 

/* show/hide browser-specific content for InternetExplorer vs. non-IE ("moz") browsers */
*[class="ieOnly"]
	{ display:none; } /* hide in moz (uses CSS selector) */
* html .mozOnly, *:first-child+html .mozOnly
	{ display: none; } /* hide in IE (uses IE6/IE7 CSS hacks) */

/* borderless tables */
.borderless, .borderless table, .borderless td, .borderless tr, .borderless th, .borderless tbody
	{ border:0 !important; margin:0 !important; padding:0 !important; }
.widetable, .widetable table
	{ width:100%; }

/* thumbnail images (fixed-sized scaled images) */
.thumbnail img { height:5em !important; }

/* stretchable images (auto-size to fit tiddler) */
.stretch img { width:95%; }

/* grouped content */
.outline
	{ display:block; padding:1em; -moz-border-radius:1em;-webkit-border-radius:1em; border:1px solid; }
.menubox
	{ display:block; padding:1em; -moz-border-radius:1em;-webkit-border-radius:1em; border:1px solid; background:#fff; color:#000; }
.menubox .button, .menubox .tiddlyLinkExisting, .menubox .tiddlyLinkNonExisting
	{ color:#009 !important; }
.groupbox
	{ display:block; padding:1em; -moz-border-radius:1em;-webkit-border-radius:1em; border:1px solid; background:#ffe; color:#000; }
.groupbox a, .groupbox .button, .groupbox .tiddlyLinkExisting, .groupbox .tiddlyLinkNonExisting
	{ color:#009 !important; }
.groupbox code
	{ color:#333 !important; }
.borderleft
	{ margin:0;padding:0;border:0;margin-left:1em; border-left:1px dotted; padding-left:.5em; }
.borderright
	{ margin:0;padding:0;border:0;margin-right:1em; border-right:1px dotted; padding-right:.5em; }
.borderbottom
	{ margin:0;padding:1px 0;border:0;border-bottom:1px dotted; margin-bottom:1px; padding-bottom:1px; }
.bordertop
	{ margin:0;padding:0;border:0;border-top:1px dotted; margin-top:1px; padding-top:1px; }

/* scrolled content */
.scrollbars { overflow:auto; }
.height10em { height:10em; }
.height15em { height:15em; }
.height20em { height:20em; }
.height25em { height:25em; }
.height30em { height:30em; }
.height35em { height:35em; }
.height40em { height:40em; }

/* compact form */
.smallform
	{ white-space:nowrap; }
.smallform input, .smallform textarea, .smallform button, .smallform checkbox, .smallform radio, .smallform select
	{ font-size:8pt; }

/* stretchable edit fields and textareas (auto-size to fit tiddler) */
.stretch input { width:99%; }
.stretch textarea { width:99%; }

/* compact input fields (limited to a few characters for entering percentages and other small values) */
.onechar input   { width:1em; }
.twochar input   { width:2em; }
.threechar input { width:3em; }
.fourchar input  { width:4em; }
.fivechar input  { width:5em; }

/* text colors */
.white { color:#fff !important }
.gray  { color:#999 !important }
.black { color:#000 !important }
.red   { color:#f66 !important }
.green { color:#0c0 !important }
.blue  { color:#99f !important }

/* rollover highlighting */
.mouseover 
	{color:[[ColorPalette::TertiaryLight]] !important;}
.mouseover a
	{color:[[ColorPalette::TertiaryLight]] !important;}
.selected .mouseover
	{color:[[ColorPalette::Foreground]] !important;}
.selected .mouseover .button, .selected .mouseover a
	{color:[[ColorPalette::PrimaryDark]] !important;}

/* rollover zoom text */
.zoomover
	{ font-size:80% !important; }
.selected .zoomover
	{ font-size:100% !important; }

/* [[ColorPalette]] text colors */
.Background	{ color:[[ColorPalette::Background]];	 }
.Foreground	{ color:[[ColorPalette::Foreground]];	 }
.PrimaryPale	{ color:[[ColorPalette::PrimaryPale]];	 }
.PrimaryLight	{ color:[[ColorPalette::PrimaryLight]];	 }
.PrimaryMid	{ color:[[ColorPalette::PrimaryMid]];	 }
.PrimaryDark	{ color:[[ColorPalette::PrimaryDark]];	 }
.SecondaryPale	{ color:[[ColorPalette::SecondaryPale]]; }
.SecondaryLight	{ color:[[ColorPalette::SecondaryLight]];}
.SecondaryMid	{ color:[[ColorPalette::SecondaryMid]];	 }
.SecondaryDark	{ color:[[ColorPalette::SecondaryDark]]; }
.TertiaryPale	{ color:[[ColorPalette::TertiaryPale]];	 }
.TertiaryLight	{ color:[[ColorPalette::TertiaryLight]]; }
.TertiaryMid	{ color:[[ColorPalette::TertiaryMid]];	 }
.TertiaryDark	{ color:[[ColorPalette::TertiaryDark]];	 }
.Error		{ color:[[ColorPalette::Error]];	 }

/* [[ColorPalette]] background colors */
.BGBackground	  { background-color:[[ColorPalette::Background]];	}
.BGForeground	  { background-color:[[ColorPalette::Foreground]];	}
.BGPrimaryPale	  { background-color:[[ColorPalette::PrimaryPale]];	}
.BGPrimaryLight	  { background-color:[[ColorPalette::PrimaryLight]];	}
.BGPrimaryMid	  { background-color:[[ColorPalette::PrimaryMid]];	}
.BGPrimaryDark	  { background-color:[[ColorPalette::PrimaryDark]];	}
.BGSecondaryPale  { background-color:[[ColorPalette::SecondaryPale]]; 	}
.BGSecondaryLight { background-color:[[ColorPalette::SecondaryLight]];	}
.BGSecondaryMid	  { background-color:[[ColorPalette::SecondaryMid]];	}
.BGSecondaryDark  { background-color:[[ColorPalette::SecondaryDark]]; 	}
.BGTertiaryPale	  { background-color:[[ColorPalette::TertiaryPale]];	}
.BGTertiaryLight  { background-color:[[ColorPalette::TertiaryLight]]; 	}
.BGTertiaryMid	  { background-color:[[ColorPalette::TertiaryMid]];	}
.BGTertiaryDark	  { background-color:[[ColorPalette::TertiaryDark]];	}
.BGError	  { background-color:[[ColorPalette::Error]];	 	}
/*}}}*/
/***
|''Name:''|TTMigrateTasks0304Plugin|
|''Description:''|Migrate task tiddler from TeamTasks v0.3 to TeamTasks v0.4 format|
|''Author:''|PhilHawksworth|
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/PhilHawksworth/Verticals/TeamTasks/teamtasks/plugins/TTMigrateTasks0304Plugin.js |
|''Version:''|0.1|
|''Date:''|Mar 13, 2008|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev |
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]] |
|''~CoreVersion:''|2.3|

''About this tool''
The migration tool is designed to be run once in order to update the metadata on older TeamTasks task tiddler.

After running the migration tool, the TiddlyWiki document should be saved in order to retain the modified tiddlers.

After going through this process, this migration tool need not be used again and the call to the macro should then be removed.

''Usage:''
Migrate all v0.3 tasks to the v0.4 format
{{{
<<TTMigrateTasks0304>>
}}}

***/

//{{{
if(!version.extensions.TTMigrateTasks0304Plugin) {
version.extensions.TTMigrateTasks0304Plugin = {installed:true};
	
	config.macros.TTMigrateTasks0304 = {};
	config.macros.TTMigrateTasks0304.converted = 0;
	config.macros.TTMigrateTasks0304.problemTiddlers = 0;
	config.macros.TTMigrateTasks0304.place;
	config.macros.TTMigrateTasks0304.targetMetaVersion = 0.4;
	

	config.macros.TTMigrateTasks0304.log = function(str) {
		createTiddlyElement(config.macros.TTMigrateTasks0304.place,"div",null,null,str);
	};


	config.macros.TTMigrateTasks0304.handler = function(place,macroName,params,wikifier,paramString,tiddler) {

		config.macros.TTMigrateTasks0304.place = place;
		config.macros.TTMigrateTasks0304.log("Converting tasks tiddlers...");		

		var taskTiddlers = store.getTaggedTiddlers("task");					
		for(var t=0; t<taskTiddlers.length; t++) {

			// Find the extended fields to convert.
			store.forEachField(taskTiddlers[t], config.macros.TTMigrateTasks0304.convert, true);

			// Test the result for quality assurance.
			var tt_meta_version = store.getValue(taskTiddlers[t],"tt_tasks_metadata_format_version");
			if(tt_meta_version == config.macros.TTMigrateTasks0304.targetMetaVersion) {
				config.macros.TTMigrateTasks0304.log("Converted to TeamTask v"+ config.macros.TTMigrateTasks0304.targetMetaVersion +" task format: " + taskTiddlers[t].title);
				config.macros.TTMigrateTasks0304.converted++;
			}
			else {
				config.macros.TTMigrateTasks0304.log("... Error. There was a problem converting " + taskTiddlers[t].title + " to TeamTask v"+ config.macros.TTMigrateTasks0304.targetMetaVersion +" task format.");
				config.macros.TTMigrateTasks0304.problemTiddlers++;
			}
		}

		// Brag about the success / apologise for the failure.
		config.macros.TTMigrateTasks0304.log(config.macros.TTMigrateTasks0304.converted + " task tiddlers successfully converted to TeamTask v"+ config.macros.TTMigrateTasks0304.targetMetaVersion +" task format.");	
		if(config.macros.TTMigrateTasks0304.problemTiddlers != 0) {
			config.macros.TTMigrateTasks0304.log("Uh-oh! We had a poblem converting " + config.macros.TTMigrateTasks0304.problemTiddlers + " naughty tiddlers.");
		}
		else
			config.macros.TTMigrateTasks0304.log("No problems. Everything is tickertyboo.");
	};


	config.macros.TTMigrateTasks0304.convert = function(tiddler,fieldName,value){
		// Convert the task metadatafields from the form 'fielddefinitions' to 'tt_field'
		// and add a "tt_tasks_metadata_format_version" field for easier future migrations.
		if(fieldName.substring(fieldName.length-11) == 'definitions'){
		 	var newFieldName = "tt_" + fieldName.substring(0, fieldName.length-11);
			store.setValue(tiddler,newFieldName,value);
			store.setValue(tiddler,fieldName,null);
			store.setValue(tiddler,"tt_tasks_metadata_format_version",config.macros.TTMigrateTasks0304.targetMetaVersion);
		}
	};

} //# end of 'install only once'
//}}}
/***
|''Name:''|TTReportViewPlugin|
|''Description:''|Add a messaging console with acticity monitor to a Tiddlywiki|
|''Author:''|PhilHawksworth|
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/PhilHawksworth/Verticals/TeamTasks/teamtasks/plugins/TTReportView.js |
|''Version:''|0.0.1|
|''Date:''|Jan 23, 2008|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev |
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]] |
|''~CoreVersion:''|2.3|

''Usage:''

Create a view of the task list showing default values.
{{{
<<TTReportView>>
}}}

Create a view of the task list showing specified fields in a given order and filtering the results.
{{{
<<TTReportView DisplayFields:"field1,field2,field3" OrderBy:"field1,[asc|desc]" fieldName:"filterValue" fieldName:"!filterValue" recent:"items">>
}}}

for example
{{{
<<TTReportView DisplayFields:"TaskName,AssignedTo,TargetDate" OrderBy:"TargetDate,asc" Status:"!closed" Project:"BigProject">>	
}}}


***/

//{{{
if(!version.extensions.TTReportViePlugin) {
version.extensions.TTReportViewPlugin = {installed:true};
	
	config.macros.TTReportView = {};
	config.macros.TTReportView.log = function(str) {
		if(window.console) {
			console.log(str);
			return;
		}
	};

	config.macros.TTReportView.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
				
		var container = story.findContainingTiddler(place);
		var wrapper = createTiddlyElement(place,"span");
		wrapper.setAttribute('refresh','content');
		wrapper.setAttribute('tiddler',tiddler.title);
		wrapper.setAttribute('force', 'true');
		
		var fieldPrefix = "tt_";
				
		//gather all of the parameters.
		var params = paramString.parseParams("anon",null,true,false,false);
		var fieldsString = getParam(params,"DisplayFields",'title');
		var displayFields = fieldsString.split(",");
		for(var i=0;i<displayFields.length;i++){
			displayFields[i] = displayFields[i].trim();
		}
		var orderString = getParam(params,"OrderBy",'title,asc');
		var orderField =  fieldPrefix + orderString.split(",")[0];
		var order =  orderString.split(",")[1];				
		var recentItems = getParam(params,"recent");
		var expectedParams = ['DisplayFields','OrderBy'];
	
		//interpret and store the filter values.	
		var filters = [];
		for(var p in params) {
			var name = params[p].name;
			var value = params[p].value;
			if((name && name != 'undefined') &!expectedParams.contains(name)) {
				var match = true;
				if(value.substring(0,1) == "!") {
					match = false;
					var str = value.substring(1);
				}
				else {
					var str = value;	
				}
				if(name != "recent") { // exclude "recent" parameter
					filters.push({'field':fieldPrefix + name, 'value':str, 'match':match});
				}
			}
		}
					
		//collect the pertinent tiddlers.
		var taskTiddlers = store.getTaggedTiddlers("task");
		var toConsider = [];
		var toDisplay = [];		
		var toExclude = [];

		// limit to recently modified tiddlers
		if(recentItems) {
			taskTiddlers.sort(function(a,b) {
				return b.modified - a.modified;
			});
			taskTiddlers = taskTiddlers.slice(0, recentItems);
		}

		// first get all the tiddlers we might want to include.
		for(var t=0; t<taskTiddlers.length; t++) {
			var consider = true;
			for(var f=0; f<filters.length; f++) {
				if(filters[f].match == true) {
					if(store.getValue(taskTiddlers[t], filters[f].field).toLowerCase() != filters[f].value.toLowerCase()){
						consider = false;
						break;
					}
				}
			}
			if(consider)
				toConsider.push(taskTiddlers[t]);
		}
		

		// now find which of our selected tiddlers we need to exclude
		for(var d=0; d<toConsider.length; d++) {
			for(var f=0; f<filters.length; f++) {
				if(filters[f].match == false) {
					if(store.getValue(toConsider[d], filters[f].field).toLowerCase() == filters[f].value.toLowerCase()) {
						toExclude.push(toConsider[d]);
					}	
				}
			}
		}
		
		// remove the excluded tiddlers.
		for (var i=0; i < toConsider.length; i++) {
			if(toExclude.contains(toConsider[i]) === false)
				toDisplay.push(toConsider[i]);
		}

		// Build a sortable table of the results.
		var tbl = createTiddlyElement(wrapper,'table',null,'sortable');
		var thead = createTiddlyElement(tbl,'thead');
		var theadr = createTiddlyElement(thead,'tr');
		for(var f=0; f<displayFields.length; f++) {
			//specifiy the sorting column if required.
			var c = null;
			if(fieldPrefix + displayFields[f].toLowerCase() == orderField.toLowerCase()) {
				var c = "autosort";
				if(order != 'asc') c += " reverse";
			}
			createTiddlyElement(theadr,'td',null,c,displayFields[f]);
		}
		var tbody = createTiddlyElement(tbl,'tbody');
		for(var d=0; d<toDisplay.length; d++) {
			var tr = createTiddlyElement(tbody,'tr');
			for(var f=0; f<displayFields.length; f++) {
				var df = displayFields[f].toLowerCase();
				if(TiddlyWiki.isStandardField(df))
					var fieldName = df;
				else
					var fieldName = fieldPrefix + df;	
				var td  = createTiddlyElement(tr,'td',null,null,null);
				var v = store.getValue(toDisplay[d], fieldName);
				if(fieldName == 'title')
					createTiddlyLink(td,v,true,null,false,false);
				else
					createTiddlyText(td,v);
			}
		}		
	};
} //# end of 'install only once'
//}}}
/***
|''Name:''|TableSortingPlugin|
|''Description:''|Dynamically sort tables by clicking on column headers|
|''Author:''|Saq Imtiaz ( lewcid@gmail.com )|
|''Source:''|http://tw.lewcid.org/#TableSortingPlugin|
|''Code Repository:''|http://tw.lewcid.org/svn/plugins|
|''Version:''|2.02|
|''Date:''|25-01-2008|
|''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion:''|2.2.3|
!!Usage:
* Make sure your table has a header row
** {{{|Name|Phone Number|Address|h}}}<br> Note the /h/ that denote a header row 
* Give the table a class of 'sortable'
** {{{
|sortable|k
|Name|Phone Number|Address|h
}}}<br>Note the /k/ that denotes a class name being assigned to the table.
* To disallow sorting by a column, place {{{<<nosort>>}}} in it's header
* To automatically sort a table by a column, place {{{<<autosort>>}}} in the header for that column
** Or to sort automatically but in reverse order, use {{{<<autosort reverse>>}}}

!!Example:
|sortable|k
|Name |Salary |Extension |Performance |File Size |Start date |h
|ZBloggs, Fred |$12000.00 |1353 |+1.2 |74.2Kb |Aug 19, 2003 21:34:00 |
|ABloggs, Fred |$12000.00 |1353 |1.2 |3350b |09/18/2003 |
|CBloggs, Fred |$12000 |1353 |1.200 |55.2Kb |August 18, 2003 |
|DBloggs, Fred |$12000.00 |1353 |1.2 |2100b |07/18/2003 |
|Bloggs, Fred |$12000.00 |1353 |01.20 |6.156Mb |08/17/2003 05:43 |
|Turvey, Kevin |$191200.00 |2342 |-33 |1b |02/05/1979 |
|Mbogo, Arnold |$32010.12 |2755 |-21.673 |1.2Gb |09/08/1998 |
|Shakespeare, Bill |�122000.00|3211 |6 |33.22Gb |12/11/1961 |
|Shakespeare, Hamlet |�9000 |9005 |-8 |3Gb |01/01/2002 |
|Fitz, Marvin |�3300.30 |5554 |+5 |4Kb |05/22/1995 |

***/
// /%
//!BEGIN-PLUGIN-CODE
config.tableSorting = {
	
	darrow: "\u2193",
	
	uarrow: "\u2191",
	
	getText : function (o) {
		var p = o.cells[SORT_INDEX];
		return p.innerText || p.textContent || '';
	},
	
	sortTable : function (o,rev) {
		SORT_INDEX = o.getAttribute("index");
		var c = config.tableSorting;
		var T = findRelated(o.parentNode,"TABLE");
		if(T.tBodies[0].rows.length<=1) 
			return;
		var itm = "";
		var i = 0;
		while (itm == "" && i < T.tBodies[0].rows.length) {
			itm = c.getText(T.tBodies[0].rows[i]).trim();
			i++;
		}
		if (itm == "") 
			return; 	
		var r = [];
		var S = o.getElementsByTagName("span")[0];		
		c.fn = c.sortAlpha; 
		if(!isNaN(Date.parse(itm)))
			c.fn = c.sortDate; 
		else if(itm.match(/^[$|�|�|\+|\-]{0,1}\d*\.{0,1}\d+$/)) 
			c.fn = c.sortNumber; 
		else if(itm.match(/^\d*\.{0,1}\d+[K|M|G]{0,1}b$/)) 
			c.fn = c.sortFile; 
		for(i=0; i<T.tBodies[0].rows.length; i++) {
			 r[i]=T.tBodies[0].rows[i]; 
		} 
		r.sort(c.reSort);
		if(S.firstChild.nodeValue==c.darrow || rev) {
			r.reverse();
			S.firstChild.nodeValue=c.uarrow;
		} 
		else 
			S.firstChild.nodeValue=c.darrow;
		var thead = T.getElementsByTagName('thead')[0]; 
		var headers = thead.rows[thead.rows.length-1].cells;
		for(var k=0; k<headers.length; k++) {
			if(!hasClass(headers[k],"nosort"))
				addClass(headers[k].getElementsByTagName("span")[0],"hidden");
		}
		removeClass(S,"hidden");
		for(i=0; i<r.length; i++) { 
			T.tBodies[0].appendChild(r[i]);
			c.stripe(r[i],i);
			for(var j=0; j<r[i].cells.length;j++){
				removeClass(r[i].cells[j],"sortedCol");
			}
			addClass(r[i].cells[SORT_INDEX],"sortedCol");
		}
	},
	
	stripe : function (e,i){
		var cl = ["oddRow","evenRow"];
		i&1? cl.reverse() : cl;
		removeClass(e,cl[1]);
		addClass(e,cl[0]);
	},
	
	sortNumber : function(v) {
		var x = parseFloat(this.getText(v).replace(/[^0-9.-]/g,''));
		return isNaN(x)? 0: x;
	},
	
	sortDate : function(v) {
		return Date.parse(this.getText(v));
	},

	sortAlpha : function(v) {
		return this.getText(v).toLowerCase();
	},
	
	sortFile : function(v) { 		
		var j, q = config.messages.sizeTemplates, s = this.getText(v);
		for (var i=0; i<q.length; i++) {
			if ((j = s.toLowerCase().indexOf(q[i].template.replace("%0\u00a0","").toLowerCase())) != -1)
				return q[i].unit * s.substr(0,j);
		}
		return parseFloat(s);
	},
	
	reSort : function(a,b){
		var c = config.tableSorting;
		var aa = c.fn(a);
		var bb = c.fn(b);
		return ((aa==bb)? 0 : ((aa<bb)? -1:1));
	}
};

Story.prototype.tSort_refreshTiddler = Story.prototype.refreshTiddler;
Story.prototype.refreshTiddler = function(title,template,force,customFields,defaultText){
	var elem = this.tSort_refreshTiddler.apply(this,arguments);
	if(elem){
		var tables = elem.getElementsByTagName("TABLE");
		var c = config.tableSorting;
		for(var i=0; i<tables.length; i++){
			if(hasClass(tables[i],"sortable")){
				var x = null, rev, table = tables[i], thead = table.getElementsByTagName('thead')[0], headers = thead.rows[thead.rows.length-1].cells;
				for (var j=0; j<headers.length; j++){
					var h = headers[j];
					if (hasClass(h,"nosort"))
						continue;
					h.setAttribute("index",j);
					h.onclick = function(){c.sortTable(this); return false;};
					h.ondblclick = stopEvent;
					if(h.getElementsByTagName("span").length == 0)
						createTiddlyElement(h,"span",null,"hidden",c.uarrow); 
					if(!x && hasClass(h,"autosort")) {
						x = j;
						rev = hasClass(h,"reverse");
					}
				}
				if(x)
					c.sortTable(headers[x],rev);		
			}
		}
	}
	return elem; 
};

setStylesheet("table.sortable span.hidden {visibility:hidden;}\n"+
	"table.sortable thead {cursor:pointer;}\n"+
	"table.sortable .nosort {cursor:default;}\n"+
	"table.sortable td.sortedCol {background:#ffc;}","TableSortingPluginStyles");

function stopEvent(e){
	var ev = e? e : window.event;
	ev.cancelBubble = true;
	if (ev.stopPropagation) ev.stopPropagation();
	return false;	
}	

config.macros.nosort={
	handler : function(place){
		addClass(place,"nosort");
	}	
};

config.macros.autosort={
	handler : function(place,m,p,w,pS){
		addClass(place,"autosort"+" "+pS);		
	}	
};
//!END-PLUGIN-CODE
// %/
/***
|Name|TaggedTemplateTweak|
|Source|http://www.TiddlyTools.com/#TaggedTemplateTweak|
|Documentation|http://www.TiddlyTools.com/#TaggedTemplateTweakInfo|
|Version|1.2.0|
|Author|Eric Shulman - ELS Design Studios|
|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|Story.prototype.chooseTemplateForTiddler()|
|Description|use alternative ViewTemplate/EditTemplate for tiddler's tagged with specific tag values|
This tweak extends story.chooseTemplateForTiddler() so that ''whenever a tiddler is marked with a specific tag value, it can be viewed and/or edited using alternatives to the standard tiddler templates.'' 
!!!!!Documentation
>see [[TaggedTemplateTweakInfo]]
!!!!!Revisions
<<<
2008.04.01 [1.2.0] added support for using systemTheme section-based template definitions (requested by Phil Hawksworth)
2008.01.22 [*.*.*] plugin size reduction - documentation moved to [[TaggedTemplateTweakInfo]]
2007.06.23 [1.1.0] re-written to use automatic 'tag prefix' search instead of hard coded check for each tag.  Allows new custom tags to be used without requiring code changes to this plugin.
| please see [[TaggedTemplateTweakInfo]] for previous revision details |
2007.06.11 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.taggedTemplate= {major: 1, minor: 2, revision: 0, date: new Date(2008,4,1)};
Story.prototype.taggedTemplate_chooseTemplateForTiddler = Story.prototype.chooseTemplateForTiddler
Story.prototype.chooseTemplateForTiddler = function(title,template)
{
	// get default template from core
	var template=this.taggedTemplate_chooseTemplateForTiddler.apply(this,arguments);

	// if the tiddler to be rendered doesn't exist yet, just return core result
	var tiddler=store.getTiddler(title); if (!tiddler) return template;

	// look for template whose prefix matches a tag on this tiddler
	for (i=0; i<tiddler.tags.length; i++) {
		var t=tiddler.tags[i]+template; // add tag prefix
		var c=t.substr(0,1).toUpperCase()+t.substr(1); // capitalized for WikiWord title
		var s=config.options.txtTheme+"##"; // systemTheme section prefix
		if (store.tiddlerExists(t)) { template=t; break; }
		if (store.tiddlerExists(c)) { template=c; break; }
		if (store.getTiddlerText(s+t)) { template=s+t; break; }
		if (store.getTiddlerText(s+c)) { template=s+c; break; }
	}
	return template;
}
//}}}
[[Tidsrammer|ScopeDefinitions]]
[[Hvem|UserDefinitions]]
[[Prioriteringer|PriorityDefinitions]]
[[Status|StatusDefinitions]]
|Tidsramme |<<ValueSwitcher type:"dropdown" valuesSource:"ScopeDefinitions">> |
|priorititet |<<ValueSwitcher type:"dropdown" valuesSource:"PriorityDefinitions">> |
|Hvem |<<ValueSwitcher type:"dropdown" valuesSource:"UserDefinitions">> |
|status |<<ValueSwitcher type:"dropdown" valuesSource:"StatusDefinitions">> |
[[Standard rapport|Overblik over arbejdsopgaver]]
[[Prioritet og status]]
[[Opgaver uden særlig tilknytning]]
[[(Lav din egen rapportoversigt)|CreatingTaskReportViews]]
The TeamTasks TiddlyWiki is an edition of TiddlyWiki which has been modified by including various plugins to provide a simple task management system.

It is flexible and extensible and can be heavily customised for your needs. For more information about how TeamTasks has been constructed take a look at the [[about|About TeamTasks]] section.

Visit the main TeamTasks site at [[www.hawksworx.com/playground/TeamTasks|http://www.hawksworx.com/playground/TeamTasks]]

Comments and suggestions are very welcome and should be directed to ph [at] osmosoft.com
Accent: #9BBE2E

TaskBorder: #EC6
TaskBackground: #FEFFA8

CodeBackground:#000
CodeColor:#23CC07

Background: #E7E7DE
Darkest: #172322
Darker: #2F403F
Dark: #77776E
LightestShade: #F3F3F3
LightShade: #DFDFD5
Shade: #d7d7cE
DarkShade: #A6A59E
DarkestShade: #757570
TiddlerBackground: #ffffff

LinkHover: transparent
[[Get your own copy of TeamTasks at getteamtasks.com|http://getteamtasks.com]]
[[TeamTasks is a vertical edition of TiddlyWiki|TiddlyWiki]]
[[TeamTasks is opensource software distributed under the BSD license|License]]
[[TeamTasks version 0.4|Release Notes]]
/***
|''Name:''|TeamTasksSkin |
|''Description:''|The basic TeamTasks theme |
|''Author:''|Phil Hawksworth - ph [at] osmosoft [dot] com |
|''~CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/PhilHawksworth/verticals/TeamTasks/teamtasks/TeamTasksSkin.tiddler |
|''Version:''|0.4|
|''Date:''|March 28th, 2008|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev |
|''License:''|[[BSD License|http://www.opensource.org/licenses/bsd-license.php]] |
|''~CoreVersion:''|2.4.0|
|''~PageTemplate:''|##PageTemplate|
|''~EditTemplate:''|##EditTemplate|
|''~taskViewTemplate:''|##taskViewTemplate|
|''~taskEditTemplate:''|##taskEditTemplate|
|''~StyleSheet:''|##StyleSheet|
***/

!PageTemplate
<!--{{{-->
<div id='messageBar'><span id='messageArea'></span></div>
<div class='header'>
<div class='headerShadow'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
<div id='topMenu' refresh='content' tiddler='TopMenu'></div>
</div>
<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>
<div id='displayArea'>
	<div id='tiddlerDisplay'></div>
</div>
<!--}}}-->


!EditTemplate
<!--{{{-->
<div class="editor">
<div class='toolbar' macro='toolbar +saveTiddler -cancelTiddler deleteTiddler'></div>
<div class='title edit' macro='edit 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='tagged edit' macro='edit tags'></div>
<div class='viewer edit' macro='edit text wikified'></div>
<div class='tagClear'></div>
</div>
<!--}}}-->


!taskViewTemplate
<!--{{{-->
<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='task'>
	<table>
	<tr>
		<td class='taskbody'><div class='viewer' macro='view text wikified'></div></td>
		<td class='taskControls'><div class='taskControls' macro='tiddler TaskTiddlerControls'></td>
	</tr>
	</table>
</div>
<div class='tagClear'></div>
<!--}}}-->

!taskEditTemplate
<!--{{{-->
<div class="editor">
<div class='toolbar' macro='toolbar +saveTiddler -cancelTiddler deleteTiddler'></div>
<div class='title edit' macro='edit 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 edit' macro='tags'></div>
<div class='task'>
	<table>
	<tr>
		<td class='taskbody'><div class='viewer edit' macro='edit text wikified'></div></div></td>
		<td class='taskControls'><div class='taskControls' macro='tiddler TaskTiddlerControls'></td>
	</tr>
	</table>
</div>
<div class='tagClear'></div>
</div>
<!--}}}-->


!StyleSheet
/*{{{*/
body { color:[[TeamTasksColors::Darkest]];}
a:hover {color:[[TeamTasksColors::Accent]]; background-color:[[TeamTasksColors::LinkHover]];}
h1,h2,h3,h4,h5,h6 {color:[[TeamTasksColors::Accent]];}
	
/* Page Framework */
body {background-color:[[TeamTasksColors::Background]]; border-top:3px solid [[TeamTasksColors::Accent]]; }
#displayArea { display: inline-block; /* IE bugfix: give layout (hasLayout = true) */ }
#displayArea { display: block; /* restore proper behavior (see IE bugfix above) */ overflow: hidden; margin: 20px 0 0 0; padding:0; border-style:none;}
#tiddlerDisplay { margin:0 10px 20px 0; padding:0;  border:none;}
#sidebar {display:none;}
#messageArea { position:inherit;  margin:0 20px 1em 10px; padding:6px; border-style:none; }

/* message bar */
#messageBar {display:block; position:relative; width:100%; margin:0; background-color:[[TeamTasksColors::LightShade]]; height:1.6em; font-size:11px;  border-top:solid 1px [[TeamTasksColors::TiddlerBackground]];}
#messageArea { position:absolute; top:0; left:0; padding:0; margin:0; border-style:none; background-color:transparent;} 
#messageArea div { margin-left:20px; padding:3px 0 0 0;}
#messageArea div.messageToolbar { position:absolute; top:0; right:0; padding:0; margin:0;}
#messageArea a { color:[[TeamTasksColors::Dark]]; text-decoration:none; }
#messageArea a:hover { color:[[TeamTasksColors::Secondary]]; text-decoration:none; }
#messageArea .button { float:right; background-color:[[TeamTasksColors::Shade]]; color:[[TeamTasksColors::TiddlerBackground]]; margin:0 0 0 1em; padding:3px 6px; }
#messageArea .button:hover {background-color:[[TeamTasksColors::Dark]]; color:[[TeamTasksColors::TiddlerBackground]];}


/* Header */
div.header,
div.headerShadow { margin:0; padding:0; top:auto;}
div.header {height:5em; background-color:[[TeamTasksColors::Background]]; position:relative;}
div.headerShadow {position:absolute; left:20px; bottom:0; height:auto;}
div.headerShadow span.siteTitle {color::[[TeamTasksColors::Darkest]]; font-size:3em; line-height:1em; letter-spacing:-2px;}
div.headerShadow span.siteSubtitle {color:[[TeamTasksColors::Dark]]; white-space:nowrap; font-size:1em;}
div.header #topMenu { position:absolute; right:20px; bottom:0;}

/* Backstage */
#backstageArea,
#backstageToolbar { background-color:[[TeamTasksColors::TiddlerBackground]]; padding-top:0;}
#backstageToolbar a.backstageTab { background-color:transparent; color:[[TeamTasksColors::Dark]]; font-weight:normal;line-height:1.5em; }
#backstageToolbar a.backstageTab:hover { background-color:[[TeamTasksColors::Accent]]; color:[[TeamTasksColors::TiddlerBackground]];  }

/* Popup */
#popup {background-color:[[TeamTasksColors::Darkest]]; border:1px solid [[TeamTasksColors::Shade]]; border-bottom:2px solid [[TeamTasksColors::Shade]];}
#popup li a { color:[[TeamTasksColors::Accent]];}
#popup li a:hover {background-color:[[TeamTasksColors::Accent]]; color:[[TeamTasksColors::TiddlerBackground]];}
#popup li.listBreak div{ border-bottom:solid 1px [[TeamTasksColors::Darker]];}

/* Top Menu*/
#topMenu a.button { border-style:none; background-color:[[TeamTasksColors::Background]]; padding:0.3em 1em; margin:0 0 0 1px; color:[[TeamTasksColors::Accent]]; display:block; float: right;}
#topMenu a.button:hover,
#mainMenu a:hover  { border-style:none; background-color:[[TeamTasksColors::Darkest]]; color:[[TeamTasksColors::Accent]];}
#topMenu a.button:active,
#mainMenu a:active  { border-style:none; background-color:[[TeamTasksColors::Accent]]; color:[[TeamTasksColors::Background]];}

/* MainMenu */
#mainMenu { position: static; float: left; width:18em; padding: 20px 0 10px 20px; margin:0;}
#mainMenu br { display:none; }
#mainMenu a { display:block; font-size:0.94em; text-align:left; margin:0 0 1px 0; border-style:none; background-color:[[TeamTasksColors::Shade]]; padding:0.3em 1em; color:[[TeamTasksColors::Darkest]];  }
#mainMenu div {  width:auto; }
#mainMenu div a {display:block;  font-size:0.9em; text-align:right; margin:0 0 1px 0; background-color:[[TeamTasksColors::LightShade]];}
#mainMenu span.search { padding:6px 6px 6px 0px; margin-bottom:10px; display:block; background-color:[[TeamTasksColors::Darkest]]; text-align:left;}
#mainMenu span.search .searchField { padding:2px 6px; border:solid 1px [[TeamTasksColors::DarkShade]]; border-top-color:[[TeamTasksColors::Dark]];  border-bottom-color:[[TeamTasksColors::TiddlerBackground]]; background-color:[[TeamTasksColors::Background]]; }
#mainMenu span.search a.searchButton { display:inline; color:[[TeamTasksColors::Accent]]; background-color:[[TeamTasksColors::Darkest]];}
#mainMenu span.search a.searchButton:hover { color:[[TeamTasksColors::TiddlerBackground]]; }

/* MetaData section */
#mainMenu div.meta { font-size:0.9em; line-height:1.1em;}
#mainMenu div.meta span { display: block; width:20em; text-align:right;}
#mainMenu div.meta a {color:[[TeamTasksColors::DarkestShade]]; background-color:[[TeamTasksColors::LinkHover]]; margin:1.4em 1em 0.2em 3em; padding:0;}
#mainMenu div.meta a:hover {color:[[TeamTasksColors::Accent]]; background-color:[[TeamTasksColors::LinkHover]];}

/* Vanilla Tiddlers */
.tiddler { background-color:[[TeamTasksColors::TiddlerBackground]]; margin:0 1em 2em 1em; padding:0 0 1em 0; border-bottom:1px solid[[TeamTasksColors::DarkShade]]; 	}

.tiddler div.toolbar { margin:0; padding:0; height:2em; visibility:hidden;}
.tiddler div.toolbar a.button:first-child {  border-left:1px solid [[TeamTasksColors::LightShade]];}
.tiddler div.toolbar a.button { background-color:[[TeamTasksColors::TiddlerBackground]]; padding:4px 1em 4px 1em; border-style:none; border-left:1px solid [[TeamTasksColors::LightShade]]; border-bottom:1px solid [[TeamTasksColors::LightShade]];  border-top:3px solid [[TeamTasksColors::Background]]; line-height:2.3em;}
.tiddler div.toolbar a.button:hover { background-color:[[TeamTasksColors::LightestShade]]; border-bottom-color:[[TeamTasksColors::DarkShade]]; color:[[TeamTasksColors::Darkest]];}
.tiddler div.toolbar a.button:active { background-color:[[TeamTasksColors::Accent]]; border-bottom-color:[[TeamTasksColors::Accent]]; color:[[TeamTasksColors::TiddlerBackground]];}

.tiddler div.title { color:[[TeamTasksColors::Accent]]; margin:4px 20px 3px 20px;}
.tiddler div.subtitle,
.tiddler div.tagged,
.tiddler div.tagging { float:none; border-style:none; background-color:[[TeamTasksColors::TiddlerBackground]]; margin:3px 20px 0 20px; padding:0; font:italic 0.95em/1em "Lucida Sans","Lucida Grande",Verdana,"Bitstream Vera Sans",Arial,sans-serif; color:[[TeamTasksColors::DarkShade]];}
.tiddler div.tagged ul,
.tiddler div.tagging ul {margin:0; padding:0;}
.tiddler div.tagged li,
.tiddler div.tagging li {display:inline; margin:0 0.4em 0 0; color:[[TeamTasksColors::DarkShade]]; }
.tiddler div.tagged li.listTitle,
.tiddler div.tagging li.listTitle {margin:0 0.1em 0 0; }
.tiddler div.tagged a.button,
.tiddler div.tagging a.button {padding:0;}
.tiddler div.subtitle a,
.tiddler div.tagged a,
.tiddler div.tagging a {color:[[TeamTasksColors::DarkestShade]]; font-weight:normal; white-space:nowrap; border-bottom:solid 1px [[TeamTasksColors::Background]];}
.tiddler div.subtitle a:hover,
.tiddler div.tagged a:hover,
.tiddler div.tagging a:hover {color:[[TeamTasksColors::Accent]]; background-color:[[TeamTasksColors::LinkHover]];  border-bottom-color:[[TeamTasksColors::Accent]];}
.tiddler div.viewer { clear:left; margin:10px 20px; border-top:solid 1px [[TeamTasksColors::Background]];}

.viewer pre {background-color:[[TeamTasksColors::Background]]; color:[[TeamTasksColors::Darker]]; border:solid 1px [[TeamTasksColors::DarkShade]]; padding:1em 2em;}
.selected div.toolbar { visibility:visible;}

/* Task Tiddlers */
.tiddler div.task { clear:left; margin:10px 20px; border-top:solid 0px [[TeamTasksColors::Background]];}
.tiddler div.task table { width:100%; margin:0; padding:0; }
.tiddler div.task table * { vertical-align:top; }
.tiddler div.task table td.taskbody { width:100%; }
.tiddler div.task table td.taskControls { width:auto; }
.tiddler div.task div.viewer { display:block; padding:1em; margin:10px 0; border:solid 1px [[TeamTasksColors::TaskBorder]]; background-color:[[TeamTasksColors::TaskBackground]]; font:italic 1.1em/1.5em "Lucida Sans","Lucida Grande",Verdana,"Bitstream Vera Sans",Arial,sans-serif; }
.tiddler div.task div.taskControls { float:right; white-space:nowrap; margin:0 0 0 10px;}
.tiddler div.task div.taskControls table { border-style:none; margin: 10px 0;}
.tiddler div.task div.taskControls table tr { border-style:none;}
.tiddler div.task div.taskControls table tr td { border-style:none;}
.tiddler div.task div.taskControls select {width: 150px; font-size:0.9em;}
.tiddler div.task div.dependencies { padding:1em; background-color:[[TeamTasksColors::LightestShade]]; border:solid 1px [[TeamTasksColors::LightShade]]; border-top-color:[[TeamTasksColors::DarkShade]];}
.tiddler div.task .label {font-size:0.9em; color:[[TeamTasksColors::DarkestShade]]; margin-bottom:0.4em;}

/* tiddler Edit mode  */
.tiddler .edit { padding:4px; background-color:[[TeamTasksColors::TiddlerBackground]]; border:solid 1px [[TeamTasksColors::LightShade]]; border-top-color:[[TeamTasksColors::DarkShade]];}
.tiddler .edit * { background-color:[[TeamTasksColors::TiddlerBackground]]; border-style:none; }
.tiddler div.editor div.title { color:[[TeamTasksColors::Dark]]; margin:10px 20px 10px 20px;}
.tiddler div.editor div.viewer {  padding: none; background-color:[[TeamTasksColors::TiddlerBackground]];}

/* New User Wizard */ 
#createTeamTaskUserForm { background-color:#f0f0f0; padding:1em; border:solid 1px #ccc;}
#createTeamTaskUserForm label { margin-bottom:10px; display:block; clear:left; font-size:0.9em;}
#createTeamTaskUserForm label input {float:left; border:1px solid #ddd; border-top:1px solid #999; padding:2px 4px; font-size:1em; width:30em;}

/* TT Report Views */
table.sortable { margin:0.5em 0; border-style:none; }
table.sortable tr {border-left-width:0; border-right-width:0;}
table.sortable * td {border-top:solid 1px [[TeamTasksColors::LightShade]]; border-bottom:solid 1px [[TeamTasksColors::LightShade]]; border-left-width:0; border-right-width:0;}
table.sortable thead tr td { background-color: [[TeamTasksColors::LightestShade]]; color:[[TeamTasksColors::Darkest]];}

/*}}}*/
/***
|Name|TiddlyLockPlugin|
|Source|http://www.minormania.com/tiddlylock/tiddlylock.html|
|Version|1.0.4|
|TiddlyWiki Core Version|2.2.4|
|Author|Richard Hobbis|
|License|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|Type|plugin|
|Overrides|config.macros.newTiddler.onClickNewTiddler()<<br>>config.commands.cancelTiddler.handler()<<br>>config.commands.deleteTiddler.handler<<br>>config.commands.editTiddler.handler()<<br>>config.commands.saveTiddler.handler()<<br>>saveChanges()<<br>>checkUnsavedChanges()|
|Description|Automatically locks and unlocks the TiddlyWiki as required, allowing multiple users to edit the TiddlyWiki without fear of overwriting other users' changes.|
!!!Usage
<<<
Simply import TiddlyLockPlugin into your TiddlyWiki!
<<<
!!!Installation
<<<
Import (or copy/paste) ''this tiddler'' into your TiddlyWiki and make sure it's tagged with <<tag systemConfig>>. Reload your TiddlyWiki to enable TiddlyLock.
<<<
!!!Configuration
<<<
None required!
<<<
!!!Revision History
<<<
''2007.06.22 [1.0.4]'' Added locking on 'new tiddler' which also traps 'new journal'. Tweaked messages.
''2007.06.20 [1.0.3]'' Fixed an issue that occurred when a user navigated away from the TiddlyWiki without saving outstanding changes.
''2007.05.10 [1.0.2]'' Implemented a timestamp to track the last update time. This fixes the multi-browser edit issue and also removes the need for a password.
''2007.05.08 [1.0.1]'' Function overrides are now done using apply() ensuring clean upgrades (thanks Martin!)
''2007.05.01 [1.0.0]'' Initial Release
<<<
!!!Known Issues
<<<
*Monkey Pirate TiddlyWiki (MPTW) adds a ''disable'' button to the toolbar for systemConfig tiddlers. This button is available even when the TW is marked as readOnly and therefore it's possible for two users to disable/enable plugins at the same time. In this case, whoever saves the TW last will 'win' and their changes will be saved. Note that this is only an issue if there are no other unsaved changes in both browsers - TiddlyLock still handles all other changes.
<<<
!!!Credits
<<<
This feature was developed by Richard Hobbis (rhobbis [at] hotmail [dot] com).
<<<
!!!Code
***/

//{{{
// Convert a date to UTC YYYYMMDDHHMMSSMMM string format
// This is the same as the builtin function convertToYYYYMMDDHHMMSSMMM() but
// without the '.' in the middle - this allows simple date comparisons
Date.prototype.TLConvertToYYYYMMDDHHMMSSMMM = function()
{
  return(String.zeroPad(this.getUTCFullYear(),4)
    + String.zeroPad(this.getUTCMonth()+1,2)
    + String.zeroPad(this.getUTCDate(),2)
    + String.zeroPad(this.getUTCHours(),2)
    + String.zeroPad(this.getUTCMinutes(),2)
    + String.zeroPad(this.getUTCSeconds(),2)
    + String.zeroPad(this.getUTCMilliseconds(),4));
}

// namespace for TiddlyLock
TiddlyLock = {};

// Load/Last Update timestamp
TiddlyLock.TimeStamp = new Date().TLConvertToYYYYMMDDHHMMSSMMM();

// Lockfile
TiddlyLock.LockPath = '';
TiddlyLock.OldLockData = '';
TiddlyLock.LockData = '';

// define messages
TiddlyLock.Msg = {
  Locked: 'File locked',
  Unlocked: 'File unlocked',
  LockFailed: 'Failed to lock file',
  UnlockFailed: 'Failed to unlock file',
  ReadOnly: 'Now in Read-Only mode.',
  Changed: 'This file has been changed by someone else.',
  Reload: 'Reload this file before editing.'};

// create/update the lock file
function TLSave(timeStamp,lockedBy)
{
  var lockedText='';
  if (lockedBy!='')
  {
    lockedText=timeStamp+'##'+lockedBy;
  }
  else lockedText=timeStamp+'##';
    var lockSave=saveFile(TiddlyLock.LockPath,lockedText);
  TiddlyLock.TimeStamp = timeStamp;
  return false;
}


// Create/update the lock file to prevent other users from editing the TW
function TLLock()
{
  clearMessage();
  lockSave = TLSave(new Date().TLConvertToYYYYMMDDHHMMSSMMM(),config.options.txtUserName);
  displayMessage(TiddlyLock.Msg.Locked,'');
  return false;
}


// Clear the lock file if necessary, but only if I have it locked, setting the
// timestamp in the lockfile to the specified value
function TLUnlock(timeStamp)
{
  if ((store && store.isDirty && !store.isDirty())
    && (story && story.areAnyDirty && !story.areAnyDirty())
    && TLIsLocked()
    && TLIsLockedByMe())
  {
    lockSave=TLSave(timeStamp,'','');
    displayMessage(TiddlyLock.Msg.Unlocked,'');
    TiddlyLock.OldLockData = TiddlyLock.LockData;
  }
  return false;
}

// Get the contents of the lock file, if it exists
function TLLockPath()
{
  var lockPath,p;
  var originalPath=document.location.toString();
  var localPath=getLocalPath(originalPath);
  if((p=localPath.lastIndexOf('.')) != -1)
    lockPath=localPath.substr(0,p) + '.lck';
  else lockPath=localPath + '.lck';
    return lockPath;
}


// Get the contents of the lock file, if it exists
function TLLockData()
{
  TiddlyLock.LockPath = TLLockPath();
  return loadFile(TiddlyLock.LockPath);
}

// Get the contents of the lock file, if it exists
function TLIsLocked()
{
  TiddlyLock.LockData = TLLockData();
  if (TiddlyLock.LockData
      && ( TLLockedBy(TiddlyLock.LockData)!='' // someone has it locked
         || TiddlyLock.TimeStamp < TLLockedTimeStamp(TiddlyLock.LockData) // changed by someone else but not currently locked
         )
     )
    return true;
  else
    return false;
}


// check if locked by me
function TLIsLockedByMe()
{
  if(TiddlyLock.LockData == TiddlyLock.TimeStamp+'##' + config.options.txtUserName)
    return true;
  else
    return false;
}


// returns just the timestamp portion of the supplied lock file contents
function TLLockedTimeStamp(lockData)
{
  if(lockData)
    return lockData.split('##')[0];
  else
    return '';
}


// returns just the username portion of the supplied lock file contents
function TLLockedBy(lockData)
{
  if(lockData)
    return lockData.split('##')[1];
  else
    return '';
}

// display a message if locked or changed
function TLChangesAllowed()
{
  if(TLIsLocked() && !TLIsLockedByMe())
  {
//    if(!readOnly)
    {
      readOnly=true;
      if(TLLockedBy(TiddlyLock.LockData))
      {
        displayMessage(TiddlyLock.Msg.Locked+' by '+TLLockedBy(TiddlyLock.LockData));
        alert(TiddlyLock.Msg.Locked+' by '+TLLockedBy(TiddlyLock.LockData)+'. '+TiddlyLock.Msg.ReadOnly);
      }
      else
      {
        displayMessage(TiddlyLock.Msg.Changed+' '+TiddlyLock.Msg.Reload);
        alert(TiddlyLock.Msg.Changed+' '+TiddlyLock.Msg.Reload);
      }
    }
    return false;
  }
  else
    return true;
}


//*********************************************
// OVERRIDE STANDARD FUNCTIONS
//*********************************************

//
// OVERRIDE onClickNewTiddler()
//
TiddlyLock.onClickNewTiddler = config.macros.newTiddler.onClickNewTiddler;
config.macros.newTiddler.onClickNewTiddler = function(event,src,title)
{
  if (TLChangesAllowed())
  {
    TiddlyLock.OldLockData = TiddlyLock.LockData;
    TLLock();
    var ret = TiddlyLock.onClickNewTiddler.apply(this,arguments);
    return ret;
  }
}

//
// OVERRIDE checkUnsavedChanges()
//
TiddlyLock.checkUnsavedChanges = checkUnsavedChanges;
checkUnsavedChanges = function(event,src,title)
{
  var ret = TiddlyLock.checkUnsavedChanges.apply(this,arguments);
  if(TLIsLocked() && TLIsLockedByMe())
    lockSave=TLSave(TLLockedTimeStamp(TiddlyLock.OldLockData),'','');
  return ret;
}


//
// OVERRIDE cancelTiddler()
//
TiddlyLock.cancelTiddler = config.commands.cancelTiddler.handler;
config.commands.cancelTiddler.handler = function(event,src,title)
{
  var ret = TiddlyLock.cancelTiddler.apply(this,arguments);
  TLUnlock(TLLockedTimeStamp(TiddlyLock.OldLockData));
  return ret;
}

//
// OVERRIDE deleteTiddler()
//
TiddlyLock.deleteTiddler = config.commands.deleteTiddler.handler;
config.commands.deleteTiddler.handler = function(event,src,title)
{
  if (TLChangesAllowed())
  {
    TiddlyLock.OldLockData = TiddlyLock.LockData;
    TLLock();
    var ret = TiddlyLock.deleteTiddler.apply(this,arguments);
    return ret;
  }
}

//
// OVERRIDE editTiddler()
//
TiddlyLock.editTiddler = config.commands.editTiddler.handler;
config.commands.editTiddler.handler = function(event,src,title)
{
  if (TLChangesAllowed())
  {
    TiddlyLock.OldLockData = TiddlyLock.LockData;
    TLLock();
  }
  var ret = TiddlyLock.editTiddler.apply(this,arguments);
  return ret;
}

//
// OVERRIDE saveChanges()
//
TiddlyLock.saveChanges = saveChanges;
saveChanges = function(onlyIfDirty)
{
  if(TLChangesAllowed())
  {
    var ret = TiddlyLock.saveChanges.apply(this,arguments);
    TLUnlock(new Date().TLConvertToYYYYMMDDHHMMSSMMM());
    return ret;
  }
  else
    return false;
}

//
// OVERRIDE saveTiddler()
//
TiddlyLock.saveTiddler= config.commands.saveTiddler.handler;
config.commands.saveTiddler.handler=function(event,src,title)
{
  var ret = TiddlyLock.saveTiddler.apply(this,arguments);
  TLUnlock(new Date().TLConvertToYYYYMMDDHHMMSSMMM());
  return ret;
}

//}}}
TiddlyWiki is a website on a stick! In one single HTML file, TiddlyWiki gives you the ability to publish and organize information in a whole manner of different ways. If you can't do what you want to, you can write plugins to change the way TiddlyWiki works. A thriving community of developers have generated huge number of plugins that turn TiddlyWiki into a number of different things, from a CD organizer to an online collaboration tool.

TiddlyWiki is a piece of open source software created by Jeremy Ruston. The copyright is now owned by the not-for-profit organisation [[UnaMesa|http://www.unamesa.com]]. TiddlyWiki has always been free and open source and will remain free and open source. Edit mode.
<<closeAll label:'Luk alle' title:Luk alle>><<permaview>><<newTiddler label:'NyTiddler'>><<newTiddler label:'Ny opgave' title:NewTask tag:task text:'Skriv noget tekst og klik på DONE for at se rullemenuerne'>> <<saveChanges Gem>>
Kan kun lade sig gøre (hvis det skal være på samme netværk som det i klassefløjen) hvis vi køber en konverterboks + trådløs switch. Switchen er til mixen (svarende til den lille sorte i nr. 13).
Der er kun 1 stik i Arken, hvilket kræver en voldsom router - og 2 stik i loftet midt på den lange gang (ved foredragssalen). Igen + routere...
/***
Description: Contains the stuff you need to use Tiddlyspot
Note, you also need UploadPlugin, PasswordOptionPlugin and LoadRemoteFileThroughProxy
from http://tiddlywiki.bidix.info for a complete working Tiddlyspot site.
***/
//{{{

// edit this if you are migrating sites or retrofitting an existing TW
config.tiddlyspotSiteId = 'lektier';

// make it so you can by default see edit controls via http
config.options.chkHttpReadOnly = false;
window.readOnly = false; // make sure of it (for tw 2.2)
window.showBackstage = true; // show backstage too

// disable autosave in d3
if (window.location.protocol != "file:")
	config.options.chkGTDLazyAutoSave = false;

// tweak shadow tiddlers to add upload button, password entry box etc
with (config.shadowTiddlers) {
	SiteUrl = 'http://'+config.tiddlyspotSiteId+'.tiddlyspot.com';
	SideBarOptions = SideBarOptions.replace(/(<<saveChanges>>)/,"$1<<tiddler TspotSidebar>>");
	OptionsPanel = OptionsPanel.replace(/^/,"<<tiddler TspotOptions>>");
	DefaultTiddlers = DefaultTiddlers.replace(/^/,"[[WelcomeToTiddlyspot]] ");
	MainMenu = MainMenu.replace(/^/,"[[WelcomeToTiddlyspot]] ");
}

// create some shadow tiddler content
merge(config.shadowTiddlers,{

'WelcomeToTiddlyspot':[
 "This document is a ~TiddlyWiki from tiddlyspot.com.  A ~TiddlyWiki is an electronic notebook that is great for managing todo lists, personal information, and all sorts of things.",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //What now?// &nbsp;&nbsp;@@ Before you can save any changes, you need to enter your password in the form below.  Then configure privacy and other site settings at your [[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]] (your control panel username is //" + config.tiddlyspotSiteId + "//).",
 "<<tiddler TspotControls>>",
 "See also GettingStarted.",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //Working online// &nbsp;&nbsp;@@ You can edit this ~TiddlyWiki right now, and save your changes using the \"save to web\" button in the column on the right.",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //Working offline// &nbsp;&nbsp;@@ A fully functioning copy of this ~TiddlyWiki can be saved onto your hard drive or USB stick.  You can make changes and save them locally without being connected to the Internet.  When you're ready to sync up again, just click \"upload\" and your ~TiddlyWiki will be saved back to tiddlyspot.com.",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //Help!// &nbsp;&nbsp;@@ Find out more about ~TiddlyWiki at [[TiddlyWiki.com|http://tiddlywiki.com]].  Also visit [[TiddlyWiki.org|http://tiddlywiki.org]] for documentation on learning and using ~TiddlyWiki. New users are especially welcome on the [[TiddlyWiki mailing list|http://groups.google.com/group/TiddlyWiki]], which is an excellent place to ask questions and get help.  If you have a tiddlyspot related problem email [[tiddlyspot support|mailto:support@tiddlyspot.com]].",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //Enjoy :)// &nbsp;&nbsp;@@ We hope you like using your tiddlyspot.com site.  Please email [[feedback@tiddlyspot.com|mailto:feedback@tiddlyspot.com]] with any comments or suggestions."
].join("\n"),

'TspotControls':[
 "| tiddlyspot password:|<<option pasUploadPassword>>|",
 "| site management:|<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . .  " + config.tiddlyspotSiteId + ">>//(requires tiddlyspot password)//<br>[[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]], [[download (go offline)|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download]]|",
 "| links:|[[tiddlyspot.com|http://tiddlyspot.com/]], [[FAQs|http://faq.tiddlyspot.com/]], [[blog|http://tiddlyspot.blogspot.com/]], email [[support|mailto:support@tiddlyspot.com]] & [[feedback|mailto:feedback@tiddlyspot.com]], [[donate|http://tiddlyspot.com/?page=donate]]|"
].join("\n"),

'TspotSidebar':[
 "<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . .  " + config.tiddlyspotSiteId + ">><html><a href='http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download' class='button'>download</a></html>"
].join("\n"),

'TspotOptions':[
 "tiddlyspot password:",
 "<<option pasUploadPassword>>",
 ""
].join("\n")

});
//}}}
<<tiddler TspotControls>>
| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |
| 14/01/2010 22:28:45 | DitNavn | [[/|http://lektier.tiddlyspot.com/]] | [[store.cgi|http://lektier.tiddlyspot.com/store.cgi]] | . | [[index.html | http://lektier.tiddlyspot.com/index.html]] | . |
| 14/01/2010 22:33:10 | DitNavn | [[/|http://lektier.tiddlyspot.com/]] | [[store.cgi|http://lektier.tiddlyspot.com/store.cgi]] | . | [[index.html | http://lektier.tiddlyspot.com/index.html]] | . |
| 24/06/2011 02:29:41 | DitNavn | [[/|http://lektier.tiddlyspot.com/]] | [[store.cgi|http://lektier.tiddlyspot.com/store.cgi]] | . | [[index.html | http://lektier.tiddlyspot.com/index.html]] | . | failed |
| 24/06/2011 02:30:00 | DitNavn | [[/|http://lektier.tiddlyspot.com/]] | [[store.cgi|http://lektier.tiddlyspot.com/store.cgi]] | . | [[index.html | http://lektier.tiddlyspot.com/index.html]] | . | failed |
| 24/06/2011 02:30:21 | DitNavn | [[/|http://lektier.tiddlyspot.com/]] | [[store.cgi|http://lektier.tiddlyspot.com/store.cgi]] | . | [[index.html | http://lektier.tiddlyspot.com/index.html]] | . | failed |
| 24/06/2011 02:31:42 | DitNavn | [[/|http://lektier.tiddlyspot.com/]] | [[store.cgi|http://lektier.tiddlyspot.com/store.cgi]] | . | [[index.html | http://lektier.tiddlyspot.com/index.html]] | . | failed |
| 24/06/2011 02:32:02 | DitNavn | [[/|http://lektier.tiddlyspot.com/]] | [[store.cgi|http://lektier.tiddlyspot.com/store.cgi]] | . | [[index.html | http://lektier.tiddlyspot.com/index.html]] | . | failed |
| 24/06/2011 02:32:29 | DitNavn | [[/|http://lektier.tiddlyspot.com/]] | [[store.cgi|http://lektier.tiddlyspot.com/store.cgi]] | . | [[index.html | http://lektier.tiddlyspot.com/index.html]] | . | failed |
| 24/06/2011 02:32:48 | DitNavn | [[/|http://lektier.tiddlyspot.com/]] | [[store.cgi|http://lektier.tiddlyspot.com/store.cgi]] | . | [[index.html | http://lektier.tiddlyspot.com/index.html]] | . |
| 24/06/2011 02:34:56 | DitNavn | [[/|http://lektier.tiddlyspot.com/]] | [[store.cgi|http://lektier.tiddlyspot.com/store.cgi]] | . | [[index.html | http://lektier.tiddlyspot.com/index.html]] | . |
/***
|''Name:''|UploadPlugin|
|''Description:''|Save to web a TiddlyWiki|
|''Version:''|4.1.3|
|''Date:''|Feb 24, 2008|
|''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: 3,
	date: new Date("Feb 24, 2008"),
	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");


//}}}

Mig
Dig
Os 2
/***
|''Name:''|ValueSwitcherPlugin|
|''Description:''|Gather values from a definition tiddler, and present the user with a UI for setting a value from those available options as an extende field |
|''Version:''|0.2|
|''Date:''|25 Sept, 2007|
|''Source:''|http://www.hawksworx.com/playground/TeamTasks/#ValueTogglerPlugin|
|''Author:''|PhilHawksworth (phawksworth (at) gmail (dot) com)|
|''License:''|[[BSD open source license]]|
|''CoreVersion:''|2.3|
***/

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

		handler: function(place,macroName,params,wikifier,paramString,tiddler) {

			var fieldPrefix = "tt_";
			var taskTiddler = story.findContainingTiddler(place);
			if(!(taskTiddler && taskTiddler != 'undefined')) {
				return;
			}
			var params = paramString.parseParams("anon",null,true,false,false);
			var ctrlType = getParam(params,"type",null);
			var id = taskTiddler.id;
			var title = id.substr(7);
			var tiddler = store.getTiddler(title);

			// build a drop down control
			if(ctrlType == 'dropdown') {
				var valueSrc = getParam(params,"valuesSource", null);
				if(!valueSrc) {
					displayMessage("No definition tiddler defined for a TeamTasks dropdown.");
					return;
				}
				var fieldName = fieldPrefix + valueSrc.toLowerCase().substr(0,valueSrc.length-11);
				var selected = fieldName + '::' + store.getValue(tiddler,fieldName);
				var values = this.getDefValues(valueSrc);
				var options = [];
				options.push({'caption': 'Please select', 'name': null});
				for (var i=0; i < values.length; i++) {
					options.push({'caption': values[i], 'name': fieldName + '::' + values[i]});				
				}
				createTiddlyDropDown(place,this.setDropDownMetaData,options,selected);
			}
			// Build a free text box.
			else if(ctrlType == 'freetext') {
				var metaDataName = getParam(params,"metaDataName", null);
				if(!metaDataName) {
					displayMessage("No metaDataName defined for a TeamTasks free text box.");
					return;
				}	
				var fieldName = fieldPrefix + metaDataName.toLowerCase();
				var text = store.getValue(tiddler,fieldName);
				if(text == undefined) text = "";	
				var i = createTiddlyElement(place,"input",null,null,null,{"value":text, "type":"input", "ttname":fieldName});
				i.onblur = config.macros.ValueSwitcher.changeFreetext;
			}

			/*
				TODO: Build in deadline support
			*/
		},


		//Get definition values for populating UI from definition tiddlers.
		getDefValues: function(src) {
			var text = store.getTiddlerText(src).split('\n');
			var output = [];
			for(var t=0; t<text.length; t++) {
				//support calling the old TaskViewBuilder macro to list the tasks here too.
				var blob = wikifyStatic(text[t],null,tiddler,null);				
				var linktitle = /tiddlylink="[^"]*"/mg;
				var titles = blob.match(linktitle);
				if(titles) {
					for(var n=0; n<titles.length; n++) {
						output.push(titles[n].replace(/tiddlylink="([^"]*)"/,'$1'));
					}
				}
				else {
					output.push(text[t]);
				}
			}
			return (output);	
		},


		// Ensure that changes to a dropdown field are stored as an extended field.
		setDropDownMetaData: function(ev) {
			var e = ev ? ev : window.event;
			var taskTiddler = story.findContainingTiddler(this);
			if(taskTiddler && taskTiddler != undefined) {
				var title = taskTiddler.getAttribute('tiddler');
				var tiddler =  store.getTiddler(title);
				var option = this[this.selectedIndex].value.split('::');
				var extField = option[0];
				var extFieldVal = option[1];
				store.setValue(tiddler,extField,extFieldVal);
				story.saveTiddler(title);
			}
		},


		// Ensure that changes to a free text field are stored as an extended field.
		changeFreetext: function(ev) {
			var e = ev ? ev : window.event;
			var ttField = this.getAttribute('ttname');
			var value = this.value;
			if(ttField) {
				var t = story.findContainingTiddler(this);
				var title = t.getAttribute('tiddler');
				var tiddler =  store.getTiddler(title);
				store.setValue(tiddler,ttField,value);
				story.saveTiddler(tiddler);
			}
			return false;
		}
	};
}
//}}}
//{{{

config.options.chkAutoSave = true;
config.options.chkAnimate = true;
config.options.chkSaveBackups = false;
config.options.txtTheme = "TeamTasksSkin";

//}}}
//{{{
config.macros.search.label=""; 
config.options.chkDisableTabsBar=false;
config.options.chkHttpReadOnly = false;
/*config.options.chkAutoSave = true;*/
config.options.chkSaveBackups = true;
config.options.chkAnimate = false;
if (window.location.protocol!="file:") showBackstage=false; 
config.options.chkShowRightSidebar= false;
config.options.chkShowLeftSidebar= true;
config.options.chkSinglePageMode= true;
config.options.chkSinglePagePermalink= false;
config.options.chkSearchTitles=true;
config.options.chkSearchText=true;
config.options.chkSearchTags=true;
config.options.chkSearchFields=true;
config.options.chkSearchTitlesFirst=false;
config.options.chkSearchList=true;
config.options.chkSearchByDate=false;
config.options.chkSearchIncremental=false;
config.options.chkSearchShadows=false; 
config.options.chkShowQuickEdit=true;
//}}}
/***
!
Name: YourSearchBookmarklet
Version: 2.1.4
Source: http://tiddlywiki.abego-software.de/#YourSearchPlugin
Author: UdoBorkowski, XavierVergés
Licence: BSD open source license (abego Software)
Copyright: &copy; 2005-2008 http://www.abego-software.de
Community: http://xdexavier.googlepages.com/yoursearch.html
***/
//{{{
(function(){var a=document.createElement("script");a.src="http://tiddlywiki.abego-software.de/archive/YourSearchPlugin/YourSearchPlugin.js";a.onload=function(){refreshPageTemplate();displayMessage("YourSearch er blevet hentet")};document.getElementsByTagName("head")[0].appendChild(a)})();
//}}}
<<calendar>>