<!--{{{-->
<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]];}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

hr {height:1px;}

a {text-decoration:none;}

dt {font-weight:bold;}

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

.txtOptionInput {width:11em;}

#contentWrapper .chkOptionInput {border:0;}

.externalLink {text-decoration:underline;}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

----
Also see AdvancedOptions
<<importTiddlers>>
|''Type:''|file|
|''URL:''|http://bradleymeck.tiddlyspot.com/|
|''Workspace:''|(default)|

This tiddler was automatically created to record the details of this server
|''Type:''|file|
|''URL:''|http://www.tiddlytools.com|
|''Workspace:''|(default)|

This tiddler was automatically created to record the details of this server
|''Type:''|file|
|''URL:''|http://www.tiddlywiki.com/coreplugins.html|
|''Workspace:''|(default)|

This tiddler was automatically created to record the details of this server
|''Type:''|file|
|''URL:''|http://yann.perrin.googlepages.com/twkd.html|
|''Workspace:''|(default)|

This tiddler was automatically created to record the details of this server
!Philosphie
* 1 fichier TiddlyWiki par projet Scrum
* Les plugins sont le moins intrusifs possibles, c'est à dire qu'il est possible de fonctionner sans eux dans l'absolu, a tout moment.
* Le fichier contient tout ce dont vous avez besoin pour 
** Gérer les UserStory et les backlog de produit ou de sprint
** Gérer les tâches, saisir et afficher les burdown chart
** Collaborer avec d'autres personnes sur un même fichier
!Les plugins installés
* SortListPlugin permet de réordonner le contenu d'un Tiddler facilement
* [[Populate/UpdateListPlugin]] permet de préremplir ou de mettre à jour une liste de Tiddler
* SliceGridPlugin permet de saisir le reste à faire quotidien sur les tâches
* HistoGramMacro permet d'afficher un burndown chart sur la base des SliceGrid
* UploadPlugin et UploadTiddlerPlugin permet de collaborer a plusieurs sur un même ficher
* ForEachTiddlerPlugin permet d'afficher des listes via un mini langage SQL) de tiddler pour avoir des tableaux de bord
!Notions techniques
* un ''tiddler'' est une page de ce wiki, qui contient du texte au format wiki ou bien du code javascript si c'est un plugin
* les tiddlers peuvent être ''taggés'' par des mots clefs qui peuvent référencer d'autres tiddlers. Ceci permet de créer des relations (0-n) entre tiddlers. Par exemple une UserStory peut être rattachée a un sprint en lui rajoutant le nom du sprint comme tag.
* Dans cet outil un ''backlog'' est une liste ''ordonnée'' de tiddlers. Il s'agit d'un lien (0-n) entre tiddlers, mais un lien ''ordonné'', alors que les tags ne permettent pas de saisir un ordre.
* Les tiddlers peuvent contenir du texte, mais aussi des valeurs. Ils servent parfois de paramétrage, comme le tiddler SprintDays qui contient la liste des jours d'un sprint.
* Les tiddlers peuvent contenir des valeurs.
** Les ''fields'' sont des valeurs non visibles (il faut cliquer sur more/fields dans la barre d'outils pour les afficher) et nommées, associées au tiddler
** les ''slice'' sont des valeurs stockées dans le texte du tiddler d'une manière particulière : la notation tableau est utilisées |nom_slice|valeur_slice|. Les slices sont utilisées pour stocker les valeurs du reste a faire quotidien chaque tâche.
!Notions scrum
* Backlog de produit : la liste globale et ordonnée des UserStory 
* UserStory : une fonctionnalité de l'application, découpée en tâches, et évalué en points.
* Sprint : une durée de temps dédié à la réalisation d'un lot de UserStory (et donc de tâches)
* Task : unité minimale de réalisation estimée en heure (entre 1h et 2 jours) destiné a être mise en place pendant un sprint
* BurndownChart
!Gérer votre projet
* Commencez par définir les [[Parameters]]
* Lancez le [[Sprint 0]] qui devrait contenir tout ce qui se passe avant de commencer a coder. C'est à dire, la création du backlog initial ordonné, et le premier découpage en tâches.
* Une fois votre [[ProductBacklog]] créé vous pouvez démarrer un nouveau sprint. Cliquez sur <new Sprint> dans le menu de droite, ou bien créé un nouveau tiddler et taggez le "sprint" (c'est la même chose). Le fait de tagger sprint ajoute automatiquement une liste triable, ainsi que le BurndownChart dans la visualisation du tiddler. Le sprint doit définir une liste de UserStories retenues, et leur découpage en tâches. 
* Les UserStories peuvent être crées de différentes manières
** Soit vous cliquez sur le bouton "Add UserStory" a la fin du backlog, ce qui va créer une UserStory vide
** ou bien avec le button "New UserStory" sur la droite
** soit vous créé un tiddler avec le tag UserStory
** soit vous écrivez toutes vos UserStory en texte (une UserStory par ligne) dans un tiddler, que vous taggé backlog, ensuite vous utilisez le bouton update qui va transformer votre texte en tiddler (en rajoutant des double crochet la ou il en manque). Il suffit alors de cliquer sur le lien pour créer un nouveau tiddler avec un titre pré-initialisé. Il faut rajouter le tag UserStory
* Les mêmes principes sont utilisez pour créer les tâches
* N'oubliez pas chaque jours de faire le DailyScrum et de saisir le reste à faire du sprint en cours (ou bien dans TaskBoard
!Collaborez
Vous pouvez travailler a plusieurs sur un même ficher sans avoir a l'échanger via la messagerie ou le partager sur un répertoire commun.
Il faut pour cela le mettre en place sur un serveur.
# Créer le fichier [[store.php]] sur votre serveur, puis éditez sa liste d'utilisateurs
# Le TiddlyWiki risque d'être en lecture seule, il faut aller dans les options modifier <<option chkHttpReadOnly>> chkHttpReadOnly
# Il faut configurer dans le backstage / Upload les options de connection HomeParameters et/ou UploadOptions
# Si vous souhaité aller plus loin et utiliser la mise a jour directe de Tiddler (au lieu de sauver le fichier d'un bloc) il faut configurer UploadTiddler :  <<option chkUploadTiddler>> chkUploadTiddler.
# Si jamais vous souhaitez gérer plusieurs projets dans le même navigateur, sachez que les options de connections sont en principe stockées dans des cookies. Afin de bypasser ce mécanisme et de les stocker dans le fichier lui même [[zCookieJar]] a été créé. Les options sont en dur. ''Attention'', quand vous changez les paramètres de connection ils ne seront pas pris en compte a moins de faire un nouveau "Bake cookies" dans CookieManagerPlugin. Pour activer le [[zCookieJar]] il faut lui rajouter le tag systemConfig.
!En cas de problème
* Consultez la liste des [[Bugs]] connus
* Contactez le responsable du projet mailto:Y.%20BABEL<ybabel@ideia.fr>?subject=TiddlyWikiScrum
* Demandez de l'aide sur les mailing liste TiddlyWiki : http://groups.google.com/group/TiddlyWiki
!!Modèle de données
* Le backlog contient la liste ''ordonnée'' de toutes les UserStory ordonnées
* Une UserStory se décompose en plusieurs tâches
* Un Sprint est une selection de UserStory ordonnées, et de leurs tâches
! Sprint0
http://www.aubryconseil.com/dotclear/index.php/2008/09/29/477-sprint-zero
Sprint 0, c'est trompeur, parce que n'est pas un sprint : sa durée est variable, les tâches qu'on y fait sont spécifiques de cette phase, il n'y a pas le cérémonial habituel des sprints, on ne produit pas une version potentiellement utilisable à la fin, on ne mesure pas de vélocité...
Les travaux spécifiquement agiles qu'on y fait, c'est élaborer le backlog initial et planifier la release. Pour cela on y mettra en œuvre des pratiques comme la vision du produit, la priorisation du backlog, l'identification des risques, la décomposition en user stories, l'estimation en points, la définition de fini et de la durée des itérations, le planning de la release, la formation de l'équipe, l'organisation de l'espace de travail.
IDEIA Public Licence Version 1.0

Copyright (c) 2008, IDEIA (http://www.ideia.fr)

* 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.
* troisième tache | 5 
* première tache | 13 
et puis une nouvelle idée a rajouter | 3
* deuxième tache | 1
<!--{{{-->
<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>
<span class='help' macro='showWhen config.options.chkVerboseHelp'><span class='viewer' macro='tiddler BacklogViewTemplateHelp'></span></span>
<span macro='newTiddler label:"new User Story" text:{{store.getTiddlerText("EmptyUserStory")}} title:"Titre court de UserStory" tag:UserStory'>
<div class='viewer' macro='SortList fields:poids'></div>
<div class='viewer' macro='PopulateUpdateList want:UserStory'></div>
<div class='tagClear'></div>
<!--}}}-->
{{fr{Le backlog de produit est une liste de UserStory. Vous pouvez les saisirs ici en tant que texte, et les transformer en liens vers des tiddler (vides) avec le bouton Update. Ou bien si vous avez créé des UserStory d'une autre manière, vous pouvez rajouter les nouvelles entrées ici grâce au même bouton.}}}
{{en{The ProductBacklog is a sorted list of UserStory. You can type them here like normal text and transform them into links toward (empty) tiddlers with the Update button. If you have created a UserStory by another way, you can add them here automatically with the same button}}}
Bugs connus :
* les tiddlers qui ont une apostrophe ' dans leur titre ne sont pas synchronisés correctement par UploadTiddler
* les sprints qui ont un espace dans leur nom peuvent poser problème
* il y a un bug d'affichage du burndown chart quand on supprime une valeur au lieu de la mettre a 0 (car undefined <> null)
* il semble que le saisie des heures / tâches pose problème parfois, sans que le bug ne soit vraiment reproductible
!Sprints
<<sliceGrid edit inline [[tags:task]] slices:+SprintDays>>
<<histoGram [[tags:task ]] width:200 slices:+SprintDays>>
<<forEachTiddler where 'tiddler.tags.contains("sprint")'
write '"! [["+tiddler.title+"]]\n<<sliceGrid edit inline [[tags:task "+tiddler.title+"]] slices:+SprintDays$))\n<<histoGram [[tags:task "+tiddler.title+"]] width:200 slices:+SprintDays$))\n"'>>
/***
|Name|ColumnCalculatorPlugin|
|Source|http://www.TiddlyTools.com/#ColumnCalculatorPlugin|
|Version|0.6.1|
|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|calculate values from table cells in a column|
|Status| ALPHA - DO NOT DISTRIBUTE - USE AT YOUR OWN RISK |

!!!!!Usage
<<<
{{{<<columncalc function startrow endrow>>}}}
where:
''function'' is a keyword:
* "total" or "sum" or //no param// - adds up numeric values for cells above it in the column
* "count" - gives number of cells in column
* "average" or "avg" - gives average of cells in column (i.e., total/count)
''startrow''/''endrow'' are optional, and specify a ONE-based range of rows for limiting the calculation.  Use negative numbers to specify an offset from the current row (e.g., {{{<<calc sum 3 5>>}}} adds up rows 3, 4 and 5, while {{{<<calc sum 1 -1>>}}} adds up all numbers in the column excluding the current row (i.e., the same as the default if no startrow/endrow params are specified)
<<<
!!!!!Examples
<<<
''with numeric values...''
{{{
| foo| 3.2 |
| bar| 1.1 |
| baz| 2.9 |
| gronk| 4.3 |
| snork| 5.5 |
| count| <<columncalc count 1 -1>> |
| total| <<columncalc sum 1 -2>> |
| avg| <<columncalc average 1 -3>> |
}}}
| foo| 3.2 |
| bar| 1.1 |
| baz| 2.9 |
| gronk| 4.3 |
| snork| 5.5 |
| count| <<columncalc count 1 -1>> |
| total| <<columncalc sum 1 -2>> |
| avg| <<columncalc average 1 -3>> |

''with time-formatted values (hh:mm:ss)...''
{{{
| foo| 00:22:15 |
| bar| 00:03:30 |
| baz| 00:01:45 |
| count| <<columncalc count 1 -1>> |
| total| <<columncalc sum 1 -2>> |
| avg| <<columncalc average 1 -3>> |
}}}
| foo| 00:22:15 |
| bar| 00:03:30 |
| baz| 00:01:45 |
| count| <<columncalc count 1 -1>> |
| total| <<columncalc sum 1 -2>> |
| avg| <<columncalc average 1 -3>> |
<<<
!!!!!Revisions
<<<
2007.10.26 [0.6.1] in handler(), using ".textContent" instead of ".innerHTML" when reading values from table cells.  This allows use of values that are transcluded from slices in other tiddlers using the {{{<<tiddler "TiddlerName::slicename">>}}} syntax.
2007.06.29 [0.6.0] added support for handling values in hh:mm:ss format
2007.04.02 [0.5.0] started
<<<
!!!!!Code
***/
//{{{
version.extensions.columncalc = {major: 0, minor: 6, revision: 1, date: new Date(2007,10,26)};
config.macros.columncalc= {
	handler:
	function(place,macroName,params,wikifier,paramString,tiddler) {
		if (place.parentNode.nodeName.toLowerCase()!="tr") return false; // not in a table
		var fn=params.shift(); // first param is function name
		var tbody=place.parentNode.parentNode;
		var row=tbody.childNodes.length-1; // current row #
		var col=place.parentNode.childNodes.length-1; // current column #
		var count=total=0;
		var startrow=0; var endrow=row-1;
		if (params[0]) var startrow=params.shift();
		if (startrow<0) startrow=1*startrow+row; else startrow=startrow-1;
		if (params[0]) var endrow=params.shift();
		if (endrow<0) endrow=1*endrow+row; else endrow=endrow-1;
		var calcTime=false;
		for (r=startrow; r<=endrow; r++) {
			var cell=tbody.childNodes[r].childNodes[col].textContent;
			if (!cell) cell=tbody.childNodes[r].childNodes[col].innerHTML; // fallback for older browsers
			if (!isNaN(cell)) {
				total=total+eval(cell);
				count++;
			} else { // maybe an hh:mm:ss time value?
				var hms=cell.split(":"); var h=hms[0]; var m=hms[1]; var s=hms[2];
				if (hms.length!=3 || isNaN(h) || isNaN(m) || isNaN(s)) continue;  // not a valid time value... skip
				var showTime=true; // found a time value... use time formatting for results.
				total=total+h*3600+m*60+s*1;
				count++;
			}
		}
		switch (fn) {
			case "count":
				var result=count;
				break;
			case "average":
			case "avg":
				var result=Math.floor(total/count*100)/100; // truncate to two decimal places
				break;
			case "total":
			case "sum":
			default:
				var result=total;
				break;
		}
		if (showTime && fn!="count") {
			var h=Math.floor(result/3600);
			var m=Math.floor((result-h*3600)/60);
			var s=Math.floor((result-h*3600-m*60)*100)/100; // truncate to two decimal places
			result=(h<10?'0':'')+h+":"+(m<10?'0':'')+m+":"+(s<10?'0':'')+s;
		}
		createTiddlyText(place,result);
	}
}
//}}}
/***
|Name|CompareTiddlersPlugin|
|Source|http://www.TiddlyTools.com/#CompareTiddlersPlugin|
|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|plugin|
|Requires||
|Overrides||
|Description|show color-coded differences between two selected tiddlers|
!!!!!Usage
<<<
{{{<<compareTiddlers>>}}}
{{smallform small{<<compareTiddlers>>}}}
<<<
!!!!!Revisions
<<<
2007.10.15 [1.0.0] converted from inline script to true plugin
2006.12.27 [0.0.0] inline script.  {{{diff()}}} and {{{diffString()}}} functions written by Bradley Meck.
<<<
!!!!!Code
***/
//{{{
version.extensions.CompareTiddlers= {major: 1, minor: 0, revision: 0, date: new Date(2007,10,15)};
//}}}
//{{{
config.shadowTiddlers.CompareTiddlers="<<compareTiddlers>>";
//}}}
//{{{
config.macros.compareTiddlers= {
	handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		setStylesheet(this.css,"CompareTiddlersStyles");
		var console=createTiddlyElement(place,"span"); console.innerHTML=this.html;
		var form=console.getElementsByTagName("form")[0];
		var target=form.nextSibling;
		this.reset(form,target);
	},
	css: ".compareTiddlersResults \
		{ display:none;clear:both;margin-top:1em;border:1px solid;-moz-border-radius:1em;padding:1em;white-space:normal; }",
	html: "<form><!-- \
		--><select name=list1 size=1 style='width:30%' \
			onchange='config.macros.compareTiddlers.pick(this,this.form.view1,this.form.edit1,this.form.text1)'></select><!-- \
		--><input type=button name=view1 style='width:10%' value='view' disabled \
			onclick='if (this.form.list1.value.length) \
				story.displayTiddler(story.findContainingTiddler(this),this.form.list1.value,DEFAULT_VIEW_TEMPLATE)'><!-- \
		--><input type=button name=edit1 style='width:10%' value='edit' disabled \
			onclick='if (this.form.list1.value.length) \
				story.displayTiddler(story.findContainingTiddler(this),this.form.list1.value,DEFAULT_EDIT_TEMPLATE)'><!-- \
		--><select name=list2 size=1 style='width:30%' \
			onchange='config.macros.compareTiddlers.pick(this,this.form.view2,this.form.edit2,this.form.text2)'></select><!-- \
		--><input type=button name=view2 style='width:10%' value='view' disabled \
			onclick='if (this.form.list2.value.length) \
				story.displayTiddler(story.findContainingTiddler(this),this.form.list2.value,DEFAULT_VIEW_TEMPLATE)'><!-- \
		--><input type=button name=edit2 style='width:10%' value='edit' disabled \
			onclick='if (this.form.list2.value.length) \
				story.displayTiddler(story.findContainingTiddler(this),this.form.list2.value,DEFAULT_EDIT_TEMPLATE)'><br><!-- \
		--><nobr><!-- \
		--><textarea name=text1 style='width:49.5%;display:none' rows='10' readonly></textarea><!-- \
		--><textarea name=text2 style='width:49.5%;display:none' rows='10' readonly></textarea><!-- \
		--></nobr><!-- \
		--><div style='float:left'><!-- \
		-->Additions are shown in <span style='color:green'>GREEN</span>, <!-- \
		-->deletions are shown in <span style='color:red'>RED</span><!-- \
		--></div><!-- \
		--><div style='text-align:right'><!-- \
		--><input type=button name=compare style='width:10%' value='compare' disabled \
			onclick='config.macros.compareTiddlers.compare(this.form,this.form.nextSibling)'><!-- \
		--><input type=button name=done style='width:10%' value='done' disabled \
			onclick='config.macros.compareTiddlers.reset(this.form,this.form.nextSibling)'><!-- \
		--></div><!-- \
		--></form><div class='compareTiddlersResults'>contents to be replaced by results of comparison</div> \
	",
	reset: function(f,target) {
		var tids=store.getTiddlers('title','excludeLists');
		f.text1.style.display="none"; f.text1.value="";
		while (f.list1.options[0]) f.list1.options[0]=null; 
		f.list1.options[0]=new Option("select a tiddler...","",false,false);
		for (i=0; i<tids.length; i++)
			f.list1.options[f.list1.length]=new Option(tids[i].title,tids[i].title,false,false);
		f.text2.style.display="none"; f.text2.value="";
		while (f.list2.options[0]) f.list2.options[0]=null; 
		f.list2.options[0]=new Option("select a tiddler...","",false,false);
		for (i=0; i<tids.length; i++)
			f.list2.options[f.list2.length]=new Option(tids[i].title,tids[i].title,false,false);
		f.view1.disabled=f.view2.disabled=f.edit1.disabled=f.edit2.disabled=f.compare.disabled=f.done.disabled=true;
		target.style.display="none";
		removeChildren(target);
	},
	pick: function(list,view,edit,text) {
		var f=list.form;
		view.disabled=edit.disabled=f.done.disabled=!list.value.length;
		f.compare.disabled=!f.list1.value.length||!f.list2.value.length;
		if (!list.value.length) return;
		f.text1.style.display=f.text2.style.display="inline";
		text.value=store.getTiddlerText(list.value);
	},
	compare: function(f,target) {
		if (!f.list1.value.length) { f.list1.focus(); return alert("select a tiddler"); }
		var t1=store.getTiddlerText(f.list1.value); if (!t1) { displayMessage(f.list1.value+" not found");return false; }
		if (!f.list2.value.length) { f.list2.focus(); return alert("select a tiddler"); }
		var t2=store.getTiddlerText(f.list2.value); if (!t2) { displayMessage(f.list2.value+" not found");return false; }
		var out=this.diffString(t1,t2); if (!out || !out.length) out="no differences";
		removeChildren(target);
		target.innerHTML=out;
		target.style.display="block";
		f.done.disabled=false;
	},
	diffString: function( o, n ) {
		// This function was written by Bradley Meck
		// returns difference between old and new text, color-formatted additions and deletions
		if (o==n) return ""; // simple check, saves time if true
		var error = 5;
		var reg = new RegExp( "\\n|(?:.{0,"+error+"})", "g" );
		var oarr = o.match( reg ); // dices text into chunks
		var narr = n.match( reg );
		var out = this.diff(oarr,narr); // compare the word arrays
		var str = ""; // construct output
		for (i=0; i<out.length; i++) {
			switch (out[i].change) {
				case "ADDED":
					str+="<span style='color:green'>";
					str+=narr.slice(out[i].index,out[i].index+out[i].length).join("");
					str+="</span> ";
					break;
				case "DELETED":
					str+="<span style='color:red'>";
					str+=oarr.slice(out[i].index,out[i].index+out[i].length).join("");
					str+="</span> ";
					break;
				default:
					str+="<span>";
					str+=oarr.slice(out[i].index,out[i].index+out[i].length).join("");
					str+="</span> ";
					break;
			}	
		}
		return str;
	},
	diff: function( oldArray, newArray ) {
		// This function was written by Bradley Meck
		// finds the differences between one set of objects and another.
		// The objects do not need to be Strings.  It outputs an array of objects with the properties value and change.
		// This function is pretty hefty but appears to be rather light for a diff and tops out at O(N^2) for absolute worst cast scenario.
		var newElementHash = { };
		for( var i = 0; i < newArray.length; i++ ) {
			if( ! newElementHash [ newArray [ i ] ] ) {
				newElementHash [ newArray [ i ] ] = [ ];
			}
			newElementHash [ newArray [ i ] ].push( i );
		}
		var substringTable = [ ];
		for( var i = 0; i < oldArray.length; i++ ) {
			if(newElementHash [ oldArray [ i ] ] ) {
				var locations = newElementHash [ oldArray [ i ] ] ;
				for( var j = 0; j < locations.length; j++){
					var length = 1;
					while( i + length < oldArray.length && locations [ j ] + length < newArray.length
						&& oldArray [ i + length ] == newArray [ locations [ j ] + length ] ){
						length++;
					}
					substringTable.push( {
						oldArrayIndex : i,
						newArrayIndex : locations [ j ],
						matchLength : length
					} );
				}
			}
		}
		substringTable.sort( function( a, b ) {
			if ( a.matchLength > b.matchLength /* a is less than b by some ordering criterion */ ) {
				return -1;
			}
			if ( a.matchLength < b.matchLength /* a is greater than b by the ordering criterion */ ) {
				return 1;
			}
			// a must be equal to b
			return 0
		} );
		//displayMessage( substringTable.toSource( ) );
		for( var i = 0; i < substringTable.length; i++) {
			for( var j = 0; j < i; j++) {
				var oldDelta = substringTable [ i ].oldArrayIndex + substringTable [ i ].matchLength - 1 - substringTable [ j ].oldArrayIndex;
				var newDelta = substringTable [ i ].newArrayIndex + substringTable [ i ].matchLength - 1 - substringTable [ j ].newArrayIndex;
				//displayMessage( "oldDelta ::: " + oldDelta );
				//displayMessage( "newDelta ::: " + newDelta );
				//displayMessage( "matchLength ::: " + substringTable [ j ].matchLength );
				if( ( oldDelta >= 0 && oldDelta <= substringTable [ j ].matchLength )
				|| ( newDelta >= 0 && newDelta <= substringTable [ j ].matchLength )
				|| ( oldDelta < 0 && newDelta > 0 )
				|| ( oldDelta > 0 && newDelta < 0 ) ) {
					substringTable.splice( i, 1 );
					i--;
					break;
				}
			}
		}
		//displayMessage( substringTable.toSource(  ) );
		substringTable.sort( function( a, b ) {
			if ( a.oldArrayIndex < b.oldArrayIndex /* a is less than b by some ordering criterion */ ) {
				return -1;
			}
			if ( a.oldArrayIndex > b.oldArrayIndex /* a is greater than b by the ordering criterion */ ) {
				return 1;
			}
			// a must be equal to b
			return 0
		} );
		//displayMessage( substringTable.toSource( ) );
		var oldArrayIndex = 0;
		var newArrayIndex = 0;
		var results = [ ];
		for( var i = 0; i < substringTable.length; i++ ) {
			if( oldArrayIndex != substringTable [ i ].oldArrayIndex ) {
				results.push( {
					change : "DELETED",
					length : substringTable [ i ].oldArrayIndex - oldArrayIndex,
					index : oldArrayIndex
				} );
			}
			if( newArrayIndex != substringTable [ i ].newArrayIndex ) {
				results.push( {
					change : "ADDED",
					length : substringTable [ i ].newArrayIndex - newArrayIndex,
					index : newArrayIndex
				} );
			}
			results.push( {
				change : "STAYED",
				length : substringTable [ i ].matchLength,
				index : substringTable [ i ].oldArrayIndex
			} );
			oldArrayIndex = substringTable [ i ].oldArrayIndex + substringTable [ i ].matchLength;
			newArrayIndex = substringTable [ i ].newArrayIndex + substringTable [ i ].matchLength;
		}
		if( oldArrayIndex != oldArray.length ) {
			results.push( {
				change : "DELETED",
				length : oldArray.length - oldArrayIndex,
				index : oldArrayIndex
			} );
		}
		if( newArrayIndex != newArray.length ) {
			results.push( {
				change : "ADDED",
				length : newArray.length - newArrayIndex,
				index : newArrayIndex
			} );
		}
		return results;
	}
}
//}}}
{{en{Describe what define a task as "completed" here}}}{{fr{Décrivez ici ce qui défini une tâche comme étant complète}}}
doc : backlog de produit > backlog de sprint > user story > critères d'acceptation > taches
timeline : sprint > planification > mélée >  burdown > revue
{{en{This page regroups all the Tiddlers that contains useful options}}} {{fr{Cette page regroupe les Tiddlers qui sont utile pour la configuration de l'outil}}}
! Project specific
* SiteTitle & SiteSubtitle
* SprintDays :{{fr{ c'est une liste (un élément par ligne) des jours d'un sprint : }}} {{en{this is a list (one element by line) of the day of the sprint : }}} J0, J1, J2, etc
* [[sprint]] / [[task]] / UserStory / [[deprecated]] / [[project]]
* [[excludeSprint]] : {{fr{permet d'exclure des UserStory de la liste a rafraichir dans un sprint}}} {{en{exclude some the UserStory tagged by the tags in this tiddler from the refresh list of a sprint, very useful to avoid refresh finished UserStory}}}
!Travail collaboratif
* [[zCookieJar]]
* HomeParameters
* <<slider chkUploadOptions UploadOptions "UploadOptions>>
* UploadTiddler @@chkUploadTiddler option: <<option chkUploadTiddler>>@@ @@chkUploadTiddlerFromFile option: <<option chkUploadTiddlerFromFile>>@@ @@txtUploadTiddlerStoreUrl: <<option txtUploadTiddlerStoreUrl>>@@
!Presentation
* MainMenu {{fr{c'est le menu de gauche}}} {{en{this is the left menu}}} OptionsPanel
* @@ chkVerboseHelp:<<option chkVerboseHelp>>@@
* DefaultTiddlers, {{fr{ce sont les tiddlers qui s'affichent au démarrage}}} {{en{the tiddlers displayed when the page is loaded}}}
* SideBarOptions, {{fr{c'est la barre a droite des bouttons de création}}} {{en{the rightside toolbar with creation buttons}}}
* ToolbarCommands
* TaskBoardBySprint / TaskBoard / BurndownChart / TaskList
!Templates
* SprintViewTemplate / [[excludeSprint]] {{fr{pour filtrer les UserStory qui sont renvoyée par le }}} {{en{this one is to filter the UserStory returned by}}} Populate/Update
* TaskEditTemplate / TaskViewTemplate
* BacklogViewTemplate
* UserStoryViewTemplate / UserStoryEditTemplate / UserStoryFormTemplate {{fr{pour la selection du poids fibbonnacci}}} {{en{where the fibonnacci suite is used to select the weight}}}
* SortListViewTemplate
* EmptyBacklog / EmptySprint / EmptyUserStory / EmptyUserStory {{fr{les modèles utilisés pour la création des nouveaux éléments}}} {{en{the templates used for the creation of new elements}}}
!Multilingue
* PolyGlotFormat
* http://www.openplans.org/projects/agile-contracts/summary from : http://www.agilex.fr/2008/10/contractualisation-agile/
/***
|Name|CoreTweaks|
|Source|http://www.TiddlyTools.com/#CoreTweaks|
|Version|n/a|
|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.2.0|
|Type|plugin|
|Requires||
|Overrides|various|
|Description|a small collection of overrides to TW core functions|
This tiddler contains some quick tweaks and modifications to TW core functions to provide minor changes in standard features or behavior.  It is hoped that some of these tweaks may be incorporated into later versions of the TW core, so that these adjustments will be available without needing these add-on definitions.
>''Note: the changes contained in this tiddler are generally applicable for the current version of TiddlyWiki (<<version>>). Please view [[CoreTweaksArchive]] for tweaks and modifications that may be used with earlier versions of TiddlyWiki.''
----
***/
// // {{block{
/***
!!!757 add removeOptionCookie() function
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/757 - OPEN
When a TW option is reset to it's hard-coded default value, the corresponding browser cookie is usually just set to that default value, which results in an accumulation of unnecessary cookies.  Unfortunately, there is a browser-imposed limit on the number of cookies that are stored for any given domain and, when that limit is reached, the browser starts removing cookies on it's own, thereby unexpectedly discarding some TW settings.  In order to allow core and/or plugin code to 'clean up after themselves' and remove unneeded cookies, this tweak provides a new 'core' function, removeOptionCookie() that is the inverse of the existing saveOptionCookie(), and results in the actual deletion of the browser cookie associated with the specified TW option.
***/
//{{{
if (window.removeOptionCookie===undefined) {
window.removeOptionCookie=function(cookie) {
	var ex=new Date();
	ex.setTime(ex.getTime()-1000);  // immediately expire cookie
	document.cookie = cookie+"=novalue; path=/; expires="+ex.toGMTString();
}
}
//}}}
// // }}}}}}// // {{block{
/***
!!!749 ieCreatePath fixup for handling / in UNC paths
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/749 - OPEN
***/
//{{{
// tweak ieCreatePath to add fallback check for / (in addition to current check for \)
var fn=window.ieCreatePath;
fn=fn.toString().replace(/function ieCreatePath\(path\)/,'window.ieCreatePath=function(path)');
fn=fn.toString().replace(/var pos = path.lastIndexOf\("\\\\"\);/,
	'var pos=path.lastIndexOf("\\\\"); if(pos==-1) pos=path.lastIndexOf("/");');
eval(fn);
//}}}
// // }}}}}}// // {{block{
/***
!!!742 #animate:... paramifier
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/742 - OPEN
Occasionally, when using some low-end browser/hardware combinations, TiddlyWiki documents can "bog down" and become almost unusable due to poor responsiveness.  Fortunately, disabling animation effects (via <<option chkAnimate>>) often makes a big difference in performance.  Unfortunately, clearing this checkbox can be nearly impossible if the document in question is already bogged down due to animations.  The "#animate:true/false" paramifier avoids this problem by allowing the user to set/clear the 'chkAnimate' flag on-the-fly while the URL is being initially loaded into the browser.
***/
//{{{
config.paramifiers.animate= {
	onstart: function(v) {
		config.options.chkAnimate=eval(v);
	}
};
//}}}
// // }}}}}}// // {{block{
/***
!!!741 allow """<hr>""" directly in wiki-formatted content
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/741 - OPEN
This tweak extends the 'horizontal rule' formatter to recognize {{{<hr>}}} (or {{{<hr />}}}) directly in tiddler content without being enclosed within an HTML block (i.e., {{{<html><hr></html>}}}).  This allows HR elements to be used within table cell content, bullet items and other ''line-mode'' syntax, where the required use of newlines surrounding the """----""" syntax would interfere with the enclosing line-mode formatting.
***/
//{{{
config.formatters[config.formatters.findByField("name","rule")].match+="|<hr ?/?>\\n?";
//}}}
// // }}}}}}// // {{block{
/***
!!!683 FireFox3 Import bug: "browse" button replacement
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/683 - OPEN
see also http://trac.tiddlywiki.org/ticket/604 - cross-platform askForFilename()
The web standard "type=file" input control that has been used as a local path/file picker for TiddlyWiki no longer works as expected in FireFox3, which has, for "security" reasons, limited javascript access to this control so that *no* local filesystem path information can be revealed, even when it is intentional and necessary, as it is with TiddlyWiki.  This tweak provides alternative HTML source that patches the backstage import panel.  It replaces the "type=file" input control with a text+button combination of controls that invokes a system-native secure 'file-chooser' dialog box to provide TiddlyWiki with access to a complete path+filename so that TW functions properly locate user-selected local files.
***/
//{{{
if (window.Components) {
	var fixhtml='<input name="txtBrowse" style="width:30em"><input type="button" value="..."'
		+' onClick="window.browseForFilename(this.previousSibling,true)">';
	var cmi=config.macros.importTiddlers;
	cmi.step1Html=cmi.step1Html.replace(/<input type='file' size=50 name='txtBrowse'>/,fixhtml);
}

merge(config.messages,{selectFile:"Please enter or select a file"}); // ready for I18N translation

window.browseForFilename=function(target,mustExist) { // note: both params are optional
	var msg=config.messages.selectFile;
	if (target && target.title) msg=target.title; // use target field tooltip (if any) as dialog prompt text
	// get local path for current document
	var path=getLocalPath(document.location.href);
	var p=path.lastIndexOf("/"); if (p==-1) p=path.lastIndexOf("\\"); // Unix or Windows
	if (p!=-1) path=path.substr(0,p+1); // remove filename, leave trailing slash
	var file=""
	var result=window.askForFilename(msg,path,file,mustExist); // requires #604
	if (target && result.length) // set target field and trigger handling
		{ target.value=result; target.onchange(); }
	return result; 
}
//}}}
// // }}}}}}// // {{block{
/***
!!!604 cross-platform askForFilename()
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/604 - OPEN
invokes a system-native secure 'file-chooser' dialog box to provide TiddlyWiki with access to a complete path+filename so that TW functions properly locate user-selected local files.
***/
//{{{
window.askForFilename=function(msg,path,file,mustExist) {
	var r = window.mozAskForFilename(msg,path,file,mustExist);
	if(r===null || r===false)
		r = window.ieAskForFilename(msg,path,file,mustExist);
	if(r===null || r===false)
		r = window.javaAskForFilename(msg,path,file,mustExist);
	if(r===null || r===false)
		r = prompt(msg,path+file);
	return r||"";
}

window.mozAskForFilename=function(msg,path,file,mustExist) {
	if(!window.Components) return false;
	try {
		netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
		var nsIFilePicker = window.Components.interfaces.nsIFilePicker;
		var picker = Components.classes['@mozilla.org/filepicker;1'].createInstance(nsIFilePicker);
		picker.init(window, msg, mustExist?nsIFilePicker.modeOpen:nsIFilePicker.modeSave);
		var thispath = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
		thispath.initWithPath(path);
		picker.displayDirectory=thispath;
		picker.defaultExtension='html';
		picker.defaultString=file;
		picker.appendFilters(nsIFilePicker.filterAll|nsIFilePicker.filterText|nsIFilePicker.filterHTML);
		if (picker.show()!=nsIFilePicker.returnCancel)
			var result=picker.file.persistentDescriptor;
	}
	catch(ex) { displayMessage(ex.toString()); }
	return result;
}

window.ieAskForFilename=function(msg,path,file,mustExist) {
	if(!config.browser.isIE) return false;
	try {
		var s = new ActiveXObject('UserAccounts.CommonDialog');
		s.Filter='All files|*.*|Text files|*.txt|HTML files|*.htm;*.html|';
		s.FilterIndex=3; // default to HTML files;
		s.InitialDir=path;
		s.FileName=file;
		return s.showOpen()?s.FileName:"";
	}
	catch(ex) { displayMessage(ex.toString()); }
	return result;
}

window.javaAskForFilename=function(msg,path,file,mustExist) {
	if(!document.applets["TiddlySaver"]) return false;
	// TBD: implement java-based askFile(...) function
	try { return document.applets["TiddlySaver"].askFile(msg,path,file,mustExist); } 
	catch(ex) { displayMessage(ex.toString()); }
}
//}}}
// // }}}}}}// // {{block{
/***
!!!676 #story:... paramifier
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/676 - OPEN
scan the specified 'story' tiddler content for embedded links, rather than simply parsing the content as a space-separated bracketed list.  This allows links from ''any'' tiddler to be used as a story, regardless of other wiki-syntax contained in that tiddler.  If specified tiddler is a shadow, fallback to using parseParams() to extract the list of links.
***/
//{{{
config.paramifiers.story = {
	onstart: function(v) {
		var t=store.getTiddler(v); if (t) t.changed();
		var list=t?t.links:store.getTiddlerText(v,"").parseParams("open",null,false);
		story.displayTiddlers(null,list);
	}
};
//}}}
// // }}}}}}// // {{block{
/***
!!!664 Loose links (case-folded/space-folded wiki words)
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/664 - OPEN
This tweak matches non-WikiWord variations of mixed-case and/or added/omitted spaces within double-bracketed text with titles of //existing// tiddlers, using a "loose" (case-folded/space-folded) comparison.  This allows text that occurs in normal prose to be more easily linked to tiddler titles by using double-brackets without the full "pretty link" syntax.  For example:
{{{
[[CoreTweaks]], [[coreTweaks]], [[core tweaks]],
[[CORE TWEAKS]], [[CoRe TwEaKs]], [[coreTWEAKS]]
}}}
>[[CoreTweaks]], [[coreTweaks]], [[core tweaks]],
>[[CORE TWEAKS]], [[CoRe TwEaKs]], [[coreTWEAKS]]
Configuration:
><<option chkLooseLinks>> Allow case-folded and/or space-folded text to link to existing tiddler titles
>"""<<option chkLooseLinks>>"""
***/
//{{{
if (!config.options.chkLooseLinks)
	config.options.chkLooseLinks=false; // default to standard behavior
window.caseFold_createTiddlyLink = window.createTiddlyLink;
window.createTiddlyLink = function(place,title,includeText,className) {
	var btn=window.caseFold_createTiddlyLink.apply(this,arguments); // create core link
	if (!config.options.chkLooseLinks) return btn;
	if (store.getTiddlerText(title)) return btn; // matching tiddler (or shadow) exists
	var target=title.toLowerCase().replace(/\s/g,"");
	var tids=store.getTiddlers("title");
	for (var t=0; t<tids.length; t++) {
		if (tids[t].title.toLowerCase().replace(/\s/g,"")==target) {
			var i=getTiddlyLinkInfo(tids[t].title,className);
			btn.setAttribute("tiddlyLink",tids[t].title);
			btn.title=i.subTitle;
			btn.className=i.classes;
			break;
		}
	}
	return btn;
}
//}}}
// // }}}}}}// // {{block{
/***
!!!657 wrap tabs onto multiple lines
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/657 - OPEN
This tweak inserts an extra space element following each tab, allowing them to wrap onto multiple lines if needed.
***/
//{{{
config.macros.tabs.handler = function(place,macroName,params)
{
	var cookie = params[0];
	var numTabs = (params.length-1)/3;
	var wrapper = createTiddlyElement(null,"div",null,"tabsetWrapper " + cookie);
	var tabset = createTiddlyElement(wrapper,"div",null,"tabset");
	tabset.setAttribute("cookie",cookie);
	var validTab = false;
	for(var t=0; t<numTabs; t++) {
		var label = params[t*3+1];
		var prompt = params[t*3+2];
		var content = params[t*3+3];
		var tab = createTiddlyButton(tabset,label,prompt,this.onClickTab,"tab tabUnselected");
		createTiddlyElement(tab,"span",null,null," ",{style:"font-size:0pt;line-height:0px"}); // ELS
		tab.setAttribute("tab",label);
		tab.setAttribute("content",content);
		tab.title = prompt;
		if(config.options[cookie] == label)
			validTab = true;
	}
	if(!validTab)
		config.options[cookie] = params[1];
	place.appendChild(wrapper);
	this.switchTab(tabset,config.options[cookie]);
};
//}}}
// // }}}}}}// // {{block{
/***
!!!637 TiddlyLink tooltip - custom formatting
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/637 - OPEN
This tweak modifies the tooltip format that appears when you mouseover a link to a tiddler.  It adds an option to control the date format, as well as displaying the size of the tiddler (in bytes)

Tiddler link tooltip format:
{{stretch{<<option txtTiddlerLinkTootip>>}}}
^^where: %0=title, %1=username, %2=modification date, %3=size in bytes, %4=description slice^^
Tiddler link tooltip date format:
{{stretch{<<option txtTiddlerLinkTooltipDate>>}}}
***/
//{{{
config.messages.tiddlerLinkTooltip="%0 - %1, %2 (%3 bytes) - %4";
config.messages.tiddlerLinkTooltipDate="DDD, MMM DDth YYYY 0hh12:0mm AM";

config.options.txtTiddlerLinkTootip=
	config.options.txtTiddlerLinkTootip||config.messages.tiddlerLinkTooltip;
config.options.txtTiddlerLinkTooltipDate=
	config.options.txtTiddlerLinkTooltipDate||config.messages.tiddlerLinkTooltipDate;

Tiddler.prototype.getSubtitle = function() {
	var modifier = this.modifier;
	if(!modifier) modifier = config.messages.subtitleUnknown;
	var modified = this.modified;
	if(modified) modified = modified.formatString(config.options.txtTiddlerLinkTooltipDate);
	else modified = config.messages.subtitleUnknown;
	var descr=store.getTiddlerSlice(this.title,"Description")||"";
	return config.options.txtTiddlerLinkTootip.format([this.title,modifier,modified,this.text.length,descr]);
};
//}}}
// // }}}}}}// // {{block{
/***
!!!628 hide "no such macro" errors
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/628 - OPEN
When invoking a macro that is not defined, this tweak prevents the display of the "error in macro... no such macro" message.  This is useful when rendering tiddler content or templates that reference macros that are defined by //optional// plugins that have not been installed in the current document.

<<option chkHideMissingMacros>> hide "no such macro" error messages
***/
//{{{
if (config.options.chkHideMissingMacros===undefined)
	config.options.chkHideMissingMacros=false;

window.coreTweaks_missingMacro_invokeMacro = window.invokeMacro;
window.invokeMacro = function(place,macro,params,wikifier,tiddler) {
	if (!config.macros[macro] || !config.macros[macro].handler)
		if (config.options.chkHideMissingMacros) return;
	window.coreTweaks_missingMacro_invokeMacro.apply(this,arguments);
}
//}}}
// // }}}}}}// // {{block{
/***
!!!609/610 toolbars - separators and transclusion
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/609 - OPEN (separators)
http://trac.tiddlywiki.org/ticket/610 - OPEN (wikify tiddler/slice/section content)
These tweaks extend the """<<toolbar>>""" macro to permit use of "|" as separators, as well as recognizing references to tiddlernames, slices, or sections and rendering their content inline within the toolbar
''see [[ToolbarCommands]] for examples of how these features can be used''
***/
//{{{
merge(config.macros.toolbar,{
	separator: "|"
	});
config.macros.toolbar.handler = function(place,macroName,params,wikifier,paramString,tiddler)
{
	for(var t=0; t<params.length; t++) {
		var c = params[t];
		switch(c) {
			case '|':  // ELS - SEPARATOR
			case '!':  // ELS - SEPARATOR (alternative for use in tiddler slices)
				createTiddlyText(place,this.separator); // ELS
				break; // ELS
			case '>':
				var btn = createTiddlyButton(place,this.moreLabel,this.morePrompt,config.macros.toolbar.onClickMore);
				addClass(btn,"moreCommand");
				var e = createTiddlyElement(place,"span",null,"moreCommand");
				e.style.display = "none";
				place = e;
				break;
			default:
				var theClass = "";
				switch(c.substr(0,1)) {
					case "+":
						theClass = "defaultCommand";
						c = c.substr(1);
						break;
					case "-":
						theClass = "cancelCommand";
						c = c.substr(1);
						break;
				}
				if(c in config.commands)
					this.createCommand(place,c,tiddler,theClass);
				else { // ELS - WIKIFY TIDDLER/SLICE/SECTION
					if (c.substr(0,1)=="~") c=c.substr(1); // ignore leading ~
					var txt=store.getTiddlerText(c);
					if (txt) {
						txt=txt.replace(/^\n*/,"").replace(/\n*$/,""); // trim any leading/trailing newlines
						txt=txt.replace(/^\{\{\{\n/,"").replace(/\n\}\}\}$/,""); // trim PRE format wrapper if any
						wikify(txt,createTiddlyElement(place,"span"),null,tiddler);
					}
				} // ELS - end WIKIFY CONTENT
				break;
		}
	}
};
//}}}
// // }}}}}}// // {{block{
/***
!!!608 toolbar - more/less toggle
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/608 - OPEN
This tweak extends the """<<toolbar>>""" macro to make the ">" (more) a //toggle// between more/less with the additional toolbar commands displayed on a separate line.
***/
//{{{
merge(config.macros.toolbar,{
	moreLabel: 'more',
	morePrompt: "Show additional commands",
	lessLabel: 'less',
	lessPrompt: "Hide additional commands"
});
config.macros.toolbar.onClickMore = function(ev)
{
	var e = this.nextSibling;
	var showing=e.style.display=="block";
	e.style.display = showing?"none":"block";
	this.innerHTML=showing?config.macros.toolbar.moreLabel:config.macros.toolbar.lessLabel;
	this.title=showing?config.macros.toolbar.morePrompt:config.macros.toolbar.lessPrompt;
	return false;
};
//}}}
// // }}}}}}// // {{block{
/***
!!!607 add HREF link on permaview command
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/607 - OPEN
This tweak automatically sets the HREF for the 'permaview' sidebar command link so you can use the 'right click' context menu for faster, easier bookmarking.  Note that this does ''not'' automatically set the permaview in the browser's current location URL... it just sets the HREF on the command link.  You still have to click the link to apply the permaview.
***/
//{{{
config.macros.permaview.handler = function(place)
{
	var btn=createTiddlyButton(place,this.label,this.prompt,this.onClick);
	addEvent(btn,"mouseover",this.setHREF);
	addEvent(btn,"focus",this.setHREF);
};
config.macros.permaview.setHREF = function(event){
	var links = [];
	story.forEachTiddler(function(title,element) {
		links.push(String.encodeTiddlyLink(title));
	});
	var newURL=document.location.href;
	var hashPos=newURL.indexOf("#");
	if (hashPos!=-1) newURL=newURL.substr(0,hashPos);
	this.href=newURL+"#"+encodeURIComponent(links.join(" "));
}
//}}}
// // }}}}}}// // {{block{
/***
!!!529 IE fixup - case-sensitive element lookup of tiddler elements
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/529 - OPEN
This tweak hijacks the standard browser function, document.getElementById(), to work-around the case-INsensitivity error in Internet Explorer (all versions up to and including IE7) //''Note: This tweak is only applied when using IE, and only for lookups of rendered tiddler elements within the containing "tiddlerDisplay" element.''//
***/
//{{{
if (config.browser.isIE) {
document.coreTweaks_coreGetElementById=document.getElementById;
document.getElementById=function(id) {
	var e=document.coreTweaks_coreGetElementById(id);
	if (!e || !e.parentNode || e.parentNode.id!="tiddlerDisplay") return e;
	for (var i=0; i<e.parentNode.childNodes.length; i++)
		if (id==e.parentNode.childNodes[i].id) return e.parentNode.childNodes[i];
	return null;
};
}
//}}}
// // }}}}}}// // {{block{
/***
!!!471 'creator' field for new tiddlers
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/471 - OPEN
This tweak HIJACKS the core's saveTiddler() function to automatically add a "creator" field to a tiddler when it is FIRST created. You can use """<<view creator>>""" (or """<<view creator wikified>>""" if you prefer) to show this value embedded directly within the tiddler content, or {{{<span macro="view creator"></span>}}} in the ViewTemplate and/or EditTemplate to display the creator value in each tiddler.  
***/
//{{{
// hijack saveTiddler()
TiddlyWiki.prototype.CoreTweaks_creatorSaveTiddler=TiddlyWiki.prototype.saveTiddler;
TiddlyWiki.prototype.saveTiddler=function(title,newTitle,newBody,modifier,modified,tags,fields)
{
	var existing=store.tiddlerExists(title);
	var tiddler=this.CoreTweaks_creatorSaveTiddler.apply(this,arguments);
	if (!existing) store.setValue(title,"creator",config.options.txtUserName);
	return tiddler;
}
//}}}
// // }}}}}}// // {{block{
/***
!!!458 add permalink-like HREFs on internal TiddlyLinks
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/458 - CLOSED: WON'T FIX
This tweak assigns a "permalink"-like HREF to internal Tiddler links (which normally do not have any HREF defined).  This permits the link's context menu (right-click) to include 'open link in another window/tab' command.  Based on a request from Dustin Spicuzza.
***/
//{{{
window.coreTweaks_createTiddlyLink=window.createTiddlyLink;
window.createTiddlyLink=function(place,title,includeText,theClass,isStatic,linkedFromTiddler,noToggle)
{
	// create the core button, then add the HREF (to internal links only)
	var link=window.coreTweaks_createTiddlyLink.apply(this,arguments);
	if (!isStatic)
		link.href=document.location.href.split("#")[0]+"#"+encodeURIComponent(String.encodeTiddlyLink(title));
	return link;
}
//}}}
// // }}}}}}// // {{block{
/***
!!!444 'tiddler' and 'place' - global variables for use in computed macro parameters
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/444 - OPEN
When invoking a macro, this tweak makes the current containing tiddler object and DOM rendering location available as global variables (window.tiddler and window.place, respectively).  These globals can then be used within "computed macro parameters" to retrieve tiddler-relative and/or DOM-relative values or perform tiddler-specific side-effect functionality.
***/
//{{{
window.coreTweaks_invokeMacro = window.invokeMacro;
window.invokeMacro = function(place,macro,params,wikifier,tiddler) {
	var here=story.findContainingTiddler(place);
	window.tiddler=here?store.getTiddler(here.getAttribute("tiddler")):null;
	window.place=place;
	window.coreTweaks_invokeMacro.apply(this,arguments);
}
//}}}
// // }}}}}}// // {{block{
/***
!!!401 PageTitle - alternative to combined ~SiteTitle/~SiteSubtitle in window titlebar
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/401 - CLOSED: WON'T FIX
This tweak allows definition of an optional [[PageTitle]] tiddler that, when present, provides alternative text for display in the browser window's titlebar, instead of using the combined text content from [[SiteTitle]] and [[SiteSubtitle]] (which will still be displayed as usual in the TiddlyWiki document header area)
***/
//{{{
window.coreTweaks_getPageTitle=window.getPageTitle;
window.getPageTitle=function() { 
	var txt=wikifyPlain("PageTitle"); if (txt.length) return txt;
	return window.coreTweaks_getPageTitle.apply(this,arguments);
}
store.addNotification("PageTitle",refreshPageTitle); // so title stays in sync with tiddler changes
//}}}
// // }}}}}}// // {{block{
/***
!!!67 Missing links - ignore non-wiki syntax source content
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/67 - OPEN
The "missing links" list includes items contained within "quoted" text (i.e., content that will not render as wiki-syntax, and so CANNOT create any tiddler links, even if the quoted text matches valid link syntax).  This tweak removes content contained between certain delimiters before scanning tiddler source for possible links.

Delimiters include:
{{{
/%...%/
{{{...}}}
"""..."""
<nowiki>...</nowiki>
<html>...</html>
<script>...</script>
}}}
***/
//{{{
Tiddler.prototype.coreTweaks_changed = Tiddler.prototype.changed;
Tiddler.prototype.changed = function()
{
	var savedtext=this.text;
	// remove 'quoted' text before scanning tiddler source
	this.text=this.text.replace(/\/%((?:.|\n)*?)%\//g,""); // /%...%/
	this.text=this.text.replace(/\{{3}((?:.|\n)*?)\}{3}/g,""); // {{{...}}}
	this.text=this.text.replace(/"{3}((?:.|\n)*?)"{3}/g,""); // """..."""
	this.text=this.text.replace(/\<nowiki\>((?:.|\n)*?)\<\/nowiki\>/g,""); // <nowiki>...</nowiki>
	this.text=this.text.replace(/\<html\>((?:.|\n)*?)\<\/html\>/g,""); // <html>...</html>
	this.text=this.text.replace(/\<script((?:.|\n)*?)\<\/script\>/g,""); // <script>...</script>
	this.coreTweaks_changed.apply(this,arguments);
	// restore quoted text to tiddler source
	this.text=savedtext;
};
//}}}
// // }}}}}}// // {{block{
/***
!!!(no ticket) """<<tag>>""" macro - sortby parameter
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/TBD - TBD
This tweak adds an optional 'sortby' parameter to the """<<tag tagname label tip sortby>>""" macro, as well as the """<<allTags excludeTag sortby>>""" macro used to generate the sidebar contents 'tags' list.  Specify the field on which the contents of each tag popup is to be sorted, with a "+" or "-" prefix to indicate ascending/descending order, respectively.

Example: """<<tag systemConfig "plugins" "list plugins by date, most recent first" "-modified">>"""
Try it: <<tag systemConfig "plugins" "list plugins by date, most recent first" "-modified">>

Similarly, to change the sort order used by the popups from all tags shown in the sidebar contents, edit the [[TagTags]] shadow tiddler and enter: """<<allTags excludeLists -modified>>"""
***/
//{{{
// hijack tag handler() to add 'sortby' attribute to tag button
config.macros.tag.CoreTweaksSortTags_handler=config.macros.tag.handler;
config.macros.tag.handler = function(place,macroName,params)
{
	this.CoreTweaksSortTags_handler.apply(this,arguments);
	var btn=place.lastChild;
	if (params[3]) btn.setAttribute("sortby",params[3]);
}

// tweak <<allTags>> macro to add 'sortby' attribute to each tag button
var fn=config.macros.allTags.handler;
var lines=fn.toString().split("\n");
lines.splice(lines.length-2,0,['if(params[1]) btn.setAttribute("sortby",params[1]);']);
fn=lines.join("\n");
eval("config.macros.allTags.handler="+fn);

// tweak event handler for clicking on a tiddler tag to use 'sortby' attribute
var fn=onClickTag;
fn=fn.toString().replace(
	/store.getTaggedTiddlers\(tag\);/g,
	'store.getTaggedTiddlers(tag);'
	+'var sortby=this.getAttribute("sortby");'
	+'if(sortby&&sortby.length) store.sortTiddlers(tagged,sortby);'
);
eval(fn);

//}}}
// // }}}}}}// // {{block{
/***
!!!(no ticket) backslash-quoting for embedding newlines in 'line-mode' formats
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/TBD - TBD
This HIJACK tweak pre-processes source content to convert "double-backslash-newline" into {{{<br>}}} before wikify(), so that literal newlines can be embedded in line-mode wiki syntax (e.g., tables, bullets, etc.).  Based on a suggestion from Sitaram Chamarty.
***/
//{{{
window.coreWikify = wikify;
window.wikify = function(source,output,highlightRegExp,tiddler)
{
	if (source) arguments[0]=source.replace(/\\\\\n/mg,"<br>");
	coreWikify.apply(this,arguments);
}
//}}}
// // }}}}}}
// // <<foldHeadings>>
{{fr{
* qu'as tu fait hier ?
* que vas-tu faire aujourd'hui ?
* qu'est-ce qui t'empêche de faire ton travail ?
''15 min max''}}}{{en{
* what did you do yesterday ?
* what will you do today ?
* what's prevent you to do your work ?
''15 min max standup meeting''
}}}
/***
|''Name''|DataTiddlerPlugin - fields version|
|''Description''|Same as original|
|''Author''|[[YBA - IDEIA <ybabel@ideia.fr>|mailto:Y.%20BABEL<ybabel@ideia.fr>?subject=NewDataTiddlerPlugin]]|
|''Version''|0.1|
|''Date''|2008.09.19|
|''Status''|@@beta@@|
|''License''|[[GNU/GPL3+|http://www.gnu.org/licenses/gpl-3.0.html]]|
|''CoreVersion''|2.4|
|''Requires''||
|''Overrides''|DataTiddlerPlugin from Udo|

!Code
***/
//{{{

// Ensure that the DataTiddler Plugin is only installed once.
//
if (!version.extensions.DataTiddlerPlugin) {

version.extensions.DataTiddlerPlugin = {
    major: 1, minor: 0, revision: 6,
    date: new Date(2006, 7, 26), 
    type: 'plugin',
    source: "http://tiddlywiki.abego-software.de/#DataTiddlerPlugin"
};

// For backward compatibility with v1.2.x
//
if (!window.story) window.story=window; 
if (!TiddlyWiki.prototype.getTiddler) {
	TiddlyWiki.prototype.getTiddler = function(title) { 
		var t = this.tiddlers[title]; 
		return (t !== undefined && t instanceof Tiddler) ? t : null; 
	};
}

//============================================================================
// DataTiddler Class
//============================================================================

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

function DataTiddler() {
}

DataTiddler = {
    // Function to stringify a JavaScript value, producing the text for the data section content.
    // (Must match the implementation of DataTiddler.parse.)
    //
    stringify : null,
    

    // Function to parse the text for the data section content, producing a JavaScript value.
    // (Must match the implementation of DataTiddler.stringify.)
    //
    parse : null
};

// Ensure access for IE
window.DataTiddler = DataTiddler;

// ---------------------------------------------------------------------------
// Data Accessor and Mutator
// ---------------------------------------------------------------------------


// Returns the value of the given data field of the tiddler.
// When no such field is defined or its value is undefined
// the defaultValue is returned.
// 
// @param tiddler either a tiddler name or a tiddler
//
DataTiddler.getData = function(tiddler, field, defaultValue) {
    var t = (typeof tiddler == "string") ? store.getTiddler(tiddler) : tiddler;
    if (!(t instanceof Tiddler)) {
        throw "Tiddler expected. Got "+tiddler;
    }

    return DataTiddler.getTiddlerDataValue(t, field, defaultValue);
};


// Sets the value of the given data field of the tiddler to
// the value. When the value is equal to the defaultValue
// no value is set (and the field is removed)
//
// Changing data of a tiddler will not trigger notifications.
// 
// @param tiddler either a tiddler name or a tiddler
//
DataTiddler.setData = function(tiddler, field, value, defaultValue) {
    var t = (typeof tiddler == "string") ? store.getTiddler(tiddler) : tiddler;
    if (!(t instanceof Tiddler)) {
        throw "Tiddler expected. Got "+tiddler+ "("+t+")";
    }

    DataTiddler.setTiddlerDataValue(t, field, value, defaultValue);
};


// Returns the data object of the tiddler, with a property for every field.
//
// The properties of the returned data object may only be read and
// not be modified. To modify the data use DataTiddler.setData(...) 
// or the corresponding Tiddler method.
//
// If no data section is defined a new (empty) object is returned.
//
// @param tiddler either a tiddler name or a Tiddler
//
DataTiddler.getDataObject = function(tiddler) {
    var t = (typeof tiddler == "string") ? store.getTiddler(tiddler) : tiddler;
    if (!(t instanceof Tiddler)) {
        throw "Tiddler expected. Got "+tiddler;
    }

    return DataTiddler.getTiddlerDataObject(t);
};

// ---------------------------------------------------------------------------
// Internal helper methods (must not be used by code from outside this plugin)
// ---------------------------------------------------------------------------

// Internal.
//
// @param t a Tiddler
//
DataTiddler.getTiddlerDataObject = function(t) {
    return t.fields;
};


// Internal.
//
// @param tiddler a Tiddler
//
DataTiddler.getTiddlerDataValue = function(tiddler, field, defaultValue) {
    var value = DataTiddler.getTiddlerDataObject(tiddler)[field];
    return (value === undefined) ? defaultValue : value;
};


// Internal.
//
// @param tiddler a Tiddler
//
DataTiddler.setTiddlerDataValue = function(tiddler, field, value, defaultValue) {
    var data = DataTiddler.getTiddlerDataObject(tiddler);
    var oldValue = data[field];
	
    if (value == defaultValue) {
        if (oldValue !== undefined) {
            delete data[field];
            DataTiddler.save(tiddler);
        }
        return;
    }
    data[field] = value;
    DataTiddler.save(tiddler);
};

DataTiddler.save = function(tiddler) {
        // Mark the store as dirty.
        store.dirty = true;
 
        // AutoSave if option is selected
        if(config.options.chkAutoSave) {
           saveChanges();
        }
};
//============================================================================
// Tiddler Class Extension
//============================================================================

// "Hijack" the changed method ---------------------------------------------------


// Define accessor methods -------------------------------------------------------

// Returns the value of the given data field of the tiddler. When no such field 
// is defined or its value is undefined the defaultValue is returned.
//
// When field is undefined (or null) the data object is returned. (See 
// DataTiddler.getDataObject.)
//
// @param field [may be null, undefined]
// @param defaultValue [may be null, undefined]
// @return [may be null, undefined]
//
Tiddler.prototype.data = function(field, defaultValue) {
    return (field) 
         ? DataTiddler.getTiddlerDataValue(this, field, defaultValue)
         : DataTiddler.getTiddlerDataObject(this);
};

// Sets the value of the given data field of the tiddler to the value. When the 
// value is equal to the defaultValue no value is set (and the field is removed).
//
// @param value [may be null, undefined]
// @param defaultValue [may be null, undefined]
//
Tiddler.prototype.setData = function(field, value, defaultValue) {
    DataTiddler.setTiddlerDataValue(this, field, value, defaultValue);
};


//============================================================================
// showData Macro
//============================================================================

config.macros.showData = {
     // Standard Properties
     label: "showData",
     prompt: "Display the values stored in the data section of the tiddler"
};

config.macros.showData.handler = function(place,macroName,params) {
    // --- Parsing ------------------------------------------

    var i = 0; // index running over the params
    // Parse the optional "JSON"
    var showInJSONFormat = false;
    if ((i < params.length) && params[i] == "JSON") {
        i++;
        showInJSONFormat = true;
    }
    
    var tiddlerName = story.findContainingTiddler(place).id.substr(7);
    if (i < params.length) {
        tiddlerName = params[i];
        i++;
    }

    // --- Processing ------------------------------------------
    try {
        if (showInJSONFormat) {
            this.renderDataInJSONFormat(place, tiddlerName);
        } else {
            this.renderDataAsTable(place, tiddlerName);
        }
    } catch (e) {
        this.createErrorElement(place, e);
    }
};

config.macros.showData.renderDataInJSONFormat = function(place,tiddlerName) {
    var text = DataTiddler.getDataText(tiddlerName);
    if (text) {
        createTiddlyElement(place,"pre",null,null,text);
    }
};

config.macros.showData.renderDataAsTable = function(place,tiddlerName) {
    var text = "|!Name|!Value|\n";
    var data = DataTiddler.getDataObject(tiddlerName);
    if (data) {
        for (var i in data) {
            var value = data[i];
            text += "|"+i+"|"+DataTiddler.stringify(value)+"|\n";
        }
    }
    
    wikify(text, place);
};


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

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


} // of "install only once"

//}}}

[[Start]]
/***
|Name|DeleteAllTaggedPlugin|
|Source|http://ido-xp.tiddlyspot.com/#DeleteAllTaggedPlugin|
|Version|1.0|

An adaptation of DeleteDoneTasks (Simon Baird) by Ido Magal
To use this insert {{{<<deleteAllTagged>>}}} into the desired tiddler.

/***
Example usage:
{{{<<deleteAllTagged>>}}}
<<deleteAllTagged>>
***/
//{{{

config.macros.deleteAllTagged = {
	handler: function ( place,macroName,params,wikifier,paramString,tiddler ) {
		var buttonTitle = "Delete Tagged w/ '"+tiddler.title+"'";
		createTiddlyButton( place, buttonTitle, "Delete every tiddler tagged with '"+tiddler.title+"'", this.deleteAllTagged( tiddler.title ));
	},

	deleteAllTagged: function(tag) {
		return function() {
			var collected = [];
			store.forEachTiddler( function ( title,tiddler ) {
				if ( tiddler.tags.contains( tag ))
				{
					collected.push( title );
				}
			});
			if ( collected.length == 0 )
			{
				alert( "No tiddlers found tagged with '"+tag+"'." );
			}
			else
			{
				if ( confirm( "These tiddlers are tagged with '"+tag+"'\n'"
						+ collected.join( "', '" ) + "'\n\n\n"
						+ "Are you sure you want to delete these?" ))
				{
					for ( var i=0;i<collected.length;i++ )
					{
						store.deleteTiddler( collected[i] );
						displayMessage( "Deleted '"+collected[i]+"'" );
					}
				}
			}
		}
	}
};

//}}}
/***
|''Name''|DeprecatedFunctionsPlugin|
|''Description''|Provides support for functions removed from the TiddlyWiki core|
|''Version''|1.0.0|
|''Status''|stable|
|''Source''|http://www.tiddlywiki.com/coreplugins.html#DeprecatedFunctionsPlugin|
|''~CodeRepository:''|http://svn.tiddlywiki.org/Trunk/association/plugins/DeprecatedFunctionsPlugin/DeprecatedFunctionsPlugin.js |
|''License''|[[BSD open source license]]|
|''~CoreVersion''|2.3.0|
|''Feedback''|[[TiddlyWiki community|http://groups.google.com/group/TiddlyWiki]] |
|''Keywords''|legacySupport|
!Code
***/
//{{{
if(!version.extensions.DeprecatedFunctionsPlugin) {
version.extensions.DeprecatedFunctionsPlugin = {installed:true};

//--
//-- Deprecated code
//--

// @Deprecated: Use createElementAndWikify and this.termRegExp instead
config.formatterHelpers.charFormatHelper = function(w)
{
	w.subWikify(createTiddlyElement(w.output,this.element),this.terminator);
};

// @Deprecated: Use enclosedTextHelper and this.lookaheadRegExp instead
config.formatterHelpers.monospacedByLineHelper = function(w)
{
	var lookaheadRegExp = new RegExp(this.lookahead,"mg");
	lookaheadRegExp.lastIndex = w.matchStart;
	var lookaheadMatch = lookaheadRegExp.exec(w.source);
	if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
		var text = lookaheadMatch[1];
		if(config.browser.isIE)
			text = text.replace(/\n/g,"\r");
		createTiddlyElement(w.output,"pre",null,null,text);
		w.nextMatch = lookaheadRegExp.lastIndex;
	}
};

// @Deprecated: Use <br> or <br /> instead of <<br>>
config.macros.br = {};
config.macros.br.handler = function(place)
{
	createTiddlyElement(place,"br");
};

// Find an entry in an array. Returns the array index or null
// @Deprecated: Use indexOf instead
Array.prototype.find = function(item)
{
	var i = this.indexOf(item);
	return i == -1 ? null : i;
};

// Load a tiddler from an HTML DIV. The caller should make sure to later call Tiddler.changed()
// @Deprecated: Use store.getLoader().internalizeTiddler instead
Tiddler.prototype.loadFromDiv = function(divRef,title)
{
	return store.getLoader().internalizeTiddler(store,this,title,divRef);
};

// Format the text for storage in an HTML DIV
// @Deprecated Use store.getSaver().externalizeTiddler instead.
Tiddler.prototype.saveToDiv = function()
{
	return store.getSaver().externalizeTiddler(store,this);
};

// @Deprecated: Use store.allTiddlersAsHtml() instead
function allTiddlersAsHtml()
{
	return store.allTiddlersAsHtml();
}

// @Deprecated: Use refreshPageTemplate instead
function applyPageTemplate(title)
{
	refreshPageTemplate(title);
}

// @Deprecated: Use story.displayTiddlers instead
function displayTiddlers(srcElement,titles,template,unused1,unused2,animate,unused3)
{
	story.displayTiddlers(srcElement,titles,template,animate);
}

// @Deprecated: Use story.displayTiddler instead
function displayTiddler(srcElement,title,template,unused1,unused2,animate,unused3)
{
	story.displayTiddler(srcElement,title,template,animate);
}

// @Deprecated: Use functions on right hand side directly instead
var createTiddlerPopup = Popup.create;
var scrollToTiddlerPopup = Popup.show;
var hideTiddlerPopup = Popup.remove;

// @Deprecated: Use right hand side directly instead
var regexpBackSlashEn = new RegExp("\\\\n","mg");
var regexpBackSlash = new RegExp("\\\\","mg");
var regexpBackSlashEss = new RegExp("\\\\s","mg");
var regexpNewLine = new RegExp("\n","mg");
var regexpCarriageReturn = new RegExp("\r","mg");

}
//}}}
http://www.agile-software-development.com/2007/09/how-to-implement-scrum-in-10-easy-steps.html

# Créer le backlog de produit ordonné (liste des choses que les utilisateurs veulent faire) par le ProductOwner
# Estimer le backlog en points collectivement
# Planifier le sprint : durée, objectif, écrire les User Stories
# Planifier le sprint : découper en taches et estimer la durée (moins de 2 jours)
# Mettre en place l'espace collaboratif (tableau de bord)
# Lancer le sprint (pas d'interférence, qualité, TDD, XP)
# Réunion quotidienne 15 min : fait, reste à faire, blocage ?
# L'équipe met a jour le Burdown Chart
# Finir le sprint : produit livrable
# Revue, Rétrospective, Répétition

/***
|!''Name:''|!''E''asily ''A''daptable ''S''ource ''E''ditor|
|''Description:''|this framework allows you to easily create commands that work on the current tiddler text selection in edit mode|
|''Version:''|0.1.0|
|''Date:''|13/01/2007|
|''Source:''|http://yann.perrin.googlepages.com/twkd.html#E.A.S.E|
|''Author:''|[[Yann Perrin|YannPerrin]]|
|''License:''|[[BSD open source license]]|
|''~CoreVersion:''|2.x|
|''Browser:''|Firefox 1.0.4+; Firefox 1.5; InternetExplorer 6.0|
***/
////Messages Definition
//{{{
config.messages.Ease = {
noselection:"nothing selected",
asktitle:"enter the new tiddler title",
exists:" already exists, please enter another title",
askForTagsLabel:"enter the new tiddler tags",
tiddlercreated:" tiddler created"
}
//}}}
////
//{{{
if (!window.TWkd) window.TWkd={context:{}};
if (!TWkd.Ease)
 TWkd.Ease = function (text,tooltip){
 this.text = text;
 this.tooltip = tooltip;
 this.modes = [];
 this.addMode = function(modeDefinition) {this.modes.push(modeDefinition);};
 this.handler = function(event,src,title) {
 TWkd.context.command = this;
 TWkd.context.selection=this.getSelection(title);
 if (this.modes.length==1) {
 this.modes[0].operation();
 }
 else {
 var popup = Popup.create(src);
 if(popup) {
 for (var i=0; i<this.modes.length; i++) {
 createTiddlyButton(createTiddlyElement(popup,"li"), this.modes[i].name, this.modes[i].tooltip, this.OperateFromButton, null, 'id'+i, null);
 }
 Popup.show(popup,false);
 event.cancelBubble = true;
 if (event.stopPropagation) event.stopPropagation();
 return false;
 }
 }
 };
 };

TWkd.Ease.prototype.OperateFromButton = function(e){
 var commandMode=this.getAttribute('Id').replace('id','');
 TWkd.context.command.modes[commandMode].operation();
};

TWkd.Ease.prototype.getTiddlerEditField = function(title,field){
 var tiddler = document.getElementById(story.idPrefix + title);
 if(tiddler != null){
 var children = tiddler.getElementsByTagName("*")
 var e = null;
 for (var t=0; t<children.length; t++){
 var c = children[t];
 if(c.tagName.toLowerCase() == "input" || c.tagName.toLowerCase() == "textarea"){
 if(!e) {e = c;}
 if(c.getAttribute("edit") == field){e = c;}
 }
 }
 if(e){return e;}
 }
} // closes getTiddlerEditField function definition
 
TWkd.Ease.prototype.getSelection = function(title,quiet) {
 var tiddlerTextArea = this.getTiddlerEditField(title,"text");
 var result = {};
 if (document.selection != null && tiddlerTextArea.selectionStart == null) {
 tiddlerTextArea.focus();
 var range = document.selection.createRange();
 var bookmark = range.getBookmark();
 var contents = tiddlerTextArea.value;
 var originalContents = contents;
 var marker = "##SELECTION_MARKER_" + Math.random() + "##";
 while(contents.indexOf(marker) != -1) {
 marker = "##SELECTION_MARKER_" + Math.random() + "##";
 }
 var selection = range.text;
 range.text = marker + range.text + marker;
 contents = tiddlerTextArea.value;
 result.start = contents.indexOf(marker);
 contents = contents.replace(marker, "");
 result.end = contents.indexOf(marker);
 tiddlerTextArea.value = originalContents;
 range.moveToBookmark(bookmark);
 range.select();
 }
 else {
 result.start=tiddlerTextArea.selectionStart;
 result.end=tiddlerTextArea.selectionEnd;
 }
 result.content=tiddlerTextArea.value.substring(result.start,result.end);
 result.source=title;
 if (!result.content&&!quiet) displayMessage(config.messages.Ease.noselection);
 return(result);
}//closes getSelection function definition

// replace selection or insert new content
TWkd.Ease.prototype.putInPlace=function(content,workplace) {
 var tiddlerText = this.getTiddlerEditField(workplace.source,"text");
 tiddlerText.value = tiddlerText.value.substring(0,workplace.start)+content+tiddlerText.value.substring(workplace.end);
}

// asking for title
TWkd.Ease.prototype.askForTitle = function(suggestion) {
 if (!suggestion)
 suggestion = "";
 var newtitle;
 while (!newtitle||store.tiddlerExists(newtitle))
 {
 if (store.tiddlerExists(newtitle))
 displayMessage(newtitle+config.messages.Ease.exists);
 newtitle = prompt(config.messages.Ease.asktitle,suggestion);
 if (newtitle==null)
 {
 displayMessage(config.messages.Ease.titlecancel);
 return(false);
 }
 }
 return(newtitle);
}//closes askForTitle function definition

// creation of a new tiddler
TWkd.Ease.prototype.newTWkdLibTiddler = function(title,content,from,askForTags){
 var tiddler = new Tiddler();
 tiddler.title = title;
 tiddler.modifier = config.options.txtUserName;
 tiddler.text = content;
 (from) ? tiddler.tags = [from] : tiddler.tags=[];
 if (askForTags)
 tiddler.tags = prompt(config.messages.Ease.askForTagsLabel,'[['+from+']]').readBracketedList();
 store.addTiddler(tiddler);
 //store.notifyAll();
 displayMessage(title+config.messages.Ease.tiddlercreated);
}

if (!TWkd.Mode)
 TWkd.Mode = function (name,tooltip,ask,operation) {
 this.name = name;
 this.tooltip = tooltip;
 this.ask = ask;
 this.operation = operation;
 };
//}}}
{{fr{Liste triée des user stories}}}{{en{Sorted list of user stories}}}
----
{{fr{Rajoutez vos commentaires ici}}}{{en{Add your comments here}}}
{{fr{Liste triée des user stories}}}{{en{Sorted list of user stories}}}
----
{{fr{Rajoutez vos commentaires ici}}}{{en{Add your comments here}}}
Description de la tache
{{fr{En tant que ... je souhaite ... afin de ...}}}{{en{As ... I would like to ... in order to ...}}}
/***
|Name|ExportTiddlersPlugin|
|Source|http://www.TiddlyTools.com/#ExportTiddlersPlugin|
|Documentation|http://www.TiddlyTools.com/#ExportTiddlersPluginInfo|
|Version|2.8.1|
|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|select and extract tiddlers from your ~TiddlyWiki documents and save them to a separate file|
ExportTiddlersPlugin lets you select and extract tiddlers from your ~TiddlyWiki documents using interactive control panel lets you specify a destination, and then select which tiddlers to export. Tiddler data can be output as complete, stand-alone TiddlyWiki documents, or just the selected tiddlers ("~PureStore" format -- smaller files!) that can be imported directly into another ~TiddlyWiki, or as an ~RSS-compatible XML file that can be published for RSS syndication.
!!!!!Documentation
>see [[ExportTiddlersPluginInfo]]
!!!!!Inline control panel (live):
><<exportTiddlers inline>>
!!!!!Revisions
<<<
2008.09.19 [2.8.1] in formatItem(), removed unnecessary convertUnicodeToUTF8() (was causing double-conversion!)
2008.09.11 [2.8.0] extensive code cleanup: moved all global functions inside macro object. Re-wrote file generator and I/O to support TiddlyWiki, PlainText, PureStore, and NewsFeed file formats.  Replaced inline 'match tags' code with use of getMatchingTiddlers() from [[MatchTagsPlugin]] (if installed), with fallback to core getTaggedTiddlers() otherwise.
|please see [[ExportTiddlersPluginInfo]] for additional revision details|
2005.10.09 [0.0.0] development started
<<<
!!!!!Code
***/
//{{{
// version
version.extensions.ExportTiddlersPlugin= {major: 2, minor: 8, revision: 1, date: new Date(2008,9,19)};

// default shadow definition
config.shadowTiddlers.ExportTiddlers="<<exportTiddlers inline>>";

// add 'export' backstage task (following built-in import task)
if (config.tasks) { // TW2.2 or above
	config.tasks.exportTask = {
		text:"export",
		tooltip:"Export selected tiddlers to another file",
		content:"<<exportTiddlers inline>>"
	}
	config.backstageTasks.splice(config.backstageTasks.indexOf("importTask")+1,0,"exportTask");
}

// $(...) function: 'shorthand' convenience syntax for document.getElementById()
if (typeof($)=="undefined") { // avoid redefinition
function $() {
	var elements=new Array();
	for (var i=0; i<arguments.length; i++) {
		var element=arguments[i];
		if (typeof element=='string') element=document.getElementById(element);
		if (arguments.length==1) return element;
		elements.push(element);
	}
	return elements;
}
}

config.macros.exportTiddlers = {
	label: "export tiddlers",
	prompt: "Copy selected tiddlers to an export document",
	okmsg: "%0 tiddlers written to %1",
	failmsg: "An error occurred while creating %1",
	mergeprompt: "%0\nalready contains tiddler definitions.\n"
		+"\nPress OK to add new/revised tiddlers to current file contents."
		+"\nPress Cancel to completely replace file contents",
	mergestatus: "Merged %0 new/revised tiddlers and %1 existing tiddlers",
	statusmsg: "%0 tiddler%1 - %2 selected for export",
	newdefault: "export.html",
	datetimefmt: "0MM/0DD/YYYY 0hh:0mm:0ss",  // for "filter date/time" edit fields
	type_TW: "tw", type_PS: "ps", type_TX: "tx", type_NF: "nf", // file type tokens
	type_map: { // map filetype param alternatives/abbreviations to token values
		tiddlywiki:"tw", tw:"tw", wiki: "tw",
		purestore: "ps", ps:"ps", store:"ps",
		plaintext: "tx", tx:"tx", text: "tx",
		newsfeed:  "nf", nf:"nf", xml:  "nf", rss:"nf"
	},
	handler: function(place,macroName,params) {
		if (params[0]!="inline")
			{ createTiddlyButton(place,this.label,this.prompt,this.togglePanel); return; }
		var panel=this.createPanel(place);
		panel.style.position="static";
		panel.style.display="block";
	},
	createPanel: function(place) {
		var panel=$("exportPanel");
		if (panel) { panel.parentNode.removeChild(panel); }
		setStylesheet(this.css,"exportTiddlers");
		panel=createTiddlyElement(place,"span","exportPanel",null,null)
		panel.innerHTML=this.html;
		this.initFilter();
		this.refreshList(0);
		var fn=$("exportFilename");
		if (window.location.protocol=="file:" && !fn.value.length) {
			// get new target path/filename
			var newPath=getLocalPath(window.location.href);
			var slashpos=newPath.lastIndexOf("/"); if (slashpos==-1) slashpos=newPath.lastIndexOf("\\"); 
			if (slashpos!=-1) newPath=newPath.substr(0,slashpos+1); // trim filename
			fn.value=newPath+this.newdefault;
		}
		return panel;
	},
	togglePanel: function(e) {
		if (!e) var e = window.event;
		var parent=resolveTarget(e).parentNode;
		var panel = $("exportPanel");
		if (panel==undefined || panel.parentNode!=parent)
			panel=config.macros.exportTiddlers.createPanel(parent);
		var isOpen = panel.style.display=="block";
		if(config.options.chkAnimate)
			anim.startAnimating(new Slider(panel,!isOpen,e.shiftKey || e.altKey,"none"));
		else
			panel.style.display = isOpen ? "none" : "block" ;
		if (panel.style.display!="none") { // update list and set focus when panel is made visible
			config.macros.exportTiddlers.refreshList(0);
			var fn=$("exportFilename"); fn.focus(); fn.select();
		}
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
		return(false);
	},
	css: '\
		#exportPanel {\
			display: none; position:absolute; z-index:12; width:35em; right:105%; top:6em;\
			background-color: #eee; color:#000; font-size: 8pt; line-height:110%;\
			border:1px solid black; border-bottom-width: 3px; border-right-width: 3px;\
			padding: 0.5em; margin:0em; -moz-border-radius:1em;\
		}\
		#exportPanel a, #exportPanel td a { color:#009; display:inline; margin:0px; padding:1px; }\
		#exportPanel table { \
			width:100%; border:0px; padding:0px; margin:0px;\
			font-size:8pt; line-height:110%; background:transparent;\
		}\
		#exportPanel tr { border:0px;padding:0px;margin:0px; background:transparent; }\
		#exportPanel td { color:#000; border:0px;padding:0px;margin:0px; background:transparent; }\
		#exportPanel select { width:98%;margin:0px;font-size:8pt;line-height:110%;}\
		#exportPanel input  { width:98%;padding:0px;margin:0px;font-size:8pt;line-height:110%; }\
		#exportPanel textarea  { width:98%;padding:0px;margin:0px;overflow:auto;font-size:8pt; }\
		#exportPanel .box { \
			border:1px solid black; padding:3px; margin-bottom:5px; \
			background:#f8f8f8; -moz-border-radius:5px; }\
		#exportPanel .topline { border-top:2px solid black; padding-top:3px; margin-bottom:5px; }\
		#exportPanel .rad { width:auto;border:0 }\
		#exportPanel .chk { width:auto;border:0 }\
		#exportPanel .btn { width:auto; }\
		#exportPanel .btn1 { width:98%; }\
		#exportPanel .btn2 { width:48%; }\
		#exportPanel .btn3 { width:32%; }\
		#exportPanel .btn4 { width:24%; }\
		#exportPanel .btn5 { width:19%; }\
	',
	html: '\
		<!-- target path/file  -->\
		<div>\
		export to path/filename:<br>\
		<input type="text" id="exportFilename" size=40 style="width:93%"><input \
			type="button" id="exportBrowse" value="..." title="select or enter a local folder/file..." style="width:5%" \
			onclick="var fn=config.macros.exportTiddlers.askForFilename(this); if (fn.length) this.previousSibling.value=fn; ">\
		</div>\
		<!-- output format -->\
		<div>\
		output file format:\
		<select id="exportFormat" size=1>\
			<option value="TW">TiddlyWiki HTML document (includes core code)</option>\
			<option value="PS">TiddlyWiki "PureStore" HTML file (tiddler data only)</option>\
			<option value="TX">TiddlyWiki plain text TXT file (tiddler source listing)</option>\
			<option value="NF">RSS NewsFeed XML file</option>\
		</select>\
		</div>\
		<!-- notes -->\
		<div>\
		notes:<br>\
		<textarea id="exportNotes" rows=3 cols=40 style="height:4em;margin-bottom:5px;" onfocus="this.select()"></textarea> \
		</div>\
		<!-- list of tiddlers -->\
		<table><tr align="left"><td>\
			select:\
			<a href="JavaScript:;" id="exportSelectAll"\
				onclick="config.macros.exportTiddlers.process(this)" title="select all tiddlers">\
				&nbsp;all&nbsp;</a>\
			<a href="JavaScript:;" id="exportSelectChanges"\
				onclick="config.macros.exportTiddlers.process(this)" title="select tiddlers changed since last save">\
				&nbsp;changes&nbsp;</a> \
			<a href="JavaScript:;" id="exportSelectOpened"\
				onclick="config.macros.exportTiddlers.process(this)" title="select tiddlers currently being displayed">\
				&nbsp;opened&nbsp;</a> \
			<a href="JavaScript:;" id="exportSelectRelated"\
				onclick="config.macros.exportTiddlers.process(this)" title="select tiddlers related to the currently selected tiddlers">\
				&nbsp;related&nbsp;</a> \
			<a href="JavaScript:;" id="exportToggleFilter"\
				onclick="config.macros.exportTiddlers.process(this)" title="show/hide selection filter">\
				&nbsp;filter&nbsp;</a>  \
		</td><td align="right">\
			<a href="JavaScript:;" id="exportListSmaller"\
				onclick="config.macros.exportTiddlers.process(this)" title="reduce list size">\
				&nbsp;&#150;&nbsp;</a>\
			<a href="JavaScript:;" id="exportListLarger"\
				onclick="config.macros.exportTiddlers.process(this)" title="increase list size">\
				&nbsp;+&nbsp;</a>\
		</td></tr></table>\
		<select id="exportList" multiple size="10" style="margin-bottom:5px;"\
			onchange="config.macros.exportTiddlers.refreshList(this.selectedIndex)">\
		</select><br>\
		</div><!--box-->\
		<!-- selection filter -->\
		<div id="exportFilterPanel" style="display:none">\
		<table><tr align="left"><td>\
			selection filter\
		</td><td align="right">\
			<a href="JavaScript:;" id="exportHideFilter"\
				onclick="config.macros.exportTiddlers.process(this)" title="hide selection filter">hide</a>\
		</td></tr></table>\
		<div class="box">\
		<input type="checkbox" class="chk" id="exportFilterStart" value="1"\
			onclick="config.macros.exportTiddlers.showFilterFields(this)"> starting date/time<br>\
		<table cellpadding="0" cellspacing="0"><tr valign="center"><td width="50%">\
			<select size=1 id="exportFilterStartBy" \
				onchange="config.macros.exportTiddlers.showFilterFields(this);">\
				<option value="0">today</option>\
				<option value="1">yesterday</option>\
				<option value="7">a week ago</option>\
				<option value="30">a month ago</option>\
				<option value="file">file date</option>\
				<option value="other">other (mm/dd/yyyy hh:mm)</option>\
			</select>\
		</td><td width="50%">\
			<input type="text" id="exportStartDate" onfocus="this.select()"\
				onchange="$(\'exportFilterStartBy\').value=\'other\';">\
		</td></tr></table>\
		<input type="checkbox" class="chk" id="exportFilterEnd" value="1"\
			onclick="config.macros.exportTiddlers.showFilterFields(this)"> ending date/time<br>\
		<table cellpadding="0" cellspacing="0"><tr valign="center"><td width="50%">\
			<select size=1 id="exportFilterEndBy" \
				onchange="config.macros.exportTiddlers.showFilterFields(this);">\
				<option value="0">today</option>\
				<option value="1">yesterday</option>\
				<option value="7">a week ago</option>\
				<option value="30">a month ago</option>\
				<option value="file">file date</option>\
				<option value="other">other (mm/dd/yyyy hh:mm)</option>\
			</select>\
		</td><td width="50%">\
			<input type="text" id="exportEndDate" onfocus="this.select()"\
				onchange="$(\'exportFilterEndBy\').value=\'other\';">\
		</td></tr></table>\
		<input type="checkbox" class="chk" id=exportFilterTags value="1"\
			onclick="config.macros.exportTiddlers.showFilterFields(this)"> match tags<br>\
		<input type="text" id="exportTags" onfocus="this.select()">\
		<input type="checkbox" class="chk" id=exportFilterText value="1"\
			onclick="config.macros.exportTiddlers.showFilterFields(this)"> match titles/tiddler text<br>\
		<input type="text" id="exportText" onfocus="this.select()">\
		</div> <!--box-->\
		</div> <!--panel-->\
		<!-- action buttons -->\
		<div style="text-align:center">\
		<input type=button class="btn4" onclick="config.macros.exportTiddlers.process(this)"\
			id="exportFilter" value="apply filter">\
		<input type=button class="btn4" onclick="config.macros.exportTiddlers.process(this)"\
			id="exportStart" value="export tiddlers">\
		<input type=button class="btn4" onclick="config.macros.exportTiddlers.process(this)"\
			id="exportDelete" value="delete tiddlers">\
		<input type=button class="btn4" onclick="config.macros.exportTiddlers.process(this)"\
			id="exportClose" value="close">\
		</div><!--center-->\
	',
	process: function(which) { // process panel control interactions
		// DEBUG alert(which.id);
		var theList=$('exportList'); if (!theList) return;
		var count = 0;
		var total = store.getTiddlers('title').length;
		switch (which.id) {
			case 'exportFilter':
				count=this.filterExportList();
				var panel=$('exportFilterPanel');
				if (count==-1) { panel.style.display='block'; break; }
				$("exportStart").disabled=(count==0);
				$("exportDelete").disabled=(count==0);
				this.displayStatus(count,total);
				if (count==0) { alert("No tiddlers were selected"); panel.style.display='block'; }
				break;
			case 'exportStart':
				this.go();
				break;
			case 'exportDelete':
				this.deleteTiddlers();
				break;
			case 'exportHideFilter':
			case 'exportToggleFilter':
				var panel=$('exportFilterPanel')
				panel.style.display=(panel.style.display=='block')?'none':'block';
				break;
			case 'exportSelectChanges':
				var lastmod=new Date(document.lastModified);
				for (var t = 0; t < theList.options.length; t++) {
					if (theList.options[t].value=="") continue;
					var tiddler=store.getTiddler(theList.options[t].value); if (!tiddler) continue;
					theList.options[t].selected=(tiddler.modified>lastmod);
					count += (tiddler.modified>lastmod)?1:0;
				}
				$("exportStart").disabled=(count==0);
				$("exportDelete").disabled=(count==0);
				this.displayStatus(count,total);
				if (count==0) alert("There are no unsaved changes");
				break;
			case 'exportSelectAll':
				for (var t = 0; t < theList.options.length; t++) {
					if (theList.options[t].value=="") continue;
					theList.options[t].selected=true;
					count += 1;
				}
				$("exportStart").disabled=(count==0);
				$("exportDelete").disabled=(count==0);
				this.displayStatus(count,count);
				break;
			case 'exportSelectOpened':
				for (var t = 0; t < theList.options.length; t++) theList.options[t].selected=false;
				var tiddlerDisplay = $("tiddlerDisplay"); // for TW2.1-
				if (!tiddlerDisplay) tiddlerDisplay = $("storyDisplay"); // for TW2.2+
				for (var t=0;t<tiddlerDisplay.childNodes.length;t++) {
					var tiddler=tiddlerDisplay.childNodes[t].id.substr(7);
					for (var i = 0; i < theList.options.length; i++) {
						if (theList.options[i].value!=tiddler) continue;
						theList.options[i].selected=true; count++; break;
					}
				}
				$("exportStart").disabled=(count==0);
				$("exportDelete").disabled=(count==0);
				this.displayStatus(count,total);
				if (count==0) alert("There are no tiddlers currently opened");
				break;
			case 'exportSelectRelated':
				// recursively build list of related tiddlers
				function getRelatedTiddlers(tid,tids) {
					var t=store.getTiddler(tid); if (!t || tids.contains(tid)) return tids;
					tids.push(t.title);
					if (!t.linksUpdated) t.changed();
					for (var i=0; i<t.links.length; i++)
						if (t.links[i]!=tid) tids=getRelatedTiddlers(t.links[i],tids);
					return tids;
				}
				// for all currently selected tiddlers, gather up the related tiddlers (including self) and select them as well
				var tids=[];
				for (var i=0; i<theList.options.length; i++)
					if (theList.options[i].selected) tids=getRelatedTiddlers(theList.options[i].value,tids);
				// select related tiddlers (includes original selected tiddlers)
				for (var i=0; i<theList.options.length; i++)
					theList.options[i].selected=tids.contains(theList.options[i].value);
				this.displayStatus(tids.length,total);
				break;
			case 'exportListSmaller':	// decrease current listbox size
				var min=5;
				theList.size-=(theList.size>min)?1:0;
				break;
			case 'exportListLarger':	// increase current listbox size
				var max=(theList.options.length>25)?theList.options.length:25;
				theList.size+=(theList.size<max)?1:0;
				break;
			case 'exportClose':
				$('exportPanel').style.display='none';
				break;
		}
	},
	displayStatus: function(count,total) {
		var txt=this.statusmsg.format([total,total!=1?'s':'',!count?"none":count==total?"all":count]);
		clearMessage();	displayMessage(txt);
		return txt;
	},
	refreshList: function(selectedIndex) {
		var theList = $("exportList"); if (!theList) return;
		// get the sort order
		var sort;
		if (!selectedIndex)   selectedIndex=0;
		if (selectedIndex==0) sort='modified';
		if (selectedIndex==1) sort='title';
		if (selectedIndex==2) sort='modified';
		if (selectedIndex==3) sort='modifier';
		if (selectedIndex==4) sort='tags';

		// unselect headings and count number of tiddlers actually selected
		var count=0;
		for (var t=5; t < theList.options.length; t++) {
			if (!theList.options[t].selected) continue;
			if (theList.options[t].value!="")
				count++;
			else { // if heading is selected, deselect it, and then select and count all in section
				theList.options[t].selected=false;
				for ( t++; t<theList.options.length && theList.options[t].value!=""; t++) {
					theList.options[t].selected=true;
					count++;
				}
			}
		}

		// disable "export" and "delete" buttons if no tiddlers selected
		$("exportStart").disabled=(count==0);
		$("exportDelete").disabled=(count==0);

		// show selection count
		var tiddlers = store.getTiddlers('title');
		if (theList.options.length) this.displayStatus(count,tiddlers.length);

		// if a [command] item, reload list... otherwise, no further refresh needed
		if (selectedIndex>4) return;

		// clear current list contents
		while (theList.length > 0) { theList.options[0] = null; }
		// add heading and control items to list
		var i=0;
		var indent=String.fromCharCode(160)+String.fromCharCode(160);
		theList.options[i++]=
			new Option(tiddlers.length+" tiddlers in document", "",false,false);
		theList.options[i++]=
			new Option(((sort=="title"   )?">":indent)+' [by title]', "",false,false);
		theList.options[i++]=
			new Option(((sort=="modified")?">":indent)+' [by date]', "",false,false);
		theList.options[i++]=
			new Option(((sort=="modifier")?">":indent)+' [by author]', "",false,false);
		theList.options[i++]=
			new Option(((sort=="tags"    )?">":indent)+' [by tags]', "",false,false);

		// output the tiddler list
		switch(sort) {
			case "title":
				for(var t = 0; t < tiddlers.length; t++)
					theList.options[i++] = new Option(tiddlers[t].title,tiddlers[t].title,false,false);
				break;
			case "modifier":
			case "modified":
				var tiddlers = store.getTiddlers(sort);
				// sort descending for newest date first
				tiddlers.sort(function (a,b) {if(a[sort] == b[sort]) return(0); else return (a[sort] > b[sort]) ? -1 : +1; });
				var lastSection = "";
				for(var t = 0; t < tiddlers.length; t++) {
					var tiddler = tiddlers[t];
					var theSection = "";
					if (sort=="modified") theSection=tiddler.modified.toLocaleDateString();
					if (sort=="modifier") theSection=tiddler.modifier;
					if (theSection != lastSection) {
						theList.options[i++] = new Option(theSection,"",false,false);
						lastSection = theSection;
					}
					theList.options[i++] = new Option(indent+indent+tiddler.title,tiddler.title,false,false);
				}
				break;
			case "tags":
				var theTitles = {}; // all tiddler titles, hash indexed by tag value
				var theTags = new Array();
				for(var t=0; t<tiddlers.length; t++) {
					var title=tiddlers[t].title;
					var tags=tiddlers[t].tags;
					if (!tags || !tags.length) {
						if (theTitles["untagged"]==undefined) { theTags.push("untagged"); theTitles["untagged"]=new Array(); }
						theTitles["untagged"].push(title);
					}
					else for(var s=0; s<tags.length; s++) {
						if (theTitles[tags[s]]==undefined) { theTags.push(tags[s]); theTitles[tags[s]]=new Array(); }
						theTitles[tags[s]].push(title);
					}
				}
				theTags.sort();
				for(var tagindex=0; tagindex<theTags.length; tagindex++) {
					var theTag=theTags[tagindex];
					theList.options[i++]=new Option(theTag,"",false,false);
					for(var t=0; t<theTitles[theTag].length; t++)
						theList.options[i++]=new Option(indent+indent+theTitles[theTag][t],theTitles[theTag][t],false,false);
				}
				break;
			}
		theList.selectedIndex=selectedIndex; // select current control item
		$("exportStart").disabled=true;
		$("exportDelete").disabled=true;
		this.displayStatus(0,tiddlers.length);
	},
	askForFilename: function(here) {
		var msg=here.title; // use tooltip as dialog box message
		var path=getLocalPath(document.location.href);
		var slashpos=path.lastIndexOf("/"); if (slashpos==-1) slashpos=path.lastIndexOf("\\"); 
		if (slashpos!=-1) path = path.substr(0,slashpos+1); // remove filename from path, leave the trailing slash
		var filetype=$("exportFormat").value.toLowerCase();
		var defext='html';
		if (filetype==this.type_TX) defext='txt';
		if (filetype==this.type_NF) defext='xml';
		var file=this.newdefault.replace(/html$/,defext);
		var result="";
		if(window.Components) { // moz
			try {
				netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
				var nsIFilePicker = window.Components.interfaces.nsIFilePicker;
				var picker = Components.classes['@mozilla.org/filepicker;1'].createInstance(nsIFilePicker);
				picker.init(window, msg, nsIFilePicker.modeSave);
				var thispath = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
				thispath.initWithPath(path);
				picker.displayDirectory=thispath;
				picker.defaultExtension=defext;
				picker.defaultString=file;
				picker.appendFilters(nsIFilePicker.filterAll|nsIFilePicker.filterText|nsIFilePicker.filterHTML);
				if (picker.show()!=nsIFilePicker.returnCancel) var result=picker.file.persistentDescriptor;
			}
			catch(e) { alert('error during local file access: '+e.toString()) }
		}
		else { // IE
			try { // XPSP2 IE only
				var s = new ActiveXObject('UserAccounts.CommonDialog');
				s.Filter='All files|*.*|Text files|*.txt|HTML files|*.htm;*.html|XML files|*.xml|';
				s.FilterIndex=defext=="txt"?2:"html"?3:"xml"?4:1;
				s.InitialDir=path;
				s.FileName=file;
				if (s.showOpen()) var result=s.FileName;
			}
			catch(e) {  // fallback
				var result=prompt(msg,path+file);
			}
		}
		return result;
	},
	initFilter: function() {
		// start date
		$("exportFilterStart").checked=false;
		$("exportStartDate").value="";
		// end date
		$("exportFilterEnd").checked=false;
		$("exportEndDate").value="";
		// tags
		$("exportFilterTags").checked=false;
		$("exportTags").value="";
		// text
		$("exportFilterText").checked=false;
		$("exportText").value="";
		// show/hide filter input fields
		this.showFilterFields();
	},
	showFilterFields: function(which) {
		var show=$('exportFilterStart').checked;
		$('exportFilterStartBy').style.display=show?"block":"none";
		$('exportStartDate').style.display=show?"block":"none";
		var val=$('exportFilterStartBy').value;
		$('exportStartDate').value
			=this.getFilterDate(val,'exportStartDate').formatString(this.datetimefmt);
		if (which && (which.id=='exportFilterStartBy') && (val=='other'))
			$('exportStartDate').focus();

		var show=$('exportFilterEnd').checked;
		$('exportFilterEndBy').style.display=show?"block":"none";
		$('exportEndDate').style.display=show?"block":"none";
		var val=$('exportFilterEndBy').value;
		$('exportEndDate').value
			=this.getFilterDate(val,'exportEndDate').formatString(this.datetimefmt);
		 if (which && (which.id=='exportFilterEndBy') && (val=='other'))
			$('exportEndDate').focus();

		var show=$('exportFilterTags').checked;
		$('exportTags').style.display=show?"block":"none";

		var show=$('exportFilterText').checked;
		$('exportText').style.display=show?"block":"none";
	},
	getFilterDate: function(val,id) {
		var result=0;
		switch (val) {
			case 'file':
				result=new Date(document.lastModified);
				break;
			case 'other':
				result=new Date($(id).value);
				break;
			default: // today=0, yesterday=1, one week=7, two weeks=14, a month=31
				var now=new Date(); var tz=now.getTimezoneOffset()*60000; now-=tz;
				var oneday=86400000;
				if (id=='exportStartDate')
					result=new Date((Math.floor(now/oneday)-val)*oneday+tz);
				else
					result=new Date((Math.floor(now/oneday)-val+1)*oneday+tz-1);
				break;
		}
		return result;
	},
	filterExportList: function() {
		var theList  = $("exportList"); if (!theList) return -1;
		var filterStart=$("exportFilterStart").checked;
		var val=$("exportFilterStartBy").value;
		var startDate=config.macros.exportTiddlers.getFilterDate(val,'exportStartDate');
		var filterEnd=$("exportFilterEnd").checked;
		var val=$("exportFilterEndBy").value;
		var endDate=config.macros.exportTiddlers.getFilterDate(val,'exportEndDate');
		var filterTags=$("exportFilterTags").checked;
		var tags=$("exportTags").value;
		var filterText=$("exportFilterText").checked;
		var text=$("exportText").value;
		if (!(filterStart||filterEnd||filterTags||filterText)) {
			alert("Please set the selection filter");
			$('exportFilterPanel').style.display="block";
			return -1;
		}
		if (filterStart&&filterEnd&&(startDate>endDate)) {
			var msg="starting date/time:\n"
			msg+=startDate.toLocaleString()+"\n";
			msg+="is later than ending date/time:\n"
			msg+=endDate.toLocaleString()
			alert(msg);
			return -1;
		}
		// if filter by tags, get list of matching tiddlers
		// use getMatchingTiddlers() (if MatchTagsPlugin is installed) for full boolean expressions
		// otherwise use getTaggedTiddlers() for simple tag matching
		if (filterTags) {
			var fn=store.getMatchingTiddlers||store.getTaggedTiddlers;
			var t=fn.apply(store,[tags]);
			var tagged=[];
			for (var i=0; i<t.length; i++) tagged.push(t[i].title);
		}
		// scan list and select tiddlers that match all applicable criteria
		var total=0;
		var count=0;
		for (var i=0; i<theList.options.length; i++) {
			// get item, skip non-tiddler list items (section headings)
			var opt=theList.options[i]; if (opt.value=="") continue;
			// get tiddler, skip missing tiddlers (this should NOT happen)
			var tiddler=store.getTiddler(opt.value); if (!tiddler) continue; 
			var sel=true;
			if ( (filterStart && tiddler.modified<startDate)
			|| (filterEnd && tiddler.modified>endDate)
			|| (filterTags && !tagged.contains(tiddler.title))
			|| (filterText && (tiddler.text.indexOf(text)==-1) && (tiddler.title.indexOf(text)==-1)))
				sel=false;
			opt.selected=sel;
			count+=sel?1:0;
			total++;
		}
		return count;
	},
	deleteTiddlers: function() {
		var list=$("exportList"); if (!list) return;
		var tids=[];
		for (i=0;i<list.length;i++)
			if (list.options[i].selected && list.options[i].value.length)
				tids.push(list.options[i].value);
		if (!confirm("Are you sure you want to delete these tiddlers:\n\n"+tids.join(', '))) return;
		store.suspendNotifications();
		for (t=0;t<tids.length;t++) {
			var tid=store.getTiddler(tids[t]); if (!tid) continue;
			var msg="'"+tid.title+"' is tagged with 'systemConfig'.\n\n";
			msg+="Removing this tiddler may cause unexpected results.  Are you sure?"
			if (tid.tags.contains("systemConfig") && !confirm(msg)) continue;
			store.removeTiddler(tid.title);
			story.closeTiddler(tid.title);
		}
		store.resumeNotifications();
		alert(tids.length+" tiddlers deleted");
		this.refreshList(0); // reload listbox
		store.notifyAll(); // update page display
	},
	go: function() {
		if (window.location.protocol!="file:") // make sure we are local
			{ displayMessage(config.messages.notFileUrlError); return; }
		// get selected tidders, target filename, target type, and notes
		var list=$("exportList"); if (!list) return;
		var tids=[]; for (var i=0; i<list.options.length; i++) {
			var opt=list.options[i]; if (!opt.selected||!opt.value.length) continue;
			var tid=store.getTiddler(opt.value); if (!tid) continue;
			tids.push(tid);
		}
		if (!tids.length) return; // no tiddlers selected
		var target = $("exportFilename").value.trim();
		if (!target.length) {
			displayMessage("A local target path/filename is required",target);
			return;
		}
		var filetype = $("exportFormat").value.toLowerCase();
		var notes=$("exportNotes").value.replace(/\n/g,"<br>");
		var total={val:0};
		var out=this.assembleFile(target,filetype,tids,notes,total);
		var link="file:///"+target.replace(/\\/g,'/');
		var ok=saveFile(target,out);
		displayMessage((ok?this.okmsg:this.failmsg).format([total.val,target]),link);
	},
	plainTextHeader:
		 '// Source'+':\n//\t%0\n'
		+'// Title:\n//\t%1\n'
		+'// Subtitle:\n//\t%2\n'
		+'// Created:\n//\t%3 by %4\n'
		+'// Application:\n//\tTiddlyWiki %5 / %6 %7\n',
	plainTextTiddler:
		'\n// ----- %0 (by %1 on %2) -----\n\n%3',
	plainTextFooter:
		'',
	newsFeedHeader:
		 '<'+'?xml version="1.0"?'+'>\n'
		+'<rss version="2.0">\n'
		+'<channel>\n'
		+'<title>%1</title>\n'
		+'<link>%0</link>\n'
		+'<description>%2</description>\n'
		+'<language>en-us</language>\n'
		+'<copyright>Copyright '+(new Date().getFullYear())+' %4</copyright>\n'
		+'<pubDate>%3</pubDate>\n'
		+'<lastBuildDate>%3</lastBuildDate>\n'
		+'<docs>http://blogs.law.harvard.edu/tech/rss</docs>\n'
		+'<generator>TiddlyWiki %5 / %6 %7</generator>\n',
	newsFeedTiddler:
		'\n%0\n',
	newsFeedFooter:
		'</channel></rss>',
	pureStoreHeader:
		 '<html><body>'
		+'<style type="text/css">'
		+'	#storeArea {display:block;margin:1em;}'
		+'	#storeArea div {padding:0.5em;margin:1em;border:2px solid black;height:10em;overflow:auto;}'
		+'	#pureStoreHeading {width:100%;text-align:left;background-color:#eeeeee;padding:1em;}'
		+'</style>'
		+'<div id="pureStoreHeading">'
		+'	TiddlyWiki "PureStore" export file<br>'
		+'	Source'+': <b>%0</b><br>'
		+'	Title: <b>%1</b><br>'
		+'	Subtitle: <b>%2</b><br>'
		+'	Created: <b>%3</b> by <b>%4</b><br>'
		+'	TiddlyWiki %5 / %6 %7<br>'
		+'	Notes:<hr><pre>%8</pre>'
		+'</div>'
		+'<div id="storeArea">',
	pureStoreTiddler:
		'%0\n%1',
	pureStoreFooter:
		'</div><!--POST-BODY-START-->\n<!--POST-BODY-END--></body></html>',
	assembleFile: function(target,filetype,tids,notes,total) {
		var revised="";
		var now = new Date().toLocaleString();
		var src=convertUnicodeToUTF8(document.location.href);
		var title = convertUnicodeToUTF8(wikifyPlain("SiteTitle").htmlEncode());
		var subtitle = convertUnicodeToUTF8(wikifyPlain("SiteSubtitle").htmlEncode());
		var user = convertUnicodeToUTF8(config.options.txtUserName.htmlEncode());
		var twver = version.major+"."+version.minor+"."+version.revision;
		var v=version.extensions.ExportTiddlersPlugin; var pver = v.major+"."+v.minor+"."+v.revision;
		var headerargs=[src,title,subtitle,now,user,twver,"ExportTiddlersPlugin",pver,notes];
		switch (filetype) {
			case this.type_TX: // plain text
				var header=this.plainTextHeader.format(headerargs);
				var footer=this.plainTextFooter;
				break;
			case this.type_NF: // news feed (XML)
				headerargs[0]=store.getTiddlerText("SiteUrl","");
				var header=this.newsFeedHeader.format(headerargs);
				var footer=this.newsFeedFooter;
				break;
			case this.type_PS: // PureStore (no code)
				var header=this.pureStoreHeader.format(headerargs);
				var footer=this.pureStoreFooter;
				break;
			case this.type_TW: // full TiddlyWiki
			default:
				var currPath=getLocalPath(window.location.href);
				var original=loadFile(currPath);
				if (!original) { displayMessage(config.messages.cantSaveError); return; }
				var posDiv = locateStoreArea(original);
				if (!posDiv) { displayMessage(config.messages.invalidFileError.format([currPath])); return; }
				var header = original.substr(0,posDiv[0]+startSaveArea.length)+"\n";
				var footer = "\n"+original.substr(posDiv[1]);
				break;
		}
		var out=this.getData(target,filetype,tids);
		var revised = header+convertUnicodeToUTF8(out.join("\n"))+footer;
		// if full TW, insert page title and language attr, and reset all MARKUP blocks...
		if (filetype==this.type_TW) {
			var newSiteTitle = convertUnicodeToUTF8(getPageTitle()).htmlEncode();
			revised = revised.replaceChunk("<title"+">","</title"+">"," " + newSiteTitle + " ");
			revised = updateLanguageAttribute(revised);
			revised = updateMarkupBlock(revised,"PRE-HEAD");
			revised = updateMarkupBlock(revised,"POST-HEAD");
			revised = updateMarkupBlock(revised,"PRE-BODY");
			revised = updateMarkupBlock(revised,"POST-SCRIPT");
		}
		total.val=out.length;
		return revised;
	},
	formatItem: function(s,f,t,u) {
		if (f==this.type_TW)
			var r=s.getSaver().externalizeTiddler(s,t);
		if (f==this.type_PS)
			var r=config.macros.exportTiddlers.pureStoreTiddler.format([t.title,s.getSaver().externalizeTiddler(s,t)]);
		if (f==this.type_NF)
			var r=this.newsFeedTiddler.format([t.saveToRss(u)]);
		if (f==this.type_TX)
			var r=this.plainTextTiddler.format([t.title,t.modifier,t.modified.toLocaleString(),t.text]);
		return r||"";
	},
	getData: function(target,filetype,tids) {
		// output selected tiddlers and gather list of titles (for use with merge)
		var out=[]; var titles=[];
		var url=store.getTiddlerText("SiteUrl","");
		for (var i=0; i<tids.length; i++) {
			out.push(this.formatItem(store,filetype,tids[i],url));
			titles.push(tids[i].title);
		}
		// if TW or PureStore format, ask to merge with existing tiddlers (if any)
		if (filetype==this.type_TW || filetype==this.type_PS) {
			var text=loadFile(target);
			if (text && text.length) {
				var remoteStore=new TiddlyWiki();
				if (remoteStore.importTiddlyWiki(text) && confirm(this.mergeprompt.format([target]))) {
					var existing=remoteStore.getTiddlers("title");
					for (var i=0; i<existing.length; i++)
						if (!titles.contains(existing[i].title))
							out.push(this.formatItem(remoteStore,filetype,existing[i],url));
					displayMessage(this.mergestatus.format([tids.length,out.length-tids.length]));
				}
			}
		}
		return out;
	}
}
//}}}
{{en{Describe the features of your project here}}}{{fr{Décrivez les fonctionnalités de votre projet ici}}}
//~~(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.
***/

/***
<<checkForDataTiddlerPlugin>>
|''Name:''|FormTiddlerPlugin|
|''Version:''|1.0.6 (2007-06-24)|
|''Source:''|http://tiddlywiki.abego-software.de/#FormTiddlerPlugin|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license]]|
|''Macros:''|formTiddler, checkForDataTiddlerPlugin, newTiddlerWithForm|
|''Requires:''|DataTiddlerPlugin|
|''TiddlyWiki:''|1.2.38+, 2.0|
|''Browser:''|Firefox 1.0.4+; InternetExplorer 6.0|
!Description
Use form-based tiddlers to enter your tiddler data using text fields, listboxes, checkboxes etc. (All standard HTML Form input elements supported).

''Syntax:'' 
|>|{{{<<}}}''formTiddler'' //tiddlerName//{{{>>}}}|
|//tiddlerName//|The name of the FormTemplate tiddler to be used to edit the data of the tiddler containing the macro.|

|>|{{{<<}}}''newTiddlerWithForm'' //formTemplateName// //buttonLabel// [//titleExpression// [''askUser'']] {{{>>}}}|
|//formTemplateName//|The name of the tiddler that defines the form the new tiddler should use.|
|//buttonLabel//|The label of the button|
|//titleExpression//|A (quoted) JavaScript String expression that defines the title (/name) of the new tiddler.|
|''askUser''|Typically the user is not asked for the title when a title is specified (and not yet used). When ''askUser'' is given the user will be asked in any case. This may be used when the calculated title is just a suggestion that must be confirmed by the user|
|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|

For details and how to use the macros see the [[introduction|FormTiddler Introduction]] and the [[examples|FormTiddler Examples]].

!Revision history
* v1.0.6 (2007-06-24)
** Fixed problem when using SELECT component in Internet Explorer (thanks to MaikBoenig for reporting)
* v1.0.5 (2006-02-24)
** Removed "debugger;" instruction
* v1.0.4 (2006-02-07)
** Bug: On IE no data is written to data section when field values changed (thanks to KenGirard for reporting)
* v1.0.3 (2006-02-05)
** Bug: {{{"No form template specified in <<formTiddler>>"}}} when using formTiddler macro on InternetExplorer (thanks to KenGirard for reporting)
* v1.0.2 (2006-01-06)
** Support TiddlyWiki 2.0
* v1.0.1 (2005-12-22)
** Features: 
*** Support InternetExplorer
*** Added newTiddlerWithForm Macro
* v1.0.0 (2005-12-14)
** initial version

!Code
***/
//{{{

//============================================================================
//============================================================================
//						FormTiddlerPlugin
//============================================================================
//============================================================================

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

abego.getOptionsValue = function(element,i) {
	var v = element.options[i].value;
	if (!v && element.options[i].text)
		v = element.options[i].text;
	return v;
};

version.extensions.FormTiddlerPlugin = {
	major: 1, minor: 0, revision: 5,
	date: new Date(2006, 2, 24), 
	type: 'plugin',
	source: "http://tiddlywiki.abego-software.de/#FormTiddlerPlugin"
};

// For backward compatibility with v1.2.x
//
if (!window.story) window.story=window; 
if (!TiddlyWiki.prototype.getTiddler) TiddlyWiki.prototype.getTiddler = function(title) { return t = this.tiddlers[title]; return (t != undefined && t instanceof Tiddler) ? t : null; } 

//============================================================================
// formTiddler Macro
//============================================================================

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

config.macros.formTiddler = {
	// Standard Properties
	label: "formTiddler",
	version: {major: 1, minor: 0, revision: 4, date: new Date(2006, 2, 7)},
	prompt: "Edit tiddler data using forms",

	// Define the "setters" that set the values of INPUT elements of a given type
	// (must match the corresponding "getter")
	setter: {  
		button:				function(e, value) {/*contains no data */ },
		checkbox:			function(e, value) {e.checked = value;},
		file:				function(e, value) {try {e.value = value;} catch(e) {/* ignore, possibly security error*/}},
		hidden:				function(e, value) {e.value = value;},
		password:			function(e, value) {e.value = value;},
		radio:				function(e, value) {e.checked = (e.value == value);},
		reset:				function(e, value) {/*contains no data */ },
		"select-one":		function(e, value) {config.macros.formTiddler.setSelectOneValue(e,value);},
		"select-multiple":	function(e, value) {config.macros.formTiddler.setSelectMultipleValue(e,value);},
		submit:				function(e, value) {/*contains no data */},
		text:				function(e, value) {e.value = value;},
		textarea:			function(e, value) {e.value = value;}
	},

	// Define the "getters" that return the value of INPUT elements of a given type
	// Return undefined to not store any data.
	getter: {  
		button:				function(e, value) {return undefined;},
		checkbox:			function(e, value) {return e.checked;},
		file:				function(e, value) {return e.value;},
		hidden:				function(e, value) {return e.value;},
		password:			function(e, value) {return e.value;},
		radio:				function(e, value) {return e.checked ? e.value : undefined;},
		reset:				function(e, value) {return undefined;},
		"select-one":		function(e, value) {return config.macros.formTiddler.getSelectOneValue(e);},
		"select-multiple":	function(e, value) {return config.macros.formTiddler.getSelectMultipleValue(e);},
		submit:				function(e, value) {return undefined;},
		text:				function(e, value) {return e.value;},
		textarea:			function(e, value) {return e.value;}
	}
};


// -------------------------------------------------------------------------------
// The formTiddler Macro Handler 
// -------------------------------------------------------------------------------

config.macros.formTiddler.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
	if (!config.macros.formTiddler.checkForExtensions(place, macroName)) {
		return;
	}
	// --- Parsing ------------------------------------------

	var i = 0; // index running over the params

	// get the name of the form template tiddler
	var formTemplateName = undefined;
	if (i < params.length) {
		formTemplateName = params[i];
		i++;
	}

	if (!formTemplateName) {
		config.macros.formTiddler.createErrorElement(place, "No form template specified in <<" + macroName + ">>.");
		return;
	}


	// --- Processing ------------------------------------------

	// Get the form template text. 
	// (This contains the INPUT elements for the form.)
	var formTemplateTiddler = store.getTiddler(formTemplateName);
	if (!formTemplateTiddler) {
		config.macros.formTiddler.createErrorElement(place, "Form template '" + formTemplateName + "' not found.");
		return;
	}
	var templateText = formTemplateTiddler.text;
	if(!templateText) {
		// Shortcut: when template text is empty we do nothing.
		return;
	}

	// Get the name of the tiddler containing this "formTiddler" macro
	// (i.e. the tiddler, that will be edited and that contains the data)
	var tiddlerName = config.macros.formTiddler.getContainingTiddlerName(place);

	// Append a "form" element. 
	var formName = "form"+formTemplateName+"__"+tiddlerName;
	var e = document.createElement("form");
	e.setAttribute("name", formName);
	place.appendChild(e);

	// "Embed" the elements defined by the templateText (i.e. the INPUT elements) 
	// into the "form" element we just created
	wikify(templateText, e);

	// Initialize the INPUT elements.
	config.macros.formTiddler.initValuesAndHandlersInFormElements(formName, DataTiddler.getDataObject(tiddlerName));
}


// -------------------------------------------------------------------------------
// Form Data Access 
// -------------------------------------------------------------------------------

// Internal.
//
// Initialize the INPUT elements of the form with the values of their "matching"
// data fields in the tiddler. Also setup the onChange handler to ensure that
// changes in the INPUT elements are stored in the tiddler's data.
//
config.macros.formTiddler.initValuesAndHandlersInFormElements = function(formName, data) {
	// config.macros.formTiddler.trace("initValuesAndHandlersInFormElements(formName="+formName+", data="+data+")");

	// find the form
	var form = config.macros.formTiddler.findForm(formName);
	if (!form) {
		return;
	}

	try {
		var elems = form.elements;
		for (var i = 0; i < elems.length; i++) {
			var c = elems[i];
		
			var setter = config.macros.formTiddler.setter[c.type];
			if (setter) {
				var value = data[c.name];
				if (value != null) {
					setter(c, value);
				}
				c.onchange = onFormTiddlerChange;
			} else {
				config.macros.formTiddler.displayFormTiddlerError("No setter defined for INPUT element of type '"+c.type+"'. (Element '"+c.name+"' in form '"+formName+"')");
			}
		}
	} catch(e) {
		config.macros.formTiddler.displayFormTiddlerError("Error when updating elements with new formData. "+e);
	}
}


// Internal.
//
// @return [may be null]
//
config.macros.formTiddler.findForm = function(formName) {
	// We must manually iterate through the document's forms, since
	// IE does not support the "document[formName]" approach

	var forms = window.document.forms;
	for (var i = 0; i < forms.length; i++) {
		var form = forms[i];
		if (form.name == formName) {
			return form;
		}
	}

	return null;
}


// Internal.
//
config.macros.formTiddler.setSelectOneValue = function(element,value) {
	var n = element.options.length;
	for (var i = 0; i < n; i++) {
		element.options[i].selected = abego.getOptionsValue(element,i) == value;
	}
}

// Internal.
//
config.macros.formTiddler.setSelectMultipleValue = function(element,value) {
	var values = {};
	for (var i = 0; i < value.length; i++) {
		values[value[i]] = true;
	}
	
	var n = element.length;
	for (var i = 0; i < n; i++) {
		element.options[i].selected = !(!values[abego.getOptionsValue(element,i)]);
	}
}

// Internal.
//
config.macros.formTiddler.getSelectOneValue = function(element) {
	var i = element.selectedIndex;
	return (i >= 0) ? abego.getOptionsValue(element,i) : null;
}

// Internal.
//
config.macros.formTiddler.getSelectMultipleValue = function(element) {
	var values = [];
	var n = element.length;
	for (var i = 0; i < n; i++) {
		if (element.options[i].selected) {
			values.push(abego.getOptionsValue(element,i));
		}
	}
	return values;
}



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

// Internal.
//
config.macros.formTiddler.checkForExtensions = function(place,macroName) {
	if (!version.extensions.DataTiddlerPlugin) {
		config.macros.formTiddler.createErrorElement(place, "<<" + macroName + ">> requires the DataTiddlerPlugin. (You can get it from http://tiddlywiki.abego-software.de/#DataTiddlerPlugin)");
		return false;
	}
	return true;
}

// Internal.
//
// Displays a trace message in the "TiddlyWiki" message pane.
// (used for debugging)
//
config.macros.formTiddler.trace = function(s) {
	displayMessage("Trace: "+s);
}

// Internal.
//
// Display some error message in the "TiddlyWiki" message pane.
//
config.macros.formTiddler.displayFormTiddlerError = function(s) {
	alert("FormTiddlerPlugin Error: "+s);
}

// Internal.
//
// Creates an element that holds an error message
// 
config.macros.formTiddler.createErrorElement = function(place, message) {
	return createTiddlyElement(place,"span",null,"formTiddlerError",message);
}

// Internal.
//
// Returns the name of the tiddler containing the given element.
// 
config.macros.formTiddler.getContainingTiddlerName = function(element) {
	return story.findContainingTiddler(element).id.substr(7);
}

// -------------------------------------------------------------------------------
// Event Handlers 
// -------------------------------------------------------------------------------

// This function must be called by the INPUT elements whenever their
// data changes. Typically this is done through an "onChange" handler.
//
function onFormTiddlerChange (e) {
	// config.macros.formTiddler.trace("onFormTiddlerChange "+e);

	if (!e) var e = window.event;

	var target = resolveTarget(e);
	var tiddlerName = config.macros.formTiddler.getContainingTiddlerName(target);
	var getter = config.macros.formTiddler.getter[target.type];
	if (getter) {
		var value = getter(target);
		DataTiddler.setData(tiddlerName, target.name, value);
	} else {
		config.macros.formTiddler.displayFormTiddlerError("No getter defined for INPUT element of type '"+target.type+"'. (Element '"+target.name+"' used in tiddler '"+tiddlerName+"')");
	}
}

// ensure that the function can be used in HTML event handler
window.onFormTiddlerChange = onFormTiddlerChange;


// -------------------------------------------------------------------------------
// Stylesheet Extensions (may be overridden by local StyleSheet)
// -------------------------------------------------------------------------------

setStylesheet(
	".formTiddlerError{color: #ffffff;background-color: #880000;}",
	"formTiddler");


//============================================================================
// checkForDataTiddlerPlugin Macro
//============================================================================

config.macros.checkForDataTiddlerPlugin = {
	// Standard Properties
	label: "checkForDataTiddlerPlugin",
	version: {major: 1, minor: 0, revision: 0, date: new Date(2005, 12, 14)},
	prompt: "Check if the DataTiddlerPlugin exists"
}

config.macros.checkForDataTiddlerPlugin.handler = function(place,macroName,params) {
	config.macros.formTiddler.checkForExtensions(place, config.macros.formTiddler.label);
}



//============================================================================
// newTiddlerWithForm Macro
//============================================================================

config.macros.newTiddlerWithForm = {
	// Standard Properties
	label: "newTiddlerWithForm",
	version: {major: 1, minor: 0, revision: 1, date: new Date(2006, 1, 6)},
	prompt: "Creates a new Tiddler with a <<formTiddler ...>> macro"
}

config.macros.newTiddlerWithForm.handler = function(place,macroName,params) {
	// --- Parsing ------------------------------------------

	var i = 0; // index running over the params

	// get the name of the form template tiddler
	var formTemplateName = undefined;
	if (i < params.length) {
		formTemplateName = params[i];
		i++;
	}

	if (!formTemplateName) {
		config.macros.formTiddler.createErrorElement(place, "No form template specified in <<" + macroName + ">>.");
		return;
	}

	// get the button label
	var buttonLabel = undefined;
	if (i < params.length) {
		buttonLabel = params[i];
		i++;
	}

	if (!buttonLabel) {
		config.macros.formTiddler.createErrorElement(place, "No button label specified in <<" + macroName + ">>.");
		return;
	}

	// get the (optional) tiddlerName script and "askUser"
	var tiddlerNameScript = undefined;
	var askUser = false;
	if (i < params.length) {
		tiddlerNameScript = params[i];
		i++;

		if (i < params.length && params[i] == "askUser") {
			askUser = true;
			i++;
		}
	}

	// --- Processing ------------------------------------------

	if(!readOnly) {
		var onClick = function() {
			var tiddlerName;
			if (tiddlerNameScript) {
				try {
					tiddlerName = eval(tiddlerNameScript);
				} catch (ex) {
				}
			}
			if (!tiddlerName || askUser) {
				tiddlerName = prompt("Please specify a tiddler name.", askUser ? tiddlerName : "");
			}
			while (tiddlerName && store.getTiddler(tiddlerName)) {
				tiddlerName = prompt("A tiddler named '"+tiddlerName+"' already exists.\n\n"+"Please specify a tiddler name.", tiddlerName);
			}

			// tiddlerName is either null (user canceled) or a name that is not yet in the store.
			if (tiddlerName) {
				var body = "<<formTiddler [["+formTemplateName+"]]>>";
				var tags = [];
				store.saveTiddler(tiddlerName,tiddlerName,body,config.options.txtUserName,new Date(),tags);
				story.displayTiddler(null,tiddlerName,1);
			}
		}

		createTiddlyButton(place,buttonLabel,buttonLabel,onClick);
    }
}

//}}}


/***
!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.
***/
{{en{Describe the goals of your project here}}}{{fr{Décrivez les buts de votre projet ici}}}
!Principles
* ''1'' file TiddlyWiki for ''1'' Scrum projet
* Plugins tries not to interfere, which means that you can work without at any time
* This TiddlyWiki contains all you should need to
** Manage UserStory and ProductBacklog or Sprint backlog
** Manage tasks, input and display BurndownChart
** Collaborate with multiple users
!Installed plugins
* SortListPlugin that allows to reorder the lines of a Tiddler easily
* [[Populate/UpdateListPlugin]] to populate or update a list of tiddlers (for example a list of tasks)
* SliceGridPlugin used to input everyday the "still to do" for each tasks 
* HistoGramMacro to display an histogram based upon what is typed in the slicegrid
* UploadPlugin et UploadTiddlerPlugin used to collaborate with multiple users
* ForEachTiddlerPlugin use like a SQL-Like mini language to display lists of tiddlers
! What is a TiddlyWiki (Beginners)
* one ''tiddler'' is a page of this wiki, it contains text in the wiki format, or javascript if it's a plugin.
* the tiddlers can be tagged with keywords (which can be also tiddlers themself). This allows creation of 0-n relations between tiddlers. For example, one UserSotry can be attached to a spint, just by adding the name of the sprint in its tags.
* In this tool, technically, a backlog is just a orderred list of tiddlers. This is also a 0-n relationship, but this one is ''ordered''.
* the tiddlers can contain some text that can be used as values (lists of terms). They are sometimes used to parameter some behaviour like SprintDays which contains a list of days for a sprint.
* the tiddlers can also contains some other values (stored in different maners)
** ''fields'' are invisible named values (you have to click on more/fields in the toolbar to display them) associated with the tiddler
** ''slices'' are also named values, but stored inside the text of the tiddler with the table notation |slice_name|slice_value|. They are used for example to store the daily "left to do" time for the tasks
!Scrum (Beginners)
* ProductBacklog : the global ordered list of UserStory
* Features : high level features of the application
* UserStory : user level feature that can be implemented during a sprint, it is decomposed in small tasks (a few days max) and evaluted in points (describing its relative complexity)
* Sprint : a time boxed period while a list of UserStory are realised
* Task : a minimal unit of "making" or realisation, it's estimated in hour and should not be more than 2 days, and it's meant to be done during a sprint
* BurndownChart which allows to follow the progression of your team and the respect of delays
!Manage your project
* Start by defining the [[Parameters]]
* Launch the [[Sprint 0]] which should contains all that is needed before starting to code. That means, during this sprint you should create the original backlog and make the first task list
* One your [[ProductBacklog]] is created you can start a new Sprint. Clik on <new Sprint> on the roght menu, or more basically you can create a new tiddler and tag it as a "sprint". By adding the sprint tag you automatically add a sortable list (of tasks) and a BurndownChart visible when the tiddler is not in edit mode. A sprint is a list of UserStory that will be implemented during the period of time allocated to the sprint. 
* UserStory can be created by various means
** Either you click on "Add UserStory" button at the end of the ProductBacklog which will create an empty UserStory
** Either with the "New UserStory" button on the right
** Either you create a tiddler and tag it as a userStory
** Either you write the list of your UserStory like a normal text (one UserStory by line) in a tiddler. Tag this tiddler with backlog, the use the "update" bouton, which will transform your text into tiddlers (adding double [ [ where it needs). Then you just have to click on the link to create new tiddlers, you have to add UserStory in the tags
* The same principles can be used to create tasks
* Don't forget to make the DailyScrum and to fill the corresponding "Todo" for the current sprint. Or Take a look in the TaskBoard. 
!Collaborate
Several users can work on the same file without having to update it by email or share it in a comme network directory. To achieve this you have to configure a php webserver.
#Create a file [[store.php]] on the server and edit inside the list of authorized users
#If the TiddlyWiki is in readonly mode, you shoud check  <<option chkHttpReadOnly>> chkHttpReadOnly
# the go in the backstage / Upload and change the  connection options : HomeParameters and/or UploadOptions
# If you want to go further you can use the direct update feature (instead of saving the file some times, each modified tiddler is saved on the fly) : you must configure  UploadTiddler :  <<option chkUploadTiddler>> chkUploadTiddler.
# You can have problems if you have many projects to handle in the same navigator. You must understand that the connections parameters are stored in cookies. To handle multiple projects, this unique cookie is not suited. So you have to bypass cookies by using [[zCookieJar]] to overide the values. [[zCookieJar]] is only active when it's tagged systemConfig. 
!Troobleshooting
* Take a look at the known [[Bugs]] 
* Contact the project master : mailto:Y.%20BABEL<ybabel@ideia.fr>?subject=TiddlyWikiScrum
* Ask for some help for TiddlyWiki : http://groups.google.com/group/TiddlyWiki
!!Data Model
* ProductBacklog is a sorted list of all the UserStory
* One UserStory is made of a list of task
* One sprint is a sorted sub set of UserStory and their tasks
/***
|Name:|HideWhenPlugin|
|Description:|Allows conditional inclusion/exclusion in templates|
|Version:|3.1 ($Rev: 3919 $)|
|Date:|$Date: 2009/12/18 16:36:41 $|
|Source:|http://mptw.tiddlyspot.com/#HideWhenPlugin|
|Author:|Simon Baird <simon.baird@gmail.com>|
|License:|http://mptw.tiddlyspot.com/#TheBSDLicense|
For use in ViewTemplate and EditTemplate. Example usage:
{{{<div macro="showWhenTagged Task">[[TaskToolbar]]</div>}}}
{{{<div macro="showWhen tiddler.modifier == 'BartSimpson'"><img src="bart.gif"/></div>}}}
***/
//{{{

window.hideWhenLastTest = false;

window.removeElementWhen = function(test,place) {
	window.hideWhenLastTest = test;
	if (test) {
		removeChildren(place);
		place.parentNode.removeChild(place);
	}
};


merge(config.macros,{

	hideWhen: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( eval(paramString), place);
	}},

	showWhen: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( !eval(paramString), place);
	}},

	hideWhenTagged: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( tiddler.tags.containsAll(params), place);
	}},

	showWhenTagged: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( !tiddler.tags.containsAll(params), place);
	}},

	hideWhenTaggedAny: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( tiddler.tags.containsAny(params), place);
	}},

	showWhenTaggedAny: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( !tiddler.tags.containsAny(params), place);
	}},

	hideWhenTaggedAll: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( tiddler.tags.containsAll(params), place);
	}},

	showWhenTaggedAll: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( !tiddler.tags.containsAll(params), place);
	}},

	hideWhenExists: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( store.tiddlerExists(params[0]) || store.isShadowTiddler(params[0]), place);
	}},

	showWhenExists: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( !(store.tiddlerExists(params[0]) || store.isShadowTiddler(params[0])), place);
	}},

	hideWhenTitleIs: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( tiddler.title == params[0], place);
	}},

	showWhenTitleIs: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( tiddler.title != params[0], place);
	}},

	'else': { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( !window.hideWhenLastTest, place);
	}}

});

//}}}

/***
|Name|HistoGramMacro|
|Source||
|Documentation||
|Version|1.0.3|
|Author|Eric Shulman - ELS Design Studios & Jean-Cédric THÉROND - www.IDEIA.fr|
|License|[[BSDLicence]]|
|~CoreVersion|2.1.0|
|Type|plugin|
|Requires||
|Overrides||
|Description|Generate an histogram from datas in tiddlers|
It's a new usage of the SliceGridPlugin core and my new Sparkline to generate histogram.
It make the sum of each value in each columns of a slicegrid and make an histogram with.
!!!!!Documentation
//{{{
<<histoGram tags:task width:200 slices:+SprintDays>>
<<sliceGrid edit inline tags:={{tiddler.title}} slices:+SprintDays>>
<<histoGram tags:={{tiddler.title}} width:200 slices:+SprintDays>>

//}}}
!!!!!Revisions
<<<
2008.09.11 [1.0] Modifications by J.-C. T.
2008.08.15 [1.0.3] add brackets around row headings when wikifying so that non-wikiword tiddler titles are linked
2008.08.13 [1.0.2] wikify row headings (in addition to slice value cells) whenever 'wikify' param is used
|please see [[SliceGridPluginInfo]] for additional revision details|
2007.01.30 [0.0.1] started
<<<
!!!!!Code
***/
//{{{
version.extensions.histoGram= {major: 1, minor: 0, revision: 0, date: new Date(2008,9,11)};

config.macros.histoGram= {
	sizeSliceName: "TiddlerSize", // shadow slice used for retrieving and showing tiddler size as a grid column
	noSlicesMsg: "\n|~SliceGrid: there are no slices to display|\n",
	handler:
	function(place,macroName,params) {
		this.slicesRE=/(?:^\|\s*[\'\/]*~?(\w+)\:?[\'\/]*\s*\|\s*(.*?)\s*\|$)/gm;
		this.wikify=false; // wiki-syntax in slices
		this.edit=false; // 'click-to-edit' feature
		this.verbose=false; // debugging/performance feedback messages
		this.alltiddlers=false; // rows for all tiddlers (even if no slices)
		this.inline=false; // slice value in cell (instead of mouseover)
		this.headers=false; // column headers
		this.cliplength=0; // limit inline display text length (0=no limit)
		this.slices=[]; // slices to show (columns)
		var tablewidth="100";
		var tableheight="100";
		var p=params.shift();


		var rowSum =[];


		while (p) {
			if (p.substr(0,6).toUpperCase()=="WIDTH:")
				tablewidth=p.substr(6);
			else if (p.substr(0,7).toUpperCase()=="HEIGHT:")
				tableheight=p.substr(7);
			else if (p.substr(0,5).toUpperCase()=="TAGS:") {
				if (p.substr(5,1)=="@") { // get tags from tiddler
					var tid=store.getTiddler(p.substr(6));
					if (p.substr(6)=="here") {
						var here=story.findContainingTiddler(place);
						if (here) var tid=store.getTiddler(here.getAttribute("tiddler"));
					}
					if (tid) var tags=tid.tags;
				}
				else if (p.substr(5,1)=="+") { // get tags from tiddler contents
					var tid=store.getTiddler(p.substr(6));
					if (p.substr(6)=="here") {
						var here=story.findContainingTiddler(place);
						if (here) var tid=store.getTiddler(here.getAttribute("tiddler"));
					}
					if (tid)
						{ var tags=tid.text.readBracketedList(); }
				}
                                else if (p.substr(5,1)=="=") { // get tags from value
                                       var tags=p.substr(6).readMacroParams();
                                }
				else var tags=p.substr(5).readBracketedList();
			}
			else if (p.substr(0,7).toUpperCase()=="SLICES:") {
				if (p.substr(7,1)=="@") { // get slices from tiddler
					var tid=p.substr(8);
					var tiddler=store.getTiddler(tid);
					if (tid=="here") {
						var here=story.findContainingTiddler(place);
						if (here) var tiddler=store.getTiddler(here.getAttribute("tiddler"));
					}
					if (tiddler) {
						var slices=tiddler.getSlices(tiddler.title); for (var s in slices) this.slices.push(s);
					}
				}
				else if (p.substr(7,1)=="+") { // get slices from tiddler contents
					var tid=p.substr(8);
					var tiddler=store.getTiddler(tid);
					if (tid=="here") {
						var here=story.findContainingTiddler(place);
						if (here) var tiddler=store.getTiddler(here.getAttribute("tiddler"));
					}
					if (tiddler)
						{ this.slices=tiddler.text.readBracketedList(); }
				}
				else this.slices=p.substr(7).readBracketedList();
			}
			else {
				if (!isNaN(p.toUpperCase())) { this.cliplength=p; break; }
				else displayMessage("unrecognized parameter: "+p);
			}
			p=params.shift();
		}
		// get rows and columns
		var rows=[]; var cols=[]; var total=0;
		var tiddlers=store.getTiddlers("title","excludeLists"); // get all tiddlers (except hidden ones)
		if (tags && tags.length) for (t=0;t<tiddlers.length;t++) // filter out tiddlers with no matching tags
			if (!tiddlers[t].tags.containsAll(tags)) { tiddlers.splice(t,1); t--; } // remove non-matching tiddler -- YBA 22.09.08 patch to have an AND operation
		for (i=0; i<tiddlers.length; i++) {
			var slices=this.getSlices(tiddlers[i].title);
			var count=0; for (var s in slices) { cols.pushUnique(s); count++; total++;}
			if (count || this.alltiddlers) rows.push(tiddlers[i].title); // only show rows for tiddlers with slices
		}
		if (!cols.length) { wikify(this.noSlicesMsg,place); return; }
		if (this.verbose) displayMessage("Found %0 slices using %1 slice names in %2 tiddlers".format([total, cols.length,rows.length]));

		// get optional list of slices to show
		if (this.slices.length) var cols=this.slices;

		// generate HTML table



for (var i=0;i<cols.length;i++){
var sumTemp = 0;

	for (var j=0;j<rows.length;j++) {
		sumTemp += parseInt( (isNaN(this.getSlices(rows[j])[cols[i]])) ? 0 : this.getSlices(rows[j])[cols[i]] );
	}

	rowSum[i] = sumTemp; 
}



	var rowSumlength = rowSum.length;
	var highest = [];
	var boxWidth = tablewidth;
	var boxHeight = tableheight;
	var tickWidth = 0;
	var tickBorderWidth = 0;
	var v;

	if(rowSumlength < 1){
		return;
	}else{
		for (var i = 0, item; item = rowSum[i]; i++ ){
			highest[i] = item;
		}
		highest.sort(config.macros.histoGram.byNum);
	}
	if (highest[0] > 0){
	tickWidth = parseInt(boxWidth/rowSumlength);
	var box = createTiddlyElement(place,"span",null,"sparkline",'');
	box.title = rowSum.join(",");
	box.style.display = 'block';
	box.style.width = rowSumlength * tickWidth+"px";
	box.style.height = boxHeight+"px";
	box.style.position = "relative";

	for( var i = 0 ; i < rowSumlength ; i++ ) {
		var tick = document.createElement("img");
		tick.style.border = tickBorderWidth;
		tick.className = "sparktick";
		tick.src = "data:image/gif,GIF89a%01%00%01%00%91%FF%00%FF%FF%FF%00%00%00%C0%C0%C0%00%00%00!%F9%04%01%00%00%02%00%2C%00%00%00%00%01%00%01%00%40%02%02T%01%00%3B";

		tick.style.width = tickWidth+'px';
		tick.style.height = (isNaN((rowSum[i]/highest[0])*boxHeight)?boxHeight:parseInt((rowSum[i]/highest[0])*boxHeight)) +"px";
		tick.style.float = 'left';
		box.appendChild(tick);
	}
	}else{
		displayMessage("no data");
	}

	},
	toggleAllColumns:
	function(here,event,defOpen) {
		if (here.expanded==undefined) here.expanded=defOpen;
		var ex=here.expanded=!here.expanded; 
		here.innerHTML=ex?"&lt;&lt;&lt;":"&gt;&gt;&gt;";
		here.title=ex?'hide all column headings':'show all column headings';
		var cells=here.parentNode.parentNode.getElementsByTagName("td");
		for (i=1; i<cells.length; i++) cells[i].firstChild.style.display=ex?"inline":"none";
		event.cancelBubble = true;
		if (event.stopPropagation) event.stopPropagation();
		return(false);
	},
	toggleColumn:
	function(here,event) {
		here.firstChild.style.display=(here.firstChild.style.display=="none")?"inline":"none";
		event.cancelBubble = true;
		if (event.stopPropagation) event.stopPropagation();
		return(false);
	},
	editSlice:
	function(here,event,tid,slice,inline) {
		// replace prompt box with edit field that is displayed until onBlur
		if (here.editing) return false; // already editing... don't re-init

		var onkeyup='if (event.keyCode==13)'; // SAVE and END
		onkeyup+='	{ config.macros.sliceGrid.setSlice(this.getAttribute(\"tid\"),"'+slice+'",this.value); this.blur(); }';
		onkeyup+='else if (event.keyCode==27)'; // END without saving
		onkeyup+='	{ this.blur(); }';

		var onblur="var tid=this.getAttribute(\"tid\"); var slice=\""+slice+"\"; var currval=config.macros.sliceGrid.getSlice(tid,slice); ";
		onblur+="if (this.value!=currval && confirm(tid+\"::\"+slice+\" has changed... save value?\"))";
		onblur+="	{ config.macros.sliceGrid.setSlice(tid,slice,this.value); currval=this.value; }";
		onblur+="var target=this.parentNode;";
		onblur+="target.editing=false;";
		onblur+="target.style.backgroundColor=target.getAttribute(\"savedColor\");";
		onblur+="target.style.padding=target.getAttribute(\"savedPadding\");";
		onblur+="target.style.width=target.getAttribute(\"savedWidth\");";
		onblur+="if (config.macros.sliceGrid.wikify) { removeChildren(target); wikify(currval,target); }";
		onblur+="else target.innerHTML="+(inline?'currval':'\"&nbsp;\"')+";";

		var style="font-size:1em;font-family:inherit;width:95%;margin:0px;padding:1px 0px 1px 3px;border:0;";
		var title=tid+"::"+slice+" (ENTER=submit, ESC=cancel)";

		here.setAttribute("savedWidth",here.style.width); if (!inline) here.style.width="99%";
		here.setAttribute("savedPadding",here.style.padding); here.style.padding="0px"; 
		here.setAttribute("savedColor",here.style.backgroundColor); here.style.backgroundColor="#fff";
		here.innerHTML="<input type='text' tid=\""+tid.replace(/"/g,"&#x22;")+"\" onkeyup='"+onkeyup+"' onblur='"+onblur+"' style='"+style+"' title='"+title+"'>";
		here.firstChild.value=config.macros.sliceGrid.getSlice(tid,slice); // avoids conflicts with nested quoting in HTML
		here.firstChild.focus();
		here.firstChild.select();
		here.editing=true;

		event.cancelBubble = true; if (event.stopPropagation) event.stopPropagation(); return(false);
	},
	getSlice:
	function(tid,slice) {
		var slices=config.macros.sliceGrid.getSlices(tid);
		return slices[slice]?slices[slice]:"";
	},
	getSlices:
	function(tid) {
		var slices = {};
		var text = store.getTiddlerText(tid,"");
		slices[this.sizeSliceName]=text.length.toString();  // 'shadow slice' for displaying tiddler size
		this.slicesRE.lastIndex = 0;
		do {
			var m = this.slicesRE.exec(text);
			if (m) { if (m[1]) slices[m[1]] = m[2]; else slices[m[3]] = m[4]; }
		} while(m);
		return slices;
	},
	setSlice:
	function(tid,slice,val) {
		var oldval=this.getSlice(tid,slice);
		if (val==oldval) return false; // value is unchanged... do nothing
		// find slice within tiddler text
		var tiddler=store.getTiddler(tid);
		this.slicesRE.lastIndex = 0;
		var lastIndex=0;
		do {
			var m=this.slicesRE.exec(tiddler.text);
			if (m && (m[1]==slice||m[3]==slice)) break;
			if (m) lastIndex=this.slicesRE.lastIndex;
		} while(m);
		if (m) { // if matching slice was found
			if (oldval.length) { // replace old value with new value
				var pos=RegExp.lastMatch.indexOf(oldval);
				var newSlice=RegExp.lastMatch.substr(0,pos)+val+RegExp.lastMatch.substr(pos+oldval.length);
			} else // insert new value into empty slice
				var newSlice=RegExp.lastMatch.substr(0,RegExp.lastMatch.length-1)+val+"|";
			var newText=RegExp.leftContext+newSlice+RegExp.rightContext;
		} else { // create new slice following last slice (or at start of tiddler if no slices)
			var newSlice="|"+slice+"|"+val+"|\n";
			var newText=newSlice+tiddler.text
			if (lastIndex) var newText=tiddler.text.substr(0,lastIndex+1)+newSlice+tiddler.text.substr(lastIndex+1);
		}
		// write tiddler contents
		var user=config.options.txtUserName; var mod=new Date();
		if (config.options.chkForceMinorUpdate)
			{ var user=tiddler.modifier; var mod=tiddler.modified; }
		store.saveTiddler(tid,tid,newText,user,mod,tiddler.tags,tiddler.fields);
		displayMessage(tid+"::"+slice+" has been "+(m?"updated":"created"));
		return(false);
	}
};

config.macros.histoGram.byNum = function(a,b)
{
return parseInt(b)-parseInt(a); 
}
//}}}
{{fr{! Comment créer un burdown
Du point de vue technique, les brudown sont générés a l'aide de tableaux de valeurs qui sont la somme des reste a faire (RAF) pour les tâches d'un sprint donné. Les RAF sont stockés dans des "slices" (tableaux de valeurs) a l'intérieur des tâches.
Afin d'éditer ces valeurs d'une manières conviviale un composant (SliceGrid) est utilisé comme une sorte de mini-tableur Calc. 
Les slices des tâches du sprint en cours sont dans des tiddlers taggés par "task" et "sprint ???". Les tâches sont aussi taggées par la UserStory qui les a générées, de sorte a pouvoir les trier pour plus de clarté de saisie.
Ensuite un autre composant (HistoGram) est utiliser pour générer le graphe a partir des slices.

! Comment gérer un backlog
Un backlog est une liste ordonnée de UserStory. Du point de vue technique il existe plusieurs possibilités pour créer une liste ordonnée. Par exemple, il serait possible de tagger les UserStory par le nom du backlog pour avoir la liste, et de leur associer un poids (stocké dans les fields) qui permettrai de déterminer leur ordre. Un autre choix a été fait, par soucis de simplicité pour l'utilisateur. Un backlog est simplement une liste de UserStory sous forme de texte, comme on l'aurait écrit à la main dans un tiddler. L'ordre est simplement l'ordre des lignes. Une petite interface graphique qui permet de réordonner le backlog peut-être rajoutée si on taggue le tiddler "backlog".
}}}{{en{
! How to create a burndown
From the technical point of view burndown are generated from arrays of values which are the sum of the "still to do"(STD) of the tasks of a given sprint. The STD are stored inside slices (tiddlywiki values extracted from arrays) inside the task itself.
In order to edit theses values in a simple way the SliceGrid is used as a mini Spreadsheet like Calc of OpenOffice.org.
The slices of the tasks of the current sprint are stored in tiddlers tagged "taks" and "sprint ???". Theses tasks are also taggéd by the UserStory that owns them, so that they are sorted in the display in a convenient way.
Then the HistoGram Plugin use these values and sum them to generate a graph : the BurndowChart.

! How to manage a backlog
A backlog is a sorted list of UserStory. From the technical point of view many ways exists to create an ordered list. For exemple, one way could be to tag all the UserStory with the name of the backlog to have a list, and then give them a weight (stored inside fields) to determine the order.
Another technical choice have been done for simplicity. The list of UserSotry is just a text list, one UserStory by line, the order of the UserStory is just the order their appear in the lines. A small interface have been added to help sorting the lines when a tiddler is tagged "backlog".
}}}

!Hints&Tips
!!{{fr{Pour générer du CSV}}}{{en{To generate CSV}}}
//{{{
<<tiddlerList tags:task format:"csv" header:"[ " footer:" ]">>
//}}}
<<<
<<tiddlerList tags:task format:"csv" header:"[ " footer:" ]">>
<<<
!!{{fr{Calculer la somme du reste a faire}}}{{en{Calculate the sum of the "still to do"}}}
//{{{
<<forEachTiddler
where 'tiddler.tags.contains("task")'
write
'"|"+store.getTiddlerSlice(tiddler.title,"j0")
+"|"+store.getTiddlerSlice(tiddler.title,"j1")
+"|"+store.getTiddlerSlice(tiddler.title,"j2")
+"|"+store.getTiddlerSlice(tiddler.title,"j3")+"|\n"'
begin '"|!j0|!j1|!j2|!j3|\n"' 
end '"|<<columncalc sum 1 -1\>\>|<<columncalc sum 1 -1\>\>|<<columncalc sum 1 -1\>\>|<<columncalc sum 1 -1\>\>|\n"'
>> 
//}}}
<<<
<<forEachTiddler
where 'tiddler.tags.contains("task")'
write
'"|"+store.getTiddlerSlice(tiddler.title,"j0")
+"|"+store.getTiddlerSlice(tiddler.title,"j1")
+"|"+store.getTiddlerSlice(tiddler.title,"j2")
+"|"+store.getTiddlerSlice(tiddler.title,"j3")+"|\n"'
begin '"|!j0|!j1|!j2|!j3|\n"' 
end '"|! <<columncalc sum 1 -1\>\>|! <<columncalc sum 1 -1\>\>|! <<columncalc sum 1 -1\>\>|! <<columncalc sum 1 -1\>\>|\n"'
>> 
<<<

/***
|Name|InlineJavascriptPlugin|
|Source|http://www.TiddlyTools.com/#InlineJavascriptPlugin|
|Documentation|http://www.TiddlyTools.com/#InlineJavascriptPluginInfo|
|Version|1.9.3|
|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|Insert Javascript executable code directly into your tiddler content.|
''Call directly into TW core utility routines, define new functions, calculate values, add dynamically-generated TiddlyWiki-formatted output'' into tiddler content, or perform any other programmatic actions each time the tiddler is rendered.
!!!!!Documentation
>see [[InlineJavascriptPluginInfo]]
!!!!!Revisions
<<<
2008.06.11 [1.9.3] added $(...) function as 'shorthand' convenience syntax for document.getElementById()
2008.03.03 [1.9.2] corrected declaration of wikifyPlainText() for 'TW 2.1.x compatibility fallback' (fixes Safari "parse error")
2008.02.23 [1.9.1] in onclick function, use string instead of array for 'bufferedHTML' attribute on link element (fixes IE errors)
2008.02.21 [1.9.0] 'onclick' scripts now allow returned text (or document.write() calls) to be wikified into a span that immediately follows the onclick link.  Also, added default 'return false' handling if no return value provided (prevents HREF from being triggered -- return TRUE to allow HREF to be processed).  Thanks to Xavier Verges for suggestion and preliminary code.
|please see [[InlineJavascriptPluginInfo]] for additional revision details|
2005.11.08 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.inlineJavascript= {major: 1, minor: 9, revision: 3, date: new Date(2008,6,11)};

config.formatters.push( {
	name: "inlineJavascript",
	match: "\\<script",
	lookahead: "\\<script(?: src=\\\"((?:.|\\n)*?)\\\")?(?: label=\\\"((?:.|\\n)*?)\\\")?(?: title=\\\"((?:.|\\n)*?)\\\")?(?: key=\\\"((?:.|\\n)*?)\\\")?( show)?\\>((?:.|\\n)*?)\\</script\\>",

	handler: function(w) {
		var lookaheadRegExp = new RegExp(this.lookahead,"mg");
		lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = lookaheadRegExp.exec(w.source)
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
			var src=lookaheadMatch[1];
			var label=lookaheadMatch[2];
			var tip=lookaheadMatch[3];
			var key=lookaheadMatch[4];
			var show=lookaheadMatch[5];
			var code=lookaheadMatch[6];
			if (src) { // load a script library
				// make script tag, set src, add to body to execute, then remove for cleanup
				var script = document.createElement("script"); script.src = src;
				document.body.appendChild(script); document.body.removeChild(script);
			}
			if (code) { // there is script code
				if (show) // show inline script code in tiddler output
					wikify("{{{\n"+lookaheadMatch[0]+"\n}}}\n",w.output);
				if (label) { // create a link to an 'onclick' script
					// add a link, define click handler, save code in link (pass 'place'), set link attributes
					var link=createTiddlyElement(w.output,"a",null,"tiddlyLinkExisting",wikifyPlainText(label));
					var fixup=code.replace(/document.write\s*\(/gi,'place.bufferedHTML+=(');
					link.code="function _out(place){"+fixup+"\n};_out(this);"
					link.tiddler=w.tiddler;
					link.onclick=function(){
						this.bufferedHTML="";
						try{ var r=eval(this.code);
							if(this.bufferedHTML.length || (typeof(r)==="string")&&r.length)
								var s=this.parentNode.insertBefore(document.createElement("span"),this.nextSibling);
							if(this.bufferedHTML.length)
								s.innerHTML=this.bufferedHTML;
							if((typeof(r)==="string")&&r.length) {
								wikify(r,s,null,this.tiddler);
								return false;
							} else return r!==undefined?r:false;
						} catch(e){alert(e.description||e.toString());return false;}
					};
					link.setAttribute("title",tip||"");
					var URIcode='javascript:void(eval(decodeURIComponent(%22(function(){try{';
					URIcode+=encodeURIComponent(encodeURIComponent(code.replace(/\n/g,' ')));
					URIcode+='}catch(e){alert(e.description||e.toString())}})()%22)))';
					link.setAttribute("href",URIcode);
					link.style.cursor="pointer";
					if (key) link.accessKey=key.substr(0,1); // single character only
				}
				else { // run inline script code
					var fixup=code.replace(/document.write\s*\(/gi,'place.innerHTML+=(');
					var code="function _out(place){"+fixup+"\n};_out(w.output);"
					try { var out=eval(code); } catch(e) { out=e.description?e.description:e.toString(); }
					if (out && out.length) wikify(out,w.output,w.highlightRegExp,w.tiddler);
				}
			}
			w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
		}
	}
} )
//}}}

// // Backward-compatibility for TW2.1.x and earlier
//{{{
if (typeof(wikifyPlainText)=="undefined") window.wikifyPlainText=function(text,limit,tiddler) {
	if(limit > 0) text = text.substr(0,limit);
	var wikifier = new Wikifier(text,formatter,null,tiddler);
	return wikifier.wikifyPlain();
}
//}}}

// // $(...) function: 'shorthand' convenience syntax for document.getElementById()
//{{{
if (typeof($)=="undefined") { // avoid redefinition
function $() {
	var elements=new Array();
	for (var i=0; i<arguments.length; i++) {
		var element=arguments[i];
		if (typeof element=='string') element=document.getElementById(element);
		if (arguments.length==1) return element;
		elements.push(element);
	}
	return elements;
}
}
//}}}
{{fr{
Ce TiddlyWiki est prêt pour vous guider dans votre projet SCRUM.
Il est convenu qu'un fichier TiddlyWiki correspond a un projet Scrum.
Les plugins pré-installé permettent de 
* gérer des backlogs (listes de UserStory triées par priorités)
* saisir et générer des BurndownChart
* collaborer a plusieurs sur un même projet
Cependant en plus de ces outils spécifiques il est possible de gérer :
* Des UserStory qui contiennent des tâches
* des sprints qui sont une selection de UserStory découpées en tâches

Pour en savoir plus sur Scrum :
* [[Concepts scrum]]
* Scrum en [[Dix étapes]]
}}}
{{en{
This TiddlyWiki is ready to help you in your SCRUM projects.
By convention, ''one'' TiddlyWiki file is used for ''one'' Scrum project.
The pre-installed plugins let you 
* handle backlogs (UserStory lists ordered by priority)
* collect and display BurndownChart
* collaborate with other users on the same project via a webserver
Moreover TiddlyWiki power let you
* define UserStory as list of tasks
* Sprints are a selection of UserStory (see excludeSprint to restrict this list)
}}}
GettingStarted
[[Start]]
[[Configuration]]
{{en{[[Help]]}}}{{fr{[[Aide]]}}}
HowTo
[[Versionning]]
[[BSDLicence]]
[[Download|http://ecm.ideia.fr/download.php?file=files/agilia.html]]
----
[[TaskBoard]]
BurndownChart
<<polyglot>>
/***
| Name:|''monkeyTagger''|
| Created by:|SaqImtiaz|
| Location:|http://tw.lewcid.org/|
| Version:|0.9 (08-Apr-2006)|
| Requires:|~TW2.07|

!About:
*an adaptation of TagAdderMacro for monkeyGTD and tagglytagging user, but could be useful to just about anyone!
*{{{<<monkeyTagger Project>>}}} gives a drop down list of all tags, tagged with Project.
*The list allows toggling of tags on the current tiddler.
*logging options for task management.

!Demo:
<<monkeyTagger Status>>

!Installation:
*Copy this tiddler to your TW with the systemConfig tag
*either copy the following to your ViewTemplate:
{{{<div class='tagged' macro='monkeyTagger tagToTrack'></div>}}}
or
*better yet, define your own toolbar class and add as many as you need to create a nice toolbar.
Eg:
{{{<div class='toolbar' >
<span style="padding-right:0.15em;" macro='monkeyTagger Project'></span>
<span style="padding-right:0.15em;" macro='monkeyTagger Status'></span>
<span macro='toolbar -closeTiddler closeOthers +editTiddler permalink references jump'></span>
</div>}}}
 (adjust padding to taste)

!Usage:

''Syntax:''
|>|{{{<<monkeyTagger source:"sourcetag" label:"customlabel" logging:"true/false" anchor:"anchortext"  arrow:"true/false">>}}}|
|label:|quoted text to use as a customlabel|
|arrow:|add arrow to custom label, values are "true" or "false"|
|anchor:|quoted text to specify where to add logging text|
|logging:|enable logging of tags added (for task management), values are "true" or "false"|

the only parameter you ''have'' to pass is the source. When passing only one parameter, you can write either something like:
{{{<<monkeyTagger "Project">>}}} or {{{<<monkeyTagger source:"Project">>}}} for <<monkeyTagger Project>>
All other parameters are optional, and can be written in any order.

''Defaults:''
|label:|default label if not specified = source tag + arrow|
|arrow:|true |
|logging:|false |
|anchor:|none used by default, logging text added to end of tiddler |

''Examples:''
|custom label| {{{<<monkeyTagger source:"Project" label:"customlabel">>}}} |<<monkeyTagger source:"Project" label:"customlabel">>|
|custom label without arrow| {{{<<monkeyTagger source:"Project" label:"customlabel" arrow:"false">>}}} |<<monkeyTagger source:"Project" label:"customlabel" arrow:"false">>|
|logging enabled| {{{<<monkeyTagger source:"Project" logging:"true"}}} |<<monkeyTagger source:"Project" logging:"true">>|
|logging enabled with anchor text|{{{<<monkeyTagger source:"Project" logging:"true" anchor:"anchortext"}}} |<<monkeyTagger source:"Project" logging:"true" anchor:"anchortext">>|

''Tips:''
*Make sure your anchor text doesn't occur more than once in every tiddler, as the first instance will be used.
*I recommend using something like {{{/%StatusLog%/}}} as an invisible anchor.
*Use a tag based template, and add monkeyTagger macro's with logging enabled to the toolbar in just your taskmanagement templates.

!To Do:
*add sorting options if requested.
*''add exclude tag feature''!

!History
*Version 0.9: 
**changed to named parameters to make it more user friendly
**added option to disable/enable dropdown arrow in custom labels
**added logging option with anchor text.

!CODE
***/
//{{{

config.macros.monkeyTagger= {};
//config.macros.monkeyTagger.dropdownchar = (document.all?"▼":"▾"); // the fat one is the only one that works in IE
config.macros.monkeyTagger.dropdownchar = "▼"; // uncomment previous line and comment this for smaller version in FF
config.macros.monkeyTagger.handler = function(place,macroName,params,wikifier,paramString,tiddler)
{
 var nAV = paramString.parseParams('test', null, true);

 if ((nAV[0].arrow)&&(nAV[0].arrow[0])=='false')
    var arrow=': ';
 else
     var arrow=': '+ config.macros.monkeyTagger.dropdownchar;

 if((nAV[0].source)&&(nAV[0].source[0])!='.')
        {var tagToTrack = nAV[0].source[0]}
 else if(params[0]&&(params[0]!='.'))
      {var tagToTrack = params[0]}
 else
       {return false;};
 var monkeylabel = ((nAV[0].label)&&(nAV[0].label[0])!='.')?nAV[0].label[0]+arrow: tagToTrack+arrow;
 var logmode = ((nAV[0].logging)&&(nAV[0].logging[0])!='.')?nAV[0].logging[0]: "false";
 if ((nAV[0].anchor)&&(nAV[0].anchor[0])!='.')
    var anchor = nAV[0].anchor[0];
 var monkeytooltip=tagToTrack + ' :';


     if(tiddler instanceof Tiddler) {
	  	var title = tiddler.title;

                var addcomment = function(tiddler,newTag) {
                    var now = new Date();
                    var timeFormat= 'DD/0MM/YY 0hh:0mm';
                    var formattednow= now.formatString(timeFormat);
                    var txt="\n*''"+tagToTrack+"'' set as ''"+newTag+"'' on "+formattednow;
                    if (anchor && anchor!='.')
                       {var pos=tiddler.text.indexOf(anchor);
                       if (pos!=-1) {pos=pos + anchor.length}
                       else if (pos==-1) {pos=tiddler.text.length}}
                    else if (!anchor){var pos = tiddler.text.length;};

                    tiddler.set(null,tiddler.text.substr(0,pos)+txt+tiddler.text.substr(pos));
                    story.refreshTiddler(tiddler.title,null,true);
                    return false;
                }

                var ontagclick = function(e) {
                    if (!e) var e = window.event;
                    var tag = this.getAttribute("tag");
                    var t=store.getTiddler(title);
                    var thistiddlertags = story.getTiddlerField(title, 'tags').value.readBracketedList();
                    if (!t || !t.tags) return;
                    if (thistiddlertags.find(tag)==null) {
                       story.setTiddlerTag(title,tag,true);
                       if (logmode=="true") {
                          addcomment(t,tag);
                       }
                    }
                    else {
                       story.setTiddlerTag(title,tag,false);
                    }
                    return false;
                };

                var onclick = function(e) {
                    if (!e) var e = window.event;
                    var popup = Popup.create(this);
                    var thistiddler=store.getTiddler(title);

                    var thistiddlertags = story.getTiddlerField(title, 'tags').value.readBracketedList();

                    var taggedarray = new Array();
                    var tagslabel = new Array();

                    var taggedtiddlers = store.getTaggedTiddlers(tagToTrack);
                    for (var t=0; t<taggedtiddlers.length; t++){
                        var taggedtitle= ((taggedtiddlers[t]).title);
                        taggedarray.push(taggedtitle);}

                    for (var t=0; t<taggedarray.length; t++){
                        var temptag = taggedarray[t];
                        if (thistiddlertags.find(temptag)==null) {
                           var temptag='[ ] '+ temptag;
                        }
                        else {
                           var temptag ='[x] '+ temptag;
                        }
                        tagslabel.push(temptag);
                    }

                    if(tagslabel.length == 0)
                       createTiddlyText(createTiddlyElement(popup,"li"),('no '+tagToTrack));
                    for (var t=0; t<tagslabel.length; t++)
                    {
                       var theTag = createTiddlyButton(createTiddlyElement(popup,"li"),tagslabel[t],("toggle '"+ ([taggedarray[t]]))+"'",ontagclick);
                       theTag.setAttribute("tag",taggedarray[t]);
                    }
       Popup.show(popup,false);
       e.cancelBubble = true;
       if (e.stopPropagation) e.stopPropagation();
       return(false);
};
 //createTiddlyButton(place,monkeylabel,monkeylabel,onclick);

var createdropperButton = function(place){
var sp = createTiddlyElement(place,"span",null,"monkeytaggerbutton");
var theDropDownBtn = createTiddlyButton(sp,monkeylabel,monkeytooltip,onclick);
};

createdropperButton(place);
 }
};
setStylesheet(
 ".toolbar .monkeytaggerbutton {margin-right:0em; border:0px solid #fff; padding:0px; padding-right:0px; padding-left:0px;}\n"+
 ".monkeytaggerbutton a.button {padding:2px; padding-left:2px; padding-right:2px;}\n"+
// ".monkeytaggerbutton {font-size:130%;}\n"+
//".monkeytaggerbutton .button {color:#703;}\n"+
 "",
"MonkeyTaggerStyles");

// Find an entry in an array. Returns the array index or null
// @Deprecated: Use indexOf instead
Array.prototype.find = function(item)
{
	var i = this.indexOf(item);
	return i == -1 ? null : i;
};


//}}}
/***
|Name|NestedSlidersPlugin|
|Source|http://www.TiddlyTools.com/#NestedSlidersPlugin|
|Documentation|http://www.TiddlyTools.com/#NestedSlidersPluginInfo|
|Version|2.4.6|
|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|show content in nest-able sliding/floating panels, without creating separate tiddlers for each panel's content|
!!!!!Documentation
>see [[NestedSlidersPluginInfo]]
!!!!!Configuration
<<<
<<option chkFloatingSlidersAnimate>> allow floating sliders to animate when opening/closing
>Note: This setting can cause 'clipping' problems in some versions of InternetExplorer.
>In addition, for floating slider animation to occur you must also allow animation in general (see [[AdvancedOptions]]).
<<<
!!!!!Revisions
<<<
2008.09.07 - 2.4.6 added removeOptionCookie() function for compatibility with [[CookieManagerPlugin]]
2008.06.07 - 2.4.5 in 'onmouseover' handler for 'open on hover' slider buttons,<br>use call() method when invoking document.onclick function (avoids error in IE)
|please see [[NestedSlidersPluginInfo]] for additional revision details|
2005.11.03 - 1.0.0 initial public release.  Thanks to RodneyGomes, GeoffSlocock, and PaulPetterson for suggestions and experiments.
<<<
!!!!!Code
***/
//{{{
version.extensions.nestedSliders = {major: 2, minor: 4, revision: 6, date: new Date(2008,9,7)};

// options for deferred rendering of sliders that are not initially displayed
if (config.options.chkFloatingSlidersAnimate===undefined)
	config.options.chkFloatingSlidersAnimate=false; // avoid clipping problems in IE

// default styles for 'floating' class
setStylesheet(".floatingPanel { position:absolute; z-index:10; padding:0.5em; margin:0em; \
	background-color:#eee; color:#000; border:1px solid #000; text-align:left; }","floatingPanelStylesheet");

// if removeOptionCookie() function is not defined by TW core, define it here.
if (window.removeOptionCookie===undefined) {
window.removeOptionCookie=function(cookie) {
	var ex=new Date(); ex.setTime(ex.getTime()-1000);  // immediately expire cookie
	document.cookie = cookie+"=novalue; path=/; expires="+ex.toGMTString();
}
}

config.formatters.push( {
	name: "nestedSliders",
	match: "\\n?\\+{3}",
	terminator: "\\s*\\={3}\\n?",
	lookahead: "\\n?\\+{3}(\\+)?(\\([^\\)]*\\))?(\\!*)?(\\^(?:[^\\^\\*\\@\\[\\>]*\\^)?)?(\\*)?(\\@)?(?:\\{\\{([\\w]+[\\s\\w]*)\\{)?(\\[[^\\]]*\\])?(\\[[^\\]]*\\])?(?:\\}{3})?(\\#[^:]*\\:)?(\\>)?(\\.\\.\\.)?\\s*",
	handler: function(w)
		{
			lookaheadRegExp = new RegExp(this.lookahead,"mg");
			lookaheadRegExp.lastIndex = w.matchStart;
			var lookaheadMatch = lookaheadRegExp.exec(w.source)
			if(lookaheadMatch && lookaheadMatch.index == w.matchStart)
			{
				var defopen=lookaheadMatch[1];
				var cookiename=lookaheadMatch[2];
				var header=lookaheadMatch[3];
				var panelwidth=lookaheadMatch[4];
				var transient=lookaheadMatch[5];
				var hover=lookaheadMatch[6];
				var buttonClass=lookaheadMatch[7];
				var label=lookaheadMatch[8];
				var openlabel=lookaheadMatch[9];
				var panelID=lookaheadMatch[10];
				var blockquote=lookaheadMatch[11];
				var deferred=lookaheadMatch[12];

				// location for rendering button and panel
				var place=w.output;

				// default to closed, no cookie, no accesskey, no alternate text/tip
				var show="none"; var cookie=""; var key="";
				var closedtext=">"; var closedtip="";
				var openedtext="<"; var openedtip="";

				// extra "+", default to open
				if (defopen) show="block";

				// cookie, use saved open/closed state
				if (cookiename) {
					cookie=cookiename.trim().slice(1,-1);
					cookie="chkSlider"+cookie;
					if (config.options[cookie]==undefined)
						{ config.options[cookie] = (show=="block") }
					show=config.options[cookie]?"block":"none";
				}

				// parse label/tooltip/accesskey: [label=X|tooltip]
				if (label) {
					var parts=label.trim().slice(1,-1).split("|");
					closedtext=parts.shift();
					if (closedtext.substr(closedtext.length-2,1)=="=")	
						{ key=closedtext.substr(closedtext.length-1,1); closedtext=closedtext.slice(0,-2); }
					openedtext=closedtext;
					if (parts.length) closedtip=openedtip=parts.join("|");
					else { closedtip="show "+closedtext; openedtip="hide "+closedtext; }
				}

				// parse alternate label/tooltip: [label|tooltip]
				if (openlabel) {
					var parts=openlabel.trim().slice(1,-1).split("|");
					openedtext=parts.shift();
					if (parts.length) openedtip=parts.join("|");
					else openedtip="hide "+openedtext;
				}

				var title=show=='block'?openedtext:closedtext;
				var tooltip=show=='block'?openedtip:closedtip;

				// create the button
				if (header) { // use "Hn" header format instead of button/link
					var lvl=(header.length>5)?5:header.length;
					var btn = createTiddlyElement(createTiddlyElement(place,"h"+lvl,null,null,null),"a",null,buttonClass,title);
					btn.onclick=onClickNestedSlider;
					btn.setAttribute("href","javascript:;");
					btn.setAttribute("title",tooltip);
				}
				else
					var btn = createTiddlyButton(place,title,tooltip,onClickNestedSlider,buttonClass);
				btn.innerHTML=title; // enables use of HTML entities in label

				// set extra button attributes
				btn.setAttribute("closedtext",closedtext);
				btn.setAttribute("closedtip",closedtip);
				btn.setAttribute("openedtext",openedtext);
				btn.setAttribute("openedtip",openedtip);
				btn.sliderCookie = cookie; // save the cookiename (if any) in the button object
				btn.defOpen=defopen!=null; // save default open/closed state (boolean)
				btn.keyparam=key; // save the access key letter ("" if none)
				if (key.length) {
					btn.setAttribute("accessKey",key); // init access key
					btn.onfocus=function(){this.setAttribute("accessKey",this.keyparam);}; // **reclaim** access key on focus
				}
				btn.setAttribute("hover",hover?"true":"false");
				btn.onmouseover=function(ev) {
					// optional 'open on hover' handling
					if (this.getAttribute("hover")=="true" && this.sliderPanel.style.display=='none') {
						document.onclick.call(document,ev); // close transients
						onClickNestedSlider(ev); // open this slider
					}
					// mouseover on button aligns floater position with button
					if (window.adjustSliderPos) window.adjustSliderPos(this.parentNode,this,this.sliderPanel);
				}

				// create slider panel
				var panelClass=panelwidth?"floatingPanel":"sliderPanel";
				if (panelID) panelID=panelID.slice(1,-1); // trim off delimiters
				var panel=createTiddlyElement(place,"div",panelID,panelClass,null);
				panel.button = btn; // so the slider panel know which button it belongs to
				btn.sliderPanel=panel; // so the button knows which slider panel it belongs to
				panel.defaultPanelWidth=(panelwidth && panelwidth.length>2)?panelwidth.slice(1,-1):"";
				panel.setAttribute("transient",transient=="*"?"true":"false");
				panel.style.display = show;
				panel.style.width=panel.defaultPanelWidth;
				panel.onmouseover=function(event) // mouseover on panel aligns floater position with button
					{ if (window.adjustSliderPos) window.adjustSliderPos(this.parentNode,this.button,this); }

				// render slider (or defer until shown) 
				w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
				if ((show=="block")||!deferred) {
					// render now if panel is supposed to be shown or NOT deferred rendering
					w.subWikify(blockquote?createTiddlyElement(panel,"blockquote"):panel,this.terminator);
					// align floater position with button
					if (window.adjustSliderPos) window.adjustSliderPos(place,btn,panel);
				}
				else {
					var src = w.source.substr(w.nextMatch);
					var endpos=findMatchingDelimiter(src,"+++","===");
					panel.setAttribute("raw",src.substr(0,endpos));
					panel.setAttribute("blockquote",blockquote?"true":"false");
					panel.setAttribute("rendered","false");
					w.nextMatch += endpos+3;
					if (w.source.substr(w.nextMatch,1)=="\n") w.nextMatch++;
				}
			}
		}
	}
)

function findMatchingDelimiter(src,starttext,endtext) {
	var startpos = 0;
	var endpos = src.indexOf(endtext);
	// check for nested delimiters
	while (src.substring(startpos,endpos-1).indexOf(starttext)!=-1) {
		// count number of nested 'starts'
		var startcount=0;
		var temp = src.substring(startpos,endpos-1);
		var pos=temp.indexOf(starttext);
		while (pos!=-1)  { startcount++; pos=temp.indexOf(starttext,pos+starttext.length); }
		// set up to check for additional 'starts' after adjusting endpos
		startpos=endpos+endtext.length;
		// find endpos for corresponding number of matching 'ends'
		while (startcount && endpos!=-1) {
			endpos = src.indexOf(endtext,endpos+endtext.length);
			startcount--;
		}
	}
	return (endpos==-1)?src.length:endpos;
}
//}}}
//{{{
window.onClickNestedSlider=function(e)
{
	if (!e) var e = window.event;
	var theTarget = resolveTarget(e);
	while (theTarget && theTarget.sliderPanel==undefined) theTarget=theTarget.parentNode;
	if (!theTarget) return false;
	var theSlider = theTarget.sliderPanel;
	var isOpen = theSlider.style.display!="none";

	// toggle label
	theTarget.innerHTML=isOpen?theTarget.getAttribute("closedText"):theTarget.getAttribute("openedText");
	// toggle tooltip
	theTarget.setAttribute("title",isOpen?theTarget.getAttribute("closedTip"):theTarget.getAttribute("openedTip"));

	// deferred rendering (if needed)
	if (theSlider.getAttribute("rendered")=="false") {
		var place=theSlider;
		if (theSlider.getAttribute("blockquote")=="true")
			place=createTiddlyElement(place,"blockquote");
		wikify(theSlider.getAttribute("raw"),place);
		theSlider.setAttribute("rendered","true");
	}
	// show/hide the slider
	if(config.options.chkAnimate && (!hasClass(theSlider,'floatingPanel') || config.options.chkFloatingSlidersAnimate))
		anim.startAnimating(new Slider(theSlider,!isOpen,e.shiftKey || e.altKey,"none"));
	else
		theSlider.style.display = isOpen ? "none" : "block";
	// reset to default width (might have been changed via plugin code)
	theSlider.style.width=theSlider.defaultPanelWidth;
	// align floater panel position with target button
	if (!isOpen && window.adjustSliderPos) window.adjustSliderPos(theSlider.parentNode,theTarget,theSlider);
	// if showing panel, set focus to first 'focus-able' element in panel
	if (theSlider.style.display!="none") {
		var ctrls=theSlider.getElementsByTagName("*");
		for (var c=0; c<ctrls.length; c++) {
			var t=ctrls[c].tagName.toLowerCase();
			if ((t=="input" && ctrls[c].type!="hidden") || t=="textarea" || t=="select")
				{ ctrls[c].focus(); break; }
		}
	}
	var cookie=theTarget.sliderCookie;
	if (cookie && cookie.length) {
		config.options[cookie]=!isOpen;
		if (config.options[cookie]!=theTarget.defOpen) saveOptionCookie(cookie);
		else removeOptionCookie(cookie); // remove cookie if slider is in default display state
	}

	// prevent SHIFT-CLICK from being processed by browser (opens blank window... yuck!)
	// prevent clicks *within* a slider button from being processed by browser
	// but allow plain click to bubble up to page background (to close transients, if any)
	if (e.shiftKey || theTarget!=resolveTarget(e))
		{ e.cancelBubble=true; if (e.stopPropagation) e.stopPropagation(); }
	Popup.remove(); // close open popup (if any)
	return false;
}
//}}}
//{{{
// click in document background closes transient panels 
document.nestedSliders_savedOnClick=document.onclick;
document.onclick=function(ev) { if (!ev) var ev=window.event; var target=resolveTarget(ev);

	if (document.nestedSliders_savedOnClick)
		var retval=document.nestedSliders_savedOnClick.apply(this,arguments);
	// if click was inside a popup... leave transient panels alone
	var p=target; while (p) if (hasClass(p,"popup")) break; else p=p.parentNode;
	if (p) return retval;
	// if click was inside transient panel (or something contained by a transient panel), leave it alone
	var p=target; while (p) {
		if ((hasClass(p,"floatingPanel")||hasClass(p,"sliderPanel"))&&p.getAttribute("transient")=="true") break;
		p=p.parentNode;
	}
	if (p) return retval;
	// otherwise, find and close all transient panels...
	var all=document.all?document.all:document.getElementsByTagName("DIV");
	for (var i=0; i<all.length; i++) {
		 // if it is not a transient panel, or the click was on the button that opened this panel, don't close it.
		if (all[i].getAttribute("transient")!="true" || all[i].button==target) continue;
		// otherwise, if the panel is currently visible, close it by clicking it's button
		if (all[i].style.display!="none") window.onClickNestedSlider({target:all[i].button}) 
	}
	return retval;
};
//}}}
//{{{
// adjust floating panel position based on button position
if (window.adjustSliderPos==undefined) window.adjustSliderPos=function(place,btn,panel) {
	if (hasClass(panel,"floatingPanel")) {
		var rightEdge=document.body.offsetWidth-1;
		var panelWidth=panel.offsetWidth;
		var left=0;
		var top=btn.offsetHeight; 
		if (place.style.position=="relative" && findPosX(btn)+panelWidth>rightEdge) {
			left-=findPosX(btn)+panelWidth-rightEdge; // shift panel relative to button
			if (findPosX(btn)+left<0) left=-findPosX(btn); // stay within left edge
		}
		if (place.style.position!="relative") {
			var left=findPosX(btn);
			var top=findPosY(btn)+btn.offsetHeight;
			var p=place; while (p && !hasClass(p,'floatingPanel')) p=p.parentNode;
			if (p) { left-=findPosX(p); top-=findPosY(p); }
			if (left+panelWidth>rightEdge) left=rightEdge-panelWidth;
			if (left<0) left=0;
		}
		panel.style.left=left+"px"; panel.style.top=top+"px";
	}
}
//}}}
//{{{
// TW2.1 and earlier:
// hijack Slider stop handler so overflow is visible after animation has completed
Slider.prototype.coreStop = Slider.prototype.stop;
Slider.prototype.stop = function()
	{ this.coreStop.apply(this,arguments); this.element.style.overflow = "visible"; }

// TW2.2+
// hijack Morpher stop handler so sliderPanel/floatingPanel overflow is visible after animation has completed
if (version.major+.1*version.minor+.01*version.revision>=2.2) {
	Morpher.prototype.coreStop = Morpher.prototype.stop;
	Morpher.prototype.stop = function() {
		this.coreStop.apply(this,arguments);
		var e=this.element;
		if (hasClass(e,"sliderPanel")||hasClass(e,"floatingPanel")) {
			// adjust panel overflow and position after animation
			e.style.overflow = "visible";
			if (window.adjustSliderPos) window.adjustSliderPos(e.parentNode,e.button,e);
		}
	};
}
//}}}
/***
|Name:|NewHerePlugin|
|Description:|Creates the new here and new journal macros|
|Version:|3.0 ($Rev: 3861 $)|
|Date:|$Date: 2009/12/18 16:36:41 $|
|Source:|http://mptw.tiddlyspot.com/#NewHerePlugin|
|Author:|Simon Baird <simon.baird@gmail.com>|
|License|http://mptw.tiddlyspot.com/#TheBSDLicense|
***/
//{{{
merge(config.macros, {
	newHere: {
		handler: function(place,macroName,params,wikifier,paramString,tiddler) {
			wikify("<<newTiddler "+paramString+" tag:[["+tiddler.title+"]]>>",place,null,tiddler);
		}
	},
	newJournalHere: {
		handler: function(place,macroName,params,wikifier,paramString,tiddler) {
			wikify("<<newJournal "+paramString+" tag:[["+tiddler.title+"]]>>",place,null,tiddler);
		}
	}
});

//}}}

{{fr{Vos options de configuration de TiddlyWiki sont sauvegardées par votre navigateur (cookies).

Nom d'utilisateur pour signer vos entrées : entrez-le sous la forme d'un nom Wiki (par exemple RaymondQueneau)}}}{{en{Your TiddlyWiki configuration options are saved by your browser (cookies).

User name to sign your entries : type it under the form of a wiki name (for example RaymondQueneau.}}}.<<option txtUserName>>
<<option chkSaveBackups>>{{fr{Backup de chaque version}}}{{en{Backup each new version}}}
<<option chkAutoSave>>{{fr{Sauvegarde automatique après chaque entrée validée}}}{{en{Automatic save after each validated entry}}}
<<option chkRegExpSearch>>{{fr{Expression régulières dans les recherches}}}{{en{Use regular expression in seach}}}
<<option chkCaseSensitiveSearch>>{{fr{Respecter la casse dans les recherches}}}{{en{Match case in search}}}
<<option chkAnimate>>{{fr{Ouverture animée des éléments}}}{{en{Animate the opening of the elements}}}
<<option chkVerboseHelp>>{{fr{Aide scrum complète dans les vues}}}{{en{Full scrum help in view}}}
-----
[[Importations|ImportTiddlers]]
[[Extensions|PluginManager]]
[[Options complémentaires|AdvancedOptions]]
<<slider chkObj [[Goals]] "Objectif" >>
<<slider chkFeatures Features "Features">>
<<slider  chkBacklog [[ProductBacklog]] "Backlog de produit">>
<<slider  chkBrouillon [[Draft]] "Brouillon">>
<!--{{{-->
<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>
<!--}}}-->
{{fr{
* Définissez le titre de votre projet SiteTitle & SiteSubtitle
* Définissez les [[Features]] et classez les par thème ansi que l'[[Goals]]
* Mettez au point une liste préliminaire de Release : [[ReleasePlan]]
* Definissez la notion de [[Completed]]
* Définissez les [[SprintDays]] qui seront utilisés pour le Burdownchart
}}}{{en{
* Define the title of your project : SiteTitle & SiteSubtitle
* Define the [[Features]] and [[Goals]] of your project
* Build a [[ReleasePlan]]
* Define when a task is [[Completed]] 
* Define the [[SprintDays]] which are used in the Burdownchart}}}
<<tiddler OutdatedTemplate with:"PolyGlotFormat" with:"easyTongue">>
/***
{{fr{
<<tiddler PolyGlotPluginDoc_fr>>}}}{{hide{
----
}}}{{en{
<<tiddler PolyGlotPluginDoc_en>>}}}
!Options
{{fr{<<option chkPolyglotHijackUrl>> ajouter le paramètre de langues aux url générées par {{{permaview}}} et {{{permalink}}} }}}{{en{<<option chkPolyglotHijackUrl>>add language parameter to {{{permalink}}} and {{{permaview}}} generated urls}}}

!Code
***/
// //{{en{ Version Info}}}{{fr{ Informations de version}}}
//{{{
version.extensions.PolyGlotPlugin = { major: 1, minor: 1, revision: 4, date: new Date(2007,31,1),
 source: "http://yann.perrin.googlepages.com/twkd.html#PolyGlotPlugin"
};
//}}}
// //{{en{ Default Settings}}}{{fr{ Paramètres par défaut}}}
//{{{
config.macros.polyglot = {
defaultlang:"fr",
languages:["fr","en"],
pluginTranslationTag:"linguo",
tooltip:"version ",
notfound:" isn't one of the supported languages",
hijackurl:false,
hidewhenactive:"hide"
};
//}}}
// //{{en{ generating CSS hiding unselected languages}}}{{fr{ génération des styles qui cachent les langages non séléctionnées}}}
//{{{
polyglotCSS = function(lang){
   var langs=[];
   langs=langs.concat(config.macros.polyglot.languages);
   var current=langs.find(lang);
   if (current != null)
      langs.splice(current,1);
   var hlangs="." + langs.join(",.");
   var css=hlangs + ",." + config.macros.polyglot.hidewhenactive + "{display:none;}";
   return css;
};
//}}}
// //{{en{ tag and process translation tiddlers}}}{{fr{ indexation et utilisation des tiddlers de traduction}}}
//{{{
polyglotTag = function(tiddler,lang){
   if (!tiddler.isTagged(lang) && tiddler.isTagged('systemConfig'))
      {
       var current = tiddler.tags.find('systemConfig');
       tiddler.tags.splice(current,1);
       tiddler.assign(tiddler.title,tiddler.text,tiddler.modifier,tiddler.modified,tiddler.tags,tiddler.created);
      };
   if (tiddler.isTagged(lang) && !tiddler.isTagged('systemConfig'))
      {
       var tags=tiddler.getTags();
       tags += " systemConfig";
       window.eval(tiddler.text);
       tiddler.assign(tiddler.title,tiddler.text,tiddler.modifier,tiddler.modified,tags,tiddler.created);
      };
};
//}}}
// //{{en{ Apply necessary changes}}}{{fr{ Application des changements}}}
//{{{
polyglotApply = function(lang) {
   config.options.txtPolyglotLang=lang;
   saveOptionCookie("txtPolyglotLang");
   setStylesheet(polyglotCSS(lang),'language');
   var tiddlers = store.getTaggedTiddlers(config.macros.polyglot.pluginTranslationTag);
   for (var i=0;i<tiddlers.length;i++)
      polyglotTag(tiddlers[i],lang);
};
//}}}
// //{{en{ Hijacking restart() to load selected language tiddlers on startup}}}{{fr{ Détournement de restart() afin de charger les tiddlers de traduction au démarrage}}}
//{{{
window.polyglotRestart=window.restart;
window.restart = function() {
if (config.options.txtPolyglotLang==undefined)
   config.options.txtPolyglotLang=config.macros.polyglot.defaultlang;
if (config.options.chkPolyglotHijackUrl==undefined)
   config.options.chkPolyglotHijackUrl = config.macros.polyglot.hijackurl;
var lang = config.options.txtPolyglotLang;
polyglotApply(lang);
polyglotRestart();
store.notifyAll();
};
//}}}
// //{{en{ refresh displayed tiddlers}}}{{fr{ rafraichit les tiddlers affichés}}}
//{{{
refreshStory = function() {
story.forEachTiddler(function(title,element){
   if(element.getAttribute("dirty") != "true")
      story.refreshTiddler(title,null,true);
   });
};
//}}}
// //{{en{ polyglot macro handler}}}{{fr{ affichage de la macro polyglot}}}
//{{{
window.polyglotOnClickHandler=function(e) {
   var btn=this;
   var lang=btn.getAttribute("id");
   polyglotApply(lang);
   store.notifyAll();
   refreshStory();
};
config.macros.polyglot.handler = function (place,macroName,params,wikifier,paramString,tiddler) {
var langs = config.macros.polyglot.languages;
for (var i=0;i<langs.length;i++)
   {
   if (i>0)
      wikify(" | ",place);
   createTiddlyButton(place,langs[i],this.tooltip+langs[i],polyglotOnClickHandler,"polyglotBtn",langs[i]);
   };
};
//}}}
// //{{en{paramifier}}}{{fr{gestion des paramètres passés par l'url}}}
//{{{
config.paramifiers.lang = {
 onconfig: function(v){
   var current=config.macros.polyglot.languages.find(v);
   if (current !=null)
      {
      config.options.txtPolyglotLang=v;
      saveOptionCookie("txtPolyglotLang");
      }
   else
      alert(v + config.macros.polyglot.notfound);
}
}
//}}}
// //{{en{hijacking permaview and permalink to add the lang: param to the url}}}{{fr{detournement de permaview et permalink afin d'ajouter le parametre de langue à l'url}}}
//{{{
var addLangToUrl = function() {
var param = "lang:"+config.options.txtPolyglotLang;
if (config.options.chkPolyglotHijackUrl)
   window.location.hash = window.location.hash+" "+param;
}
window.PolyGlotPermaLink=config.commands.permalink.handler;
config.commands.permalink.handler = function(event,src,title) {
PolyGlotPermaLink(event,src,title);
addLangToUrl();
}
window.PolyGlotPermaView=config.macros.permaview.onClick;
config.macros.permaview.onClick=function(e) {
PolyGlotPermaView(e);
addLangToUrl();
return false;
}
//}}}
// //{{en{shadow links to documentation}}}{{fr{liens vers la documentation si elle n'est pas présente}}}
//{{{
config.shadowTiddlers.PolyGlotPluginDoc_en = "Documentation for this plugin is available [[here|" + version.extensions.PolyGlotPlugin.source +"Doc_en]]";
config.shadowTiddlers.PolyGlotPluginDoc_fr = "La documentation de ce plugin est disponible [[ici|" + version.extensions.PolyGlotPlugin.source +"Doc_fr]]";
//}}}
|Name|PolyGlotPlugin|
|Author|YannPerrin|
|Source|http://yann.perrin.googlepages.com/twkd.html#PolyGlotPlugin ([[del.icio.us|http://del.icio.us/post?url=http://yann.perrin.googlepages.com/twkd.html#PolyGlotPlugin]])|
|Version|1.1.4|
|Require|~TW2.0.7+|

!Description
This plugin allows you to create a multilingual TiddlyWiki. It will adapt display to the user language preference.
It does not, however, translate content by itself.
.
!Installation
*import (or copy/paste in edit mode) the following tiddler in your document : <<br>>PolyGlotPlugin (tag it : <<tag systemConfig>>)
*adapt the "Default Parameter" section of the code to your needs
*import (or copy/paste in edit mode) the necessary [[language tiddlers|linguo]] in your document.
*tag these tiddlers according to the defined "Default Parameters"
*in order to allow the user to change language, you still need to install the polyglot macro
**in a tiddler by writing {{{<<polyglot>>}}} in it's body
**and/or by writing  {{{<div macro='polyglot'></div>}}} or {{{<span macro='polyglot'></span>}}} in the PageTemplate
*if you want offline access to this documentation, import (or copy/paste in edit mode) the following tiddler in your document : <<br>>PolyGlotPluginDoc_en
*finally, save changes and reload the document.


!Usage
''Once properly installed'' (see above), this plugin adapt the display to the user preferences by :
*loading the tiddlers tagged with the chosen language and with the tag defined as pluginTranslationTag (by default <<tag linguo>>) as if they were plugins. Which will result in interface translation.
*tiddler content marked like that :
{{{
{{**{content}}}
}}}
is shown if ** is the chosen language and hidden if ** is one of the other defined language.

!Revisions History
2007.31.01-1.1.4
>bug correction related to changes in Tiddlywiki core code
2006.08.06-1.1.3
>added a class that is always hidden when the plugin is installed so that a good presentation is possible when it is not.
2006.01.05-1.1.2
>display bug correction
>improved compatibility with other plugins
>(suggestions by BidiX)
2006.20.04-1.1.1
>optionnal addition of language parameter to permalink and permaview generated urls
2006.18.04-1.1.0
>added {{{lang:}}} paramifier support
>examples :
> http://yann.perrin.googlepages.com/twkd.html#lang:fr
> http://yann.perrin.googlepages.com/twkd.html#lang:en
> http://yann.perrin.googlepages.com/twkd.html#lang:ru (this one is to show how the plugin handle wrong language choice)
2006.15.04-1.0.3
>correction of an internet explorer specific bug.
2006.13.04-1.0.2
>correction of an internet explorer specific bug preventing the first language to display(spotted by BidiX)
2006.13.04-1.0.1
>added toolbar refreshing of open tiddlers (spotted by Udo Borkowski)
2006.12.04-1.0.0
>Initial Public Release

!Credits
Thanks to :
*[[Jeremy Ruston]] for TiddlyWiki
*[[Bram Chen]] for his [english translation tiddler|en-US]] that i slightly modified to use in TWkd
*[[Jacques Turbé]] for ~AdaptationFrancaise2 wich was the basis of the [[fr-FR]] tiddler
*My father, which gave me the idea and desire to write this plugin
|Nom|PolyGlotPlugin|
|Auteur|YannPerrin|
|Source|http://yann.perrin.googlepages.com/twkd.html#PolyGlotPlugin ([[del.icio.us|http://del.icio.us/post?url=http://yann.perrin.googlepages.com/twkd.html#PolyGlotPlugin]])|
|Version|1.1.4|
|Requiert|~TW2.0.7+|

!Description
Ce plugin permet de créer un tiddlywiki multilingue, et d'adapter l'affichage à la langue choisie par l'utilisateur.
Il n'effectue pas par lui même de traduction de contenu.
.
!Installation
*importez (ou copiez/collez en mode édition) le tiddler suivant dans votre document : <<br>>PolyGlotPlugin (indexez le : systemConfig)
*adaptez la section "Paramètres par défaut" du code selon vos besoins
*importez (ou copiez/collez en mode édition) les [[tiddlers de langages|linguo]] nécessaires dans votre document.
*indexez ces tiddlers selon les "Paramètres par défaut" que vous avez défini (langue & pluginTranslationTag)
*afin de permettre le changement de langue, il faut encore installer la macro polyglot
**dans un tiddler sous la forme {{{<<polyglot>>}}}
**et/ou dans le PageTemplate sous la forme {{{<div macro='polyglot'></div>}}} ou {{{<span macro='polyglot'></span>}}}
*si vous souhaitez accéder hors-ligne à cette documentation, importez (ou copiez/collez en mode édition) le tiddler suivant dans votre document : <<br>>PolyGlotPluginDoc_fr
*enfin, sauvegardez les changements et rechargez le document.


!Usage
''Une fois correctement installé'' (voir ci-dessus), ce plugin utilise deux systèmes afin d'adapter l'affichage à la langue choisie :
*les tiddlers indexés avec la langue choisie et l'index défini comme pluginTranslationTag (par défaut <<tag linguo>>) sont marqués de l'index <<tag systemConfig>> et leur contenu est chargé comme un plugin
*le contenu marqué de la manière suivante :
{{{
{{**{contenu}}}
}}}
est affiché si ** correspond à la langue choisie et masqué si ** correspond à une des autres langues utilisées.

!Historique des Révisions
2007.31.01-1.1.4
>correction d'un bug lié au changement du code source de TiddlyWiki
2006.08.06-1.1.3
>ajout d'une classe qui est toujours cachée lorsque le plugin est installé pour permettre une présentation correcte quand il est absent
2006.01.05-1.1.2
>correction d'un bug d'affichage
>amélioration de la compatibilité avec d'autres plugins
>(suggestions de BidiX)
2006.20.04-1.1.1
>ajout optionnel du parametre de langue aux urls générées par permaview et permalink
2006.18.04-1.1.0
>ajout du support pour la transmission du langage choisi par l'url sous la forme lang:**
>exemples :
> http://yann.perrin.googlepages.com/twkd.html#lang:fr
> http://yann.perrin.googlepages.com/twkd.html#lang:en
> http://yann.perrin.googlepages.com/twkd.html#lang:ru (ce dernier montre comment le plugin réagit en cas d'erreur)
2006.15.04-1.0.3
>correction du problème de fonctionnement sous internet explorer
2006.13.04-1.0.2
>correction du non-affichage de la première langue sous internet explorer (signalé par BidiX)
2006.13.04-1.0.1
>correction du non-rafraichissement des barres d'outils des éléments ouverts (détecté par Udo Borkowski)
2006.12.04-1.0.0
>Première version publique

!Crédits
Merci à :
*[[Jeremy Ruston]] pour TiddlyWiki
*[[Bram Chen]] pour son [tiddler de traduction anglaise|en-US]] que j'ai légèrement adapté à TWkd
*[[Jacques Turbé]] pour son ~AdaptationFrancaise2 qui a servi de base pour le tiddler [[fr-FR]]
*Mon père qui m'a donné l'idée et l'envie d'écrire ce plugin
/***
|''Name''|[[Populate/UpdateListPlugin]]|
|''Description''|Populate or update a sorted list by getting the tiddlers filtered by tags, wanted and unwanted.|
|''Author''|[[Jean-Cédric THÉROND - IDEIA <jctherond@ideia.fr>|mailto:Jean-Cédric%20THÉROND<jctherond@ideia.fr>?subject=Plugin%20updatePopulate%20TW]]|
|''Contributors''|[[YBA - IDEIA <ybabel@ideia.fr>|mailto:Y.%20BABEL<ybabel@ideia.fr>?subject=Plugin%20updatePopulate%20TW]]|
|''Version''|0.8//b//|
|''Date''|2008.09.17|
|''Status''|@@font-variant: small-caps;font-size:1.2em;stable@@|
|''Source''|//void//|
|''CodeRepository''|//void//|
|''Copyright''|jean-Cédric THÉROND - IDEIA|
|''License''|[[BSDLicence]]|
|''CoreVersion''|2.4|
|''Requires''|[[SortListPlugin]]|
|''Overrides''|//void//|
|''Feedback''|jctheron@ideia.fr|
|''Documentation''|[[Populate/UpdateListPluginDocumentation]]|
|''Keywords''|sorted list populate update filter tag|

!Code
***/
//{{{
config.macros.PopulateUpdateList = {
	label: "Update Backlog",
	prompt: "Update a BackLog",
	warning: "Do you really want to populate/update this backlog ?",

	handler: function(place, macroName, params, wikifier, paramString, tiddler) {
  	        var wantedTags="";
	        var unwantedTags="";
		var p=params.shift();
		while (p) {
			if (p.substr(0,5).toUpperCase()=='WANT:') {
				var wantedTags=p.substr(5).readMacroParams(); // YBA 26.09.08
			}
			else if (p.substr(0,9).toUpperCase()=='DONTWANT:') {
				var unwantedTags=p.substr(9).readMacroParams(); // YBA 26.09.08
			}
			p=params.shift();
		}
		this.createPopulateUpdateListButton(wantedTags, unwantedTags, place);
	},

	createPopulateUpdateListButton : function(wantedTags, unwantedTags, place){
    		var title= story.findContainingTiddler(place).id.substr(7);
		var btn = createTiddlyButton(place, this.label, this.prompt, this.onclickPopulateUpdateListButton);
                btn.setAttribute("wanted", wantedTags);
                btn.setAttribute("unwanted", unwantedTags);
                btn.setAttribute("tiddler.title", title);
		return false;
	},

	onclickPopulateUpdateListButton : function(e){
               var title = this.getAttribute("tiddler.title");
		var tiddlerDeTravail =  store.getTiddler(title);
		if(confirm(config.macros.PopulateUpdateList.warning)) {
		var wantedTags = this.getAttribute("wanted");
		var unwantedTags = this.getAttribute("unwanted");
//alert(wantedTags+" -- "+unwantedTags);
		if (wantedTags){wantedTags = wantedTags.replace(/,/gi, "").readBracketedList();}
		if (unwantedTags){unwantedTags = unwantedTags.replace(/,/gi, "").readBracketedList();}
//alert(wantedTags+" -- "+unwantedTags);

		/**
		 * for(var i = 0; i < wantedTags.length; i++){displayMessage('wanted : '+wantedTags[i]);}
		 * for(var i = 0; i < unwantedTags.length; i++){displayMessage('unwanted : '+unwantedTags[i]);}
		**/

		var results = new Array();
		store.forEachTiddler(function(title,tiddler) {
			if (tiddler.tags.containsAny(wantedTags) && !tiddler.tags.containsAny(unwantedTags)){
				//var dateDiff = (parseInt(tiddler.modified.getTime())-parseInt(invokTiddler.modified.getTime()))/1000;
				//if (dateDiff > 0){
				results.unshift(tiddler.title);
				//}
			}
		});

		//for (var i = 0; i < results.length; i++){alert('which ?'+ results[i]);}


		var tags=[]; // an empty array
		var fields={}; // an empty object
		var who=config.options.txtUserName; // current username
		var when=new Date(); // current timestamp

		var original = tiddlerDeTravail.text.split('\n');
		var bottom = original.splice(original.indexOf('----'),original.length);
		results = results.mergeUnique(original.linkify()).linkify().concat(bottom);
		var output = results.join('\n');
		tags=tiddlerDeTravail.tags; fields=tiddlerDeTravail.fields;
                store.saveTiddler(tiddlerDeTravail.title,tiddlerDeTravail.title,output,who,when,tags,fields);
		}
		return false;
	}

};
//}}}

//{{{
/**
 * Array.unique( strict ) - Remove duplicate values
 * source: http://4umi.com/web/javascript/array.php#unique
 * heavyly modded by Jean-Cédric THÉROND <jctherond@ideia.fr>
**/
Array.prototype.unique = function() {
var a=[], b = this, L = b.length, i, j=0;

for(i=0;i<L;i++) {
	if(b[i] != '\n'){
		a.pushUnique(b[i],true);
	}
}
return a;
};
//}}}

//{{{
Array.prototype.linkify = function() {
	var a = this,L = a.length,i;
	for(i=0;i<L;i++){
		if ( (a[i].indexOf('<<',0) == -1) && (a[i].indexOf('[[',0) == -1) ){
			a[i] = '[['+a[i]+']]';
		}
	}
	return a;
}
//}}}

//{{{
Array.prototype.mergeUnique = function(items){

	var p, a=this.linkify(), aL = this.length, b=items, bL=items.length, i;

	for (i=0 ; i < aL ; i++){
		if (a[i] != undefined){
			p = -1;
			p = b.indexOf(a[i]);
			if(p > -1){
				a.splice(i,1,'DEAD');
			}
		}
	}

	
	for (i=0 ; i < a.length ; i++){
		if(a[i] != 'DEAD'){
			b.push(a[i]);
		}
	}
	return b;
}
//}}}
!Description
populate or update a sorted list by getting the tiddlers filtered by tags, wanted and unwanted.
!Notes
*Never call a task or a userStory "DEAD", or else she'll buried.
*__Don't__ search tiddler with __space containing tags__ !
!Usage
{{{
<<PopulateUpdateList want:'tag1',"tag2" dontwant:"tag3",'tag4'>>
}}}
!!Parameters
*want:comma separated list of quoted tags __without space__.
*dontwant:comma separated list of quoted tags __without space__.
!!Examples
@@color:red;font-size:1.3em;font-weight:bolder;ONLY IN A SortList TIDDLER@@
!Configuration Options
//void//
!Revision History
>v0.8 (2008-09-19) : Now it preserves the order of tasks and adds those found at the end.
>v0.3 (2008-09-17)
!To Do
//Improve ("space containing tags" search will be a ''great'' improvement)//
/***
***/

//{{{

config.commands.refresh = {
 text: 'refresh',
 tooltip: 'Refresh this tiddler',
 handler: function(e,src,title) {
  clearMessage();
  story.refreshTiddler(title,false,true); // force=true
  return false;
 }
};

//}}}
/***
|Name:|RenameTagsPlugin|
|Description:|Allows you to easily rename or delete tags across multiple tiddlers|
|Version:|3.0 ($Rev: 5501 $)|
|Date:|$Date: 2009/12/18 16:36:41 $|
|Source:|http://mptw.tiddlyspot.com/#RenameTagsPlugin|
|Author:|Simon Baird <simon.baird@gmail.com>|
|License|http://mptw.tiddlyspot.com/#TheBSDLicense|
Rename a tag and you will be prompted to rename it in all its tagged tiddlers.
***/
//{{{
config.renameTags = {

	prompts: {
		rename: "Rename the tag '%0' to '%1' in %2 tidder%3?",
		remove: "Remove the tag '%0' from %1 tidder%2?"
	},

	removeTag: function(tag,tiddlers) {
		store.suspendNotifications();
		for (var i=0;i<tiddlers.length;i++) {
			store.setTiddlerTag(tiddlers[i].title,false,tag);
		}
		store.resumeNotifications();
		store.notifyAll();
	},

	renameTag: function(oldTag,newTag,tiddlers) {
		store.suspendNotifications();
		for (var i=0;i<tiddlers.length;i++) {
			store.setTiddlerTag(tiddlers[i].title,false,oldTag); // remove old
			store.setTiddlerTag(tiddlers[i].title,true,newTag);  // add new
		}
		store.resumeNotifications();
		store.notifyAll();
	},

	storeMethods: {

		saveTiddler_orig_renameTags: TiddlyWiki.prototype.saveTiddler,

		saveTiddler: function(title,newTitle,newBody,modifier,modified,tags,fields,clearChangeCount,created) {
			if (title != newTitle) {
				var tagged = this.getTaggedTiddlers(title);
				if (tagged.length > 0) {
					// then we are renaming a tag
					if (confirm(config.renameTags.prompts.rename.format([title,newTitle,tagged.length,tagged.length>1?"s":""])))
						config.renameTags.renameTag(title,newTitle,tagged);

					if (!this.tiddlerExists(title) && newBody == "")
						// dont create unwanted tiddler
						return null;
				}
			}
			return this.saveTiddler_orig_renameTags(title,newTitle,newBody,modifier,modified,tags,fields,clearChangeCount,created);
		},

		removeTiddler_orig_renameTags: TiddlyWiki.prototype.removeTiddler,

		removeTiddler: function(title) {
			var tagged = this.getTaggedTiddlers(title);
			if (tagged.length > 0)
				if (confirm(config.renameTags.prompts.remove.format([title,tagged.length,tagged.length>1?"s":""])))
					config.renameTags.removeTag(title,tagged);
			return this.removeTiddler_orig_renameTags(title);
		}

	},

	init: function() {
		merge(TiddlyWiki.prototype,this.storeMethods);
	}
}

config.renameTags.init();

//}}}

/***
!Revisions Plugin
!!!About
|Author : Bradley Meck|
|Date : Dec 24, 2006|

This plugin allows people to save multiple revisions of tiddlers and view the changes of tiddlers over time with the ability to restore previous versions of a tiddler.
***/
//{{{
config.macros.revisionsPlugin = { };
config.macros.revisionsPlugin.addRevision = function( tiddler, newContent ){
	
}
//}}}

<<search>><<closeAll>><<newTiddler>>{{en{<<newTiddler label:"new User Story}" text:{{store.getTiddlerText("EmptyUserStory")}} title:"Short UserStory title" tag:UserStory>><<newTiddler label:"new Sprint" tag:sprint title:"New sprint" text:{{store.getTiddlerText("EmptySprint")}}>><<newTiddler label:"new Task" tag:task text:{{store.getTiddlerText("EmptyTask")}}>><<newTiddler label:"new Backlog" tag:backlog text:{{store.getTiddlerText("EmptyBacklog")}}>>}}}{{fr{<<newTiddler label:"nouvelle User Story" text:{{store.getTiddlerText("EmptyUserStory")}} title:"Titre court de UserStory" tag:UserStory>><<newTiddler label:"nouveau Sprint" tag:sprint title:"Nouveau sprint" text:{{store.getTiddlerText("EmptySprint")}}>><<newTiddler label:"nouvelle Tâche" tag:task text:{{store.getTiddlerText("EmptyTask")}}>><<newTiddler label:"nouveau Backlog" tag:backlog text:{{store.getTiddlerText("EmptyBacklog")}}>>}}}<<saveChanges>><<slider chkSliderOptionsPanel OptionsPanel "options »" "Change TiddlyWiki advanced options">>
{{en{Scrum project manager}}}{{fr{Gestionnaire de projet scrum}}}
TiddlyScrum
/***
|Name|SliceGridPlugin|
|Source|http://www.TiddlyTools.com/#SliceGridPlugin|
|Documentation|http://www.TiddlyTools.com/#SliceGridPluginInfo|
|Version|1.0.3|
|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.3|
|Type|plugin|
|Requires||
|Overrides||
|Description|Generate a "slice grid" table to get an instant 'birds-eye' overview of your entire document|
Rows are tiddlers, columns are slice names.  If a tiddler has a value defined for a given slice, that grid cell is colored. Move the mouse over a grid cell to view the value for that tiddler slice.  To keep the grid display from getting very wide, the slice names used as column headings are not initially displayed.  ''Click directly above the column to show/hide that heading'', or toggle all column headings at once by clicking the {{{>>>}}} symbol in the upper-left corner of the grid display.
!!!!!Documentation
>see [[SliceGridPluginInfo]]
!!!!!Revisions
<<<
2008.08.15 [1.0.3] add brackets around row headings when wikifying so that non-wikiword tiddler titles are linked
2008.08.13 [1.0.2] wikify row headings (in addition to slice value cells) whenever 'wikify' param is used
|please see [[SliceGridPluginInfo]] for additional revision details|
2007.01.30 [0.0.1] started
<<<
!!!!!Code
***/
//{{{
version.extensions.sliceGrid= {major: 1, minor: 0, revision: 3, date: new Date(2008,8,15)};

config.macros.sliceGrid= {
	sizeSliceName: "TiddlerSize", // shadow slice used for retrieving and showing tiddler size as a grid column
	noSlicesMsg: "\n|~SliceGrid: there are no slices to display|\n",
	handler:
	function(place,macroName,params) {
		this.slicesRE=/(?:^\|\s*[\'\/]*~?(\w+)\:?[\'\/]*\s*\|\s*(.*?)\s*\|$)/gm;
		this.wikify=false; // wiki-syntax in slices
		this.edit=false; // 'click-to-edit' feature
		this.verbose=false; // debugging/performance feedback messages
		this.alltiddlers=false; // rows for all tiddlers (even if no slices)
		this.inline=false; // slice value in cell (instead of mouseover)
		this.headers=false; // column headers
		this.cliplength=0; // limit inline display text length (0=no limit)
		this.slices=[]; // slices to show (columns)
		var tablewidth="auto"; // default CSS for table width
		var p=params.shift();
		while (p) {
			if (p.substr(0,6).toUpperCase()=="WIDTH:")
				tablewidth=p.substr(6);
			else if (p.substr(0,5).toUpperCase()=="TAGS:") {
				if (p.substr(5,1)=="@") { // get tags from tiddler
					var tid=store.getTiddler(p.substr(6));
					if (p.substr(6)=="here") {
						var here=story.findContainingTiddler(place);
						if (here) var tid=store.getTiddler(here.getAttribute("tiddler"));
					}
					if (tid) var tags=tid.tags;
				}
				else if (p.substr(5,1)=="+") { // get tags from tiddler contents
					var tid=store.getTiddler(p.substr(6));
					if (p.substr(6)=="here") {
						var here=story.findContainingTiddler(place);
						if (here) var tid=store.getTiddler(here.getAttribute("tiddler"));
					}
					if (tid)
						{ var tags=tid.text.readBracketedList(); }
				}
                                else if (p.substr(5,1)=="=") { // get tags from value
                                       var tags=p.substr(6).readMacroParams();
                                }
				else var tags=p.substr(5).readBracketedList();
			}
			else if (p.substr(0,7).toUpperCase()=="SLICES:") {
				if (p.substr(7,1)=="@") { // get slices from tiddler
					var tid=p.substr(8);
					var tiddler=store.getTiddler(tid);
					if (tid=="here") {
						var here=story.findContainingTiddler(place);
						if (here) var tiddler=store.getTiddler(here.getAttribute("tiddler"));
					}
					if (tiddler) {
						var slices=tiddler.getSlices(tiddler.title); for (var s in slices) this.slices.push(s);
					}
				}
				else if (p.substr(7,1)=="+") { // get slices from tiddler contents
					var tid=p.substr(8);
					var tiddler=store.getTiddler(tid);
					if (tid=="here") {
						var here=story.findContainingTiddler(place);
						if (here) var tiddler=store.getTiddler(here.getAttribute("tiddler"));
					}
					if (tiddler)
						{ this.slices=tiddler.text.readBracketedList(); }
				}
				else this.slices=p.substr(7).readBracketedList();
			}
			else switch (p.toUpperCase()) {
				case "EDIT":
					this.edit=true && !readOnly; break; // no editing allowed if readOnly mode
				case "WIKIFY":
					this.wikify=true; break;
				case "VERBOSE":
					this.verbose=true; break;
				case "ALL":
					this.alltiddlers=true; break;
				case "INLINE":
					this.inline=true; this.headers=true; break; // default to show headers with inline grid
				default:
					if (!isNaN(p)) { this.cliplength=p; break; }
					else displayMessage("unrecognized parameter: "+p);
			}
			p=params.shift();
		}
		// get rows and columns
		var rows=[]; var cols=[]; var total=0;
		var tiddlers=store.getTiddlers("title","excludeLists"); // get all tiddlers (except hidden ones)
		if (tags && tags.length) for (t=0;t<tiddlers.length;t++) // filter out tiddlers with no matching tags
			if (!tiddlers[t].tags.containsAll(tags)) { tiddlers.splice(t,1); t--; } // remove non-matching tiddler -- YBA 22.09.08 patch to get a AND operation
		for (i=0; i<tiddlers.length; i++) {
			var slices=this.getSlices(tiddlers[i].title);
			var count=0; for (var s in slices) { cols.pushUnique(s); count++; total++;}
			if (count || this.alltiddlers) rows.push(tiddlers[i].title); // only show rows for tiddlers with slices
		}
		if (!cols.length) { wikify(this.noSlicesMsg,place); return; }
		if (this.verbose) displayMessage("Found %0 slices using %1 slice names in %2 tiddlers".format([total, cols.length,rows.length]));

		// get optional list of slices to show
		if (this.slices.length) var cols=this.slices;

		// generate HTML table
		var out="";
		out+="<html><table cellpadding='0' cellspacing='0' style='border:0;border-collapse:collapse;width:"+tablewidth+"'>";
		// column headings
		out+="<tr style='border:0;'><td style='text-align:right;border:0'>";
		out+="<a href='javascript:;' style='font-size:80%;'";
		out+="	title='show all column headings'";
		out+="	onclick='return config.macros.sliceGrid.toggleAllColumns(this,event,"+(this.headers?"true":"false")+")'>";
		out+=this.headers?"&lt;&lt;&lt;":"&gt;&gt;&gt;";
		out+="</a>";
		out+="</td>";
		for (var i=0;i<cols.length;i++) {
			out+="<td style='text-align:center;cursor:pointer;border:0;padding-left:2px;padding-right:2px;' ";
			out+="	title='show/hide column heading' ";
			out+="	onclick='return config.macros.sliceGrid.toggleColumn(this,event)'>";
			out+="<span style='display:"+(this.headers?"block":"none")+"'>"+cols[i]+"</span>";
			out+="</td>";
		}
		out+="</tr>";
		for (var i=0;i<rows.length;i++) {
			var tiddlersrc=rows[i].replace(/"/g,"&#x22;");
			out +="<tr style='border:0'>";
			// row heading
			out +="<td style='text-align:right;border:0;padding-right:2px;white-space:nowrap;"+(this.inline?'width:1%':'')+";'>";
			out +="<a href='javascript:;' tid=\""+tiddlersrc+"\" class='slicegrid_heading' ";
			out +="		onclick='story.displayTiddler(this,this.getAttribute(\"tid\"));return false'>"+tiddlersrc+"</a>";
			out +="</td>";
			var slices=this.getSlices(rows[i]);
			for (var j=0;j<cols.length;j++) {
				var val=slices[cols[j]]; if (!val) val="";
				var bgcolor=val.length?"#999":"transparent";
				var content="&nbsp;";
				if (val.length && this.inline) {
					content=val.htmlEncode();
					if (this.cliplength) content=val.substr(0,this.cliplength)+(val.length>this.cliplength?"...":"");
					bgcolor="transparent";
				}
				out+="<td style='background-color:"+bgcolor+";border:1px solid;"+(!this.inline?'width:1em;':'');
				if (this.inline && cols[j]==this.sizeSliceName) out+="text-align:right !important;"; // right align tiddler size pseudo-slice
				out+="'"; 
				if (this.edit && !(cols[j]==this.sizeSliceName)) { // add edit-in-place, except for tiddler size pseudo-slice
					var onclick="return config.macros.sliceGrid.editSlice(this,event,this.getAttribute(\"tid\"),\""+cols[j]+"\","+(this.inline?"true":"false")+")";
					out+=" tid=\""+tiddlersrc+"\" onclick='"+onclick+"'";
				}
				out+=" title=\""+tiddlersrc+"::"+cols[j]+(!this.inline?("="+val):"")+"\"";
				out+="><span class='slicegrid_content'>"+content+"</span></td>";
			}
			out+="</tr>";
		}
		out+="</table>";
		out+="</html>";
		var span=createTiddlyElement(place,"span")
		span.innerHTML=out;
		if (this.wikify) {
			// find all TD's in table and replace span content with wikified elements
			var tds=span.getElementsByTagName("td");
			for (var t=0; t<tds.length; t++) {
				var content=tds[t].firstChild;
				if (hasClass(content,"slicegrid_heading")||hasClass(content,"slicegrid_content")) {
					var txt=getPlainText(content);
					if (hasClass(content,"slicegrid_heading")) txt="[["+txt+"]]";
					removeChildren(content);
					wikify(txt,content);
				}
			}
		}
	},
	toggleAllColumns:
	function(here,event,defOpen) {
		if (here.expanded==undefined) here.expanded=defOpen;
		var ex=here.expanded=!here.expanded; 
		here.innerHTML=ex?"&lt;&lt;&lt;":"&gt;&gt;&gt;";
		here.title=ex?'hide all column headings':'show all column headings';
		var cells=here.parentNode.parentNode.getElementsByTagName("td");
		for (i=1; i<cells.length; i++) cells[i].firstChild.style.display=ex?"inline":"none";
		event.cancelBubble = true;
		if (event.stopPropagation) event.stopPropagation();
		return(false);
	},
	toggleColumn:
	function(here,event) {
		here.firstChild.style.display=(here.firstChild.style.display=="none")?"inline":"none";
		event.cancelBubble = true;
		if (event.stopPropagation) event.stopPropagation();
		return(false);
	},
	editSlice:
	function(here,event,tid,slice,inline) {
		// replace prompt box with edit field that is displayed until onBlur
		if (here.editing) return false; // already editing... don't re-init

		var onkeyup='if (event.keyCode==13)'; // SAVE and END
		onkeyup+='	{ config.macros.sliceGrid.setSlice(this.getAttribute(\"tid\"),"'+slice+'",this.value); this.blur(); }';
		onkeyup+='else if (event.keyCode==27)'; // END without saving
		onkeyup+='	{ this.blur(); }';

		var onblur="var tid=this.getAttribute(\"tid\"); var slice=\""+slice+"\"; var currval=config.macros.sliceGrid.getSlice(tid,slice); ";
		onblur+="if (this.value!=currval && confirm(tid+\"::\"+slice+\" has changed... save value?\"))";
		onblur+="	{ config.macros.sliceGrid.setSlice(tid,slice,this.value); currval=this.value; }";
		onblur+="var target=this.parentNode;";
		onblur+="target.editing=false;";
		onblur+="target.style.backgroundColor=target.getAttribute(\"savedColor\");";
		onblur+="target.style.padding=target.getAttribute(\"savedPadding\");";
		onblur+="target.style.width=target.getAttribute(\"savedWidth\");";
		onblur+="if (config.macros.sliceGrid.wikify) { removeChildren(target); wikify(currval,target); }";
		onblur+="else target.innerHTML="+(inline?'currval':'\"&nbsp;\"')+";";

		var style="font-size:1em;font-family:inherit;width:95%;margin:0px;padding:1px 0px 1px 3px;border:0;";
		var title=tid+"::"+slice+" (ENTER=submit, ESC=cancel)";

		here.setAttribute("savedWidth",here.style.width); if (!inline) here.style.width="99%";
		here.setAttribute("savedPadding",here.style.padding); here.style.padding="0px"; 
		here.setAttribute("savedColor",here.style.backgroundColor); here.style.backgroundColor="#fff";
		here.innerHTML="<input type='text' tid=\""+tid.replace(/"/g,"&#x22;")+"\" onkeyup='"+onkeyup+"' onblur='"+onblur+"' style='"+style+"' title='"+title+"'>";
		here.firstChild.value=config.macros.sliceGrid.getSlice(tid,slice); // avoids conflicts with nested quoting in HTML
		here.firstChild.focus();
		here.firstChild.select();
		here.editing=true;

		event.cancelBubble = true; if (event.stopPropagation) event.stopPropagation(); return(false);
	},
	getSlice:
	function(tid,slice) {
		var slices=config.macros.sliceGrid.getSlices(tid);
		return slices[slice]?slices[slice]:"";
	},
	getSlices:
	function(tid) {
		var slices = {};
		var text = store.getTiddlerText(tid,"");
		slices[this.sizeSliceName]=text.length.toString();  // 'shadow slice' for displaying tiddler size
		this.slicesRE.lastIndex = 0;
		do {
			var m = this.slicesRE.exec(text);
			if (m) { if (m[1]) slices[m[1]] = m[2]; else slices[m[3]] = m[4]; }
		} while(m);
		return slices;
	},
	setSlice:
	function(tid,slice,val) {
		var oldval=this.getSlice(tid,slice);
		if (val==oldval) return false; // value is unchanged... do nothing
		// find slice within tiddler text
		var tiddler=store.getTiddler(tid);
		this.slicesRE.lastIndex = 0;
		var lastIndex=0;
		do {
			var m=this.slicesRE.exec(tiddler.text);
			if (m && (m[1]==slice||m[3]==slice)) break;
			if (m) lastIndex=this.slicesRE.lastIndex;
		} while(m);
		if (m) { // if matching slice was found
			if (oldval.length) { // replace old value with new value
				var pos=RegExp.lastMatch.indexOf(oldval);
				var newSlice=RegExp.lastMatch.substr(0,pos)+val+RegExp.lastMatch.substr(pos+oldval.length);
			} else // insert new value into empty slice
				var newSlice=RegExp.lastMatch.substr(0,RegExp.lastMatch.length-1)+val+"|";
			var newText=RegExp.leftContext+newSlice+RegExp.rightContext;
		} else { // create new slice following last slice (or at start of tiddler if no slices)
			var newSlice="|"+slice+"|"+val+"|\n";
			var newText=newSlice+tiddler.text
			if (lastIndex) var newText=tiddler.text.substr(0,lastIndex+1)+newSlice+tiddler.text.substr(lastIndex+1);
		}
		// write tiddler contents
		var user=config.options.txtUserName; var mod=new Date();
		if (config.options.chkForceMinorUpdate)
			{ var user=tiddler.modifier; var mod=tiddler.modified; }
		store.saveTiddler(tid,tid,newText,user,mod,tiddler.tags,tiddler.fields);
		displayMessage(tid+"::"+slice+" has been "+(m?"updated":"created"));
		return(false);
	}
};
//}}}
/***
|Name|SliceGridPluginInfo|
|Source|http://www.TiddlyTools.com/#SliceGridPlugin|
|Documentation|http://www.TiddlyTools.com/#SliceGridPluginInfo|
|Version|1.0.3|
|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.3|
|Type|documentation|
|Requires||
|Overrides||
|Description|documentation for SliceGridPlugin|
Rows are tiddlers, columns are slice names.  If a tiddler has a value defined for a given slice, that grid cell is colored. Move the mouse over a grid cell to view the value for that tiddler slice.  To keep the grid display from getting very wide, the slice names used as column headings are not initially displayed.  ''Click directly above the column to show/hide that heading'', or toggle all column headings at once by clicking the {{{>>>}}} symbol in the upper-left corner of the grid display.
!!!!!Usage
<<<
{{{<<sliceGrid [[tags:tag tag...]] [[slices:slice slice...]]  inline wikify edit all cliplength verbose>>}}}

all parameters are optional, where:
''tags:'' (list)
> display rows only for those tiddlers with at least ONE of the specified tags (space-separated).  default is to show all tiddlers that have at least one slice defined, regardless of tags
> To use a list of tags defined in a separate tiddler, specify ''{{{tags:+TiddlerName}}}''.  To use the same tags that are being used by a given tiddler, use ''{{{tags:@TiddlerName}}}''
''slices:'' (list)
> display columns for the specified slices.  Default is to display all defined slices
> To use a list of slices defined in a separate tiddler, specify ''{{{slices:+TiddlerName}}}''.  To use the same slices that are being used by a given tiddler, use ''{{{slices:@TiddlerName}}}''.  Note: a special "shadow slice", ''TiddlerSize'', can be used to automatically compute and display the tiddler size in a grid column.  If a tiddler contains a slice named ''TiddlerSize'', then it supercedes the computed value.
''inline'' (keyword)
> display slice value directly in table cell.  Default is to use colored blocks for defined slices, with mouseover 'tooltip' to show value
''wikify'' (keyword)
> parse and format wiki-syntax contained in slice values.  Default is to show slice values "as-is", without converting embedded formatting.
''edit'' (keyword)
> enable click-to-edit to change slice values.  Default is to display only.
''all'' (keyword)
> display a row for each tiddler, even tiddlers that have NO slices defined.   Default is to only show tiddlers that have slices defined. Note: if tags: param is used to select tiddler by tag, then only tiddlers with matching tags are included.
''cliplength'' (number)
> # of characters to show in table cell when using 'inline' keyword.  Text display is truncated with "..."
''verbose'' (keyword)
> adds messages to report on slice grid processing

Note: uses modified version of slices pattern:
{{{slicesRE = /(?:^\|[\'\/]*~?(\w+)\:?[\'\/]*\|\s*(.*?)\s*\|$)/gm;}}}
* eliminates TONS of spurious slices caused by over-eager "description" format pattern matches
* enforces beginning-of-line and end-of-line sequences.  (Allows slice values to contain |, such as in pretty links)
<<<
!!!!!Examples
<<<
{{{<<sliceGrid inline wikify edit [[slices:Version Description]]>>}}}
+++[click to view example...]...<<sliceGrid inline wikify edit [[slices:Version Description]]>>===

{{{<<sliceGrid edit tags:systemConfig>>}}}
+++[click to view example...]...<<sliceGrid edit tags:systemConfig>>===
<<<
!!!!!Revisions
<<<
2008.08.15 [1.0.3] add brackets around row headings when wikifying so that non-wikiword tiddler titles are linked
2008.08.13 [1.0.2] wikify row headings (in addition to slice value cells) whenever 'wikify' param is used
2008.05.01 [1.0.1] in editSlice(), corrected fixup for titles containing double-quotes
2007.09.18 [1.0.0] added 'wikify' param and handling to format wiki-syntax contained in slice values
2008.05.01 [1.0.1] in editSlice(), corrected fixup for titles containing double-quotes
2007.09.18 [1.0.0] added 'wikify' param and handling to format wiki-syntax contained in slice values
2007.08.02 [0.9.8] when generating HTML, replace double-quotes in tiddler titles with {{{&#x22;}}} (entity equivalence) to avoid ambiguity with quotes used as HTML attribute syntax delimiters.
2007.07.22 [0.9.7] removed hard-coded 99% 'width bias' and wordwrap from Description cells, default to autosize (equal size for all columns).  Added width:xxxx param to easily stretch table to fit containing space
2007.06.08 [0.9.6] fixed generation of javascript for rows headings and in edit_slice(), so tiddler titles containing single-quote characters will not create syntax errors in the DOM event handlers
2007.04.24 [0.9.5] added 'shadow slice', "TiddlerSize", so that tiddler size can be retrieved and displayed as a grid column.  Also, fixed click on column headings for show/hide...
2007.04.13 [0.9.4] when getting tiddlers, honor "excludeLists" tag so that 'hidden' tiddlers aren't displayed in the grid
2007.04.08 [0.9.3] corrected setting of cell background color (non-inline grid 'blocks') after edit-in-place adds/clears a slice value
2007.04.07 [0.9.2] support edit in place for non-inline grids (color 'blocks'), and also handle creating new slices in tiddlers where a slice didn't exist previously
2007.04.07 [0.9.1] use locally-defined slicesRE (and getSlice() method) instead of re-defining core slicesRE.  Avoids breaking use of shadow ColorPalette slices.  
2007.04.05 [0.9.0] Added functioning "set slice" handler and "edit-in-place" feature.  Eliminated mouseover popups (use tooltips instead).  Added ''tags:'', ''slices:'' and ''edit'' params.  Lots of code cleanup.
2007.04.04 [0.8.1] in info() and popup() functions, instead of creating popup display, use element tooltip to show mouseover details.   Avoids incorrect positioning of popup if the 'root' element for the popup is in a DIV that has been scrolled.
2007.03.25 [0.8.0] change to BETA status and added support for "tags:tag tag tag tag" filtering param
2007.02.03 [0.0.2] change display of slices from "tiddler[slidename]" to "tiddler:slicename" to match TW slice syntax
2007.01.30 [0.0.1] started (adapted from TagGridPlugin)
<<<
/***
|Name|SortListPlugin|
|Version|0.0.3|
|Author|Yoann BABEL <ybabel@ideia.fr> & Jean-Cédric THÉROND <jctherond@ideia.fr>|
|License|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|~CoreVersion|2.4.0|
|Type|plugin|
|Requires|InlineJavascriptPlugin,NestedSlidersPlugin (Optional)|
|Options|##Configuration|
|Overrides||
|Description|Displays to do information from data elements in the calling tiddler.|
!!!!!Usage
Use sorlist in a tiddler, or in a ViewTemplate
All the lines in the tiddler are displayed in a sortable array
all text after ---- is ignored and not included in the sortable list
!!!!!Configuration
<<<
nope
<<<
!!!!!Revisions
<<<
2009.09.18 |0.0.3| add ---- support
2008.09.12 [0.0.2] fields support added
2008.09.09 [0.0.1] initial release
<<<
!!!!!Known Bugs
* none for the moment
!!!!!Code
***/
//{{{
version.extensions.SortList = {major: 0, minor: 0, revision: 2, date: new Date(2008,9,12)};

config.macros.SortList = {
  handler:
  function(place,macroName, params, wikifier) {
    if (!window.story) window.story=window;
    if (!this.checkForExtensions(place, macroName)) {
      return;
    }
    // Check for NestedSlidersPlugin.
    var nSliders = this.checkForNestedSliders(place, macroName);
    var wrapper = createTiddlyElement(place, "span");
    var title= story.findContainingTiddler(place).id.substr(7);
    var myTiddler = store.getTiddler(title);
    var titleURI = encodeURIComponent(title);
    var text = "";
    var completeText = "";
    var p=params.shift();
    var fieldsToInspect = [];
    var splitParamsFieldsRE = new RegExp("[,]+", "g");
    var FTILength = 0;

    while (p) {
	if (p.substr(0,7).toUpperCase()=="FIELDS:" || p.substr(0,1).match(splitParamsFieldsRE) ){
		fieldsToInspect = p.substring(7).split(splitParamsFieldsRE);
	}
	else {
		if (!isNaN(p.toUpperCase())) { this.cliplength=p; break; }
		else displayMessage("unrecognized parameter: "+p);
	}
	p=params.shift();
    }
    FTILength = fieldsToInspect.length;

    // Collect the number of tasks in this tiddler.
    var dataCount = parseInt(this.getCount(title));

    // Shortcut variable setup for the scripts below.
    var headJs = 'var t = store.getTiddler(title);';
    headJs += 'var count = parseInt(config.macros.SortList.getCount(title)) || 0;';

    // Shortcut to refresh the current tiddler, used below.
    var refreshJs = 'store.setDirty(title, true);';
    refreshJs += 'story.refreshTiddler(title,null,true);';

    // Insert a simple style sheet eliminating the borders around the table.
    text += '<html><style id="ToDoPlugin" type="text/css">';
    text += '.viewer .noBorder,.viewer .noBorder td,.viewer .noBorder th,.viewer .noBorder tr{border:0} ';
    text += '</style></html>';

    /*
    // Inline script to add a task to the end of the list.
    text += '<script label="Add task">';
    text += 'var title=story.findContainingTiddler(place).id.substr(7);';
    text += headJs;
    text += 'config.macros.SortList.TDPWriter(title,count,\'Task\');';
    text += refreshJs;
    text += '</script>';
    */

    // Global function to swap a task from this tiddler's list with another either above or below it.
    text += '<script>';
    text += 'window.TDPSwapTask = function(title,item, pos) {';
    text += headJs;
    text += 'var i = parseInt(item);';
    text += '  var tmpVal = config.macros.SortList.TDPReader(title,i);';
    text += '  config.macros.SortList.TDPWriter(title,i,config.macros.SortList.TDPReader(title,String(parseInt(i+pos))));';
    text += '  config.macros.SortList.TDPWriter(title,String(parseInt(i+pos)),tmpVal);';
    text += '};';
    text += '</script>';

    // Global function to delete a task from this tiddler's list.
    text += '<script>';
    text += 'window.TDPDeleteTask = function(title,item) {';
    text += headJs;
    text += 'var oneFewer = String(parseInt(count-1));';
    text += 'var i = parseInt(item);';
    text += 'for (var v=i+1;v<count;v++) TDPSwapTask(title,v,-1);';
    text += 'config.macros.SortList.TDPErase(title,oneFewer);';
    text += refreshJs;
    text += '};';
    text += '</script>';

    text += "\n|noBorder|k";
    text += "\n|!|!&nbsp;";
	for (var i = 0; i < FTILength; i++ ){
		text += "|!"+fieldsToInspect[i];
	}
    text += "|!|!|";

    for (var i = 0; i < dataCount ; i++) {
      var addDate = "";
      var cdate = "";
      var textboxONC = "";
      var checkboxONC = "";
      var checkboxCMD = "";
      var deleteCMD = "";

      // Setup two commonly used lines in the onclick scripts.
      inlineSetup = 'var title=&#x27;' + title + '&#x27;;';
      refreshTiddler = 'story.refreshTiddler(title,null,true);';

      // Create the onchange script. (&#x27; is a single quote)
      // Assign unique HTML ID to the input element, "tF{TiddlerName}{count}"
      textboxONC = inlineSetup;
      textboxONC += 'config.macros.SortList.TDPWriter(title,' + i + ',';
      textboxONC += 'document.getElementById(&#x27;tF' + titleURI + i + '&#x27;).value;';//.replace(/&#x27;/g,&#x27;\\&#x27;&#x27;));';
      textboxONC += 'store.setDirty(title, true);';

      // Create the delete task table entry.
      deleteCMD = '|<script label="&#x2326;" title="delete task">';
      deleteCMD += 'TDPDeleteTask("' + title + '",' + i + ');';
      deleteCMD += '</script>';

      // Create the text entry box.
      textentryCMD = '|'+this.TDPReader(title,i,FTILength,fieldsToInspect)+' |';//.replace(/'/,'&#x27;')+' |';

        text += "\n";
	
        // Output the delete task button.
        text += deleteCMD;

        text += textentryCMD;

        // Move selected task up one space.
       if (i<dataCount-1) {
          text += '<script label="&#x25BC;" title="move task down">';
          text += 'var title = \'' + title + '\';';
          text += 'TDPSwapTask(title,' + i + ',+1);';
          text += refreshJs;
          text += '</script>';
        }
        text += '|';
        // Move selected task down one space.
        if (i>0) {
          text += '<script label="&#x25B2;" title="move task up">';
          text += 'var title = \'' + title + '\';';
          text += 'TDPSwapTask(title,' + i + ',-1);';
          text += refreshJs;
          text += '</script>';
        }
        text += '|';
    } // For loop

    // Add the text gathered above for completed items, if any.
    text += completeText;

  // YBA 18.09.2008 "----" patch
  var lines = new Array();
  var chunks = new Array();
  chunks = myTiddler.text.split('\n----\n');
  chunks[0] = text;
  text = chunks.join('\n----\n'); 
  // YBA 18.09.2008 "----" patch

    wikify(text, wrapper, null);
    //wikifier.source = "";
  }
}

// Internal.
//
config.macros.SortList.TDPWriter = function(title,item,value) {
  var t = store.getTiddler(title);
  var i = parseInt(item);
  var lines = new Array();
  var text = "";
  var chunks = new Array();   // YBA 18.09.2008 "----" patch
  chunks = t.text.split('\n----\n');   
  text = chunks[0];  
  lines = text.split('\n');
  lines[i] = value;
  chunks[0] = lines.join('\n');  
  t.text = chunks.join('\n----\n');    
}

// Internal.
//
config.macros.SortList.TDPReader = function(title,item,FTILength,fieldsToInspect) {
  var t = store.getTiddler(title);
  var i = parseInt(item);
  var Ctiddler;
  var lines = new Array();
  var text = "";
  var chunks = new Array(); // YBA 18.09.2008 "----" patch
  chunks = t.text.split('\n----\n');
  text = chunks[0];
  lines = text.split('\n');
  text = lines[i];//.replace(/'/g, "&#x27;").replace(/"/g, "&quot;");

        // JCT 12.09.2008 parse ref to tiddlers PATCH
	var firstDoubleHook = parseInt(lines[i].indexOf("[[",0) + 2);
	var secondDoubleHook = parseInt(lines[i].indexOf("]]",firstDoubleHook));	
	var TwoBeforEnd = parseInt(lines[i].length) - 2;

	var trueTitle = lines[i].slice(firstDoubleHook, secondDoubleHook);

	if (store.getTiddler(trueTitle)){
		Ctiddler = store.getTiddler(trueTitle);
		for (var i = 0; i < FTILength; i++ ){
			if (Ctiddler.fields[fieldsToInspect[i]]){
			  text += " | "+Ctiddler.fields[fieldsToInspect[i]];
			}else{ text += " | ";}
		}
	}else{
		for (var j = 0; j < FTILength; j++ ){
			text += "|";
		}
	}

  return(text);
}

// Internal.
//
config.macros.SortList.getCount = function(title,item,field) {
  var t = store.getTiddler(title);
  var lines = new Array();
  var text = "";
  text = t.text.split('\n----\n')[0]; // YBA 18.09.2008 "----" patch
  lines = text.split('\n');
  return(lines.length);
}


// Internal
//
config.macros.SortList.TDPErase = function(title,item) {
  var t = store.getTiddler(title);
  var i = parseInt(item);
  var lines = new Array();
  var text = "";
  var chunks = new Array(); // YBA 18.09.2008 "----" patch
  chunks = t.text.split('\n----\n');
  text = chunks[0];
  lines = text.split('\n');
  lines.splice(i,1);
  chunks[0] = lines.join('\n');
  t.text = chunks.join('\n----\n'); 
}

// Internal.
//
config.macros.SortList.checkForExtensions = function(place,macroName) {
  if (!version.extensions.inlineJavascript) {
    displayMessage("<<" + macroName + ">> requires the InlineJavascriptPlugin (You can get it from http://www.tiddlytools.com/#InlineJavascriptPlugin)");
    return false;
  }
  return true;
}

// Internal.
//
config.macros.SortList.checkForNestedSliders = function(place,macroName) {
  if (!version.extensions.nestedSliders) {
    return false;
  }
  return true;
}
//}}}
<!--{{{-->
<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='SortList'></div>
<div class='tagClear'></div>
<!--}}}-->
/***
|''Name''|SparklinePlugin|
|''Description''|provides support for [[sparklines|http://www.edwardtufte.com/bboard/q-and-a-fetch-msg?msg_id=0001OR&topic_id=1]]|
|''Version''|1.0.0|
|''Status''|stable|
|''Source''|http://www.tiddlywiki.com/plugins.html#SparklinePlugin|
|''~CodeRepository:''|http://svn.tiddlywiki.org/Trunk/association/plugins/SparklinePlugin/SparklinePlugin.js |
|''License''|[[BSD open source license]]|
|''~CoreVersion''|2.3.0|
|''Feedback''|[[TiddlyWiki community|http://groups.google.com/group/TiddlyWiki]] |
|''Keywords''|visualization|
!Usage
{{{
<<sparkline numbers>>
}}}
The macro accepts space-separated numeric values as parameter.
!!Examples
Activity on http://www.tiddlywiki.com during the month of April 2005:
{{{<<sparkline 163 218 231 236 232 266 176 249 289 1041 1835 2285 3098 2101 1755 3283 3353 3335 2898 2224 1404 1354 1825 1839 2142 1942 1784 1145 979 1328 1611>>}}}
<<sparkline 163 218 231 236 232 266 176 249 289 1041 1835 2285 3098 2101 1755 3283 3353 3335 2898 2224 1404 1354 1825 1839 2142 1942 1784 1145 979 1328 1611>>
!Code
***/
//{{{
if(!version.extensions.SparklinePlugin) {
version.extensions.SparklinePlugin = {installed:true};

//--
//-- Sparklines
//--

config.macros.sparkline = {};
config.macros.sparkline.handler = function(place,macroName,params)
{
	var data = [];
	var min = 0;
	var max = 0;
	var v;
	for(var t=0; t<params.length; t++) {
		v = parseInt(params[t]);
		if(v < min)
			min = v;
		if(v > max)
			max = v;
		data.push(v);
	}
	if(data.length < 1)
		return;
	var box = createTiddlyElement(place,"span",null,"sparkline",String.fromCharCode(160));
	box.title = data.join(",");
	var w = box.offsetWidth;
	var h = box.offsetHeight;
	box.style.paddingRight = (data.length * 2 - w) + "px";
	box.style.position = "relative";
	for(var d=0; d<data.length; d++) {
		var tick = document.createElement("img");
		tick.border = 0;
		tick.className = "sparktick";
		tick.style.position = "absolute";
		tick.src = "data:image/gif,GIF89a%01%00%01%00%91%FF%00%FF%FF%FF%00%00%00%C0%C0%C0%00%00%00!%F9%04%01%00%00%02%00%2C%00%00%00%00%01%00%01%00%40%02%02T%01%00%3B";
		tick.style.left = d*2 + "px";
		tick.style.width = "2px";
		v = Math.floor(((data[d] - min)/(max-min)) * h);
		tick.style.top = (h-v) + "px";
		tick.style.height = v + "px";
		box.appendChild(tick);
	}
};


}
//}}}
<!--{{{-->
<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='tagged' macro='tags'></div>
<span class='help' macro='showWhen config.options.chkVerboseHelp'><span class='viewer' macro='tiddler SprintViewTemplateHelp'></span></span>
<div class='viewer' macro='PopulateUpdateList want:UserStory dontwant:{{store.getTiddlerText("excludeSprint")}}'></div>
<div class='viewer' macro='SortList'></div>
<h1>TaskBoard</h1>
<div class='viewer' macro='tiddler TaskBoardBySprint with: {{tiddler.title}}'></div>
<div class='tagClear'></div>
<h1>BurdownChart</h1>
<div class='viewer' macro='tiddler sliceGridBySprint with: {{tiddler.title}}'></div>
<hr/>
<div class='viewer' macro='sliceGrid edit inline tags:=task {{tiddler.title}} slices:+SprintDays'></div>
<hr/>
<div class='viewer' macro='histoGram tags:={{tiddler.title}} width:200 slices:+SprintDays'></div>
<!--}}}-->
{{fr{Pour pré-remplir la liste des UserStory, cliqué sur ce bouton. Il vous suffit ensuite de supprimer celles que vous ne voulez pas. Utilisez '- - - -' pour séparer la liste des UserStory du reste du contenu du sprint.}}}
{{en{To fill the UserStory list, click on that button. You just have to delete those you don't want. Use '- - - -' to separate the rest of the sprint description with that list}}}
{{fr{
! Avant de commencer votre projet
* L'[[Introduction]] présente les fonctionnalités de cet outil
* En cas de problème consultez l'[[Help]] ou le HowTo
! Préliminaires (Sprint0)
* Définissez vos [[Parameters]] généraux (nom du projet, features, notion de fini)
* Rédigez votre [[ProductBacklog]]
* Saisissez des idées en vrac [[Draft]] si nécessaire
* Voir le [[Overview]] de votre projet
! Sprintez
* Liste des sprints <<newTiddler label:"new Sprint" tag:sprint title:"Nouveau sprint" text:{{store.getTiddlerText("EmptySprint")}} >>
<<forEachTiddler where 'tiddler.tags.contains("sprint")' sortBy 'tiddler.title'
write '"** [["+tiddler.title+"]]\n"'>>
* Taches a faire : (ou bien voir le TaskBoard - ou le [[BurndownChart]])
<<forEachTiddler where 'tiddler.tags.contains("task") && !tiddler.tags.contains("Done")'
write '"** [["+tiddler.title+"]]\n"'>>
* Vérifiez que toutes les tâches ont au moins un tag d'état :
<<forEachTiddler where 'tiddler.tags.contains("task") && !tiddler.tags.contains("InProgress") && !tiddler.tags.contains("ToDo") && !tiddler.tags.contains("ToVerify") && !tiddler.tags.contains("Done")'
write '"** [["+tiddler.title+"]]\n"'>>
* Chaque jours :
** DailyScrum
** Remplir le reste à faire sur les tâches en cours [[BurndownChart]]
}}}{{en{
! Before you start
* [[Introduction]] presents the features of this tool
* You can consult[[Help]] or HowTo to get further information
! Preliminaries (Sprint0)
* Define your global [[Parameters]] 
* Fill the [[ProductBacklog]]
* You can also take some random [[Draft]] if necessary
* Take a look at the [[Overview]] 
! Sprint
* Sprint list <<newTiddler label:"new Sprint" tag:sprint title:"New sprint" text:{{store.getTiddlerText("EmptySprint")}} >>
<<forEachTiddler where 'tiddler.tags.contains("sprint")' sortBy 'tiddler.title'
write '"** [["+tiddler.title+"]]\n"'>>
* Tasks to do : (or take a look a the TaskBoard - or the [[BurndownChart]])
<<forEachTiddler where 'tiddler.tags.contains("task") && !tiddler.tags.contains("Done")'
write '"** [["+tiddler.title+"]]\n"'>>
* Check that all the tasks have a defined state :
<<forEachTiddler where 'tiddler.tags.contains("task") && !tiddler.tags.contains("InProgress") && !tiddler.tags.contains("ToDo") && !tiddler.tags.contains("ToVerify") && !tiddler.tags.contains("Done")'
write '"** [["+tiddler.title+"]]\n"'>>
* Every day :
** DailyScrum
** Fill the [[BurndownChart]]
}}}
/*{{{*/
* html .tiddler {height:1%;}

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

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

hr {height:1px;}

a {text-decoration:none;}

dt {font-weight:bold;}

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

.txtOptionInput {width:11em;}

#contentWrapper .chkOptionInput {border:0;}

.externalLink {text-decoration:underline;}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

.whenBackstage {display:none;}
.backstageVisible .whenBackstage {display:block;}

/* ============= new div based columns ================= */
.col {
  float: left;
  vertical-align:top;
}

.cols3, .cols2 {
	overflow: auto; /* contains floats. tnx FND */
}

/* IE not doing these right :( */
/* .cols3&gt;br, .col&gt;br { display:none; } */

/* so try this instead. it's annoying and will mean you have trouble 
with brs in non-mgtdlist content. .normal might help */
.cols2 br, .cols3 br  { display:none; }
.mgtdList br, .normal { display:block!important; }
.col .mgtdList { margin-bottom:1.5em; } /* since we're no longer seeing the brs... */

.cols3 .col {
  width: 33%;
}
.cols2 .col {
  width: 49%; /* 50% makes IE put them under each other */
}
.clear {
  clear: left;
}


/*}}}*/
/***
|Name|TaggedTemplateTweak|
|Source|http://www.TiddlyTools.com/#TaggedTemplateTweak|
|Documentation|http://www.TiddlyTools.com/#TaggedTemplateTweakInfo|
|Version|1.4.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.05.15 [1.4.0] support use of *shadow* tagged templates (e.g., [[DiscussionViewTemplate]] created by [[DiscussionPlugin]])
2008.05.10 [1.3.0] corrected handling for determining core template when using theme with sections
2008.05.01 [1.2.5] added support for tagged templates stored as sections in a theme
| please see [[TaggedTemplateTweakInfo]] for previous revision details |
2007.06.11 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.taggedTemplate= {major: 1, minor: 4, revision: 0, date: new Date(2008,5,15)};

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;

	// split core template into theme prefix and template name
	var theme="";
	var parts=template.split(config.textPrimitives.sectionSeparator);
	if (parts[1]) { theme=parts[0]; template=parts[1]; }
	else theme=config.options.txtTheme||""; // fallback if theme is not specified
	theme+=config.textPrimitives.sectionSeparator;

	// 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 to template
		var c=t.substr(0,1).toUpperCase()+t.substr(1); // capitalized for WikiWord title
		if (store.getTiddlerText(theme+t))	{ template=theme+t; break; } // theme##tagTemplate
		if (store.getTiddlerText(theme+c))	{ template=theme+c; break; } // theme##TagTemplate
		if (store.getTiddlerText(t)) 		{ template=t; break; }	     // tagTemplate
		if (store.getTiddlerText(c))		{ template=c; break; }	     // TagTemplate
	}
	return template;
}
//}}}
! Global
<<tiddler TaskBoardBySprint with:task>>
----
<<forEachTiddler where 'tiddler.tags.contains("sprint")'
write '"![["+tiddler.title+"]]\n<<tiddler TaskBoardBySprint with: "+tiddler.title+"$))\n"'>>
{{cols2{

{{col{

!!{{fr{A faire}}}{{en{To do}}}
<<forEachTiddler where 'tiddler.tags.contains("task") && tiddler.tags.contains("$1") && tiddler.tags.contains("ToDo")' 
write '"* [["+tiddler.title+"]]\n"'>>
}}}

{{col{

!!{{fr{En cours}}}{{en{In progress}}}
<<forEachTiddler where 'tiddler.tags.contains("task") && tiddler.tags.contains("$1") && tiddler.tags.contains("InProgress")'
write '"* [["+tiddler.title+"]]\n"'>>
}}}

}}}

{{cols2{

{{col{

!!{{fr{A vérfier}}}{{en{To verify}}}
<<forEachTiddler where 'tiddler.tags.contains("task") && tiddler.tags.contains("$1") && tiddler.tags.contains("ToVerify")'
write '"* [["+tiddler.title+"]]\n"'>>
}}}

{{col{
!!{{fr{Fait}}}{{en{Done}}}
<<forEachTiddler where 'tiddler.tags.contains("task") && tiddler.tags.contains("$1") && tiddler.tags.contains("Done")'
write '"* [["+tiddler.title+"]]\n"'>>

}}}

}}}
!!{{fr{Non taggé}}}{{en{Not tagged}}}
<<forEachTiddler where 'tiddler.tags.contains("task") && tiddler.tags.contains("$1") && !tiddler.tags.contains("InProgress") && !tiddler.tags.contains("ToDo") && !tiddler.tags.contains("ToVerify") && !tiddler.tags.contains("Done")'
write '"* [["+tiddler.title+"]]\n"'>>
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]]'><span style="padding-right:0.15em;" macro='monkeyTagger sprint source:sprint'><span style="padding-right:0.15em;" macro='monkeyTagger sprint source:status'><span style="padding-right:0.15em;" macro='monkeyTagger UserStory source:UserStory'></div>
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div macro='annotations'></div>
<div class='editor' macro='edit text'></div>
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser'></span></div>
<!--}}}-->
<<forEachTiddler where 'tiddler.tags.contains("task") && tiddler.tags.contains("$1")'
write '"* [["+tiddler.title+"]]\n"'>>
<!--{{{-->
<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>
<span macro='toggleTag ToDo .'></span>
<span macro='toggleTag InProgress .'></span>
<span macro='toggleTag ToVerify .'></span>
<span macro='toggleTag Done .'></span>
<span class='help' macro='showWhen config.options.chkVerboseHelp'><span class='viewer' macro='tiddler TaskViewTemplateHelp'></span></span>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<!--}}}-->
{{fr{Une tâche doit appartenir (=être taggée) à une UserStory, et à un ''@@color:red;Sprint@@'' (pour qu'elle puisse apparaitre dans son <b>BurndowChart</b>. Son état (Done, ToDo, InProgress, ToVerify) détermine dans quelle section du TaskBoard elle va apparaître.}}}
{{en{A task must belong (eg. be tagged by) a UserStory, and a ''@@color:red;Sprint@@'' so that it can appear in its BurndownChart. It's state (Done, ToDo, InProgress, ToVerify) determine in which section of the TaskBoard it will appear}}}
/***
|''Name:''|TiddlerListMacro|
|''Version:''|2.3 (8-Jan-2008)|
|''Source''|http://jackparke.googlepages.com/jtw.html#TiddlerListMacro ([[del.icio.us|http://del.icio.us/post?url=http://jackparke.googlepages.com/jtw.html%23TiddlerListMacro]])|
|''Author:''|[[Jack]]|
|''Type:''|Macro|
|''Documentation:''|[[TiddlerListMacroDocumentation]]|
!Usage
{{{<<tiddlerList parameter1:"value1" parameter2:"value2" ...>>}}}
See TiddlerListMacroDocumentation and TiddlerListMacroExamples
!Code
***/
//{{{
version.extensions.tiddlerList = {major: 2, minor: 3, revision: 0, date: new Date("Jan 08, 2008")};
// template = [header, item, separator, group, footer]
config.macros.tiddlerList={
 formats : {list:true, nlist:true, span:true, stack:true, csv:true, table:true},
 templates : {
 list : [ "%0\n", "* %0\n", "", "%group\n", "%0\n"],
 nlist : [ "%0", "# %0\n", "", "%group\n", "%0\n"],
 span : [ "%0", "%0", " ", "%group", "%0"],
 stack : [ "%0", "%0", "\n", "%group", "%0"],
 csv : [ "%0", "%0", ", ", "%0", "%0\n"],
 table : ["|!%0|\n", "|%0|\n", "", "|%group|\n", "|%0|\n"]
 },
 dateFormat : "DD MMM YYYY"
}

if (typeof gCurrentTiddler == 'undefined')
 var gCurrentTiddler;

config.macros.tiddlerList.handler = function(place,macroName,params,wikifier,paramString,tiddler)
{
 // Some globals
 var count=0, groupCount=0, theGroup="", lastGroup="", firstInGroup = false;
 var currentTiddler = tiddler;
 gCurrentTiddler = tiddler;
 var listWikiText="";
 var formats = this.formats;
 
 // SQL-Like parameters
 var parameters = paramString.parseParams("name",null,true);
 var pTags = parameters[0]["tags"]?parameters[0]["tags"][0].split(","):[];
 var pOrder = parameters[0]["order"]?parameters[0]["order"][0]:"title";
 var pTop = parameters[0]["top"]?parameters[0]["top"][0]:-1;
 var pText = parameters[0]["text"]?parameters[0]["text"][0]:"";
 var pTitle = parameters[0]["title"]?parameters[0]["title"][0]:"";
 var pSearch = parameters[0]["search"]?parameters[0]["search"][0]:"";
 var pFilter = parameters[0]["filter"]?parameters[0]["filter"][0]:"";
 var pHeader = parameters[0]["header"]?paramFormat(parameters[0]["header"][0]):"";
 var pFooter = parameters[0]["footer"]?paramFormat(parameters[0]["footer"][0]):"";
 var pGroup = parameters[0]["group"]?parameters[0]["group"][0]:"";
 var pDateFormat = parameters[0]["dateFormat"]?parameters[0]["dateFormat"][0]:this.dateFormat;
 var pCustomParameter = parameters[0]["customParameter"]?parameters[0]["customParameter"][0]:"";
 var pFormat = parameters[0]["format"]?parameters[0]["format"][0]:"list";
 pFormat = formats[pFormat]?pFormat:"list"
 
 // Separator
 var pSeparator = parameters[0]["separator"]?paramFormat(parameters[0]["separator"][0]):(parameters[0]["seperator"]?paramFormat(parameters[0]["seperator"][0]):this.templates[pFormat][2])

 // Template for group
 var pGroupTemplate = this.templates[pFormat][3];
 if (parameters[0]["groupTemplate"])
 pGroupTemplate = paramFormat(parameters[0]["groupTemplate"][0])
 pGroupTemplate = pGroupTemplate.replace("$))", ">>")
 
 // Template for group footer
 var pGroupFooterTemplate = "";
 if (parameters[0]["groupFooterTemplate"])
 pGroupFooterTemplate = paramFormat(parameters[0]["groupFooterTemplate"][0])
 pGroupFooterTemplate = pGroupFooterTemplate.replace("$))", ">>")
 
 // Template for item
 var pItemTemplate = this.templates[pFormat][1];
 if (parameters[0]["itemTemplate"])
 pItemTemplate = paramFormat(parameters[0]["itemTemplate"][0])
 pItemTemplate = pItemTemplate.replace("$))", ">>").replace("%link", "%0").replace("%item", "%1").replace("%abstract", "%2").replace("%text", "%3").replace("%created", "%4").replace("%modified", "%5").replace("%modifier", "%6").replace("%group", "%7").replace("%title", "%8").replace("%tags", "%9").replace("%nolink", "%10").replace("%custom", "%11")
 // Template for footer
 var pFooterTemplate = this.templates[pFormat][4].replace("%count", "%1")

 // Get all tiddlers
 var tiddlers = store.reverseLookup("tags","excludeLists",false);

 // Sorting
 if(!pOrder)
 pOrder = "title";
 if (pOrder.match(/^\-/i)) {
 pOrder = pOrder.substr(1)
 var sortDesc = true;
 }
 // Sorting on a standard field
 if (pOrder.match(/(title)|(text)|(modifier)|(modified)|(created)|(tags)/))
  if (sortDesc)
   tiddlers.sort(function (a,b) {if(a[pOrder] == b[pOrder]) return(0); else return (a[pOrder] > b[pOrder]) ? -1 : +1; });
  else
  tiddlers.sort(function (a,b) {if(a[pOrder] == b[pOrder]) return(0); else return (a[pOrder] < b[pOrder]) ? -1 : +1; });
 else
  if (sortDesc)
   tiddlers.sort(function (a,b) {if(a.fields[pOrder] == b.fields[pOrder]) return(0); else return (a.fields[pOrder] > b.fields[pOrder]) ? -1 : +1; });
  else
   tiddlers.sort(function (a,b) {if(a.fields[pOrder] == b.fields[pOrder]) return(0); else return (a.fields[pOrder] < b.fields[pOrder]) ? -1 : +1; });

 // Header
 if (pHeader)
 listWikiText += formatItem(this.templates[pFormat][0], [pHeader], pFormat)
 
 for(var t=0; t<tiddlers.length; t++) {
 tiddler = tiddlers[t];
 if (pText!="" && tiddler.text=="") tiddler.text=store.getValue(tiddler, 'text')
 if (pTop==-1 || count<pTop) {
 if (pText=="" || tiddler.text.match(pText)) {
 if (pTitle=="" || tiddler.title.match(pTitle)) {
 if (pSearch=="" || (tiddler.title.match(pSearch) || tiddler.text.match(pSearch))) {
 if (pFilter=="" || eval(pFilter)) {
 if (pTags.length==0 || compareArrays(tiddler.tags, pTags, "all")) {
 count++;
 if (tiddler.text=="") tiddler.text=store.getValue(tiddler, 'text')
 // Grouping
 if (pGroup) {
 theGroup = eval(pGroup);
 if(theGroup != lastGroup) {
 groupCount++;firstInGroup = true;
 if (pGroupFooterTemplate && groupCount>1)
 listWikiText += pGroupFooterTemplate.replace("%group", theGroup)
 listWikiText += pGroupTemplate.replace("%group", theGroup)
 lastGroup = theGroup;
 } else
  firstInGroup = false;
 }
 // Separators
 if (count>1 && !firstInGroup) listWikiText += pSeparator;
 //Plaintext title
 var noLink = tiddler.title.match(config.textPrimitives.wikiLink)?"~" + tiddler.title:tiddler.title;
 // Custom parameter
 if (pCustomParameter)
 var custom="";
 try {
 custom = eval(pCustomParameter)
 } catch (e) {}
 // List individual tiddler
 var strItem = formatItem(pItemTemplate,["[[" + tiddler.title + "]]",count,tiddler.text.substr(0,300),tiddler.text,tiddler.created.formatString(pDateFormat),tiddler.modified.formatString(pDateFormat),tiddler.modifier,theGroup,tiddler.title,tiddler.tags.join(" "),noLink,custom], pFormat)
 for (var fld in tiddler.fields) strItem = strItem.replace('%field.' + fld, tiddler.fields[fld]);
 listWikiText += strItem
 }
 }
 }
 }
 }
 }
 }
 
 // Last group footer
 if (pGroup && pGroupFooterTemplate && count>0)
 listWikiText += pGroupFooterTemplate.replace("%group", theGroup)

 // Footer
 if (pFooter) {
 pFooter = pFooter.replace("%count", count)
 listWikiText += formatItem(pFooterTemplate, [pFooter], pFormat)
 }
 
 // Render result
 if (!parameters[0]["debug"])
 wikify(listWikiText,place, null, currentTiddler)
 else
 place.innerHTML = "<textarea style=\"width:100%;\" rows=30>" + listWikiText + "</textarea>"
 
 
 // Local functions
 
 function paramFormat(param) {
 // Allow "\n" in non evalled parameters
 return param.replace(/\\n/g, "\n");
 }
 
 function formatItem(template, values, format) {
 // Fill template with values (depending on list format)
 if (format.match(/table/) && values[0].match(/\|/))
 return ("%0\n").format(values)
 else
 return template.format(values)
 }
 
 function compareArrays(array, values, logic) {
 // Compare items in array with AND("all") or OR("any") logic
 var matches=0;
 for(var v=0; v<values.length; v++) 
 if(values[v].replace(/^\s+|\s+$/g,"").match(/^\-/) && !array.contains(values[v].replace(/^\s+|\s+$/g,"").substr(1)))
 matches++;
 else if (array.contains(values[v]))
 matches++;
 return ((logic=="all" && matches==values.length) || (logic!="all" && matches>0))
 }
 
}

String.prototype.prettyTrim = function(len,prefix,postfix) {
 var result = this.trim().replace(/\r\n/g,' ').replace(/\n/g,' ');
 if (!prefix) prefix = '';
 if (!postfix) postfix = '';
 if (result.length > len - 3)
 return prefix + result.substr(0,len) + '...' + postfix;
 else if (result.length > 0)
 return prefix + result + postfix;
 else
 return result;
}

//}}}
Examples using the TiddlerListMacro:
!List Formatting
List all tiddlers tagged with "Plugin"
{{{<<tiddlerList tags:Plugin>>}}}
<<tiddlerList tags:Plugin>>
List top 1 plugins which are not templates:
{{{<<tiddlerList tags:"Plugin,-Template" top:1>>}}}
<<tiddlerList tags:"Plugin,-Template" top:1>>
List all tiddlers containing "Plugin" in their title and text (newest first):
{{{<<tiddlerList title:"Plugin" text:"Plugin" order:"-created">>}}}
<<tiddlerList title:"Plugin" text:"Plugin" order:"-created">>
List all tiddlers containing "Jack" in their title or text (oldest first):
{{{<<tiddlerList search:"Jack" order:"created">>}}}
<<tiddlerList search:"Jack" order:"created">>
List all tiddlers starting with "T":
{{{<<tiddlerList title:"^T">>}}}
<<tiddlerList title:"^T">>
List all tiddlers tagged with the current tiddler's title:
{{{<<tiddlerList tags:{{window.currentTiddler.title}}>>}}}
<<tiddlerList tags:{{window.currentTiddler.title}}>>
!Other Formats
Simple unnumbered list of tiddlers
{{{<<tiddlerList top:"3" format:"list">>}}}
<<tiddlerList top:"3" format:"list">>
Numbered list of tiddlers
{{{<<tiddlerList top:"3" format:"nlist">>}}}
<<tiddlerList top:"3" format:"nlist">>
Table with header and footer
{{{<<tiddlerList top:"3" format:"table" header:"Plugins" footer:"Tiddlers: %count">>}}}
<<tiddlerList top:"3" format:"table" header:"Plugins" footer:"Tiddlers: %count">>
Simple horizontal list:
{{{<<tiddlerList top:"3" format:"span">>}}}
<<tiddlerList top:"3" format:"span">>
Comma Separated list
{{{<<tiddlerList top:"3" format:"csv" header:"Plugins: [ " footer:" ]">>}}}
<<tiddlerList top:"3" format:"csv" header:"Plugins: [ " footer:" ]">>
Custom Separated list
{{{<<tiddlerList top:"10" separator:" - " format:"span">>}}}
<<tiddlerList top:"10" separator:" - " format:"span">>
!Grouping
Group tiddlers by first letter
{{{<<tiddlerList top:"7" group:"tiddler.title.substr(0,1)">>}}}
<<tiddlerList top:"7" group:"tiddler.title.substr(0,1)">>
!Custom Item Templates
List tiddlers in a custom format (title, date, abstract)
{{{<<tiddlerList tags:"News,-Template" itemTemplate:"* %link (%created)<<br>>%abstract\n" order:"-created">>}}}
<<tiddlerList tags:"News,-Template" filter:"tiddler.title!=currentTiddler.title" itemTemplate:"%link (%created)\n%abstract" order:"-created">>
!!!Beware of infinite recursion!!
!Advanced
Tiddlers created today
{{{<<tiddlerList format:table filter:"tiddler.created.formatString('YYYYMMDD')==(new Date()).formatString('YYYYMMDD')" header:{{'Tiddlers created on ' + (new Date()).formatString('DDD, DD MMM YYYY')}}>>}}}
<<tiddlerList format:table filter:"tiddler.created.formatString('YYYYMMDD')==(new Date()).formatString('YYYYMMDD')" header:{{'Tiddlers created on ' + (new Date()).formatString('DDD, DD MMM YYYY')}}>>
Fancy table with grouping on modified date
{{{<<tiddlerList top:"10" header:"|>|!Tiddlers|\n|bgcolor(#ddf):''Title''|bgcolor(#ddf):''Created''|" itemTemplate:"|%0|%4|\n" format:"table" group:"tiddler.created.formatString('DD MMM YYYY')" groupTemplate:"|>|bgcolor(#eef): ''Updated: %group'' |\n" dateFormat:"DDD, DD MM YYYY">>}}}
<<tiddlerList top:"10" header:"|>|!Tiddlers|\n|bgcolor(#ddf):''Title''|bgcolor(#ddf):''Created''|" itemTemplate:"|%0|%4|\n" format:"table" group:"tiddler.created.formatString('DD MMM YYYY')" groupTemplate:"|>|bgcolor(#eef): ''Updated: %group'' |\n" dateFormat:"DDD, DD MM YYYY">>
Un Wiki est un type particulier de site web dont le plus connu est Wikipedia. Le but du Wiki est de construire un site web rapidement. Afin de lier automatiquement les pages entre elles, leur nom sont écrites par convention sous la forme TiddlyWiki, c'est a dire sous la forme de mots, dont la première lettre est en majuscule, collés les uns aux autres. Cliquer sur un de ces mots permet d'aller directement sur la page concernée, ou d'en créer une nouvelle.

TiddlyWiki est un fichier DHTML (une page HTML qui contient du javascript) qui fonctionne comme un Wiki. Le stockage se fait dans un fichier local au lieu d'une base de données.

Les wikis supportent une syntaxe simplifiée pour mettre en forme le texte. Par exemple, le texte suivant s'affiche :
//{{{
* listes ''a puces''
* contenant du //texte// mis en forme
* Lien vers une NouvellePage
//}}}
* listes ''a puces''
* contenant du //texte// mis en forme
* Lien vers une NouvellePage

Beaucoup de wiki supportent aussi le versionning de pages, c'est à dire, qu'ils stockent chaque nouvelle version de la page afin d'en garder l'historique. Cela permet, dans le cas où les contributions sont ouvertes au public, de pouvoir revenir en arrière en cas de mauvaise contribution. TiddlyWiki ne possède pas cette fonctionnalité par défaut, étant en principe destiné à un usage personnel ou restreint. Cette fonctionnalité peut cependant être rajoutée grâce à un plugin (morceaux de code JavaScript).

Les différentes pages d'un TiddlyWiki sont nommées "tiddler". Chaque tiddler peut être catégorisé via un tag (mot clé). Ce mécanisme, très puissant dans la pratique, permet de relier des tiddlers entre eux. Il est possible, par exemple, de taguer un tiddler par "project" pour indiquer qu'il décrit un projet, puis un autre par "task" pour indiquer qu'il s'agit d'une tâche. Il suffit d'ajouter un deuxième tag à la tâche (ici le nom du tiddler qui contient le projet) pour la relier au projet auquel elle appartient.

Par ailleurs, TiddlyWiki peut être enrichi par des plugins.  Il devien alors très facile de modifier l'affichage, l'édition, ou de créer des requêtes sur les tiddlers. Concrètement TiddlyWiki peut être utilisé comme une mini base de données textuelle (un équivalent light d'Access). Dans la pratique, cela permet d'organiser des notes et des réflexions, de faire de la gestion de projet, et de concevoir facilement un site web. La souplesse et la puissance de TiddlyWiki en font un outil privilégié.


/***
|Name:|ToggleTagPlugin|
|Description:|Makes a checkbox which toggles a tag in a tiddler|
|Version:|3.1.0 ($Rev: 4907 $)|
|Date:|$Date: 2009/12/18 16:36:41 $|
|Source:|http://mptw.tiddlyspot.com/#ToggleTagPlugin|
|Author:|Simon Baird <simon.baird@gmail.com>|
|License:|http://mptw.tiddlyspot.com/#TheBSDLicense|
!!Usage
{{{<<toggleTag }}}//{{{TagName TiddlerName LabelText}}}//{{{>>}}}
* TagName - the tag to be toggled, default value "checked"
* TiddlerName - the tiddler to toggle the tag in, default value the current tiddler
* LabelText - the text (gets wikified) to put next to the check box, default value is '{{{[[TagName]]}}}' or '{{{[[TagName]] [[TiddlerName]]}}}'
(If a parameter is '.' then the default will be used)
* TouchMod flag - if non empty then touch the tiddlers mod date. Note, can set config.toggleTagAlwaysTouchModDate to always touch mod date
!!Examples
|Code|Description|Example|h
|{{{<<toggleTag>>}}}|Toggles the default tag (checked) in this tiddler|<<toggleTag>>|
|{{{<<toggleTag TagName>>}}}|Toggles the TagName tag in this tiddler|<<toggleTag TagName>>|
|{{{<<toggleTag TagName TiddlerName>>}}}|Toggles the TagName tag in the TiddlerName tiddler|<<toggleTag TagName TiddlerName>>|
|{{{<<toggleTag TagName TiddlerName 'click me'>>}}}|Same but with custom label|<<toggleTag TagName TiddlerName 'click me'>>|
|{{{<<toggleTag . . 'click me'>>}}}|dot means use default value|<<toggleTag . . 'click me'>>|
!!Notes
* If TiddlerName doesn't exist it will be silently created
* Set label to '-' to specify no label
* See also http://mgtd-alpha.tiddlyspot.com/#ToggleTag2
!!Known issues
* Doesn't smoothly handle the case where you toggle a tag in a tiddler that is current open for editing
* Should convert to use named params
***/
//{{{

if (config.toggleTagAlwaysTouchModDate == undefined) config.toggleTagAlwaysTouchModDate = false;

merge(config.macros,{

	toggleTag: {

		createIfRequired: true,
		shortLabel: "[[%0]]",
		longLabel: "[[%0]] [[%1]]",

		handler: function(place,macroName,params,wikifier,paramString,tiddler) {
			var tiddlerTitle = tiddler ? tiddler.title : '';
			var tag   = (params[0] && params[0] != '.') ? params[0] : "checked";
			var title = (params[1] && params[1] != '.') ? params[1] : tiddlerTitle;
			var defaultLabel = (title == tiddlerTitle ? this.shortLabel : this.longLabel);
			var label = (params[2] && params[2] != '.') ? params[2] : defaultLabel;
			var touchMod = (params[3] && params[3] != '.') ? params[3] : "";
			label = (label == '-' ? '' : label); // dash means no label
			var theTiddler = (title == tiddlerTitle ? tiddler : store.getTiddler(title));
			var cb = createTiddlyCheckbox(place, label.format([tag,title]), theTiddler && theTiddler.isTagged(tag), function(e) {
				if (!store.tiddlerExists(title)) {
					if (config.macros.toggleTag.createIfRequired) {
						var content = store.getTiddlerText(title); // just in case it's a shadow
						store.saveTiddler(title,title,content?content:"",config.options.txtUserName,new Date(),null);
					}
					else 
						return false;
				}
				if ((touchMod != "" || config.toggleTagAlwaysTouchModDate) && theTiddler)
						theTiddler.modified = new Date();
				store.setTiddlerTag(title,this.checked,tag);
				return true;
			});
		}
	}
});

//}}}

|~ViewToolbar|refresh closeTiddler closeOthers +editTiddler > fields syncing permalink references jump|
|~EditToolbar|+saveTiddler -cancelTiddler deleteTiddler|
<<deleteAllTagged>>
| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |
| 16/09/2008 10:46:43 | YBA | [[scrum.html|file:///home/yba/scrum/scrum.html]] | [[store.php|http://192.168.2.23/scrum/store.php]] | . | [[scrumweb.html | http://192.168.2.23/scrum/scrumweb.html]] |  | ok |
| 16/09/2008 10:47:20 | YBA | [[scrum.html|file:///home/yba/scrum/scrum.html]] | [[store.php|http://192.168.2.23/scrum/store.php]] | . | [[scrum.html | http://192.168.2.23/scrum/scrum.html]] |  | ok |
| 16/09/2008 10:49:21 | YBA | [[scrum.html|file:///home/yba/scrum/scrum.html]] | [[store.php|http://192.168.2.23/scrum/store.php]] | . | [[scrum.html | http://192.168.2.23/scrum/scrum.html]] |  | ok |
| 16/09/2008 10:58:38 | YourName | [[scrum.html|http://192.168.2.23/scrum/scrum.html]] | [[store.php|http://192.168.2.23/scrum/store.php]] | . | [[scrum.html | http://192.168.2.23/scrum/scrum.html]] |  |
| 16/09/2008 14:27:34 | Jean-Cédric T. | [[scrum.html|http://192.168.2.23/scrum/scrum.html]] | [[store.php|http://192.168.2.23/scrum/store.php]] | . | [[scrum.html | http://192.168.2.23/scrum/scrum.html]] |  | ok |
| 16/09/2008 14:35:05 | Jean-Cédric T. | [[scrum.html|http://192.168.2.23/scrum/scrum.html]] | [[store.php|http://192.168.2.23/scrum/store.php]] | . | [[scrum.html | http://192.168.2.23/scrum/scrum.html]] |  |
| 17/09/2008 16:09:54 | YBA | [[scrum.html|file:///home/yba/scrum/scrum.html]] | [[store.php|http://192.168.2.23/scrum/store.php]] | . | [[scrum.html | http://192.168.2.23/scrum/scrum.html]] |  | ok |
<<deleteAllTagged>>
<!--{{{-->
<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='viewer' macro='formTiddler UserStoryFormTemplate'></div>
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser'></span></div>
<!--}}}-->
<html>
<table style="border:none;">
<tr  style="border:none;">
<td style="border:none;">Poids : </td><td style="border:none;"><select name=poids ><option>1<option>2<option>3<option>5<option>8<option>13<option>21<option>34<option>55<option>89</select ></td>
</tr>
</table>
</html>
{{fr{Une UserStory se décompose en plusieurs tâches. Elle peut "appartenir" a un sprint si elle a été traitée ou en cours de traitement. Si on la tagge "Done", c'est qu'elle est finie}}}
{{en{A UserStory is decomposed in several tasks. It can belong to a sprint if it's currently been implemented. When all the tasks are finished the UserStory can be tagged "Done".}}}
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></div>
<div class='tagged' macro='tags'></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>
<span class='help' macro='showWhen config.options.chkVerboseHelp'><span class='viewer' macro='tiddler UserStoryTemplateHelp'></span></span>
<div>Poids: <span macro="view poids"></span></div>
<div class='viewer' macro='SortList'></div>
<div class='tagging' macro='tagging'></div>
<div class='tagClear'></div>
<span macro='newHere label:"new Task" text:{{store.getTiddlerText("EmptyTask")}} title:"Titre de la tâche" tag:task'>
<!--}}}-->
! 22.09.08
* Outil de selection de liste (backlog)
* Burdown
* Saisie du poids fibonnacci
* Aide et préconfiguration scrum intégrée
! 23.09.08
* améliorations de l'aide
* améliorations des ViewTemplate (aide intégrée, meilleure structure des US, task, backlog, boutons d'état pour les tâches facilement accessible)
* TaskBoard par sprint
* RVE : Amélioration pour les UserStory en texte (sans les double crochet) mais qui existent en tant que tiddler sont reconnues par le bouton Update -- au lieu d'être dupliquées
! 25.09.08
* Ajout des templates d'objet EmptyBacklog / EmptySprint / EmptyUserStory / EmptyUserStory 
! 26.09.08
* RVE : Possibilité dans le [[Populate/UpdateListPlugin]] de mettre des paramètres évalués, ce qui permet de stocker dans un tiddler la liste des sprints a exclure (SprintViewTemplate) via le [[excludeSprint]]
! 10.10.08
* RVE : la sliceGrid d'un sprint est triée par UserStory
! 13.10.08
* YBA : amélioration de l'aide et de la présentation générale
! 5.11.08
* YBA : ajout de la config chkVerboseHelp pour cacher l'aider si besoin est
! 11.12.08
* 3.12.08 : YBA traduction en anglais a l'aide des plugins PolyGlot
<<deleteAllTagged>>
/***
|!''Name:''|!easyFormat|
|''Description:''|the format command format selection according to your choice|
|''Version:''|0.1.0|
|''Date:''|13/01/2007|
|''Source:''|[[TWkd|http://yann.perrin.googlepages.com/twkd.html#easyFormat]]|
|''Author:''|[[Yann Perrin|YannPerrin]]|
|''License:''|[[BSD open source license]]|
|''~CoreVersion:''|2.x|
|''Browser:''|Firefox 1.0.4+; Firefox 1.5; InternetExplorer 6.0|
|''Requires:''|@@color:red;''E.A.S.E''@@|
***/
//{{{
config.commands.format = new TWkd.Ease('Format','format selection accordingly to chosen mode');
config.commands.format.addMode({
 name:'Bold',
 tooltip:'turns selection into bold text',
 operation:function(){
 config.commands.format.putInPlace("''"+TWkd.context.selection.content+"''",TWkd.context.selection);
 }
});
config.commands.format.addMode({
 name:'Italic',
 tooltip:'turns selection into italic text',
 operation:function(){
 config.commands.format.putInPlace("//"+TWkd.context.selection.content+"//",TWkd.context.selection);
 }
});
config.commands.format.addMode({
 name:'Underlined',
 tooltip:'turns selection into underlined text',
 operation:function(){
 config.commands.format.putInPlace("__"+TWkd.context.selection.content+"__",TWkd.context.selection);
 }
});
config.commands.format.addMode({
 name:'Strikethrough',
 tooltip:'turns selection into striked text',
 operation:function(){
 config.commands.format.putInPlace("--"+TWkd.context.selection.content+"--",TWkd.context.selection);
 }
});
config.commands.format.addMode({
 name:'Superscript',
 tooltip:'turns selection into superscript',
 operation:function(){
 config.commands.format.putInPlace("^^"+TWkd.context.selection.content+"^^",TWkd.context.selection);
 }
});
config.commands.format.addMode({
 name:'Subscript',
 tooltip:'turns selection into subscript',
 operation:function(){
 config.commands.format.putInPlace("~~"+TWkd.context.selection.content+"~~",TWkd.context.selection);
 }
});
config.commands.format.addMode({
 name:'Highlight',
 tooltip:'highlight selection',
 operation:function(){
 config.commands.format.putInPlace("@@"+TWkd.context.selection.content+"@@",TWkd.context.selection);
 }
});
//}}}
/***
|!''Name:''|!easySlicer|
|''Description:''|The slice command allows you to create microcontent tiddlers from bigger ones.<<br>>It turns selected text into a new independent tiddler, and replace it in the original tiddler with a reference to the newly created tiddler.|
|''Version:''|0.1.0|
|''Date:''|13/01/2007|
|''Source:''|[[TWkd|http://yann.perrin.googlepages.com/twkd.html#easySlicer]]|
|''Author:''|[[Yann Perrin|YannPerrin]]|
|''License:''|[[BSD open source license]]|
|''~CoreVersion:''|2.x|
|''Browser:''|Firefox 1.0.4+; Firefox 1.5; InternetExplorer 6.0|
|''Requires:''|@@color:red;''E.A.S.E''@@|
***/
//{{{
config.commands.slice = new TWkd.Ease('8<','divide tiddler into parts');
config.commands.slice.addMode({
	name:'tiddler',
	tooltip:'turns selection into a new tiddler and replace it with a macro diplaying the new tiddler content',
	operation:function(){
		var newtitle=config.commands.slice.askForTitle();
		if(!newtitle) {
			displayMessage(config.messages.Ease.cancel);
			return(false);
		}
		config.commands.slice.newTWkdLibTiddler(newtitle,TWkd.context.selection.content,TWkd.context.selection.source,true);
		config.commands.slice.putInPlace("<<tiddler "+newtitle+">>",TWkd.context.selection);
	}
});
config.commands.slice.addMode({
	name:'link',
	tooltip:'turns selection into a new tiddler and replace it with a link to the new tiddler',
	operation:function(){
		var newtitle=config.commands.slice.askForTitle();
		if(!newtitle) {
			displayMessage(config.messages.Ease.cancel);
			return(false);
		}
		config.commands.slice.newTWkdLibTiddler(newtitle,TWkd.context.selection.content,TWkd.context.selection.source,true);
		config.commands.slice.putInPlace("[["+newtitle+"]]",TWkd.context.selection);
	}
});
config.commands.slice.addMode({
	name:'slider',
	tooltip:'turns selection into a new tiddler and replace it with a slider containing the new tiddler',
	sliderTooltip:'content of ',
	operation:function(){
		var newtitle=config.commands.slice.askForTitle();
		if(!newtitle) {
			displayMessage(config.messages.Ease.cancel);
			return(false);
		}
		config.commands.slice.newTWkdLibTiddler(newtitle,TWkd.context.selection.content,TWkd.context.selection.source,true);
		config.commands.slice.putInPlace('<<slider chkSlice [['+newtitle+']] "'+newtitle+'" "'+this.sliderTooltip+newtitle+'">>',TWkd.context.selection);
	}
});
if (version.extensions.nestedSliders) {
config.commands.slice.addMode({
	name:'nestedslider',
	tooltip:'turns selection into a slider',
	operation:function(){
		var newtitle=config.commands.slice.askForTitle();
		if(!newtitle) {
			displayMessage(config.messages.Ease.cancel);
			return(false);
		}
		config.commands.slice.putInPlace("+++["+newtitle+"]\n"+TWkd.context.selection.content+"\n===",TWkd.context.selection);
	}
});
}
if (version.extensions.PartTiddlerPlugin) {
config.commands.slice.addMode({
	name:'part',
	tooltip:'turns selection into a part',
	operation:function(){
		var newtitle=config.commands.slice.askForTitle();
		if(!newtitle) {
			displayMessage(config.messages.Ease.cancel);
			return(false);
		}
		config.commands.slice.putInPlace("<part "+newtitle+">"+TWkd.context.selection.content+"</part>",TWkd.context.selection);
	}
});
}
//}}}
/***
|!''Name:''|!easyTongue|
|''Description:''|The tongue command allows you to mark selection as being from the chosen language|
|''Version:''|0.1.0|
|''Date:''|13/01/2007|
|''Source:''|[[TWkd|http://yann.perrin.googlepages.com/twkd.html#easyTongue]]|
|''Author:''|[[Yann Perrin|YannPerrin]]|
|''License:''|[[BSD open source license]]|
|''~CoreVersion:''|2.x|
|''Browser:''|Firefox 1.0.4+; Firefox 1.5; InternetExplorer 6.0|
|''Requires:''|@@color:red;''E.A.S.E''@@|
***/
//{{{
config.commands.tongue = new TWkd.Ease(':P','mark selection as being in selected language');
if (version.extensions.PolyGlotPlugin) {
	for (var i=0; i<config.macros.polyglot.languages.length; i++)
		config.commands.tongue.addMode({
			name:config.macros.polyglot.languages[i],
			tooltip:'mark selection as being in '+config.macros.polyglot.languages[i]+' language',
			operation:function(){
				config.commands.tongue.putInPlace("{{"+this.name+"{"+TWkd.context.selection.content+"}}}",TWkd.context.selection);
			}
		});
	config.commands.tongue.addMode({
		name:config.macros.polyglot.hidewhenactive,
		tooltip:'selection should be hidden from view when PolyGlotPlugin is installed',
		operation:function(){
			config.commands.tongue.putInPlace("{{"+this.name+"{"+TWkd.context.selection.content+"}}}",TWkd.context.selection);
		}
	});
	}
else {
	config.commands.tongue.addMode({
		name:'Unfulfilled dependency',
		tooltip:'PolyGlotPlugin is needed',
		operation:function(){displayMessage('PolyGlotPlugin is needed to run this command','http://yann.perrin.googlepages.com/twkd.html#PolyGlotPlugin');}
});
}
//}}}

/***
''Version 2.1.3 31/01/07''

!English messages taken from the TiddlyWiki core
***/
//{{{
merge(config.messages,{
	customConfigError: "Problems were encountered loading plugins. See PluginManager for details",
	pluginError: "Error: %0",
	pluginDisabled: "Not executed because disabled via 'systemConfigDisable' tag",
	pluginForced: "Executed because forced via 'systemConfigForce' tag",
	pluginVersionError: "Not executed because this plugin needs a newer version of TiddlyWiki",
	nothingSelected: "Nothing is selected. You must select one or more items first",
	savedSnapshotError: "It appears that this TiddlyWiki has been incorrectly saved. Please see http://www.tiddlywiki.com/#DownloadSoftware for details",
	subtitleUnknown: "(unknown)",
	undefinedTiddlerToolTip: "The tiddler '%0' doesn't yet exist",
	shadowedTiddlerToolTip: "The tiddler '%0' doesn't yet exist, but has a pre-defined shadow value",
	tiddlerLinkTooltip: "%0 - %1, %2",
	externalLinkTooltip: "External link to %0",
	noTags: "There are no tagged tiddlers",
	notFileUrlError: "You need to save this TiddlyWiki to a file before you can save changes",
	cantSaveError: "It's not possible to save changes. This could be because your browser doesn't support saving (instead, use FireFox if you can), or because the pathname to your TiddlyWiki file contains illegal characters",
	invalidFileError: "The original file '%0' does not appear to be a valid TiddlyWiki",
	backupSaved: "Backup saved",
	backupFailed: "Failed to save backup file",
	rssSaved: "RSS feed saved",
	rssFailed: "Failed to save RSS feed file",
	emptySaved: "Empty template saved",
	emptyFailed: "Failed to save empty template file",
	mainSaved: "Main TiddlyWiki file saved",
	mainFailed: "Failed to save main TiddlyWiki file. Your changes have not been saved",
	macroError: "Error in macro <<%0>>",
	macroErrorDetails: "Error while executing macro <<%0>>:\n%1",
	missingMacro: "No such macro",
	overwriteWarning: "A tiddler named '%0' already exists. Choose OK to overwrite it",
	unsavedChangesWarning: "WARNING! There are unsaved changes in TiddlyWiki\n\nChoose OK to save\nChoose CANCEL to discard",
	confirmExit: "--------------------------------\n\nThere are unsaved changes in TiddlyWiki. If you continue you will lose those changes\n\n--------------------------------",
	saveInstructions: "SaveChanges",
	unsupportedTWFormat: "Unsupported TiddlyWiki format '%0'",
	tiddlerSaveError: "Error when saving tiddler '%0'",
	tiddlerLoadError: "Error when loading tiddler '%0'",
	wrongSaveFormat: "Cannot save with storage format '%0'. Using standard format for save.",
	invalidFieldName: "Invalid field name %0",
	fieldCannotBeChanged: "Field '%0' cannot be changed"});

merge(config.messages.messageClose,{
	text: "close",
	tooltip: "close this message area"});

config.messages.dates.months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November","December"];
config.messages.dates.days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
config.messages.dates.shortMonths = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
config.messages.dates.shortDays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];

merge(config.views.wikified.tag,{
	labelNoTags: "no tags",
	labelTags: "tags: ",
	openTag: "Open tag '%0'",
	tooltip: "Show tiddlers tagged with '%0'",
	openAllText: "Open all",
	openAllTooltip: "Open all of these tiddlers",
	popupNone: "No other tiddlers tagged with '%0'"});

merge(config.views.wikified,{
	defaultText: "The tiddler '%0' doesn't yet exist. Double-click to create it",
	defaultModifier: "(missing)",
	shadowModifier: "(built-in shadow tiddler)",
	createdPrompt: "created"});

merge(config.views.editor,{
	tagPrompt: "Type tags separated with spaces, [[use double square brackets]] if necessary, or add existing",
	defaultText: "Type the text for '%0'"});

merge(config.views.editor.tagChooser,{
	text: "tags",
	tooltip: "Choose existing tags to add to this tiddler",
	popupNone: "There are no tags defined",
	tagTooltip: "Add the tag '%0'"});

merge(config.macros.search,{
	label: "search",
	prompt: "Search this TiddlyWiki",
	accessKey: "F",
	successMsg: "%0 tiddlers found matching %1",
	failureMsg: "No tiddlers found matching %0"});

merge(config.macros.tagging,{
	label: "tagging: ",
	labelNotTag: "not tagging",
	tooltip: "List of tiddlers tagged with '%0'"});

merge(config.macros.timeline,{
	dateFormat: "DD MMM YYYY"});

merge(config.macros.allTags,{
	tooltip: "Show tiddlers tagged with '%0'",
	noTags: "There are no tagged tiddlers"});

config.macros.list.all.prompt = "All tiddlers in alphabetical order";
config.macros.list.missing.prompt = "Tiddlers that have links to them but are not defined";
config.macros.list.orphans.prompt = "Tiddlers that are not linked to from any other tiddlers";
config.macros.list.shadowed.prompt = "Tiddlers shadowed with default contents";

merge(config.macros.closeAll,{
	label: "close all",
	prompt: "Close all displayed tiddlers (except any that are being edited)"});

merge(config.macros.permaview,{
	label: "permaview",
	prompt: "Link to an URL that retrieves all the currently displayed tiddlers"});

merge(config.macros.saveChanges,{
	label: "save changes",
	prompt: "Save all tiddlers to create a new TiddlyWiki",
	accessKey: "S"});

merge(config.macros.newTiddler,{
	label: "new tiddler",
	prompt: "Create a new tiddler",
	title: "New Tiddler",
	accessKey: "N"});

merge(config.macros.newJournal,{
	label: "new journal",
	prompt: "Create a new tiddler from the current date and time",
	accessKey: "J"});

merge(config.macros.plugins,{
	skippedText: "(This plugin has not been executed because it was added since startup)",
	noPluginText: "There are no plugins installed",
	confirmDeleteText: "Are you sure you want to delete these tiddlers:\n\n%0",
	listViewTemplate : {
		columns: [
			{name: 'Selected', field: 'Selected', rowName: 'title', type: 'Selector'},
			{name: 'Title', field: 'title', tiddlerLink: 'title', title: "Title", type: 'TiddlerLink'},
			{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: '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'}
			],
		actions: [
			{caption: "More actions...", name: ''},
			{caption: "Remove systemConfig tag", name: 'remove'},
			{caption: "Delete these tiddlers forever", name: 'delete'}
			]}
	});

merge(config.macros.refreshDisplay,{
	label: "refresh",
	prompt: "Redraw the entire TiddlyWiki display"
	});

merge(config.macros.importTiddlers,{
	readOnlyWarning: "You cannot import tiddlers into a read-only TiddlyWiki. Try opening the TiddlyWiki file from a file:// URL",
	defaultPath: "http://www.tiddlywiki.com/index.html",
	fetchLabel: "fetch",
	fetchPrompt: "Fetch the tiddlywiki file",
	fetchError: "There were problems fetching the tiddlywiki file",
	confirmOverwriteText: "Are you sure you want to overwrite these tiddlers:\n\n%0",
	wizardTitle: "Import tiddlers from another TiddlyWiki file",
	step1: "Step 1: Locate the TiddlyWiki file",
	step1prompt: "Enter the URL or pathname here: ",
	step1promptFile: "...or browse for a file: ",
	step1promptFeeds: "...or select a pre-defined feed: ",
	step1feedPrompt: "Choose...",
	step2: "Step 2: Loading TiddlyWiki file",
	step2Text: "Please wait while the file is loaded from: %0",
	step3: "Step 3: Choose the tiddlers to import",
	step4: "%0 tiddler(s) imported",
	step5: "Done",
	listViewTemplate: {
		columns: [
			{name: 'Selected', field: 'Selected', rowName: 'title', type: 'Selector'},
			{name: 'Title', field: 'title', title: "Title", type: 'String'},
			{name: 'Snippet', field: 'text', title: "Snippet", type: 'String'},
			{name: 'Tags', field: 'tags', title: "Tags", type: 'Tags'}
			],
		rowClasses: [
			],
		actions: [
			{caption: "More actions...", name: ''},
			{caption: "Import these tiddlers", name: 'import'}
			]}
	});

merge(config.commands.closeTiddler,{
	text: "close",
	tooltip: "Close this tiddler"});

merge(config.commands.closeOthers,{
	text: "close others",
	tooltip: "Close all other tiddlers"});

merge(config.commands.editTiddler,{
	text: "edit",
	tooltip: "Edit this tiddler",
	readOnlyText: "view",
	readOnlyTooltip: "View the source of this tiddler"});

merge(config.commands.saveTiddler,{
	text: "done",
	tooltip: "Save changes to this tiddler"});

merge(config.commands.cancelTiddler,{
	text: "cancel",
	tooltip: "Undo changes to this tiddler",
	warning: "Are you sure you want to abandon your changes to '%0'?",
	readOnlyText: "done",
	readOnlyTooltip: "View this tiddler normally"});

merge(config.commands.deleteTiddler,{
	text: "delete",
	tooltip: "Delete this tiddler",
	warning: "Are you sure you want to delete '%0'?"});

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

merge(config.commands.references,{
	text: "references",
	tooltip: "Show tiddlers that link to this one",
	popupNone: "No references"});

merge(config.commands.jump,{
	text: "jump",
	tooltip: "Jump to another open tiddler"});

merge(config.shadowTiddlers,{
	DefaultTiddlers: "GettingStarted",
	MainMenu: "GettingStarted",
	SiteTitle: "My TiddlyWiki",
	SiteSubtitle: "a reusable non-linear personal web notebook",
	SiteUrl: "http://www.tiddlywiki.com/",
	GettingStarted: "To get started with this blank TiddlyWiki, you'll need to modify the following tiddlers:\n* SiteTitle & SiteSubtitle: The title and subtitle of the site, as shown above (after saving, they will also appear in the browser title bar)\n* MainMenu: The menu (usually on the left)\n* DefaultTiddlers: Contains the names of the tiddlers that you want to appear when the TiddlyWiki is opened\nYou'll also need to enter your username for signing your edits: <<option txtUserName>>",
	SideBarOptions: "<<search>><<closeAll>><<permaview>><<newTiddler>><<newJournal 'DD MMM YYYY'>><<saveChanges>><<slider chkSliderOptionsPanel OptionsPanel 'options �' 'Change TiddlyWiki advanced options'>>",
	OptionsPanel: "These InterfaceOptions for customising TiddlyWiki are saved in your browser\n\nYour username for signing your edits. Write it as a WikiWord (eg JoeBloggs)\n\n<<option txtUserName>>\n<<option chkSaveBackups>> SaveBackups\n<<option chkAutoSave>> AutoSave\n<<option chkRegExpSearch>> RegExpSearch\n<<option chkCaseSensitiveSearch>> CaseSensitiveSearch\n<<option chkAnimate>> EnableAnimations\n\n----\nAdvancedOptions\nPluginManager\nImportTiddlers",
	AdvancedOptions: "<<option chkGenerateAnRssFeed>> GenerateAnRssFeed\n<<option chkOpenInNewWindow>> OpenLinksInNewWindow\n<<option chkSaveEmptyTemplate>> SaveEmptyTemplate\n<<option chkToggleLinks>> Clicking on links to tiddlers that are already open causes them to close\n^^(override with Control or other modifier key)^^\n<<option chkHttpReadOnly>> HideEditingFeatures when viewed over HTTP\n<<option chkForceMinorUpdate>> Treat edits as MinorChanges by preserving date and time\n^^(override with Shift key when clicking 'done' or by pressing Ctrl-Shift-Enter^^\n<<option chkConfirmDelete>> ConfirmBeforeDeleting\nMaximum number of lines in a tiddler edit box: <<option txtMaxEditRows>>\nFolder name for backup files: <<option txtBackupFolder>>\n<<option chkInsertTabs>> Use tab key to insert tab characters instead of jumping to next field",
	SideBarTabs: "<<tabs txtMainTab Timeline Timeline TabTimeline All 'All tiddlers' TabAll Tags 'All tags' TabTags More 'More lists' TabMore>>",
	TabTimeline: "<<timeline>>",
	TabAll: "<<list all>>",
	TabTags: "<<allTags>>",
	TabMore: "<<tabs txtMoreTab Missing 'Missing tiddlers' TabMoreMissing Orphans 'Orphaned tiddlers' TabMoreOrphans Shadowed 'Shadowed tiddlers' TabMoreShadowed>>",
	TabMoreMissing: "<<list missing>>",
	TabMoreOrphans: "<<list orphans>>",
	TabMoreShadowed: "<<list shadowed>>",
	PluginManager: "<<plugins>>",
	ImportTiddlers: "<<importTiddlers>>"});
//}}}
/***
''Version 2.1.0 3/10/06 ''
!Traduction française des messages intégrés dans le TiddlyWiki de base de JeremyRuston, à jour avec la version 2.1.0
__NDT:__
^^Toute traduction peut-être discutée. Celle-ci a été faite en pensant à un utilisateur non spécialiste.
D'où les choix :
| //tiddler -> élément<<br>>tag, to tag -> index, indexer<<br>>plugin -> extension<<br>>empty file template -> fichier de base "empty.html"//<<br>>Mais :<<br>>//backup -> backup//<<br>>(traduire ce terme consacré introduirait des confusions) |
//Traduction// Jacques Turbé : http://avm.free.fr//TiddlyWiki-fr.html ^^

Avec la version 2.1.0 de TiddlyWiki apparaissent deux nouvelles fonctions intégrées :
''Importations'' et ''Extensions'' : Les boutons d'appel correspondants sont ajoutés au bas de votre OptionPanel par le code suivant : {{{[[Importations|ImportTiddlers]]}}} et {{{[[Extensions|PluginManager]]}}}

!!!Script de fusion des textes //''pour les versions antérieures à 2.0.11''//
***/
/*{{{*/
if(window.merge == undefined)
{
merge = function(dst,src)
{
 for (p in src)
 dst[p] = src[p];
 return dst;
}
}
/*}}}*/
/***
!!!Chaînes traduites
***/
/*{{{*/

// Messages
merge(config.messages,{
	customConfigError: "Problème rencontré pour charger des extensions. Activer le menu 'Extensions' pour les détails",
	pluginError: "Erreur: %0",
	pluginDisabled: "Extension désactivée en raison de l'index 'systemConfigDisable' tag",
	pluginForced: "Exécution forcée en raison de l'index 'systemConfigForce' tag",
	pluginVersionError: "Cette extension ne peut être exécutée car elle nécessite une version plus récente de TiddlyWiki",
	nothingSelected: "Pas de sélection faite. Il faut sélectionner au moins un item d'abord",
 savedSnapshotError: "Cet exemplaire de TiddlyWiki ne semble pas conforme. Reportez-vous à http://www.tiddlywiki.com/#DownloadSoftware",
 subtitleUnknown: "(inconnu)",
 undefinedTiddlerToolTip: "L'élément '%0' n'est pas encore créé",
 shadowedTiddlerToolTip: "L'élément '%0' n'est pas encore créé, mais a un contenu par défaut.",
 tiddlerLinkTooltip: "%0 - %1, %2",
 externalLinkTooltip: "%0",
 noTags: "Il n'y a pas d'éléments indexés",
 notFileUrlError: "Les données entrées sont mémorisées pendant cette session. Pour les conserver, il faudra faire une sauvegarde avant de quitter",
 cantSaveError: "Sauvegarde impossible : soit votre navigateur ne permet pas de sauvegarder les changements (préférez FireFox si possible), soit l'adresse de votre fichier contient des caractères invalides.",
 invalidFileError: "Le fichier '%0' choisi ne semble pas être un TiddlyWiki valide",
 backupSaved: "Sauvegarde effectuée",
 backupFailed: "Echec de l'enregistrement du backup",
 rssSaved: "Flux RSS sauvegardé",
 rssFailed: "Echec de l'enregistrement du flux RSS",
 emptySaved: "Fichier de base 'empty.html' enregistré",
 emptyFailed: "Echec de l'enregistrement du fichier neuf 'empty'",
 mainSaved: "Mise à jour du fichier TiddlyWiki enregistrée",
 mainFailed: "Echec de l'enregistrement du nouveau fichier TiddlyWiki. Vos modifications ne sont pas enregistrées",
 macroError: "Erreur dans la macro <<%0>>",
 macroErrorDetails: "Erreur d'exécution de la macro <<%0>>:\n%1",
 missingMacro: "Macro non trouvée",
 overwriteWarning: "Il y a déjà un élément nommé '%0'. Confirmez pour le remplacer",
 unsavedChangesWarning: "ATTENTION! Les dernières modifications de ce TiddlyWiki n'ont pas été enregistrées.\n\nOK pour les enregistrer\nANNULER pour les abandonner",
 confirmExit: "--------------------------------\n\nSi vous quittez maintenant vous perdrez les modifications qui n'ont pas été sauvegardées.\n\n--------------------------------",
 saveInstructions: "Sauvegarder"});

merge(config.messages.messageClose,{
 text: "fermer",
 tooltip: "ferme cette zône messages"});

config.messages.dates.months = ["janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre","décembre"];
config.messages.dates.days = ["dimanche", "lundi","mardi", "mercredi", "jeudi", "vendredi", "samedi"];

merge(config.views.wikified.tag,{
 labelNoTags: "non indexé",
 labelTags: "Index : ",
 openTag: "Ouvrir '%0'",
 tooltip: "Afficher les éléments indexés avec '%0'",
 openAllText: "Ouvrir tous",
 openAllTooltip: "Ouvrir tous les éléments de cet index",
 popupNone: "Pas d'autres éléments indexés avec '%0'"});

merge(config.views.wikified,{
 defaultText: "'%0' n'a pas encore été créé. Double-cliquez pour entrer un texte.",
 defaultModifier: "(absent)",
 shadowModifier: "(défaut)"});

merge(config.views.editor,{
 tagPrompt: "Séparez les index avec un espace (doubles crochets si besoin), ou sélectionnez un index existant",
 defaultText: "Entrez le texte de '%0'"});

merge(config.views.editor.tagChooser,{
 text: "index",
 tooltip: "Sélectionner les index existants à associer à cet élément",
 popupNone: "Pas d'index déjà définis",
 tagTooltip: "Associer à l'index '%0'"});

merge(config.macros.search,{
 label: "chercher",
 prompt: "Rechercher dans ce TiddlyWiki",
 accessKey: "F",
 successMsg: "%0 éléments correspondent à %1",
 failureMsg: "Aucun élément ne correspond à %0"});

merge(config.macros.tagging,{
 label: "éléments indexés:",
 labelNotTag: "pas d'index",
 tooltip: "Lister les éléments indexés '%0'"});

merge(config.macros.timeline,{
 dateFormat: "DD MMM YYYY"});

merge(config.macros.allTags,{
 tooltip: "Afficher les éléments indexés '%0'",
 noTags: "Pas d'éléments indexés"});

config.macros.list.all.prompt = "Tous les éléments par ordre alphabétique";
config.macros.list.missing.prompt = "Eléments désignés par un lien mais non créés";
config.macros.list.orphans.prompt = "Eléments ne faisant l'objet d'aucun lien";
config.macros.list.shadowed.prompt = "Eléments ayant un contenu par défaut";

merge(config.macros.closeAll,{
 label: "page blanche",
 prompt: "Retirer tous les éléments de l'affichage (sauf ceux en cours d'édition)"});

merge(config.macros.permaview,{
 label: "permavue",
 prompt: "URL de la page actuellement constituée"});

merge(config.macros.saveChanges,{
 label: "sauvegarde sur le disque",
 prompt: "Créer le fichier TiddlyWiki avec tous les éléments mis à jour - Raccourci : 'S'"});

merge(config.macros.newTiddler,{
 label: "nouveau",
 prompt: "Créer un nouvel élément",
 title: "EntréeNouvelle",
 accessKey: "N"});


merge(config.macros.importTiddlers,{
	defaultPath: "http://www.tiddlywiki.com/index.html",
	fetchLabel: "Accéder",
	fetchPrompt: "Accèder au fichier tiddlywiki",
	fetchError: "Problèmes rencontrés pour accéder au fichier tiddlywiki",
	confirmOverwriteText: "Confirmez l'écrasement de ces éléments :\n\n%0",
	wizardTitle: "Importation d'éléments depuis un autre fichier TiddlyWiki",
	step1: "Etape 1: Identification du fichier TiddlyWiki",
	step1prompt: "Saisir l'URL ou le chemin d'accès: ",
	step1promptFile: "...parcourez les fichiers: ",
	step1promptFeeds: "...ou sélectionnez une importation prédéfinie: ",
	step1feedPrompt: "Choisir...",
	step2: "Etape 2: Chargement des éléments du fichier TiddlyWiki",
	step2Text: "Patientez pendant le chargement des éléments de: %0",
	step3: "Etape 3: Choix des éléments à importer",
	step4: "%0 élément(s) importés",
	step5: "Terminé",
	listViewTemplate: {
		columns: [
			{name: 'Selected', field: 'Selected', rowName: 'title', type: 'Selector'},
			{name: 'Title', field: 'title', title: "Plugin", type: 'String'},
			{name: 'Snippet', field: 'text', title: "Extrait", type: 'String'},
			{name: 'Tags', field: 'tags', title: "Index", type: 'Tags'}
			],
		rowClasses: [
			],
		actions: [
			{caption: "Autres actions...", name: ''},
			{caption: "Importer ces éléments", name: 'import'}
			]}
	});

merge(config.macros.newJournal,{
 label: "journal",
 prompt: "Créer une nouvelle entrée ayant pour titre la date et l'heure",
 accessKey: "J"});

merge(config.macros.plugins,{
	skippedText: "(Extension non exécutée car ajoutée depuis le début de cette session)",
	noPluginText: "Il n'y a pas d'extensions installées",
	confirmDeleteText: "Confirmez-vous la suppression de ces éléments:\n\n%0",
	listViewTemplate : {
		columns: [
			{name: 'Selected', field: 'Selected', rowName: 'title', type: 'Selector'},
			{name: 'Title', field: 'title', tiddlerLink: 'title', title: "Extension", type: 'TiddlerLink'},
			{name: 'Forced', field: 'forced', title: "Forcée", tag: 'systemConfigForce', type: 'TagCheckbox'},
			{name: 'Disabled', field: 'disabled', title: "Désactivée", tag: 'systemConfigDisable', type: 'TagCheckbox'},
			{name: 'Executed', field: 'executed', title: "Chargée", type: 'Boolean', trueText: "Yes", falseText: "No"},
			{name: 'Error', field: 'error', title: "Etat", type: 'Boolean', trueText: "Error", falseText: "OK"},
			{name: 'Log', field: 'log', title: "Log", type: 'StringList'}
			],
		rowClasses: [
			{className: 'error', field: 'error'},
			{className: 'warning', field: 'warning'}
			],
		actions: [
			{caption: "Autres actions...", name: ''},
			{caption: "Supprimer l'index systemConfig", name: 'remove'},
			{caption: "Supprimer définitivement ces extensions", name: 'delete'}
			]}
	});


merge(config.commands.closeTiddler,{
 text: "fermer",
 tooltip: "Retirer cet élément de l'affichage"});

merge(config.commands.closeOthers,{
 text: "isoler",
 tooltip: "Refermer tous les autres éléments"});
merge(config.commands.editTiddler,{
 text: "éditer",
 tooltip: "Editer cet élément",
 readOnlyText: "voir",
 readOnlyTooltip: "Montrer le texte source de cet élément"});

merge(config.commands.saveTiddler,{
 text: "valider",
 tooltip: "Enregistrer les modifications apportées à cet élément"});

merge(config.commands.cancelTiddler,{
 text: "annuler",
 tooltip: "Abandonner les modifications apportées à cet élément",
 warning: "Confirmez-vous l'abandon des modifications de '%0'?",
 readOnlyText: "retour",
 readOnlyTooltip: "Revenir à l'affichage normal de cet élément"});

merge(config.commands.deleteTiddler,{
 text: "supprimer",
 tooltip: "Supprimer cet élément du fichier TiddlyWiki",
 warning: "Confirmez-vous la suppression de '%0'?"});

merge(config.commands.permalink,{
 text: "permalien",
 tooltip: "Permalien de cet élément"});

merge(config.commands.references,{
 text: "référents",
 tooltip: "Lister les éléments faisant référence à celui-ci",
 popupNone: "Pas de référents"});

merge(config.commands.jump,{
 text: "atteindre",
 tooltip: "Positionner l'affichage sur un autre élément déjà ouvert"});

merge(config.shadowTiddlers,{
 DefaultTiddlers: "PourCommencer",
 MainMenu: "PourCommencer",
 SiteTitle: "Mon TiddlyWiki",
 SiteSubtitle: "organiseur personnel web interactif",
 SiteUrl: "http://www.tiddlywiki.com/",
 PourCommencer: "Pour utiliser ce carnet TiddlyWiki, commencez par modifier les éléments suivants (//tiddlers// dans le jargon TiddlyWiki) :\n\n* SiteTitle & SiteSubtitle: Le titre et le sous-titre ci-dessus (après sauvegarde et rafraîchissement ils deviendront votre titre de page, qui s'affichera aussi dans la barre titre du navigateur)\n* MainMenu: Le menu (généralement à gauche)\n* DefaultTiddlers: Liste les noms des éléments que vous voulez voir s'afficher à l'ouverture de votre TiddlyWiki. \n\nEntrez également le nom utilisateur avec lequel seront signées chacune de vos entrées : <<option txtUserName>>",
 SideBarOptions: "<<search>><<closeAll>><<permaview>><<newTiddler>><<newJournal 'DD MMM YYYY'>><<saveChanges>><<slider chkSliderOptionsPanel OptionsPanel 'options »' 'Modifier les options avancées de ce TiddlyWiki'>>",
 OptionsPanel: "Vos options de configuration de TiddlyWiki sont sauvegardées par votre navigateur (cookies).\n\nNom d'utilisateur pour signer vos entrées : entrez-le sous la forme d'un nom Wiki (par exemple RaymondQueneau).<<option txtUserName>>\n<<option chkSaveBackups>>Backup de chaque version\n<<option chkAutoSave>>Sauvegarde automatique après chaque entrée validée\n<<option chkRegExpSearch>>Expression régulières dans les recherches\n<<option chkCaseSensitiveSearch>>Respecter la casse dans les recherches\n<<option chkAnimate>>Ouverture animée des éléments\n-----\n[[Importations|ImportTiddlers]]\n[[Extensions|PluginManager]]\n[[Options complémentaires|AdvancedOptions]]",
 AdvancedOptions: "<<option chkGenerateAnRssFeed>> Création flux RSS\n<<option chkOpenInNewWindow>> Ouverture des liens externes dans une nouvelle fenêtre\n<<option chkSaveEmptyTemplate>> Sauvegarde du fichier de base 'empty.html' de la dernière version\n<<option chkToggleLinks>> Recliquer sur un lien ferme l'élément qu'il a ouvert\n^^(hors fonction en appuyant sur la touche Ctrl)^^\n<<option chkHttpReadOnly>> Masque les fonctions d'édition lorsque le fichier est accédé depuis le Web\n<<option chkForceMinorUpdate>> L'entrée d'une modification ne modifie pas la date et l'heure déjà enregistrées pour l'élément\n^^(hors fonction en cliquant 'valider' avecla touche Maj enfoncée, ou en appuyant Ctrl-Maj-Entrée^^\n<<option chkConfirmDelete>> Confirmations avant suppressions\nNombre maximum de lignes de la fenêtre d'édition: <<option txtMaxEditRows>>\nRépertoire des backups : <<option txtBackupFolder>>\n",
 SideBarTabs: "<<tabs txtMainTab Chrono 'Affichage chronologique' TabTimeline Alpha 'Liste alphabétique des éléments' TabAll Index 'Liste des index' TabTags Suite 'Autres listes' TabMore>>",
 TabTimeline: "<<timeline>>",
 TabAll: "<<list all>>",
 TabTags: "<<allTags>>",
 TabMore: "<<tabs txtMoreTab Manquants 'Eléments désignés par un lien mais non créés' TabMoreMissing Orphelins 'Eléments sans liens pour les appeler' TabMoreOrphans Défauts 'Eléments ayant un contenu par défaut' TabMoreShadowed>>",
 TabMoreMissing: "<<list missing>>",
 TabMoreOrphans: "<<list orphans>>",
 TabMoreShadowed: "<<list shadowed>>"});

/*}}}*/
<<deleteAllTagged>>
<<forEachTiddler where 'tiddler.tags.contains("UserStory") && tiddler.tags.contains("$1")' sortBy 'tiddler.title'
write '"! "+tiddler.title+"\n<<sliceGrid edit inline [[tags:task $1 \""+tiddler.title+"\"]]  slices:+SprintDays$))\n"'>>
<<deleteAllTagged>>
<<deleteAllTagged>>