!Get started:\nStart by saving GTDTiddlyWiki to your computer (right click on [[this link|#]] and select 'Save link as...' or 'Save target as...').\n \nYou can edit entries, or "Tidders", by clicking "edit" or double clicking anywhere on the Tiddler. When you click "done" or press [ctrl+enter] your changes are saved.\n\nThanks to JeremyRuston for creating such a great Open Source project!\n----\nTiddlyWiki and GTD Tiddly Wiki are published under an OpenSourceLicense and carry NoWarranty.
{{{\n!Header 1\n!!Header 2\n!!!Header 3\n!!!!Header 4\n!!!!!Header 5\n}}}\nproduces:\n----\n!Header 1\n!!Header 2\n!!!Header 3\n!!!!Header 4\n!!!!!Header 5
{{{\n* Like this one\n* And this one\n** And this second-level one\n* And a final one\n}}}\nproduces:\n----\n* Like this one\n* And this one\n** And this second-level one\n* And a final one
{{{\n''Bold''\n==Strike==\n__Underline__\n//Italic//\n2^^3^^=8\na~~ij~~ = -a~~ji~~\n@@highlight@@\n@@color(green):green colored@@\n@@bgcolor(#ff0000):color(#ffffff):red colored@@\n}}}\nproduces:\n----\n''Bold''\n==Strike==\n__Underline__\n//Italic//\n2^^3^^=8\na~~ij~~ = -a~~ji~~\n@@highlight@@\n@@color(green):green colored@@\n@@bgcolor(#ff0000):color(#ffffff):red colored@@
{{{\n#item1\n#item2\n##item2.1\n##item2.2\n##item2.3\n#item3\n##item3.1\n###item3.1.1\n###item3.1.2\n}}}\n\nproduces:\n----\n#item1\n#item2\n##item2.1\n##item2.2\n##item2.3\n#item3\n##item3.1\n###item3.1.1\n###item3.1.2
{{{\n[[University of Warwick|http://www.warwick.ac.uk]]\n}}}\nproduces:\n----\n[[University of Warwick|http://www.warwick.ac.uk]]
{{{\nJeremyRuston said:\n\n<<<\nA TiddlyWiki is like a blog because it's divided up into neat little chunks, but it encourages you to read it by hyperlinking rather than\nsequentially: if you like, a non-linear blog analogue that binds the individual microcontent items into a cohesive whole. I think that TiddlyWiki \nrepresents a novel medium for writing, and will promote it's own distinctive WritingStyle. This is the first version of TiddlyWiki and so, as \ndiscussed in TiddlyWikiDev, it's bound to be FullOfBugs, have many MissingFeatures and fail to meet all of the DesignGoals. And of course \nthere's NoWarranty, and it might be judged a StupidName.\n<<<\n}}}\nproduces:\n----\nJeremyRuston said:\n\n<<<\nA TiddlyWiki is like a blog because it's divided up into neat little chunks, but it encourages you to read it by hyperlinking rather than sequentially: if you like, a non-linear blog analogue that binds the individual microcontent items into a cohesive whole. I think that TiddlyWiki represents a novel medium for writing, and will promote it's own distinctive WritingStyle. This is the first version of TiddlyWiki and so, as discussed in TiddlyWikiDev, it's bound to be FullOfBugs, have many MissingFeatures and fail to meet all of the DesignGoals. And of course there's NoWarranty, and it might be judged a StupidName.\n<<<
{{{\n>level 1\n>level 1\n>>level 2\n>>level 2\n>>>level 3\n>>>level 3\n>>level 2\n>level 1\n}}}\nproduces:\n----\n>level 1\n>level 1\n>>level 2\n>>level 2\n>>>level 3\n>>>level 3\n>>level 2\n>level 1
{{{\nYou can divide a tiddler into\n----\nsections by typing four dashes on a line by themselves\n}}}\nproduces:\n----\nYou can divide a tiddler into\n----\nsections by typing four dashes on a line by themselves
{{{\n|!th1111111111|!th2222222222|\n|>| colspan |\n| rowspan |left|\n|~| right|\n|bgcolor(#a0ffa0):colored| center |\n|caption|c\n}}}\nproduces:\n----\n|!th1111111111|!th2222222222|\n|>| colspan |\n| rowspan |left|\n|~| right|\n|bgcolor(#a0ffa0):colored| center |\n|caption|c
{{{\n {{{\nThis is a preformatted block.\n Leading indentation is preserved.\nAnd the text is rendeded in a fixed-width font.\n }}}\n}}}\n(//note: the leading spaces on the "{{{" lines should be omitted//) produces:\n----\n{{{\nThis is a preformatted block.\n Leading indentation is preserved.\nAnd the text is rendeded in a fixed-width font.\n}}}
* [[Headings & Sub-headings]]\n* [[Bullet lists]]\n* [[Numbered Lists]]\n* [[Character formatting]]\n* [[External links]]\n* [[Embedded images]]\n* [[Block quotes]]\n* [[Multi-level quotes]]\n* [[Horizontal rules]]\n* [[Preformatted blocks]]\n* [[Tables]]
{{{\n[img[SAP logo|images/sunset.jpg]]\n}}}\nproduces:\n----\n[img[SAP logo|images/sunset.jpg]]
?b6424Qmxj2Z7+8LIRHbqNGQFK4TUK39M/UZoJvDLKi75pQB1k7EEHOWl04jWoJf\nEPF4nxfNkbcVnHX9rx2wRea9VmKXJTdOXmtL8p63tZnQx29wvq92z/99nM/YN//q\nr51tDarwK5nTYkmrR6vEUcmqf+nDqC3BovjnOmQgcbnm6Co=?64b\n
?b64tK06P/cEWYz0yGohwC52Ju2cwNP1vZ9HhQQIZ85s4c43OFZ2+pnzREiF3kej\nZwOtrsU3eJvl5lupyz+DIJcU1fESJbRS8Qw5s73U+LiO22Lu1pDrlIMZFAJRhMhG\nitO/kHAYzV8qd95ju32Si3z/mONwUi9deYJJe6acwto3Y2VJ0FI7FJgQGPX6qMkl\nZ8Itc/3KKWDGO9XlmL10NT5w6FoHoCZi6vu6XlMgQDmSD1jNH9Vb/KNnNpia7WME\nVyozXCBNXgn4QPFHiuV2YVN4MQ==?64b\n
<<tabs txtMoreTab\nAll "All tiddlers" TabMoreAll\nMissing "Missing tiddlers" TabMoreMissing\nOrphans "Orphaned tiddlers" TabMoreOrphans\nUntagged "Untagged tiddlers" TabMoreUntagged\n>>
<<list untagged>>
All of the features of this wiki are documebted in the following tiddlers:\n<<listTags usage title #>>
YATWA
If checked, search results and tag searches produce a list of folded tiddlers. If unchecked, the results list is unfolded.
* Ported to 1.2.19\n* Change sort order of tag sort, so they appear in increasing, not decreasing, order of title.\n* Removed the UserCode tiddler - doesn't make sense while the vanilla TiddlyWiki is changing so quickly. Support for it left in.\n* Fixes to "AutoSaveMessage" option:\n** Forgot to suppress messages when autosaving empty template and RSS feed
* Finished porting the tagging stuff to the new storage model in version 1.2.16\n* Changes the sort order of tags in the tag menu - now sorts in alpha order of tag name
* Prototype "folding mechanism" for tiddlers.\n** Click on the "fold" button on a tiddler toolbar to hide the body, leaving just the title.\n** Click on the "fold" button again to unfold.\n** Search function displays matching tiddlers folded.\n** Clicking on a tag in the tags menu also displays tiddlers folded.\n* Still to do:\n** The "fold" should change to "unfold" when the tiddler is folded\n** Clicking "edit" should unfold the tiddler first!
* Finished off the folding mechanism:\n** A folded tiddler now has "unfold" on the toolbar, rather than "fold"\n** Editing an folded tiddler unfolds it first\n** Added "fold all" and "unfold all" buttons to the command panel\n** Added an option to control whether search results and tag lists are folded or unfolded by default\n* Added an option to control whether or not the "Saved" message is produced for autosaves\n** Default is to produce the message\n* Ported to TiddlyWiki version 1.2.17
* Port to 1.2.22
* Add "close others" button to the tiddler toolbar
* Ported to 1.2.21\n** Kept left hand tags menu for now, because I like the ability to pop up all the tiddlers, folded.
* Ported to TiddlyWiki 1.2.20
* Add "specials" to More tab. Changes required here:\n{{{\nvar moreTabModes = {\n moreTabMissing: {label: "Missing", prompt: "Tiddlers that have links to them but are not defined"},\n moreTabOrphans: {label: "Orphans", prompt: "Tiddlers that are not linked to from any other tiddlers"},\n moreTabSpecials: { label: "Specials", prompt: "Special tiddlers"} // SJR - add "specials" list\n };\n\nfunction refreshTabMore()\n{\n var place = document.getElementById("sidebarContent");\n while(place.firstChild != null)\n place.removeChild(place.firstChild);\n var selWrapper = createTiddlyElement(place,"div",null,"tabContentMorePrompt",null);\n var sel = createTiddlyElement(selWrapper,"select","optTabMore",null,null);\n sel.onchange = onChangeTabMore;\n for(var m in moreTabModes)\n {\n var opt = createTiddlyElement(sel,"option",null,null,moreTabModes[m].label);\n opt.value = m;\n if(m == options.txtTabMore)\n opt.selected = true;\n }\n var prompt = createTiddlyElement(place,"div",null,"tabContentMorePrompt",moreTabModes[options.txtTabMore].prompt);\n var results;\n switch(options.txtTabMore)\n {\n case "moreTabMissing":\n default:\n results = store.getMissingLinks();\n break;\n case "moreTabOrphans":\n results = store.getOrphans();\n break;\n case "moreTabSpecials": // SJR - add "specials" list\n results = specialTiddlers;\n break;\n }\n for (t = 0; t < results.length; t++)\n {\n createTiddlyLink(place,results[t],true);\n place.appendChild(document.createElement("br"));\n }\n}\n}}}
* Ported to TW 1.2.24
* Added BackupFolder tiddler to specify the name of the folder to store backups. If no value is specified, default is to store them in the same folder as the main wiki file.
* Version 1 of EncryptedTiddlers
* Added an "Untagged" option to the More tab\n* Added SinglePageMode from Knipster GTDTiddlyWiki
* Added SortableGrids from Knipster GTDTiddlyWiki
* PrettyLinks for internal links\n* Fixed "double-click" bug for tiddlers in edit mode, which changed the toolbar to the display toolbar\n* Added [[checkboxes|Checkboxes]] - code from Roberto
Individual tiddlers can be encrypted. Simply edit the tiddler and click on the //encrypt// button on the toolbar. You will be asked for a password, and the edited text will be replaced with an encrypted version.\n\nWhen you display an encrypted tiddler, the encrytped version will be displayed. To see the plain text, click on the "decrypt" button on the toolbar. You will be asked for a password and the tiddler text will be replaced with the decrypted version, assuming you supplied the correct password of course! The decrypted text will not be saved. If you close and reopen the tiddler, you'll get the encrypted version again.\n\nTo permanently decrypt a tiddler, edit it and use the decrypt button on the toolbar. As an example, [[This is encrypted]] - use password "foo" to decrypt it. [[This is also encrypted]] but I'm, not going to tell you the password. I hope that means you can't read it.\n\n!! Notes\n\nThe password is cached. Once you enter it will be remembered and used for subsequent encryption and decryption operations. To forget the password, reload the wiki. You can use different passwords for different tiddlers, but you do need to flush the cached password.
<<listTags changeHistory title>>
* Change the password request interface\n* Stop wikifying encrypted tiddlers
I already use hierarchical tags (like tiddlywiki:todo) but they don't behave hierarchically. What should they do?\n* The tags display should be able to expand and collapse like a folder list\n* "All tiddlers tagged with xxx" should include tiddlers tagged with sub-tags
As TiddlyWiki acquires more features that make extensions easier, especially extensions that can be done entirely in tiddlers and require no code changes, YATWA will migrate into a set of extensions provided in tiddlers. Ultimately, I hope YATWA will require no code changes at all and will therefore cease to be an adaptation. I guess that means I'll have to think of a new name for it <<smiley>>.\n\nI also have some ideas for new features I'm thinking about, and a list of things I'm definitely going to look at. Ideas first:\n<<listTags ideas title *>>\nAnd now my definite todo list:\n<<listTags todo title *>>
* Smiley macro <<smiley>>\n* listTags macro
You can insert a smiley with the "smiley" macro:\n{{{\n< <smiley>>\n< <smiley :-)>>\n< <smiley :-(>>\n< <smiley ;-)>>\n< <smiley :-|>>\n< <smiley :-D>>\n}}\nproduces:\n<<smiley>>\n<<smiley :-)>>\n<<smiley :-(>>\n<<smiley ;-)>>\n<<smiley :-|>>\n<<smiley :-D>>\n
#styleListHeading\n { font-size:7pt; margin:0em; }\n#styleList\n { width: 100%; font-size:8pt; margin:0em; }\n/* HACK - IE listbox too wide (=100%+scrollbar width), use fixed width as workaround */\n#styleList { width: 14em; }\n
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 chkGenerateAnRssFeed>> GenerateAnRssFeed\n<<option chkRegExpSearch>> RegExpSearch\n<<option chkCaseSensitiveSearch>> CaseSensitiveSearch\n<<option chkAnimate>> EnableAnimations\n\n<<selectStylesheet>>\n\nSee AdvancedOptions
http://www.rumsby.org/yatwa/
* Added Eric Shulman's "import tiddlers" extension\n* Ported to TW 1.2.27\n* Added Eric Shulman's "select stylesheet" extension\n** I've included some example stylesheets from the [[TiddlyWiki StyleSheet Repository|http://www.zrenard.com/tiddlywiki/stylesrepository.php]]\n
* {\n margin: 0px;\n padding: 0px;\n font-family: Arial, Helvetica, sans-serif;\n}\n\nbody {\n background-color: #fff; color: #333;\n}\n\n#header {\n color: #ff0084;\n padding: 20px 20px 10px 10px;\n height: auto;\n}\n\n#titleline{\n background-color: transparent;\n padding:0;\n}\n\n#displayArea {\n margin: 1em 13em 0em 16em;\n}\n\na {\n color: #0063dc;\n text-decoration: none;\n background: transparent;\n}\n\na:hover, a:active {\n color: #ff0084;\n text-decoration: none;\n}\n\n/* HEADER ========================================================== */\n\n#siteTitle {\n color: 0063dc;\n font-size: 30px;\n}\n\n#siteSubtitle {\n font-size: 13px;\n padding-left: 10px;\n color: #ff0084;\n}\n\n#titleLine a {\n color: #0063dc;\n}\n\n#titleLine a:hover {\n color: #ff0084;\n}\n\n/* SIDEBARS ========================================================== */\n\n#mainMenu{\n float: left;\n width: 175px;\n margin-top: -8px;\n}\n\n#mainMenu h1,#mainMenu h2,#mainMenu h3{\n color: #ff0084;\n font-weight: bold;\n padding: 2px 0px 2px 0px;\n font-size: 13px;\n letter-spacing: .1em;\n border-bottom: dotted 1px #ccc;\n background-color: transparent;\n display: block;\n}\n\n#mainMenu a.button,#mainMenu a.tiddlyLink {\n line-height: 1.75em;\n font-size: 12px;\n color: #0063dc;\n text-transform: capitalize;\n}\n\n#mainMenu a.externalLink{\n display: block;\n float: left;\n margin: 0 0 1em 0;\n padding: 0;\n text-align: left;\n line-height: 1em;\n font-size: 11px;\n color: #999;\n text-decoration: none;\n}\n\n#mainMenu a.button:hover,#mainMenu a.tiddlyLink:hover, #mainMenu a.externalLink:hover {\n color: #ff0084;\n background-color: transparent;\n}\n\n#mainMenu input{\n display: block;\n margin:0 0 0 auto;\n}\n\n#contentWrapper #mainMenu a.tab{\n border: dotted 1px #ccc ;\n border-bottom: 0;\n font-weight: bold;\n}\n\n#contentWrapper #mainMenu a.tabSelected{\n padding-bottom: 4px;\n background-color: #fff;\n color: #ff0084;\n}\n\n#contentWrapper #mainMenu a.tabUnselected{\n padding-bottom: 3px;\n}\n\n#contentWrapper #mainMenu .tabset{\n border-bottom: dotted 1px #ccc;\n}\n\n#contentWrapper #mainMenu .tabContents{\n font-size: 11px;\n background-color: transparent;\n border: 0;\n}\n\n#contentWrapper #mainMenu .tabContents a{\n line-height: 1.5em;\n}\n\n#contentWrapper #mainMenu .tabContents a:hover{\n color: #ff0084;\n}\n\n#mainMenu .sliderPanel{\n border: dotted 1px #ccc;\n margin: 3px;\n padding: 5px 5px 15px 5px;\n font-size: 11px;\n text-align: left;\n line-height: 1em;\n}\n\n#mainMenu .sliderPanel a{\n font-weight: normal;\n font-size: 11px;\n}\n\n#mainMenu .sliderPanel input{\n display: inline;\n}\n\n#optionsPanel {\n display: none;\n padding: 4px;\n font-size: 11px;\n border: dotted 1px #ccc;\n text-align: left;\n}\n\n#optionsPanel div{\n margin: 5px 0;\n}\n\n#optionsPanel a {\n display: inline;\n font-weight: normal;\n}\n\n#optionsPanel a:hover, #optionsPanel a:active {\n color: #ff0084;\n}\n\n#optionsPanel input {\n float: right;\n}\n\n#sidebar {\n float: right;\n width: 14em;\n background-color: transparent;\n}\n\n#sidebarOptions{\n// display:none\n}\n\n#sidebarOptions {\n padding-top: 0.5em;\n background-color: transparent;\n}\n\n#sidebarOptions .button {\n color: #0066dc;\n background-color: transparent;\n}\n\n#sidebarOptions .button:hover {\n color: #ff0084;\n background-color: transparent;\n}\n\n#sidebarOptions .button:active {\n color: #ff0084;\n background-color: transparent;\n}\n\n#sidebarOptions .sliderPanel {\n background-color: transparent;\n}\n\n#sidebarOptions .sliderPanel A {\n color: #0063dc;\n font-weight: bold;\n}\n\n#sidebarOptions .sliderPanel A:hover {\n color: #ff0084;\n background-color: transparent;\n}\n\n#sidebarOptions .sliderPanel A:active {\n color: #ff0084;\n background-color: #transparent;\n}\n\n#sidebarTabs{\n background-color: transparent;\n}\n\n#contentWrapper #sidebar a.tab {\n font-weight: bold;\n}\n\n#contentWrapper #sidebar a.tabSelected {\n font-size: 16px;\n color: #ff0084 !important;\n background-color: #fff !important;\n padding: 2px 4px 4px 4px;\n border: 1px solid #e6e6e6;\n border-bottom: 0;\n}\n\n#contentWrapper #sidebar a.tabUnselected {\n font-size: 14px;\n color: #0063dc !important;\n background-color: #e6e6e6 !important;\n padding: 2px 4px 2px 4px;\n}\n\n#contentWrapper #sidebar a.tab:hover {\n color: #ff0084 !important;\n text-decoration: none;\n}\n\n#contentWrapper #sidebar .tabContents{\n border: 1px solid #e6e6e6;\n}\n\n#contentWrapper #sidebar .tabContents a{\n color: #0063dc;\n line-height: 1.6em;\n margin-left: -.5em;\n}\n\n#contentWrapper #sidebar .tabContents a:hover{\n color: #ff0084;\n background-color: transparent;\n}\n\n#contentWrapper #sidebar .tabContents a:before{\n color: #ff0084;\n font-weight: bold;\n content: "» ";\n margin-right: .5em;\n}\n\n#popup{\n color: #000;\n background-color: #fff;\n text-align: left;\n}\n\n#popup hr{\n border: 0;\n border-top: solid 1px #e6e6e6;\n height: 1px;\n color: #e6e6e6;\n width: 98%;\n\n}\n\n#popup a{\n color: #ff0084;\n background-color: #fff;\n}\n\n#popup a:hover{\n color: #0063dc;\n background-color: #fff;\n}\n\n/* SIDEBAR (RIGHT) =============================================================*/\n\n#sidebarTabs {\n padding: 8px 0 0 10px;\n}\n\n#sidebarTabs a {\n/* color: #fff;*/\n padding: 2px 8px 1px 8px;\n height: 22px;\n}\n\n#sidebarTabs a:hover {\n}\n\n#sidebarContent {\n padding: 0 10px 10px 10px;\n font-size: 11px;\n clear: both;\n border-left: solid 1px #e6e6e6;\n}\n\n#sidebarContent br{\n display: none;\n}\n\n.sidebarSubHeading {\n padding: 8px 0 0 0;\n display: block;\n width: 100%;\n color: #000;\n}\n\n#sidebarContent a {\n display: block;\n margin: 5px 0 1px 12px;\n}\n\n#sidebarContent span.arrows {\n float: left;\n font-weight: bold;\n color: #ff0084;\n margin-top: 5px;\n}\n\n#sidebarContent a:hover {\n}\n\n/*===================================================================*/\n\n#contentWrapper a.tab {\n font-weight: normal;\n display: inline;\n margin: 0px 1px; \n}\n\n#contentWrapper a.tabSelected {\n background-color: #fff !important;\n padding: 2px 4px 2px 4px;\n border: 1px solid #999;\n border-bottom: 0;\n}\n\n#contentWrapper a.tabUnselected {\n background-color: #e6e6e6 !important;\n padding: 2px 4px 0px 4px;\n}\n\n#contentWrapper .selectedTiddler a.tabSelected {\n color: #ff0084 !important;\n}\n\n#contentWrapper .selectedTiddler a.tabUnselected {\n color: #0063dc !important;\n}\n\n#contentWrapper .selectedTiddler a.tab:hover {\n color: #ff0084 !important;\n text-decoration: none;\n}\n\n/*===========================================================================================*/\n\n#sidebarTabs{\n margin: 0;\n padding: 0;\n}\n\n#contentWrapper .tabContents {\n background-color: transparent;\n border:1px solid #999;\n}\n\n#contentWrapper .tabContents a.tiddlyLink, #contentWrapper .tabContents a.button{\n background-color: transparent;\n}\n\n#contentWrapper .tabContents a:hover{\n color: #b44;\n}\n\n#contentWrapper .txtMoreTab a.tabUnselected {\n background-color: #f5d7b4 !important;\n padding: 2px 4px 0px 4px;\n color: #000;\n}\n\n#contentWrapper .txtMoreTab a.tabSelected {\n background-color: #cf936c !important;\n padding: 2px 4px 2px 4px;\n color: #000;\n}\n\n.txtMoreTab .tabContents {\n background-color: #cf936c !important;\n border-bottom: solid #aaa 1px;\n color: #fff;\n}\n\n.txtMoreTab .tabContents a{\n background-color: transparent;\n}\n\n/* TIDDLER DISPLAY/EDIT SPACE ========================================================== */\n\n#contentWrapper .tiddler {\n margin: 0 0 10px 0;\n padding: 0 15px !important;\n border: dotted 1px #fff;\n color: #666;\n}\n\n.tiddler .title {\n background-color: #e9e9e9;\n}\n\n.selectedTiddler {\n border: dotted 1px #ccc;\n margin: -1px;\n}\n\n.selectedTiddler .viewer {\n color: #000;\n}\n\n.selectedTiddler .viewer * {\n color: #000;\n}\n\n.selectedTiddler .viewer h2, .selectedTiddler .viewer h4, .selectedTiddler .viewer h6, .selectedTiddler .viewer h3, .selectedTiddler .viewer h5 {\n color: #0063dc;\n}\n\n.selectedTiddler .viewer pre{\n color: #000;\n}\n\n.selectedTiddler .title {\n color: #ff0084;\n background-color: #e9e9e9;\n}\n\n#contentWrapper .selectedTiddler .viewer a {\n color: #0063dc;\n background-color: transparent;\n}\n\n#contentWrapper .selectedTiddler .viewer a:hover {\n color: #ff0084;\n \n}\n\n#messageArea {\n font-size: 13px;\n font-weight: bold;\n padding: 5px;\n margin: 10px 20px;\n color: #ff0084;\n border: dotted 1px #ccc;\n text-align: center;\n background: transparent;\n}\n\n#messageArea a {\n color: #0063dc !important;\n}\n\n#messageArea a:hover {\n color: #ff0084 !important;\n}\n\n#displayArea .tiddlyLinkExisting {\n font-weight: bold;\n text-decoration: none;\n}\n\n#displayArea .tiddlyLinkNonExisting {\n font-style: italic;\n text-decoration: none;\n}\n\n#displayArea .externalLink {\n text-decoration: underline;\n}\n\n.title {\n font-size: 1.3em;\n padding: 0 0 0 0;\n font-weight: bold;\n display: block;\n color: #0063dc;\n}\n\n.toolbar {\n font-weight: normal;\n font-size: 11px;\n visibility: hidden;\n text-align: right;\n padding: 0 0 5px 0;\n margin: -8px 0 0 0;\n}\n\n.toolbar a.button {\n padding: 1px 5px;\n color: #fff;\n text-decoration: none;\n border: 1px outset #0063dc;\n background: #0063dc;\n}\n\n.toolbar a.button:hover {\n color: #fff;\n background: #ff0084;\n border: 1px outset #ff0084;\n}\n\n.toolbar a.button:active {\n color: #fff;\n background: #ff0084;\n border: 1px inset #ff0084;\n}\n\n.tagLinks {\n padding-top: 5px;\n margin-top: 10px;\n border-top: 1px dotted #ccc;\n color: #aaa;\n}\n\n.tagLinks a {\n color: #aaa;\n}\n\n.selectedTiddler .tagLinks a {\n color: #0063dc;\n}\n\n.tagLinks a:hover {\n color: #ff0084;\n}\n\n\n#contentWrapper .viewer {\n line-height: 140%;\n color: #999;\n}\n\n#contentWrapper .viewer a{\n font-weight: bold;\n color: #999;\n text-decoration: none;\n background-color: transparent;\n}\n\n#contentWrapper .viewer h1, #contentWrapper .viewer h2, #contentWrapper .viewer h3, #contentWrapper .viewer h4, #contentWrapper .viewer h5, #contentWrapper .viewer h6{\n background-color: transparent;\n border-bottom: 1px dotted #999;\n margin-bottom: .25em;\n}\n\n.viewer blockquote {\n border-left: 3px solid #777;\n margin: 5px;\n padding: 5px;\n}\n\n.viewer ul {\n padding-left: 30px;\n}\n\n.viewer ol {\n padding-left: 30px;\n}\n\nol\n{\n list-style-type: decimal;\n}\n\nol ol\n{\n list-style-type: lower-alpha;\n}\n\nol ol ol\n{\n list-style-type: lower-roman;\n}\n\n.viewer ul, .viewer ol, .viewer p {\n margin: 5px 0 12px 0;\n}\n\n.viewer li {\n margin: 3px 0;\n}\n\n.viewer pre{\n font-family: monspace;\n}\n\nh2,h3,h4,h5,h6 {\n font-weight: bold;\n}\n\n#contentWrapper .viewer *{\n color: #999;\n}\n\n\n.viewer h2 {\n font-size: 1.2em;\n}\n\n.viewer h3 {\n font-size: 1.1em;\n font-style: italic;\n}\n\n.viewer h4 {\n font-size: 1em;\n}\n\n.viewer h5 {\n font-size: .9em;\n font-style: italic;\n}\n\n.viewer h6 {\n font-size: .8em;\n}\n\n.viewer table {\n border-collapse: collapse;\n border: 2px solid #303030;\n font-size: 11px;\n margin: 10px 0;\n}\n\n.viewer th {\n background: #eee;\n border: 1px solid #aaa;\n padding: 3px;\n}\n\n.viewer td {\n border: 1px solid #aaa;\n padding: 3px;\n}\n\n.viewer caption {\n padding: 3px;\n}\n\n.viewer hr {\n border: none;\n border-top: dotted 1px #777;\n height: 1px;\n color: #fff;\n margin: 7px 0;\n}\n\n.body {\n margin: 5px 0 0px 0;\n padding: 5px 0;\n/* border-top: 1px dotted #ccc;*/\n}\n\n.highlight {\n color: #000;\n background: #ffe72f;\n}\n\n.editor {\n font-size: 8pt;\n color: #402c74;\n font-weight: normal;\n padding: 10px 0;\n}\n\n.editor input, .editor textarea {\n display: block;\n font: 13px/130% "Andale Mono", "Monaco", "Lucida Console", "Courier New", monospace;\n margin: 0 0 10px 0;\n border: 1px inset #333;\n padding: 2px 0;\n}\n\n.editor textarea {\n height: 500px;\n}\n\n.footer a.button,.editorFooter a.button{\n color: #e6e6e6;\n}\n\n.selectedTiddler .footer a.button,\n.selectedTiddler .editorFooter a.button{\n color: #0063dc;\n}\n\n.selectedTiddler .footer a.button:hover,\n.selectedTiddler .editorFooter a.button:hover{\n color: #ff0084;\n background-color: transparent;\n}\n\ninput:focus, textarea:focus {\n background: #ffe;\n border: 1px solid #000 !important;\n}\n\n#storeArea, #copyright {\n display: none;\n}\n\n.zoomer {\n border: 1px solid #0063dc;\n color: #9cf;\n width: 1px;\n}\n
* Port to TW 1.2.28\n* Use Eric Shulman's code to load stylesheets for extensions\n* Fix TiddlyTag style to include options panel, so that you can change the style back again <<smiley>>\n* Temporarily remove GTD style sheet until I make it work properly\n* Include MonkeyMind style from the [[TiddlyWiki StyleSheet Repository|http://www.zrenard.com/tiddlywiki/stylesrepository.php]]\n** Needed some extra CSS to fix the colours of the message area - see the end of [[MonkeyMind style]]\n* Added code to calendar implementation to re-arrange the document structure and so avoid changing it in the HTML file\n* Changed "Open all tiddlers tagged with..." action to fold results if FolderSearch checked, like it used to\n* Tagged all the stylesheets as "systemTiddlers" so that they appear in empty.html - delete any you don't want!
* Ported to 1.2.29
config.options.chkSinglePage = false;\nconfig.options.chkAutoSaveMessage = true;\n
// Save this tiddlywiki with the pending changes\nfunction saveChanges()\n{\n clearMessage();\n // Get the URL of the document\n var originalPath = document.location.toString();\n // Check we were loaded from a file URL\n if(originalPath.substr(0,5) != "file:")\n {\n alert(config.messages.notFileUrlError);\n displayTiddler(null,"SaveChanges",0,null,null,false,false);\n return;\n }\n // Remove any location part of the URL\n var hashPos = originalPath.indexOf("#");\n if(hashPos != -1)\n originalPath = originalPath.substr(0,hashPos);\n // Convert to a native file format assuming\n // "file:///x:/path/path/path..." - pc local file --> "x:\spath\spath\spath..."\n // "file://///server/share/path/path/path..." - FireFox pc network file --> "\s\sserver\sshare\spath\spath\spath..."\n // "file:///path/path/path..." - mac/unix local file --> "/path/path/path..."\n // "file://server/share/path/path/path..." - pc network file --> "\s\sserver\sshare\spath\spath\spath..."\n var localPath;\n if(originalPath.charAt(9) == ":") // pc local file\n localPath = unescape(originalPath.substr(8)).replace(new RegExp("/","g"),"\s\s");\n else if(originalPath.indexOf("file://///") == 0) // FireFox pc network file\n localPath = "\s\s\s\s" + unescape(originalPath.substr(10)).replace(new RegExp("/","g"),"\s\s");\n else if(originalPath.indexOf("file:///") == 0) // mac/unix local file\n localPath = unescape(originalPath.substr(7));\n else // pc network file\n localPath = "\s\s\s\s" + unescape(originalPath.substr(7)).replace(new RegExp("/","g"),"\s\s");\n // Load the original file\n var original = loadFile(localPath);\n if(original == null)\n {\n alert(config.messages.cantSaveError);\n displayTiddler(null,"SaveChanges",0,null,null,false,false);\n return;\n }\n // Locate the storeArea div's\n var posOpeningDiv = original.indexOf(startSaveArea);\n var posClosingDiv = original.lastIndexOf(endSaveArea);\n if((posOpeningDiv == -1) || (posClosingDiv == -1))\n {\n alert(config.messages.invalidFileError.format([localPath]));\n return;\n }\n // Save the backup\n if(config.options.chkSaveBackups)\n {\n// BEGIN SJR - Save backups in a folder\n var backSlash = true;\n var dirPathPos = localPath.lastIndexOf("\s\s");\n if (dirPathPos == -1) {\n dirPathPos = localPath.lastIndexOf("/");\n backSlash = false;\n }\n //put it in the backup directory\n var backupFolder = store.getTiddlerText("BackupFolder");\n if(!backupFolder)\n backupFolder = ".";\n var backupPath = localPath.substr(0,dirPathPos) + (backSlash ? "\s\s" : "/")\n + backupFolder + localPath.substr(dirPathPos, localPath.length - dirPathPos);\n backupPath = backupPath.substr(0,backupPath.lastIndexOf(".")) + "." + (new Date()).convertToYYYYMMDDHHMMSSMMM() + ".html";\n var backup = saveFile(backupPath,original);\n if(backup)\n displayMessage(config.messages.backupSaved,"file://" + backupPath);\n else\n alert(config.messages.backupFailed);\n }\n // Save Rss\n if(config.options.chkGenerateAnRssFeed)\n {\n var rssPath = localPath.substr(0,localPath.lastIndexOf(".")) + ".xml";\n var rssSave = saveFile(rssPath,convertUnicodeToUTF8(generateRss()));\n if(rssSave)\n displayMessage(config.messages.rssSaved,"file://" + rssPath);\n else\n alert(config.messages.rssFailed);\n }\n // Save empty template\n if(config.options.chkSaveEmptyTemplate)\n {\n var emptyPath,p;\n if((p = localPath.lastIndexOf("/")) != -1)\n emptyPath = localPath.substr(0,p) + "/empty.html";\n else if((p = localPath.lastIndexOf("\s\s")) != -1)\n emptyPath = localPath.substr(0,p) + "\s\sempty.html";\n else\n emptyPath = localPath + ".empty.html";\n var empty = original.substr(0,posOpeningDiv + startSaveArea.length) + convertUnicodeToUTF8(generateEmpty()) + original.substr(posClosingDiv);\n var emptySave = saveFile(emptyPath,empty);\n if(emptySave)\n displayMessage(config.messages.emptySaved,"file://" + emptyPath);\n else\n alert(config.messages.emptyFailed);\n }\n // Save new file\n var revised = original.substr(0,posOpeningDiv + startSaveArea.length) + \n convertUnicodeToUTF8(allTiddlersAsHtml()) + "\sn\st\st" +\n original.substr(posClosingDiv);\n var save = saveFile(localPath,revised);\n if(save) {\n displayMessage(config.messages.mainSaved,"file://" + localPath);\n store.setDirty(false);\n }\n else\n alert(config.messages.mainFailed);\n}\n
* Calendar plug-in version 0.1\n* Re-implementation is a set of pure plugins for vanilla TW 1.2.31 code base
Type the text for 'New TiAfter playing with the vanilla TiddlyWiki for a bit, and then some of the existing variations, I decided that what I wanted was a combination of a number of adaptations. Specifically:\n* [[TiddlyTagWiki|http://www.digitaldimsum.co.uk/]]\n* [[GTDTiddlyWiki|http://shared.snapgrid.com/gtd_tiddlywiki.html]]\n* and the work done by David Bockes to incorporate [[jscalendar|http://www.dynarch.com/projects/calendar/]]\n\nI've done one or two other little things also:\n* Incorporated the TiddlyTagWiki change to keep automatic backups in a sub-directory, keeping things tidier\n* Made a few style changes using the StyleSheet tiddler\n* Added [[Folding]] to make large collections of tiddlers easier to manage - especially useful with tags\n* Added [[Sortable tables]]\n* Added EncryptedTiddlers\n\nThis is the result. You'll see that I've kept the standard TiddyWiki layout, with the options and timeline on the right and main menu on the left, but joined by the calendar and list of tags.\n\nThere's a complete [[revision history|Recent Changes]] and [[documentation|Usage]] for each feature.\n\nThis wiki is based on TiddlyWiki version 1.2.29. Upgrading to it from versions prior to 1.23 is still tricky. A version of yatwa based on TW 1.2.22 is available [[here|yatwa-old.html]] for anybody that needs it.\n\n[[Steve Rumsby|mailto:yatwa@rumsby.org]]\nddler'
[[Welcome to YATWA version 2]]
config.macros.getversion = {}\nconfig.macros.getversion.handler = function(place,macroName,params)\n{\nvar versionData = version.extensions[params].major + "." + version.extensions[params].minor + "." + version.extensions[params].revision;\ncreateTiddlyElement(place,"span",null,null,versionData);\n}\n\nconfig.macros.getversiondate = {}\nconfig.macros.getversiondate.handler = function(place,macroName,params)\n{\nvar versionDate = version.extensions[params[0]].date.formatString(params[1].trim());\ncreateTiddlyElement(place,"span",null,null,versionDate);\n}\n
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Because TiddlyWiki is a single HTML file, you've actually already downloaded the entire software just by viewing this site. If you want to be able to SaveChanges, you can save your own blank TiddlyWiki to your local drive by right clicking on [[this link|empty.html]] and selecting 'Save link as...' or 'Save target as...'. You can choose where to save the file, and what to call it (but keep the .HTML extension).\n\nDo ''not'' use the File/Save command in your browser to save TiddlyWiki, because of SaveUnpredictabilities.
Upgrading from previous versions of YATWA, especially those based on versions of TiddlyWiki before 1.2.23, is unlikely to work. A simpler and more reliable method is to download the empty wiki following the [[download instructions|Downloading]] and then use the ImportTiddlers function to copy your content from the old version to the new.\n\nIf you are upgrading from a YATWA of version 2 or newer, you can use the following process:\n* Open your TiddlyWiki file in FireFox (say it's called "mystuff.html")\n* SaveChanges (with SaveBackups switched on) to make sure that you've got a backup of it\n* Without closing that page, right-click on [[this link|http://www.tiddlywiki.com/empty.html]], select 'Save target' or 'Save link' and save it as "mystuff.html", replacing your existing file\n* Now go back to the previously opened copy of "mystuff.html" in your browser and SaveChanges again. It will inherit the newly saved code\n* Refresh the page in the browser to verify that the upgrade has worked\n\nNote that triggered by the embarrassing AreaBug, this revision of TiddlyWiki changes the StorageFormat used for content. This means that once you upgrade, you can't easily downgrade back to a previous version.\n
/*\n{{{\n*/\n\nbody {\n background: #D5D0C4;\n font-size: 9pt;\n font-family: verdana,arial,helvetica;\n padding: 0em 0em 0em 0em;\nmargin: 0em 0em 0em 0em;\n z-index: 0;\nposition: relative;\ntext-align: center;\nbackground-repeat: repeat-y;\nbackground-position: center; \nbackground-image: url(data:image/gif;base64,R0lGODlh0gMCAIAAANXQxP///yH5BAAAAAAALAAAAADSAwIAAAI3hI95we0Po5y02ouz3rz7D4biSJbmiabqyrbuC8fyTL/Kjed4zff+DwwKh8Si8YhMKpfMi05XAAA7);\n\n}\n\na:link, a:visited {\n text-decoration: none;\n}\n\na:hover, a:active {\n text-decoration: none;\n}\n\n#contentFooter {\nbackground-color: #FFF;\nmax-height: 100%;\nposition: float;\n}\n\n#contentWrapper {\nwidth: 920px;\nmargin: auto;\ntext-align: left;\nbackground-color: #FFFFFF;\npadding: 10px;\nheight: 100%;\n}\n\n\n#header {\nbackground-color: #C9DCB2;\npadding: 0px;\n}\n\n#titleLine {\n background-color: #C9DCB2;\nbackground: #999 url(data:image/gif;base64,R0lGODlhBAAEAIAAALu7u5mZmSH5BAAAAAAALAAAAAAEAAQAAAIFDGKomQUAOw==);\n padding: 5em 1em 1em 1em;\n}\n\n#titleLine a {\n color: #CCFF66;\n}\n\n#siteTitle {\n font-size: 26pt;\n}\n\n#siteSubtitle {\n padding-left: 1em;\n font-size: 10pt;\n}\n\n#mainMenu {\n position: absolute;\n left: 10px;\n float: left;\n width: 10em;\n line-height: 166%;\n padding: 1.5em 0.5em 0.5em 0.5em;\n font-size: 10pt;\n color: black;\n text-align: right;\n}\n\n#mainMenu .tiddlyLink {\n color: #aec650;\n}\n\n#mainMenu .tiddlyLink:hover {\n background-color: #B1DCEF;\n}\n\n#mainMenu .externalLink {\n color: #996633;\n text-decoration: underline;\n}\n\n#mainMenu .externalLink:hover {\n background-color: #B1DCEF;\n}\n\n#mainMenu .button {\n color: #C1D399;\n margin: 0em 0.25em 0em 0.25em;\n padding: 0em 0.25em 0em 0.25em;\n background-color: #FFF;\n border-right: 1px solid #999;\n border-bottom: 1px solid #999;\n}\n\n#mainMenu .button:hover {\n color: #FFFFFF;\n background-color: #C1D399;\n}\n\n\n#displayArea {\n margin: 1em 17em 0em 14em;\n}\n\n#tiddlerDisplay {\n}\n\n#messageArea {\n background-color: #EC7230;\n color: #ffffff;\n padding: 0.5em 0.5em 0.5em 0.5em;\n display: none;\n}\n\n#messageArea a:link, #messageArea a:visited {\n display: inline;\n text-decoration: underline;\n color: #FFF;\n}\n\n#messageArea a:hover {\n color: #333;\n}\n\n#messageArea a:active {\n color: #ffffff;\n}\n\n#popup {\n display: none;\n position: absolute;\n font-size: 8pt;\n color: #999;\n background-color: #EEE;\n padding: 0.25em 0.25em 0.25em 0.25em;\n border-right: 1px solid #330000;\n border-bottom: 1px solid #330000;\n z-index: 10;\nfilter:alpha(opacity=50);\n-moz-opacity:0.5;\nopacity: 0.5;\n}\n\n#popup a {\n display: block;\n color: #333;\n line-height: 100%;\n}\n\n#popup a:hover {\n background-color: #FFF;\n color: #330000;\n}\n\n#popup hr {\n border-top: solid 1px #666;\n border-left: none;\n border-right: none;\n border-bottom: none;\n height: 1px;\n color: #666;\n}\n\n.tabset {\n padding: 1em 0em 0em 0.5em;\n}\n\n.tab {\n margin: 0em 0em 0em 0.25em;\n padding: 2px 2px 2px 2px;\n} \n\n.tabSelected {\n background-color: #333333;\n}\n\n.tabUnselected {\n background-color: #999999;\n}\n\n.tab:hover {\n}\n\n.tab:active {\n}\n\n.tabContents {\n padding: 2px;\n background-color: #333333;\n}\n\n.tiddler {\n padding: 1em 1em 0em 1em;\n font-size: 9pt;\n}\n\n.selectedTiddler {\nborder: 1px solid #EEE;\nmargin: 5px;\n}\n\n.unselectedTiddler {\nborder: 1px solid #EEE;\nmargin: 5px;\n}\n\n.tiddler .tiddlyLinkExisting {\n font-weight: bold;\n}\n\n.tiddler .tiddlyLinkNonExisting {\n font-style: italic;\n}\n\n.tiddler .externalLink {\n text-decoration: underline;\n}\n\n.tiddler .button {\n padding: 0.2em 0.4em 0.2em 0.4em;\n color: #AAAAAA;\n}\n\n.tiddler .button:hover {\n text-decoration: none;\n color: #999999;\n background-color: #DAEEF7;\n}\n\n.tiddler .button:active {\n color: #ffffff;\n background-color: #C1D399;\n}\n\n.title {\n font-size: 10pt;\n color: #666;\n font-weight: bold;\npadding-left:5px;\n}\n\n.selectedTiddler .title {\n font-size: 10pt;\n color: #333;\n font-weight: bold;\n}\n\n.toolbar {\n text-align: right;\n font-weight: normal;\n font-size: 8pt;\n padding: 0em 0em 0em 2em;\n color: #aaaaaa;\n visibility: hidden;\n}\n\n.toolbar #popup {\n text-align: left;\n}\n\n.selectedTiddler .toolbar {\n visibility: visible;\n}\n\n.footer {\n font-weight: normal;\n font-size: 8pt;\n margin: 0.5em 0em 0em 0em;\n padding: 0em 0em 0em 0em;\n color: #dddddd;\n}\n\n.selectedTiddler .footer {\n color: #888888;\n}\n\n.body {\n padding-top: 0.5em;\n}\n\n.viewer {\n color: #000000;\n line-height: 15px;\n padding: 8px 8px 8px 8px;\n}\n\n.viewer a:link, .body a:visited {\n text-decoration: none;\n color: #C1D399;\n}\n\n.viewer a:hover {\n color: #ffffff;\n background-color: #B1DCEF;\n text-decoration: none;\n}\n\n.viewer .button {\n margin: 0em 0.25em 0em 0.25em;\n padding: 0em 0.25em 0em 0.25em;\n color: #999;\n background-color: #FFF;\n border-right: 1px solid #999;\n border-bottom: 1px solid #999;\n}\n\n.viewer .button:hover {\n background-color: #C1D399;\n color: #FFF;\n}\n\n.viewer blockquote {\n font-size: 8pt;\n line-height: 150%;\n border-left: 3px solid #666666;\n padding-left: 0.8em;\n margin-left: 2.5em;\n}\n\n.viewer ul {\n margin-left: 0.5em;\n padding-left: 1.5em;\n}\n\n.viewer ol {\n margin-left: 0.5em;\n padding-left: 1.5em;\n}\n\n.viewer h1,h2,h3,h4,h5 {\n font-weight: bold;\n text-decoration: none;\nborder-bottom: dashed 1px #d6d6d6;\nbackground-color: #FFF;\n}\n\n.viewer h1 {\n font-size: 12pt;\n}\n\n.viewer h2 {\n font-size: 10pt;\n}\n\n.viewer h3 {\n font-size: 10pt;\n}\n\n.viewer h4 {\n font-size: 9pt;\n}\n\n.viewer h5 {\n font-size: 8pt;\n}\n\n.viewer table {\n border-collapse: collapse;\n border: 2px solid #303030;\n margin-left: 1.0em;\n margin-right: 1.0em;\n margin-top: 0.8em;\n margin-bottom: 0.8em;\n font-size: 100%;\n}\n\n.viewer th {\n background-color: #999966;\n border: 1px solid #606060;\n color: #ffffff;\n padding: 3px;\n}\n\n.viewer td, tr {\n border: 1px solid #606060;\n padding: 3px;\n}\n\n.viewer caption {\n padding: 3px;\n}\n\n.viewer pre, .viewer code {\n font-size: 100%;\n line-height: 1.4em;\n color: #660000;\n}\n\n.viewer hr {\n border-top: dashed 1px #606060;\n border-left: none;\n border-right: none;\n border-bottom: none;\n height: 1px;\n color: #666666;\n}\n\n.highlight, .marked {\n color: #000000;\n background-color: #ffe72f;\n}\n\n.editor {\n font-size: 8pt;\n color: #402C74;\n font-weight: normal;\n}\n\n.editor input {\n display: block;\n border: 1px solid black;\n width: 100%;\n}\n\n.editor textarea {\n display: block;\n font: inherit;\n border: 1px solid black;\n width: 100%;\n}\n\n.editorFooter {\n padding: 0.25em 0em 0.25em 0em;\n font-size: 8pt;\n color: #aaaaaa;\n}\n\n.editorFooter A {\n padding: 0.2em 0.4em 0.2em 0.4em;\n color: #993300;\n}\n\n.editorFooter A:hover {\n text-decoration: none;\n color: #ccff66;\n background-color: #993300;\n}\n\n.editorFooter A:active {\n color: #ffffff;\n background-color: #cc9900;\n}\n\n#sidebar {\n float: right;\n width: 16em;\n color: #000000;\n font-size: 8pt;\npostion: absolute;\n}\n\n#sidebarOptions {\n padding-top: 0.5em;\nmargin-top:10px;\nmargin-right: 10px;\n background-color: #F1EFEB;\n}\n\n#sidebarOptions .button {\n color: #999;\n padding: 0.3em 0.2em 0.3em 1em;\n display: block;\n}\n\n#sidebarOptions .button:hover {\n color: #999;\n background-color: #B1DCEF;\n}\n\n#sidebarOptions .button:active {\n color: #CFC9BC;\n background-color: #EEE;\n}\n\n#sidebarOptions input {\n margin: 0.4em 0em 0.3em 1em;\n}\n\n#sidebarOptions .sliderPanel {\n padding: 0.5em 0.5em 0.5em 0.5em;\n font-size: 7pt;\n background-color: #FFF;\n}\n\n#sidebarOptions .sliderPanel A {\n color: #6999C9;\n font-weight: bold;\n}\n\n#sidebarOptions .sliderPanel A:hover {\n color: #C1D399;\n background-color: #FFF;\n}\n\n#sidebarOptions .sliderPanel A:active {\n color: #333;\n background-color: #FFF;\n}\n\n#sidebarOptions .sliderPanel input {\n margin: 0em 0em 0.3em 0em;\n}\n\n.sidebarSubHeading {\n font-size: 7pt;\n color: #330000;\n}\n\n#sidebarTabs {\n background-color: #fff;\nmargin-right:2px;\n}\n\n#sidebarTabs .tabSelected {\n color: #999;\n background-color: #ECF8FD;\n position: relative;\n top: -1px;\n}\n\n#sidebarTabs .tabUnselected {\n color: #999;\n background-color: #F5F5F5;\n}\n\n#sidebarTabs .tabContents {\n background-color: #ECF8FD;\nmargin-right: 10px;\n}\n\n#sidebarTabs .txtMoreTab .tabSelected {\n background-color: #F5F5F5;\n}\n\n#sidebarTabs .txtMoreTab .tabUnselected {\n background-color: #ECF8FD;\n}\n\n#sidebarTabs .txtMoreTab .tabContents {\n background-color: #F5F5F5;\n}\n\n#sidebarTabs .tabContents .tiddlyLink {\n color: #6999C9;\n}\n\n#sidebarTabs .tabContents .tiddlyLink:hover {\n background-color: #ECF8FD;\n color: #330000;\n}\n\n#sidebarTabs .tabContents .button {\n color: #6999C9;\n padding: 0em 0em 0em 0em;\n display: inline;\n}\n\n#sidebarTabs .tabContents .button:hover {\n color: #999;\n background-color: #ECF8FD;\n}\n\n#licensePanel {\n padding: 0.5em 0em 0.5em 0em;\n}\n\n#licensePanel A {\n display: block;\n padding: 0.2em 0.2em 0.2em 0.2em;\n color: #993300;\n}\n\n#licensePanel A:hover {\n text-decoration: none;\n color: #ccff66;\n background-color: #993300;\n}\n\n#licensePanel A:active {\n color: #993300;\n background-color: #ccff66;\n}\n\n#storeArea, #copyright {\n display: none;\n}\n\n.sparkline {\n background-color: #eeeeaa;\n border: none;\n line-height: 100%;\n}\n\n.sparktick {\n background-color: #993300;\n outline: 0;\n}\n\n.errorNoSuchMacro {\n color: #ffff00;\n background-color: #ff0000;\n}\n\n.zoomer {\n font-size: 10pt;\n display: none;\n color: #000000;\n position: absolute;\n padding: 1em 1em 1em 1em;\n border: 1px solid #000000;\n}\n\n#saveTest {\n display: none;\n}\n\n@media print {\n\n#mainMenu, #sidebar, #messageArea {\n display: none ! important;\n}\n\n#displayArea {\n margin: 1em 1em 0em 1em;\n}\n\n}10px\n\n}}}
/*\n{{{\n*/\n\nbody {\n background: #FFFFFF;\n font-size: 9pt;\n font-family: verdana,arial,helvetica;\n padding: 0em 0em 0em 0em;\nmargin: 0em 0em 0em 0em;\n z-index: 0;\nposition: relative;\ntext-align: center;\nbackground-repeat: repeat-y;\nbackground-position: center; \nbackground-image: url(data:image/gif;base64,R0lGODlh0gMCALMAAP7+/vX19eLi4unp6dnZ2c/Pz/z8/Pn5+e/v7////wAAAAAAAAAAAAAAAAAAAAAAACH5BAAAAAAALAAAAADSAwIAAARLMMlJawXmBDQEKVYojmRpnmiqrmzrvnAsz3Rt33iu73zv/8CgcEjUFQiCASJwMACEGA3HAypar9isdsvter/gsHhMLnuPyWXz2YoAADs=);\n\n}\n\na:link, a:visited {\n text-decoration: none;\n}\n\na:hover, a:active {\n text-decoration: none;\n}\n\n#contentFooter {\nbackground-color: #FFF;\nmax-height: 100%;\nposition: float;\n}\n\n#bodydashboard {\nbackground-color: #f4f4f4;\nborder: solid 2px #EEE;\n}\n\n#tiddlerdashboard .selectedTiddler {\nborder: solid 0px #FFF;\n}\n\n\n#tiddlerdashboard .unselectedTiddler {\nborder: 0px solid #FFF;\n}\n\n#contentWrapper {\nwidth: 920px;\nborder-left: solid .01em #EEE;\nborder-right: solid .01em #EEE;\nmargin: auto;\ntext-align: left;\nbackground-color: #FFFFFF;\npadding: 0px;\nheight: 100%;\n}\n\n\n#header {\nmargin: 0px;\n background-color: #333333;\n}\n\n#titleLine {\n background-color: #333333;\nheight: 58px;\ntext-align: right;\nbackground: #333 url(data:image/gif;base64,R0lGODlhBABiAOYAADw8PSsrKxkZGTg4ODMzNBcXFz8/P1NTUyEiIicnJyQjIxITEx0dHEFBQUlJST4+PkZGRkBAQFBQUDo6OkdHRxQTFDIyMjc3N09PTzAwMC8vLyoqKkhIRygoKBMUE01NS0ZGRU1NTSwsLD49PhQTE09QUEhJSDIxMTg3N0VFRj09PVRUVEdISCEhHzo5ORAQDkJBQioqKDk6OignKA4QEEVFQ1BQTyUlIycoJ0NFQzo8PElKSU1OTTo6OUFCQUVFRVRUUzM1Mzw6PDM1NVBSUlRTUxsdG01LSy8vMDg4N0hHSE5NTVBSUE5NTigoKi8tL09QT0dIRz0+PiooKkNFRT9APzAvL1JSUC0tLU5OTjExMVJSUgwMDA4ODhYWFSYlJjY2NkNCQhEREUpKSh4eHhoaGgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAAAAAAALAAAAAAEAGIAAAf/gEArBytFB4dbW4iJW0RbV1sSTBISNhIlElAlNhidWZ9ZGJ9NnyE8IUsfqiFjR2OvsLE7Yw60Jg4Otywcu0ocFBxRFBAQFMMgxCAgKSk1NT85YdJU0tXVPjAwDdvbEd7eBlUGDwbl5A/oIyNSKgAA7e4AEwBCOhP3EzI9LjIuA/8AB6BAkeQCmAsGwShMqDDIEIUEIhKwMHGilhMWtFzUyDGDxwwakFjR8ASLBg1YUmIRoTJAABEiXMrcQHPKhhgxnHTYiWNGhxkJggb9kuCL0aNHFSi4oQCB0qYIoiJoQYYqmatYs5JhwHWrkTIMyogdS3asALEC0qotwLatl7dwKuFW8OKBhIe7JCroXcB3gRi/fsUIHiz4hRgaNLp0eaG4cRcuj7lInswlEAA7);\n padding: 30px 1em 1em 1em;\n}\n\n#titleLine a {\n color: #CCFF66;\n}\n\n#siteTitle {\n font-size: 26pt;\n}\n\n#siteSubtitle {\n padding-left: 1em;\n font-size: 10pt;\nfloat: right;\nmargin-bottom: 10px;\n}\n\n#mainMenu {\n position: absolute;\n left: 10px;\n float: left;\n width: 10em;\n line-height: 166%;\n padding: 1.5em 0.5em 0.5em 0.5em;\n font-size: 10pt;\n color: black;\n text-align: right;\n}\n\n#mainMenu .tiddlyLink {\n color: #aec650;\n}\n\n#mainMenu .tiddlyLink:hover {\n background-color: #B1DCEF;\n}\n\n#mainMenu .externalLink {\n color: #996633;\n text-decoration: underline;\n}\n\n#mainMenu .externalLink:hover {\n background-color: #B1DCEF;\n}\n\n#mainMenu .button {\n color: #C1D399;\n margin: 0em 0.25em 0em 0.25em;\n padding: 0em 0.25em 0em 0.25em;\n background-color: #FFF;\n border-right: 1px solid #999;\n border-bottom: 1px solid #999;\n}\n\n#mainMenu .button:hover {\n color: #FFFFFF;\n background-color: #C1D399;\n}\n\n\n#displayArea {\n margin: 1em 17em 0em 14em;\n}\n\n#tiddlerDisplay {\n}\n\n#messageArea {\n background-color: #EC7230;\n color: #ffffff;\n padding: 0.5em 0.5em 0.5em 0.5em;\n display: none;\n}\n\n#messageArea a:link, #messageArea a:visited {\n display: inline;\n text-decoration: underline;\n color: #FFF;\n}\n\n#messageArea a:hover {\n color: #333;\n}\n\n#messageArea a:active {\n color: #ffffff;\n}\n\n#popup {\n display: none;\n position: absolute;\n font-size: 8pt;\n color: #999;\n background-color: #EEE;\n padding: 0.25em 0.25em 0.25em 0.25em;\n border-right: 1px solid #330000;\n border-bottom: 1px solid #330000;\n z-index: 10;\nfilter:alpha(opacity=50);\n-moz-opacity:0.5;\nopacity: 0.5;\n}\n\n#popup a {\n display: block;\n color: #333;\n line-height: 100%;\n}\n\n#popup a:hover {\n background-color: #FFF;\n color: #330000;\n}\n\n#popup hr {\n border-top: solid 1px #666;\n border-left: none;\n border-right: none;\n border-bottom: none;\n height: 1px;\n color: #666;\n}\n\n.tabset {\n padding: 1em 0em 0em 0.5em;\n}\n\n.tab {\n margin: 0em 0em 0em 0.25em;\n padding: 2px 2px 2px 2px;\n} \n\n.tabSelected {\n background-color: #333333;\n}\n\n.tabUnselected {\n background-color: #999999;\n}\n\n.tab:hover {\n}\n\n.tab:active {\n}\n\n.tabContents {\n padding: 2px;\n background-color: #333333;\n}\n\n.tiddler {\n padding: 1em 1em 0em 1em;\n font-size: 9pt;\n}\n\n.selectedTiddler {\nborder: 1px solid #EEE;\nmargin: 5px;\n}\n\n.unselectedTiddler {\nborder: 1px solid #EEE;\nmargin: 5px;\n}\n\n.tiddler .tiddlyLinkExisting {\n font-weight: bold;\n}\n\n.tiddler .tiddlyLinkNonExisting {\n font-style: italic;\n}\n\n.tiddler .externalLink {\n text-decoration: underline;\n}\n\n.tiddler .button {\n padding: 0.2em 0.4em 0.2em 0.4em;\n color: #AAAAAA;\n}\n\n.tiddler .button:hover {\n text-decoration: none;\n color: #999999;\n background-color: #DAEEF7;\n}\n\n.tiddler .button:active {\n color: #ffffff;\n background-color: #C1D399;\n}\n\n.title {\n font-size: 10pt;\n color: #666;\n font-weight: bold;\npadding-left:5px;\n}\n\n.selectedTiddler .title {\n font-size: 10pt;\n color: #333;\n font-weight: bold;\n}\n\n.toolbar {\n text-align: right;\n font-weight: normal;\n font-size: 8pt;\n padding: 0em 0em 0em 2em;\n color: #aaaaaa;\n visibility: hidden;\n}\n\n.toolbar #popup {\n text-align: left;\n}\n\n.selectedTiddler .toolbar {\n visibility: visible;\n}\n\n.footer {\n font-weight: normal;\n font-size: 8pt;\n margin: 0.5em 0em 0em 0em;\n padding: 0em 0em 0em 0em;\n color: #dddddd;\n}\n\n.selectedTiddler .footer {\n color: #888888;\n}\n\n.body {\n padding-top: 0.5em;\n}\n\n.viewer {\n color: #000000;\n line-height: 15px;\n padding: 8px 8px 8px 8px;\n}\n\n.viewer a:link, .body a:visited {\n text-decoration: none;\n color: #C1D399;\n}\n\n.viewer a:hover {\n color: #ffffff;\n background-color: #B1DCEF;\n text-decoration: none;\n}\n\n.viewer .button {\n margin: 0em 0.25em 0em 0.25em;\n padding: 0em 0.25em 0em 0.25em;\n color: #999;\n background-color: #FFF;\n border-right: 1px solid #999;\n border-bottom: 1px solid #999;\n}\n\n.viewer .button:hover {\n background-color: #C1D399;\n color: #FFF;\n}\n\n.viewer blockquote {\n font-size: 8pt;\n line-height: 150%;\n border-left: 3px solid #666666;\n padding-left: 0.8em;\n margin-left: 2.5em;\n}\n\n.viewer ul {\n margin-left: 0.5em;\n padding-left: 1.5em;\n}\n\n.viewer ol {\n margin-left: 0.5em;\n padding-left: 1.5em;\n}\n\n.viewer h1,h2,h3,h4,h5 {\n font-weight: bold;\n text-decoration: none;\nborder-bottom: dashed 1px #d6d6d6;\nbackground-color: #FFF;\n}\n\n.viewer h1 {\n font-size: 12pt;\n}\n\n.viewer h2 {\n font-size: 10pt;\n}\n\n.viewer h3 {\n font-size: 10pt;\n}\n\n.viewer h4 {\n font-size: 9pt;\n}\n\n.viewer h5 {\n font-size: 8pt;\n}\n\n.viewer table {\n border-collapse: collapse;\n border: 2px solid #303030;\n margin-left: 1.0em;\n margin-right: 1.0em;\n margin-top: 0.8em;\n margin-bottom: 0.8em;\n font-size: 100%;\n}\n\n.viewer th {\n background-color: #999966;\n border: 1px solid #606060;\n color: #ffffff;\n padding: 3px;\n}\n\n.viewer td, tr {\n border: 1px solid #606060;\n padding: 3px;\n}\n\n.viewer caption {\n padding: 3px;\n}\n\n.viewer pre, .viewer code {\n font-size: 100%;\n line-height: 1.4em;\n color: #660000;\n}\n\n.viewer hr {\n border-top: dashed 1px #606060;\n border-left: none;\n border-right: none;\n border-bottom: none;\n height: 1px;\n color: #666666;\n}\n\n.highlight, .marked {\n color: #000000;\n background-color: #ffe72f;\n}\n\n.editor {\n font-size: 8pt;\n color: #402C74;\n font-weight: normal;\n}\n\n.editor input {\n display: block;\n border: 1px solid black;\n width: 100%;\n}\n\n.editor textarea {\n display: block;\n font: inherit;\n border: 1px solid black;\n width: 100%;\n}\n\n.editorFooter {\n padding: 0.25em 0em 0.25em 0em;\n font-size: 8pt;\n color: #aaaaaa;\n}\n\n.editorFooter A {\n padding: 0.2em 0.4em 0.2em 0.4em;\n color: #993300;\n}\n\n.editorFooter A:hover {\n text-decoration: none;\n color: #ccff66;\n background-color: #993300;\n}\n\n.editorFooter A:active {\n color: #ffffff;\n background-color: #cc9900;\n}\n\n#sidebar {\n float: right;\n width: 16em;\n color: #000000;\n font-size: 8pt;\npostion: absolute;\n}\n\n#sidebarOptions {\n padding-top: 0.5em;\nmargin-top:10px;\nmargin-right: 10px;\n background-color: #F1EFEB;\n}\n\n#sidebarOptions .button {\n color: #999;\n padding: 0.3em 0.2em 0.3em 1em;\n display: block;\n}\n\n#sidebarOptions .button:hover {\n color: #999;\n background-color: #B1DCEF;\n}\n\n#sidebarOptions .button:active {\n color: #CFC9BC;\n background-color: #EEE;\n}\n\n#sidebarOptions input {\n margin: 0.4em 0em 0.3em 1em;\n}\n\n#sidebarOptions .sliderPanel {\n padding: 0.5em 0.5em 0.5em 0.5em;\n font-size: 7pt;\n background-color: #FFF;\n}\n\n#sidebarOptions .sliderPanel A {\n color: #6999C9;\n font-weight: bold;\n}\n\n#sidebarOptions .sliderPanel A:hover {\n color: #C1D399;\n background-color: #FFF;\n}\n\n#sidebarOptions .sliderPanel A:active {\n color: #333;\n background-color: #FFF;\n}\n\n#sidebarOptions .sliderPanel input {\n margin: 0em 0em 0.3em 0em;\n}\n\n.sidebarSubHeading {\n font-size: 7pt;\n color: #330000;\n}\n\n#sidebarTabs {\n background-color: #fff;\nmargin-right:2px;\n}\n\n#sidebarTabs .tabSelected {\n color: #999;\n background-color: #ECF8FD;\n position: relative;\n top: -1px;\n}\n\n#sidebarTabs .tabUnselected {\n color: #999;\n background-color: #F5F5F5;\n}\n\n#sidebarTabs .tabContents {\n background-color: #ECF8FD;\nmargin-right: 10px;\n}\n\n#sidebarTabs .txtMoreTab .tabSelected {\n background-color: #F5F5F5;\n}\n\n#sidebarTabs .txtMoreTab .tabUnselected {\n background-color: #ECF8FD;\n}\n\n#sidebarTabs .txtMoreTab .tabContents {\n background-color: #F5F5F5;\n}\n\n#sidebarTabs .tabContents .tiddlyLink {\n color: #6999C9;\n}\n\n#sidebarTabs .tabContents .tiddlyLink:hover {\n background-color: #ECF8FD;\n color: #330000;\n}\n\n#sidebarTabs .tabContents .button {\n color: #6999C9;\n padding: 0em 0em 0em 0em;\n display: inline;\n}\n\n#sidebarTabs .tabContents .button:hover {\n color: #999;\n background-color: #ECF8FD;\n}\n\n#licensePanel {\n padding: 0.5em 0em 0.5em 0em;\n}\n\n#licensePanel A {\n display: block;\n padding: 0.2em 0.2em 0.2em 0.2em;\n color: #993300;\n}\n\n#licensePanel A:hover {\n text-decoration: none;\n color: #ccff66;\n background-color: #993300;\n}\n\n#licensePanel A:active {\n color: #993300;\n background-color: #ccff66;\n}\n\n#storeArea, #copyright {\n display: none;\n}\n\n.sparkline {\n background-color: #eeeeaa;\n border: none;\n line-height: 100%;\n}\n\n.sparktick {\n background-color: #993300;\n outline: 0;\n}\n\n.errorNoSuchMacro {\n color: #ffff00;\n background-color: #ff0000;\n}\n\n.zoomer {\n font-size: 10pt;\n display: none;\n color: #000000;\n position: absolute;\n padding: 1em 1em 1em 1em;\n border: 1px solid #000000;\n}\n\n#saveTest {\n display: none;\n}\n\n@media print {\n\n#mainMenu, #sidebar, #messageArea {\n display: none ! important;\n}\n\n#displayArea {\n margin: 1em 1em 0em 1em;\n}\n\n}10px\n\n}}}
/* Alternative Style created by monkymind */\n\nbody {\n background-color: #eae9ee;\n font-size: 9pt;\n font-family: verdana,arial,helvetica;\n margin: 0em 0em 0em 0em;\n padding: 0em 0em 0em 0em;\n position: relative;\n z-index: 0;\n}\n#siteTitle {\n font-size: 38pt;\n}\n#titleLine {\n color: #ffffff;\n background-color: #6b69ad;\n padding: 2em 1em 1em 1em;\n}\n\n#titleLine a {\n color: #fff;\n}\n#mainMenu {\n width: 12em;\n font-weight: bold;\n}\n#mainMenu .tiddlyLink {\n color: red;\n}\n#mainMenu .tiddlyLink:hover {\n background-color: white;\n color: red;\n}\n#mainMenu .externalLink {\n color: red;\n text-decoration: underline;\n}\n#mainMenu .externalLink:hover {\n background-color: white;\n color: red;\n}\n#mainMenu .button {\n color: red;\n}\n\n#mainMenu .button:hover {\n color: red;\n background-color: #fff;\n}\n#sidebarOptions {\n padding-top: 0.5em;\n background-color: #eae9ee;\n}\n#sidebarOptions .button {\n color: red;\n padding: 0.3em 0.2em 0.3em 1em;\n display: block;\n}\n#sidebarOptions .button:hover {\n color: red;\n background-color: #fff;\n}\n#sidebarTabs {\n background-color: #eae9ee;\n}\n#sidebarTabs .tabSelected {\n color: #fff;\n background-color: #6b69ad;\n position: relative;\n top: -2px;\n}\n#sidebarTabs .tabUnselected {\n color: #000;\n background-color: #d7d8e8;\n}\n#sidebarTabs .tabContents {\n color: black;\n background-color: #e2e2e2;\n}\n#sidebarTabs .txtMoreTab .tabSelected {\n background-color: #6b69ad;\n}\n\n#sidebarTabs .txtMoreTab .tabUnselected {\n background-color: #d7d8e8;\n}\n#sidebarTabs .txtMoreTab .tabContents {\n background-color: #e2e2e2;\n}\n\n#sidebarTabs .tabContents .tiddlyLink {\n color: #6b69ad;\n}\n#sidebarTabs .tabContents .tiddlyLink:hover {\n background-color: #6b69ad;\n color: white;\n}\n#sidebarTabs .tabContents .button {\n color: red;\n padding: 0em 0em 0em 0em;\n display: inline;\n}\n#sidebarTabs .tabContents .button:hover {\n color: red;\n background-color: #fff;\n}\n#tiddlerDisplay {\n background-color: white;\n}\n.tiddler .button {\n padding: 0.2em 0.4em 0.2em 0.4em;\n color: #6b69ad;\n}\n\n.tiddler .button:hover {\n text-decoration: none;\n color: #fff;\n background-color: #6b69ad;\n}\n.viewer a:link, .body a:visited {\n text-decoration: none;\n color: red;\n}\n\n.viewer a:hover {\n color: #fff;\n background-color: #6b69ad;\n text-decoration: none;\n}\n#sidebarOptions .sliderPanel {\n padding: 0.5em 0.5em 0.5em 0.5em;\n font-size: 7pt;\n background-color: #e2e2e2;\n}\n\n#sidebarOptions .sliderPanel A {\n color: red;\n font-weight: bold;\n}\n\n#sidebarOptions .sliderPanel A:hover {\n color: red;\n background-color: #fff;\n}\n#popup {\n color: red;\n background-color: #fff;\n}\n#popup a {\n display: block;\n color: #6b69ad;\n line-height: 100%;\n}\n\n#popup a:hover {\n background-color: #6b69ad;\n color: #fff;\n}\n\n#messageArea {\n color: red;\n background: #eae9ee;\n}\n\n#messageArea a {\n color: #red;\n}\n\n#messageArea a:hover {\n color: #red;\n}\n\n#messageArea a:link, #messageArea a:visited {\n color: #6b69ad;\n}
/*\n{{{\n*/\n\nbody{\n background: #000;\n}\n\n#contentWrapper{\n margin: 0 10px;\n background: #321c10;\n border: 1px solid #613725;\n}\n\n#mainMenu{\n position: relative;\n float: left;\n font-size: 12px;\n text-align: left;\n background: #321c10;\n color: #c5886b;\n width: 15em;\n padding: .2em .5em .2em 0;\n}\n\n#MainMenu h1{\n font-size: 13px;\n font-weight: normal;\n margin: 0 0 0 2px;\n}\n\n#mainMenu li, #mainMenu ul{\n padding: 0;\n margin: 0;\n}\n\n#mainMenu ul, #messageArea{\n display: block;\n border: 1px solid #905437;\n padding: 0 0 0 1em;\n background: #522d1e;\n margin: 0 0 1em 0;\n}\n\n#messageArea{\n display: none;\n padding: 1em;\n}\n\n#mainMenu li{\n list-style: none;\n}\n\n#contentWrapper #mainMenu a.button,\n#contentWrapper #mainMenu a.tiddlyLink,\n#contentWrapper #mainMenu a.externalLink,\n#messageArea a:link, #sidebar .button{\n color: #fb9950;\n text-decoration: none;\n}\n\n#contentWrapper #mainMenu a.button:hover,\n#contentWrapper #mainMenu a.tiddlyLink:hover,\n#contentWrapper #mainMenu a.externalLink:hover,\n#messageArea a:hover, #sidebar .button:hover{\n color: #c17135;\n background: transparent;\n text-decoration: underline;\n}\n\n#sidebar{\n position: relative; \n float: right;\n}\n\n#sidebar .sliderPanel{\n background: #000;\n color: #94532d;\n}\n\n#titleLine{\n color: #94532d;\n background: #000;\n padding: 1em;\n border-bottom: 1px solid #613725;\n}\n\n#siteTitle{\n font-size: 24px;\n font-weight: bold;\n}\n\n#titleLine a{\n color: #fb9950;\n}\n\n#sidebar, #sidebarOptions, #sidebarTabs{\n background: transparent;\n}\n\n#contentWrapper .tabSelected{\n background: #522d1e;\n border: 1px solid #905437;\n border-bottom: 0;\n padding-bottom: 3px;\n cursor: default;\n color: #fb9950;\n font-weight: bold;\n}\n\n#contentWrapper .tabUnselected, #contentWrapper .tabcontents .tabSelected{\n background: #2a170d;\n border: 1px solid #542e21;\n border-bottom: 0;\n padding-bottom: 0px;\n color: #fb9950;\n}\n\n#contentWrapper .tabUnselected:hover{\n color: #c17135\n}\n\n#contentWrapper .tabcontents .tabSelected{\n padding-bottom: 3px;\n border: 1px solid #905437;\n border-bottom: 0;\n}\n\n#contentWrapper .tabcontents .tabUnselected{\nbackground: #522d1e;\n border: 1px solid #613725;\n border-bottom: 0;\n padding-bottom: 0;\n}\n\n/* TiddlySinister was desgined by Clint Checketts (http://15black.bluedepot.com) and inspired from Minz Meyer (http://www.minzweb.de) */\n\n\n#contentWrapper .tabContents{\n background: #522d1e;\n border: 1px solid #905437;\n border-width: 1px 0;\n}\n\n#contentWrapper .tabContents .tabContents{\nbackground: #2a170d;\n border: 1px solid #905437;\n}\n\n#contentWrapper .tabContents li.listTitle{\n color: #c5886b;\n}\n\n#contentWrapper .tabContents li a.tiddlyLink,#contentWrapper .tabContents li a.button{\n color: #fb9950\n}\n\n#contentWrapper .tabContents li a.tiddlyLink:hover, #contentWrapper .tabContents li a.button:hover{\n color: #c17135;\n background: transparent;\n text-decoration: underline;\n}\n\n#popup{\n background: #522d1e;\n border: 1px solid #905437;\n z-index: 50;\n}\n\n.toolbar #popup{\n min-width: 12em;\n}\n\n#popup hr{\n border-top: 1px solid #905437;\n width: 75%;\n}\n\n#popup a.button,#popup a.tiddlyLink{\n color: #fb9950\n}\n\n#popup a.button:hover,#popup a.tiddlyLink:hover{\n color: #c17135;\n background: transparent;\n text-decoration: underline;\n}\n\n#displayArea{\n position: relative;\n margin: 0 14em 0em 15.5em;\n padding: 1em 2em 0 2em;\n background: #33180a;\n border: 1px solid #613725;\n min-height: 400px;\n _position: static;\n}\n\ndiv.unselectedTiddler, div.selectedTiddler{\n border-top: 25px solid #000;\n}\n\n.tiddler{\n background: #2a170d;\n border: 1px solid #542e21;\n margin: 0 0 2em 0;\n position: relative;\n _position; static;\n}\n\n.title{\n position: absolute;\n top:1px;\n left: 5px;\n color: #fb9950;\n font-size: 14px;\n font-weight: normal;\n line-height: 23px;\n _position: static;\n}\n\n.toolbar{\n position: absolute;\n top: 5px;\n right: 2px;\n _position: static; /* Dumb IE hack */\n}\n\n\n.viewer h1, h2, h3, h4, h5, h6{\n background: transparent;\n}\n\n#contentWrapper #displayArea a.button,#contentWrapper #displayArea a.tiddlyLink,#contentWrapper #displayArea a.externalLink{\n color: #fb9950;\n background: transparent;\n border: 0;\n}\n\n\n#contentWrapper #displayArea a.button:hover,#contentWrapper #displayArea a.tiddlyLink:hover,#contentWrapper #displayArea a.externalLink:hover{\n color: #c17135;\n background: transparent;\n text-decoration: underline;\n}\n\n.viewer, .editer, .editorFooter{\n color: #c5886b;\n}\n\n.editor textarea, input{\n max-height: 35em;\n background: #c5886b;\n border: 2px inset #613725;\n}\n\n.editor textarea:focus, input:focus{\n background: #ddb9a8;\n}\n\n\n/*\n}}}\n*/\n
// zRenardBlue\n #tiddlerNotes .title {background-color: #FFCD62; color: #6A6A6A}\n\ndiv[tags~="todo"].viewer {background-color: #FFF5DC;}\n\n #popup { background-color: #4275A8; color: #FFF;border-right: 2px solid #BCBCBC;\n border-bottom: 2px solid #BCBCBC;}\n #popup a {color: #EEE;}\n #popup a:hover {background-color: #6699CC;color: #FFF;}\n.toolbar {position:relative;top:19px;left:-1px;border-bottom: 2px solid #DCDCDC;border-right: 2px solid #DCDCDC; background-color: #EEE; color:#000; height:16px;padding-top:2px;margin-left:250px;padding-right:0}\n.toolbar A{color: #4275A8;}\n.toolbar A:active {color: #ffffff;background-color: #4275A8;}\n.toolbar A:hover {color: #ffffff;background-color: #6699CC;}\n.toolbar #popup {background-color: #4275A8; color: #FFF;border-right: 2px solid #BCBCBC;\n border-bottom: 2px solid #BCBCBC; width:50%}\n.toolbar #popup a {color: #EEE;}\n.toolbar #popup a:hover {background-color: #6699CC;color: #FFF;}\nhr { border: none; border-top: dotted 1px #777; height: 1px; color: #777;margin: 7px 0;} \n\n.tiddler .button {color: #6699CC;}\n.tiddler .button:active {background-color: #FFF;color: #4275A8;}\n.tiddler .button:hover {background-color: #6699CC;color: #FFF;}\n\n #messageArea {background-color: #FFD85D; color: #000000;}\n #messageArea a:link, #messageArea a:visited {color: #4275A8;}\n #messageArea a:hover {color: #FFF;background-color: #4275A8;}\n #messageArea a:active {color: #4275A8;}\n\n #mainMenu {border: 1px solid #555;background-color:#EEE;padding-top:0px;color:#4275A8;font-size: 10pt;}\n #mainMenu .tiddlyLink {color: #4275A8;}\n#mainMenu h1 { font-size:11pt;}\n#mainMenu h1 .tiddlyLink{ font-size:11pt;color:#FFF}\n#mainMenu h2 { font-size:10pt;}\n#mainMenu h2 .tiddlyLink { font-size:10pt;color:#FFF}\n #mainMenu .tiddlyLink:hover {background-color: #4275A8;color: #ffffff;}\n #mainMenu .externalLink:hover {background-color: #4275A8;color: #ffffff; text-decoration: underline;}\n #mainMenu .externalLink{color: #4275A8;text-decoration: none}\n\n #titleLine {color: #ffffff; background-color: #6699CC; padding: 5px;padding-top:15px}\n body {\n font: 13px/125% "Lucida Grande", "Trebuchet MS", "Bitstream Vera Sans", Verdana, Helvetica, sans-serif;\n }\n .editor textarea {height:300px;background-color:#F2F2F2;}\n .editor input {background-color:#DCDCDC;}\n .title {font-size: 10pt; font-weight: bold; background-color:#DCDCDC; color:#4275A8;display:inline;margin:0px;padding-left:30px;padding-right:30px;}\n .viewer h1,h2,h3,h4,h5,h6 {background-color: #8BA3FF; color:#FFF;text-align:center}\n .viewer{padding:10px;border: 1px solid #DCDCDC;background-color:#F2F2F2;z-index: -2;}\n .viewer a:link, .body a:visited {text-decoration: none; color: #4275A8;}\n .viewer a:hover { color: #ffffff; background-color: #4275A8;}\n .viewer table {border-collapse: collapse;border: 2px solid #303030;font-size: 11px;margin: 5px;}\n .viewer th {background: #DEDEDE;border: 1px solid #aaa;color:#000;padding: 3px;}\n .viewer td {border: 1px solid #aaa;padding: 3px;}\n .viewer caption {padding: 3px;}\n .viewer hr { border: none; border-top: dotted 1px #777; height: 1px; color: #777;margin: 7px 0;} \n .viewer pre { border:1px solid #CBCBCB; margin:5px;padding: 2px;background: #EAEAEA;color:#3C6FA2;}\n.viewer code {background: #EAEAEA;color:#3C6FA2;}\n.viewer input { border: 0px solid black;color:#4275A8;}\n.viewer #popup {background-color: #4275A8; color: #FFF;border-right: 2px solid #BCBCBC;\n border-bottom: 2px solid #BCBCBC;}\n.viewer #popup a {color: #6699CC;}\n.viewer #popup a:hover {background-color: #6699CC;color: #FFF;}\n.viewer .button {background-color: transparent;}\n.viewer .button:active {background-color: #FFF;color: #4275A8;}\n.viewer .button:hover {background-color: #6699CC;color: #FFF;}\n\n//.sparkline {background-color: #99CCFF;border: none;}\n.sparkline {background-color: transparent;border: none;}\n.sparktick {background-color: #6699CC;outline: 0;}\n\n#sidebar {float: right; width: 16em;color: #000;font-size: 8pt;}\n#\n sidebar input { border: 0px solid black;background-color:#F2F2F2; color:#4275A8;}\n\n#sidebar a {color: #4275A8;}\n#sidebar a:active {background-color: #FFF;color: #4275A8;}\n#sidebar a:hover {background-color: #6699CC;color: #FFF;}\n\n#sidebarOptions {padding-top: 0.5em;background-color: #FBFBFB;color:#000;}\n#sidebarOptions .button {color: #6699CC;}\n#sidebarOptions .button:active {background-color: #FFF;color: #4275A8;}\n#sidebarOptions .button:hover {background-color: #6699CC;color: #FFF;}\n\n#sidebarOptions .sliderPanel {background-color:#DCDCDC; }\n#sidebarOptions .sliderPanel A {color: #4275A8;}\n#sidebarOptions .sliderPanel A:active {color: #FFF;background-color: #4275A8;}\n#sidebarOptions .sliderPanel A:hover {color: #FFF;background-color: #6699CC;}\n\n.sidebarSubHeading {font-size: 7pt;color: #FBFBFB;}\n\n#sidebarTabs { color: #000;background-color: #FBFBFB; }\n\n #sidebarTabs a {color: #4275A8;}\n #sidebarTabs a:hover {color: #FFF;background-color: #4275A8;}\n #sidebarTabs a:active {color: #000;background-color: #4275A8;}\n\n#sidebarTabs .tabSelected {color: #6699CC; font-weight: bold;background-color: #DCDCDC;position: relative;top: -2px;}\n#sidebarTabs .tabUnselected {font-style:italic;color: #6699CC;background-color: #EEE;}\n#sidebarTabs .tabContents {color: #7189E5;background-color: #DCDCDC;}\n#sidebarTabs .tabContents span {font-weight: bold;}\n#sidebarTabs .tabContents .tiddlyLink {color: #6699CC;}\n#sidebarTabs .tabContents .tiddlyLink:hover {color: #FFF;background-color: #4275A8;}\n\n#sidebarTabs .txtMoreTab .tabSelected {color: #FFF;background-color: #8BA3FF;}\n#sidebarTabs .txtMoreTab .tabUnselected {font-weight: normal;font-style:italic;color: #FFF;background-color: #4275A8;}\n\n#sidebarTabs .txtMoreTab .tabContents { color: #000;background-color: #8BA3FF;}\n#sidebarTabs .txtMoreTab .tabContents .tiddlyLink {color: #FFF;}\n\n#sidebarTabs .tabContents .button {color: #FFF;}\n#sidebarTabs .tabContents .button:active {background-color: #FFF;color: #4275A8;}\n#sidebarTabs .tabContents .button:hover {background-color: #6699CC;color: #FFF;}\n#sidebarTabs .tabContents #popup {background-color: #4275A8; color: #FFF;border-right: 2px solid #BCBCBC;\n border-bottom: 2px solid #BCBCBC;}\n#sidebarTabs .tabContents #popup a {color: #EEE;}\n#sidebarTabs .tabContents hr{color: #FFF;}\n#sidebarTabs .tabContents #popup a:hover {background-color: #6699CC;color: #FFF;}\n
function onClickToolbarEncrypt(e)\n{\n if (!e) var e = window.event;\n if(encryptKey == "")\n encryptChangePassword();\n var title = this.parentNode.id.substr(7);\n var newBody = document.getElementById("editorBody" + title).value;\n newBody = encryptContents(newBody);\n document.getElementById("editorBody" + title).value = newBody;\n}\n\nfunction onClickToolbarEditDecrypt(e)\n{\n if (!e) var e = window.event;\n if(encryptKey == "")\n encryptChangePassword();\n var title = this.parentNode.id.substr(7);\n var newBody = document.getElementById("editorBody" + title).value;\n newBody = decryptContents(newBody);\n document.getElementById("editorBody" + title).value = newBody;\n}\n\nfunction onClickToolbarDecrypt(e)\n{\n if (!e) var e = window.event;\n if(encryptKey == "")\n encryptChangePassword();\n\n var title = this.parentNode.id.substr(7);\n var theBody = document.getElementById("body" + title);\n var theViewer = document.getElementById("viewer" + title);\n if(theViewer)\n theViewer.parentNode.removeChild(theViewer);\n var theViewer = createTiddlyElement(theBody,"div","viewer" + title,"viewer",null);\n\n var newText = store.getTiddlerText(title);\n newText = decryptContents(newText);\n wikify(newText,theViewer,false,false);\n}
yatwa-backups
Eric has prooduced a number of very clever and useful TW plugins. Not all are currently included in YATWA. For the complete set, see his [[ELS Design Studios|http://www.elsdesign.com/tiddlywiki/#%5B%5BDocument%20Info%5D%5D]] web site.
The plugins contained in this version of YATWA are:\n<<listTags plugins title *>>
// Eric Shulman - ELS Design Studios\n// "Mixed HTML and wiki-style rendering" Plug-in for TiddlyWiki version 1.2.25 or above\nversion.extensions.HTMLFormatting = {major: 1, minor: 0, revision: 1, date: new Date(2005,7,26)};\nwindow.coreWikify=window.wikify;\nwindow.wikify = function(tiddlerText,theViewer,highlightText,highlightCaseSensitive)\n{\n var startHTML = tiddlerText.indexOf('<'+'html'+'>');\n var endHTML = tiddlerText.lastIndexOf('<'+'/html'+'>');\n if (startHTML==-1) // bypass HTML parsing\n { coreWikify(tiddlerText,theViewer,highlightText,highlightCaseSensitive); return; }\n if (startHTML>0) // wikify everything up to HTML tag\n coreWikify(tiddlerText.substr(0,startHTML-1),theViewer,highlightText,highlightCaseSensitive);\n if (startHTML!=-1) // browser parse everything between HTML and /HTML tags (or end of text)\n {\n var HTMLText = tiddlerText.substr(startHTML);\n if (endHTML!=-1) HTMLText = tiddlerText.substring(startHTML,endHTML+7);\n // suppress wiki-style literal handling of newlines\n if (HTMLText.indexOf('<hide linebreaks>')!=-1) HTMLText=HTMLText.replace(regexpNewLine,' ');\n // strip any carriage returns added by Internet Explorer's textarea edit field\n HTMLText=HTMLText.replace(regexpCarriageReturn,'');\n // encode newlines as \sn so Internet Explorer's HTML parser won't eat them\n HTMLText=HTMLText.replace(regexpNewLine,'\s\sn');\n // encode macro brackets (<< and >>) so HTML parser won't eat them\n HTMLText=HTMLText.replace(/<</g,'%macro(').replace(/>>/g,')%');\n // create a span to hold browser-parsed DOM objects\n var newSpan = createTiddlyElement(theViewer,"span",null,null,null);\n // give HTML source to browser's parser (builds DOM nodes)\n newSpan.innerHTML=HTMLText;\n newSpan.normalize();\n // walk resulting node tree and call wikify() on each text node\n wikifyTextNodes(newSpan,highlightText,highlightCaseSensitive);\n }\n if (endHTML!=-1) // wikify everything after HTML tag\n coreWikify(tiddlerText.substr(endHTML+8),theViewer,highlightText,highlightCaseSensitive);\n // DEBUG showNodeTree(theViewer.parentNode,theViewer);\n\n}\n\nfunction wikifyTextNodes(theNode,highlightText,highlightCaseSensitive)\n{\n // pre-order traversal\n for (var i=0;i<theNode.childNodes.length;i++)\n {\n var theChild=theNode.childNodes.item(i);\n wikifyTextNodes(theChild,highlightText,highlightCaseSensitive);\n if (theChild.nodeName=='#text')\n {\n // don't bother to wikify pure whitespace nodes (if any)\n if (theChild.nodeValue.replace(/\ss+/,"").replace(/\st+/,"").length!=0)\n {\n // DEBUG alert('wikify text: "'+theChild.nodeValue.replace(regexpBackSlashEn,'\sn')+'"');\n var theClass = theNode.id.substr(0,6)=="viewer"?"viewer":theNode.id;\n var newNode = createTiddlyElement(null,"span",null,theClass,null);\n // decode newlines and macro brackets for wikification\n var theText = theChild.nodeValue.replace(regexpBackSlashEn,'\sn').replace(/\s%macro\s(/g,'<<').replace(/\s)\s%/g,'>>');\n coreWikify(theText,newNode,highlightText,highlightCaseSensitive);\n theNode.replaceChild(newNode,theChild);\n }\n }\n }\n}\n\n// Use this function to generate a report of the DOM tree objects starting from a given node.\n// place = where to display DOM object report, theNode = root of DOM object tree to be reported\nfunction showNodeTree(place,theNode)\n{\n createTiddlyElement(place,"HR",null,null,null);\n var theReport = createTiddlyElement(place,"div",null,null,null);\n walkNodeTree(theReport,theNode,'');\n}\nfunction walkNodeTree(theOutput,theNode,thePrefix)\n{\n var msg=thePrefix+':'+((theNode.nodeName=='#text')?' ':theNode.nodeName);\n var href = (theNode.href)?' href='+theNode.href:'';\n var id = (theNode.id)?' id='+theNode.id:'';\n var val = (theNode.name)?' '+theNode.name+((theNode.value)?'='+theNode.value:''):'';\n var text = (theNode.nodeName=='#text')?'"'+theNode.nodeValue.replace(regexpBackSlashEn,'\sn')+'"':'';\n if ( (theNode.nodeName!='B')\n &&(theNode.nodeName!='I')\n &&(theNode.nodeName!='TBODY')\n &&(theNode.nodeName!='SPAN'))\n createTiddlyElement(theOutput,"div",null,null,msg+val+id+href+text);\n for (var i=0;i<theNode.childNodes.length;i++)\n {\n var theChild=theNode.childNodes.item(i);\n var childmsg=msg;\n if (theNode.childNodes.length>1) childmsg+='['+(i+1)+']';\n walkNodeTree(theOutput,theChild,childmsg);\n }\n}\n
Select alternative TiddlyWiki CSS stylesheet 'themes' from a list of tiddlers tagged with "stylesheets". Also provides CSS stylesheet 'overlays' that let you quickly adjust the themes with optional colors, fonts, sizes, wallpaper, etc. that match your mood!.\n\n''Usage:''\n<<<\n# Create (or import) a custom style sheet tiddler (i.e, a tiddler containing CSS definitions)\n# Tag this tiddler with <<tag stylesheets>> (so it appears in the stylesheet droplist)\n# Select 'options' from the sidebar menu (options panel will be displayed)\n# Select your desired stylesheet from the droplist, or ''[none]'' to bypass all stylesheet tiddlers and use the built-in CSS definitions. The currently selected stylesheet is indicated by a '>' symbol.\n\n//Note: If a previously selected stylesheet tiddler no longer exists (i.e, the tiddler was deleted or renamed after it had been selected for use), the [default] CSS tiddler ("StyleSheet") will be used as a fallback. If this tiddler does not exist either, then the built-in CSS definitions are used.//\n<<<\n''Parameters:''\n<<<\nThe selectStylesheet macro accepts parameters to control various features and functions. //Note: while each parameter is optional and may be omitted from the macro, the parameters (when present) must appear in the order shown below.//\n* ''size:nnn''\nDetermines the number of lines to display in the stylesheet list. If this parameter is omitted or "size:1" is specified, a single-line droplist is created. When a size > 1 is provided, a standard, fixed-size scrollable listbox is created. You can use "size:0" or "size:auto" to display a varible-height listbox that automatically adjusts to fit the current list contents without scrolling.\n* ''width:nnn[cm|px|em|%]''\nControls the width of the stylesheet list. Overrides the built-in CSS width declaration (=100%). Use standard CSS width units (cm=centimeters, px=pixels, em=M-space, %=proportional to containing area). You can also use a ".selectStylesheet" custom CSS class definition to override the built-in CSS declarations for the stylesheet list.\n* ''tags'' (0 or more)\nYou can create optional stylesheet 'overlays' that supplement or override the CSS definitions from the main stylesheet theme you have selected.\n## first, define separate tiddlers containing the CSS definitions for each optional stylesheet overlay.\n## next, group the overlays into relevant categories by tagging them with any tag values you like.\n## finally, list these tag values as parameters to the selectStylesheet macro.\n## When the list is created, in addition to tiddlers tagged with "stylesheets", it will also contain a section for each tag parameter, showing all the tiddlers with that tag. The currently selected overlay (if any) in each section is indicated by a '>' symbol. \n## Whenever an overlay is used, a ''[default]'' choice is added to that section so that you can disable the overlay and revert to the previous CSS declarations for those styles.\n<<<\n''Examples:''\n<<<\nsee SelectStylesheetExamples\n<<<\n''Installation:''\n<<<\nimport (or copy/paste) the following tiddlers into your document:\n''SelectStylesheetPlugin'' (tagged with <<tag systemConfig>>)\n^^javascript for SelectStylesheethandling^^\n''SelectStylesheetHelp''\n^^end-user documentation for this plugin^^\n''SelectStylesheetExamples''\n^^examples of macro usage for this plugin^^\n\ncreate/edit ''OptionsPanel'':\nAdd "<< {{{selectStylesheet [size:nnn] [width:nnn[cm|px|em|%] [tag]* }}} >>" macro.\nSee macro examples above for more details.\n\n''Obsolete tiddlers:''\n//Note: ''The SelectStylesheetPanel and SelectStylesheetStyleSheet tiddlers included in previous releases are no longer required for this plugin to operate'', and can be safely deleted from your document once you have upgraded to the current plugin release.//\n<<<\n''Revision History:''\n<<<\n''2005.08.07 [2.0.0]''\nMajor re-write to not use static ID values for listbox controls, so that multiple macro instances can exist without corrupting each other or the DOM. Moved HTML and CSS definitions into plugin code instead of using separate tiddlers. Added new features: support for multiple groups of overlay stylesheets with collapsible tree display. Added size and width params for listbox display.\n''2005.07.27 [1.0.3]''\ncore update 1.2.29: custom overlayStyleSheet() replaced with new core setStylesheet()\n''2005.07.25 [1.0.2]''\ncorrect 'fallback' handling in selectStyleSheet()\n''2005.07.23 [1.0.1]''\nadded parameter checks and corrected addNotification() usage\n''2005.07.20 [1.0.0]''\nInitial Release\n<<<\n''Credits:''\n<<<\nThis feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]]. Thanks to David Jaquith for testing and bug reports.\n<<<\n
The shorthand Wiki-style formatting syntax of ~TiddlyWiki is very convenient and enables most content to be reasonably well presented. However, there are times when tried-and-true HTML formatting syntax allows more more precise control of the content display. The ~HTMLFormatting plugin allows you to ''embed standard HTML syntax in your content'' simply by, umm, well... //embedding them in your content// (duh!).\n\n''Usage:''\n<<<\nWhen a tiddler is about to be displayed, the ~HTMLFormatting plugin looks for tiddler content contained within ''<{{{html}}}>'' and ''<{{{/html}}}>'' HTML tags. This content (if any) is passed directly to the browser's internal "rendering engine" to process as ~HTML-formatted content. Once the HTML formatting has been processed, all the pieces of text occuring in between the HTML formatting are processed by the ~TiddlyWiki rendering engine, one piece at a time, so that normal wiki-style formatting can be applied to the text pieces.\n\nNote: content preceding the ''<{{{html}}}>'' tag or following the ''<{{{/html}}}>'' tag is always processed as normal wiki-style formatted content, without any additional HTML rendering.\n<<<\n''Line breaks:''\n<<<\nOne major difference between Wiki formatting and HTML formatting is how "line breaks" are processed. Wiki formatting treats all line breaks as literal content to be displayed //as-is//. However, because HTML normally ignores line breaks and actually processes them as simple "word separators" instead, many people who write HTML include extra line breaks in their documents, just to make the "source code" easier to read.\n\nEven though you can now use HTML tags within your tiddler content, the default treatment for line breaks still follows the Wiki-style rule (i.e., all new lines are displayed as-is). When adding HTML content to a tiddler (especially if you cut-and-paste it from another web page), you should take care to avoid adding extra line breaks to the text.\n\nIf removing all the extra line breaks from your HTML content would be a big hassle, you can quickly //override the default Wiki-style line break rule// so that the line breaks use the standard HTML rules instead. Placing a ''<{{{hide newlines}}}>'' tag within the tiddler's HTML content changes all line breaks to to spaces before rendering the content, so that the literal line breaks will be processed as simple word-breaks instead.\n\nNote: this does //not// alter the actual tiddler content that is stored in the document, just the manner in which it is displayed. Any line breaks contained in the tiddler will still be there when you edit its content. Also, to include a literal line break when the ''<{{{hide newlines}}}>'' tag is present, you will need to use a ''<{{{br}}}>'' or ''<{{{p}}}>'' HTML tag instead of simply typing a line break.\n<<<\n''Installation:''\n<<<\nimport (or copy/paste) the following tiddlers into your document:\n''HTMLFormattingPlugin'' (tagged with <<tag systemConfig>>)\n^^javascript for HTMLFormatting handling^^\n''HTMLFormattingHelp''\n^^end-user documentation for this plugin^^\n\n''Obsolete tiddlers:''\n//Note: ''The HTMLFormattingPanel and HTMLFormattingStyleSheet tiddlers included in previous releases are no longer required for this plugin to operate'', and can be safely deleted from your document once you have upgraded to the current plugin release.//\n<<<\n''Revision History:''\n<<<\n''2005.08.05 [1.1.0]''\nmoved HTML and CSS definitions into plugin code instead of using separate tiddlers\n''2005.07.26 [1.0.1]''\nRe-released as a plugin.\nAdded <{{{html}}}>...</{{{nohtml}}}> and <{{{hide newlines}}}> handling\n''2005.07.20 [1.0.0]''\nInitial Release (as code adaptation)\n<<<\n''Credits:''\n<<<\nThis feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]]\n<<<\n
config.views.editor.toolbarEncrypt = { text: "encrypt", tooltip: "Encrypt this tiddler"};\nconfig.views.editor.toolbarDecrypt = { text: "decrypt", tooltip: "Decrypt this tiddler"};\nconfig.views.wikified.toolbarDecrypt = { text: "decrypt", tooltip: "Decrypt this tiddler"};\n\n// BEGIN SJR - borrowed from EncryptedTiddlyWiki by Yoshimov\n// for encryption\n\nvar encryptKey = "";\nvar prng;\n\nfunction encryptChangePassword() {\n var pass = prompt("Please input encrypt password");\n/*\n if (window.showModalDialog) {\n var pass = window.showModalDialog('password.html', null, \n 'dialogWidth: 200px; dialogHeight: 200px;');\n } else {\n var pass = window.open('password.html','name',\n 'height=200,width=200,toolbar=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=no,modal=yes');\n }\n*/\n if (pass == null || pass == "") {\n encryptKey = "";\n return;\n }\n var s = pass;\n var i, kmd5e, kmd5o;\n\n if (s.length == 1) {\n s += s;\n }\n md5_init();\n for (i = 0; i < s.length; i += 2) {\n md5_update(s.charCodeAt(i));\n }\n md5_finish();\n kmd5e = byteArrayToHex(digestBits);\n md5_init();\n for (i = 1; i < s.length; i += 2) {\n md5_update(s.charCodeAt(i));\n }\n md5_finish();\n kmd5o = byteArrayToHex(digestBits);\n\n var hs = kmd5e + kmd5o;\n encryptKey = hexToByteArray(hs);\n}\n\nfunction encryptContents(contentSrc) {\n if (encryptKey != "") {\n addEntropyTime();\n prng = new AESprng(keyFromEntropy());\n var encryptContent = armour_base64(rijndaelEncrypt(contentSrc, encryptKey, "CBC"));\n if (encryptContent != null) {\n return encryptContent;\n }\n }\n return contentSrc;\n}\n\nfunction decryptTiddlers() {\n var storeArea = document.getElementById("storeArea");\n storeArea.innerHTML = decryptContents(storeArea.innerHTML);\n}\n\nfunction decryptContents(contentSrc) {\n if (encryptKey != "") {\n var contentArray = rijndaelDecrypt(disarm_base64(contentSrc), encryptKey, "CBC");\n if (contentArray != null) {\n var content = "";\n for (i = 0; i < contentArray.length; i++) {\n if(contentArray[i])\n content += String.fromCharCode(contentArray[i]);\n }\n return content;\n }\n }\n return contentSrc;\n}\n\n// for AES\n/* rijndael.js Rijndael Reference Implementation\n\n This is a modified version of the software described below,\n produced in September 2003 by John Walker for use in the\n JavsScrypt browser-based encryption package. The principal\n changes are replacing the original getRandomBytes function with\n one which calls our pseudorandom generator (which must\n be instantiated and seeded before the first call on getRandomBytes),\n and changing keySizeInBits to 256. Some code not required by the\n JavsScrypt application has been commented out. Please see\n http://www.fourmilab.ch/javascrypt/ for further information on\n JavaScrypt.\n \n The following is the original copyright and application\n information.\n\n Copyright (c) 2001 Fritz Schneider\n \n This software is provided as-is, without express or implied warranty. \n Permission to use, copy, modify, distribute or sell this software, with or\n without fee, for any purpose and by any individual or organization, is hereby\n granted, provided that the above copyright notice and this paragraph appear \n in all copies. Distribution as a part of an application or binary must\n include the above copyright notice in the documentation and/or other materials\n provided with the application or distribution.\n\n As the above disclaimer notes, you are free to use this code however you\n want. However, I would request that you send me an email \n (fritz /at/ cs /dot/ ucsd /dot/ edu) to say hi if you find this code useful\n or instructional. Seeing that people are using the code acts as \n encouragement for me to continue development. If you *really* want to thank\n me you can buy the book I wrote with Thomas Powell, _JavaScript:\n _The_Complete_Reference_ :)\n\n This code is an UNOPTIMIZED REFERENCE implementation of Rijndael. \n If there is sufficient interest I can write an optimized (word-based, \n table-driven) version, although you might want to consider using a \n compiled language if speed is critical to your application. As it stands,\n one run of the monte carlo test (10,000 encryptions) can take up to \n several minutes, depending upon your processor. You shouldn't expect more\n than a few kilobytes per second in throughput.\n\n Also note that there is very little error checking in these functions. \n Doing proper error checking is always a good idea, but the ideal \n implementation (using the instanceof operator and exceptions) requires\n IE5+/NS6+, and I've chosen to implement this code so that it is compatible\n with IE4/NS4. \n\n And finally, because JavaScript doesn't have an explicit byte/char data \n type (although JavaScript 2.0 most likely will), when I refer to "byte" \n in this code I generally mean "32 bit integer with value in the interval \n [0,255]" which I treat as a byte.\n\n See http://www-cse.ucsd.edu/~fritz/rijndael.html for more documentation\n of the (very simple) API provided by this code.\n\n Fritz Schneider\n fritz at cs.ucsd.edu\n \n*/\n\n\n// Rijndael parameters -- Valid values are 128, 192, or 256\n\nvar keySizeInBits = 256;\nvar blockSizeInBits = 128;\n\n//\n// Note: in the following code the two dimensional arrays are indexed as\n// you would probably expect, as array[row][column]. The state arrays\n// are 2d arrays of the form state[4][Nb].\n\n\n// The number of rounds for the cipher, indexed by [Nk][Nb]\nvar roundsArray = [ ,,,,[,,,,10,, 12,, 14],, \n [,,,,12,, 12,, 14],, \n [,,,,14,, 14,, 14] ];\n\n// The number of bytes to shift by in shiftRow, indexed by [Nb][row]\nvar shiftOffsets = [ ,,,,[,1, 2, 3],,[,1, 2, 3],,[,1, 3, 4] ];\n\n// The round constants used in subkey expansion\nvar Rcon = [ \n0x01, 0x02, 0x04, 0x08, 0x10, 0x20, \n0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, \n0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, \n0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, \n0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 ];\n\n// Precomputed lookup table for the SBox\nvar SBox = [\n 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, \n118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, \n114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, \n216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, \n235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, \n179, 41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, \n190, 57, 74, 76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69, \n249, 2, 127, 80, 60, 159, 168, 81, 163, 64, 143, 146, 157, 56, 245, \n188, 182, 218, 33, 16, 255, 243, 210, 205, 12, 19, 236, 95, 151, 68, \n23, 196, 167, 126, 61, 100, 93, 25, 115, 96, 129, 79, 220, 34, 42, \n144, 136, 70, 238, 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73,\n 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109, \n141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37, \n 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62, \n181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, 225,\n248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223,\n140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, \n 22 ];\n\n// Precomputed lookup table for the inverse SBox\nvar SBoxInverse = [\n 82, 9, 106, 213, 48, 54, 165, 56, 191, 64, 163, 158, 129, 243, 215, \n251, 124, 227, 57, 130, 155, 47, 255, 135, 52, 142, 67, 68, 196, 222, \n233, 203, 84, 123, 148, 50, 166, 194, 35, 61, 238, 76, 149, 11, 66, \n250, 195, 78, 8, 46, 161, 102, 40, 217, 36, 178, 118, 91, 162, 73, \n109, 139, 209, 37, 114, 248, 246, 100, 134, 104, 152, 22, 212, 164, 92, \n204, 93, 101, 182, 146, 108, 112, 72, 80, 253, 237, 185, 218, 94, 21, \n 70, 87, 167, 141, 157, 132, 144, 216, 171, 0, 140, 188, 211, 10, 247, \n228, 88, 5, 184, 179, 69, 6, 208, 44, 30, 143, 202, 63, 15, 2, \n193, 175, 189, 3, 1, 19, 138, 107, 58, 145, 17, 65, 79, 103, 220, \n234, 151, 242, 207, 206, 240, 180, 230, 115, 150, 172, 116, 34, 231, 173,\n 53, 133, 226, 249, 55, 232, 28, 117, 223, 110, 71, 241, 26, 113, 29, \n 41, 197, 137, 111, 183, 98, 14, 170, 24, 190, 27, 252, 86, 62, 75, \n198, 210, 121, 32, 154, 219, 192, 254, 120, 205, 90, 244, 31, 221, 168,\n 51, 136, 7, 199, 49, 177, 18, 16, 89, 39, 128, 236, 95, 96, 81,\n127, 169, 25, 181, 74, 13, 45, 229, 122, 159, 147, 201, 156, 239, 160,\n224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83, 153, 97, \n 23, 43, 4, 126, 186, 119, 214, 38, 225, 105, 20, 99, 85, 33, 12,\n125 ];\n\n// This method circularly shifts the array left by the number of elements\n// given in its parameter. It returns the resulting array and is used for \n// the ShiftRow step. Note that shift() and push() could be used for a more \n// elegant solution, but they require IE5.5+, so I chose to do it manually. \n\nfunction cyclicShiftLeft(theArray, positions) {\n var temp = theArray.slice(0, positions);\n theArray = theArray.slice(positions).concat(temp);\n return theArray;\n}\n\n// Cipher parameters ... do not change these\nvar Nk = keySizeInBits / 32; \nvar Nb = blockSizeInBits / 32;\nvar Nr = roundsArray[Nk][Nb];\n\n// Multiplies the element "poly" of GF(2^8) by x. See the Rijndael spec.\n\nfunction xtime(poly) {\n poly <<= 1;\n return ((poly & 0x100) ? (poly ^ 0x11B) : (poly));\n}\n\n// Multiplies the two elements of GF(2^8) together and returns the result.\n// See the Rijndael spec, but should be straightforward: for each power of\n// the indeterminant that has a 1 coefficient in x, add y times that power\n// to the result. x and y should be bytes representing elements of GF(2^8)\n\nfunction mult_GF256(x, y) {\n var bit, result = 0;\n \n for (bit = 1; bit < 256; bit *= 2, y = xtime(y)) {\n if (x & bit) \n result ^= y;\n }\n return result;\n}\n\n// Performs the substitution step of the cipher. State is the 2d array of\n// state information (see spec) and direction is string indicating whether\n// we are performing the forward substitution ("encrypt") or inverse \n// substitution (anything else)\n\nfunction byteSub(state, direction) {\n var S;\n if (direction == "encrypt") // Point S to the SBox we're using\n S = SBox;\n else\n S = SBoxInverse;\n for (var i = 0; i < 4; i++) // Substitute for every byte in state\n for (var j = 0; j < Nb; j++)\n state[i][j] = S[state[i][j]];\n}\n\n// Performs the row shifting step of the cipher.\n\nfunction shiftRow(state, direction) {\n for (var i=1; i<4; i++) // Row 0 never shifts\n if (direction == "encrypt")\n state[i] = cyclicShiftLeft(state[i], shiftOffsets[Nb][i]);\n else\n state[i] = cyclicShiftLeft(state[i], Nb - shiftOffsets[Nb][i]);\n\n}\n\n// Performs the column mixing step of the cipher. Most of these steps can\n// be combined into table lookups on 32bit values (at least for encryption)\n// to greatly increase the speed. \n\nfunction mixColumn(state, direction) {\n var b = []; // Result of matrix multiplications\n for (var j = 0; j < Nb; j++) { // Go through each column...\n for (var i = 0; i < 4; i++) { // and for each row in the column...\n if (direction == "encrypt")\n b[i] = mult_GF256(state[i][j], 2) ^ // perform mixing\n mult_GF256(state[(i+1)%4][j], 3) ^ \n state[(i+2)%4][j] ^ \n state[(i+3)%4][j];\n else \n b[i] = mult_GF256(state[i][j], 0xE) ^ \n mult_GF256(state[(i+1)%4][j], 0xB) ^\n mult_GF256(state[(i+2)%4][j], 0xD) ^\n mult_GF256(state[(i+3)%4][j], 9);\n }\n for (var i = 0; i < 4; i++) // Place result back into column\n state[i][j] = b[i];\n }\n}\n\n// Adds the current round key to the state information. Straightforward.\n\nfunction addRoundKey(state, roundKey) {\n for (var j = 0; j < Nb; j++) { // Step through columns...\n state[0][j] ^= (roundKey[j] & 0xFF); // and XOR\n state[1][j] ^= ((roundKey[j]>>8) & 0xFF);\n state[2][j] ^= ((roundKey[j]>>16) & 0xFF);\n state[3][j] ^= ((roundKey[j]>>24) & 0xFF);\n }\n}\n\n// This function creates the expanded key from the input (128/192/256-bit)\n// key. The parameter key is an array of bytes holding the value of the key.\n// The returned value is an array whose elements are the 32-bit words that \n// make up the expanded key.\n\nfunction keyExpansion(key) {\n var expandedKey = new Array();\n var temp;\n\n // in case the key size or parameters were changed...\n Nk = keySizeInBits / 32; \n Nb = blockSizeInBits / 32;\n Nr = roundsArray[Nk][Nb];\n\n for (var j=0; j < Nk; j++) // Fill in input key first\n expandedKey[j] = \n (key[4*j]) | (key[4*j+1]<<8) | (key[4*j+2]<<16) | (key[4*j+3]<<24);\n\n // Now walk down the rest of the array filling in expanded key bytes as\n // per Rijndael's spec\n for (j = Nk; j < Nb * (Nr + 1); j++) { // For each word of expanded key\n temp = expandedKey[j - 1];\n if (j % Nk == 0) \n temp = ( (SBox[(temp>>8) & 0xFF]) |\n (SBox[(temp>>16) & 0xFF]<<8) |\n (SBox[(temp>>24) & 0xFF]<<16) |\n (SBox[temp & 0xFF]<<24) ) ^ Rcon[Math.floor(j / Nk) - 1];\n else if (Nk > 6 && j % Nk == 4)\n temp = (SBox[(temp>>24) & 0xFF]<<24) |\n (SBox[(temp>>16) & 0xFF]<<16) |\n (SBox[(temp>>8) & 0xFF]<<8) |\n (SBox[temp & 0xFF]);\n expandedKey[j] = expandedKey[j-Nk] ^ temp;\n }\n return expandedKey;\n}\n\n// Rijndael's round functions... \n\nfunction Round(state, roundKey) {\n byteSub(state, "encrypt");\n shiftRow(state, "encrypt");\n mixColumn(state, "encrypt");\n addRoundKey(state, roundKey);\n}\n\nfunction InverseRound(state, roundKey) {\n addRoundKey(state, roundKey);\n mixColumn(state, "decrypt");\n shiftRow(state, "decrypt");\n byteSub(state, "decrypt");\n}\n\nfunction FinalRound(state, roundKey) {\n byteSub(state, "encrypt");\n shiftRow(state, "encrypt");\n addRoundKey(state, roundKey);\n}\n\nfunction InverseFinalRound(state, roundKey){\n addRoundKey(state, roundKey);\n shiftRow(state, "decrypt");\n byteSub(state, "decrypt"); \n}\n\n// encrypt is the basic encryption function. It takes parameters\n// block, an array of bytes representing a plaintext block, and expandedKey,\n// an array of words representing the expanded key previously returned by\n// keyExpansion(). The ciphertext block is returned as an array of bytes.\n\nfunction encrypt(block, expandedKey) {\n var i; \n if (!block || block.length*8 != blockSizeInBits)\n return; \n if (!expandedKey)\n return;\n\n block = packBytes(block);\n addRoundKey(block, expandedKey);\n for (i=1; i<Nr; i++) \n Round(block, expandedKey.slice(Nb*i, Nb*(i+1)));\n FinalRound(block, expandedKey.slice(Nb*Nr)); \n return unpackBytes(block);\n}\n\n// decrypt is the basic decryption function. It takes parameters\n// block, an array of bytes representing a ciphertext block, and expandedKey,\n// an array of words representing the expanded key previously returned by\n// keyExpansion(). The decrypted block is returned as an array of bytes.\n\nfunction decrypt(block, expandedKey) {\n var i;\n if (!block || block.length*8 != blockSizeInBits)\n return;\n if (!expandedKey)\n return;\n\n block = packBytes(block);\n InverseFinalRound(block, expandedKey.slice(Nb*Nr)); \n for (i = Nr - 1; i>0; i--) \n InverseRound(block, expandedKey.slice(Nb*i, Nb*(i+1)));\n addRoundKey(block, expandedKey);\n return unpackBytes(block);\n}\n\n/* !NEEDED\n// This method takes a byte array (byteArray) and converts it to a string by\n// applying String.fromCharCode() to each value and concatenating the result.\n// The resulting string is returned. Note that this function SKIPS zero bytes\n// under the assumption that they are padding added in formatPlaintext().\n// Obviously, do not invoke this method on raw data that can contain zero\n// bytes. It is really only appropriate for printable ASCII/Latin-1 \n// values. Roll your own function for more robust functionality :)\n\nfunction byteArrayToString(byteArray) {\n var result = "";\n for(var i=0; i<byteArray.length; i++)\n if (byteArray[i] != 0) \n result += String.fromCharCode(byteArray[i]);\n return result;\n}\n*/\n\n// This function takes an array of bytes (byteArray) and converts them\n// to a hexadecimal string. Array element 0 is found at the beginning of \n// the resulting string, high nibble first. Consecutive elements follow\n// similarly, for example [16, 255] --> "10ff". The function returns a \n// string.\n\nfunction byteArrayToHex(byteArray) {\n var result = "";\n if (!byteArray)\n return;\n for (var i=0; i<byteArray.length; i++)\n result += ((byteArray[i]<16) ? "0" : "") + byteArray[i].toString(16);\n\n return result;\n}\n\n// This function converts a string containing hexadecimal digits to an \n// array of bytes. The resulting byte array is filled in the order the\n// values occur in the string, for example "10FF" --> [16, 255]. This\n// function returns an array. \n\nfunction hexToByteArray(hexString) {\n var byteArray = [];\n if (hexString.length % 2) // must have even length\n return;\n if (hexString.indexOf("0x") == 0 || hexString.indexOf("0X") == 0)\n hexString = hexString.substring(2);\n for (var i = 0; i<hexString.length; i += 2) \n byteArray[Math.floor(i/2)] = parseInt(hexString.slice(i, i+2), 16);\n return byteArray;\n}\n\n// This function packs an array of bytes into the four row form defined by\n// Rijndael. It assumes the length of the array of bytes is divisible by\n// four. Bytes are filled in according to the Rijndael spec (starting with\n// column 0, row 0 to 3). This function returns a 2d array.\n\nfunction packBytes(octets) {\n var state = new Array();\n if (!octets || octets.length % 4)\n return;\n\n state[0] = new Array(); state[1] = new Array(); \n state[2] = new Array(); state[3] = new Array();\n for (var j=0; j<octets.length; j+= 4) {\n state[0][j/4] = octets[j];\n state[1][j/4] = octets[j+1];\n state[2][j/4] = octets[j+2];\n state[3][j/4] = octets[j+3];\n }\n return state; \n}\n\n// This function unpacks an array of bytes from the four row format preferred\n// by Rijndael into a single 1d array of bytes. It assumes the input "packed"\n// is a packed array. Bytes are filled in according to the Rijndael spec. \n// This function returns a 1d array of bytes.\n\nfunction unpackBytes(packed) {\n var result = new Array();\n for (var j=0; j<packed[0].length; j++) {\n result[result.length] = packed[0][j];\n result[result.length] = packed[1][j];\n result[result.length] = packed[2][j];\n result[result.length] = packed[3][j];\n }\n return result;\n}\n\n// This function takes a prospective plaintext (string or array of bytes)\n// and pads it with null (previously pseudorandom) bytes if its length is not a multiple of the block \n// size. If plaintext is a string, it is converted to an array of bytes\n// in the process. The type checking can be made much nicer using the \n// instanceof operator, but this operator is not available until IE5.0 so I \n// chose to use the heuristic below. \n\nfunction formatPlaintext(plaintext) {\n var bpb = blockSizeInBits / 8; // bytes per block\n var i;\n\n // if primitive string or String instance\n if (typeof plaintext == "string" || plaintext.indexOf) {\n plaintext = plaintext.split("");\n // Unicode issues here (ignoring high byte)\n for (i=0; i<plaintext.length; i++)\n plaintext[i] = plaintext[i].charCodeAt(0) & 0xFF;\n } \n\n for (i = bpb - (plaintext.length % bpb); i > 0 && i < bpb; i--) \n plaintext[plaintext.length] = 0;\n/*\n i = plaintext.length % bpb;\n if (i > 0) {\n plaintext = plaintext.concat(getRandomBytes(bpb - i));\n }\n*/\n return plaintext;\n}\n\n// Returns an array containing "howMany" random bytes.\n\nfunction getRandomBytes(howMany) {\n var i, bytes = new Array();\n \n for (i = 0; i < howMany; i++) {\n bytes[i] = prng.nextInt(255);\n }\n return bytes;\n}\n\n// rijndaelEncrypt(plaintext, key, mode)\n// Encrypts the plaintext using the given key and in the given mode. \n// The parameter "plaintext" can either be a string or an array of bytes. \n// The parameter "key" must be an array of key bytes. If you have a hex \n// string representing the key, invoke hexToByteArray() on it to convert it \n// to an array of bytes. The third parameter "mode" is a string indicating\n// the encryption mode to use, either "ECB" or "CBC". If the parameter is\n// omitted, ECB is assumed.\n// \n// An array of bytes representing the cihpertext is returned. To convert \n// this array to hex, invoke byteArrayToHex() on it.\n\nfunction rijndaelEncrypt(plaintext, key, mode) {\n var expandedKey, i, aBlock;\n var bpb = blockSizeInBits / 8; // bytes per block\n var ct; // ciphertext\n\n if (!plaintext || !key)\n return;\n if (key.length*8 != keySizeInBits)\n return; \n if (mode == "CBC") {\n ct = getRandomBytes(bpb); // get IV\n//dump("IV", byteArrayToHex(ct));\n } else {\n mode = "ECB";\n ct = new Array();\n }\n\n // convert plaintext to byte array and pad with zeros if necessary. \n plaintext = formatPlaintext(plaintext);\n\n expandedKey = keyExpansion(key);\n \n for (var block = 0; block < plaintext.length / bpb; block++) {\n aBlock = plaintext.slice(block * bpb, (block + 1) * bpb);\n if (mode == "CBC") {\n for (var i = 0; i < bpb; i++) {\n aBlock[i] ^= ct[(block * bpb) + i];\n }\n }\n ct = ct.concat(encrypt(aBlock, expandedKey));\n }\n\n return ct;\n}\n\n// rijndaelDecrypt(ciphertext, key, mode)\n// Decrypts the using the given key and mode. The parameter "ciphertext" \n// must be an array of bytes. The parameter "key" must be an array of key \n// bytes. If you have a hex string representing the ciphertext or key, \n// invoke hexToByteArray() on it to convert it to an array of bytes. The\n// parameter "mode" is a string, either "CBC" or "ECB".\n// \n// An array of bytes representing the plaintext is returned. To convert \n// this array to a hex string, invoke byteArrayToHex() on it. To convert it \n// to a string of characters, you can use byteArrayToString().\n\nfunction rijndaelDecrypt(ciphertext, key, mode) {\n var expandedKey;\n var bpb = blockSizeInBits / 8; // bytes per block\n var pt = new Array(); // plaintext array\n var aBlock; // a decrypted block\n var block; // current block number\n\n if (!ciphertext || !key || typeof ciphertext == "string")\n return;\n if (key.length*8 != keySizeInBits)\n return; \n if (!mode) {\n mode = "ECB"; // assume ECB if mode omitted\n }\n\n expandedKey = keyExpansion(key);\n \n // work backwards to accomodate CBC mode \n for (block=(ciphertext.length / bpb)-1; block>0; block--) {\n aBlock = \n decrypt(ciphertext.slice(block*bpb,(block+1)*bpb), expandedKey);\n if (mode == "CBC") \n for (var i=0; i<bpb; i++) \n pt[(block-1)*bpb + i] = aBlock[i] ^ ciphertext[(block-1)*bpb + i];\n else \n pt = aBlock.concat(pt);\n }\n\n // do last block if ECB (skips the IV in CBC)\n if (mode == "ECB")\n pt = decrypt(ciphertext.slice(0, bpb), expandedKey).concat(pt);\n\n return pt;\n}\n\n // AES based pseudorandom number generator\n\n /* Constructor. Called with an array of 32 byte (0-255) values\n containing the initial seed. */\n\n function AESprng(seed) {\n this.key = new Array();\n this.key = seed;\n this.itext = hexToByteArray("9F489613248148F9C27945C6AE62EECA3E3367BB14064E4E6DC67A9F28AB3BD1");\n this.nbytes = 0; // Bytes left in buffer\n \n this.next = AESprng_next;\n this.nextbits = AESprng_nextbits;\n this.nextInt = AESprng_nextInt;\n this.round = AESprng_round;\n \n /* Encrypt the initial text with the seed key\n three times, feeding the output of the encryption\n back into the key for the next round. */\n \n bsb = blockSizeInBits;\n blockSizeInBits = 256; \n var i, ct;\n for (i = 0; i < 3; i++) {\n this.key = rijndaelEncrypt(this.itext, this.key, "ECB");\n }\n \n /* Now make between one and four additional\n key-feedback rounds, with the number determined\n by bits from the result of the first three\n rounds. */\n \n var n = 1 + (this.key[3] & 2) + (this.key[9] & 1); \n for (i = 0; i < n; i++) {\n this.key = rijndaelEncrypt(this.itext, this.key, "ECB");\n }\n blockSizeInBits = bsb;\n }\n \n function AESprng_round() {\n bsb = blockSizeInBits;\n blockSizeInBits = 256; \n this.key = rijndaelEncrypt(this.itext, this.key, "ECB");\n this.nbytes = 32;\n blockSizeInBits = bsb;\n }\n \n // Return next byte from the generator\n\n function AESprng_next() {\n if (this.nbytes <= 0) {\n this.round();\n }\n return(this.key[--this.nbytes]);\n }\n \n // Return n bit integer value (up to maximum integer size)\n \n function AESprng_nextbits(n) {\n var i, w = 0, nbytes = Math.floor((n + 7) / 8);\n\n for (i = 0; i < nbytes; i++) {\n w = (w << 8) | this.next();\n }\n return w & ((1 << n) - 1);\n }\n\n // Return integer between 0 and n inclusive\n \n function AESprng_nextInt(n) {\n var p = 1, nb = 0;\n \n // Determine smallest p, 2^p > n\n // nb = log_2 p\n \n while (n >= p) {\n p <<= 1;\n nb++;\n }\n p--;\n \n /* Generate values from 0 through n by first generating\n values v from 0 to (2^p)-1, then discarding any results v > n.\n For the rationale behind this (and why taking\n values mod (n + 1) is biased toward smaller values, see\n Ferguson and Schneier, "Practical Cryptography",\n ISBN 0-471-22357-3, section 10.8). */\n\n while (true) {\n var v = this.nextbits(nb) & p;\n \n if (v <= n) {\n return v;\n }\n }\n }\n\n// Varieties of ASCII armour for binary data\n\n var maxLineLength = 64; // Maximum line length for armoured text\n \n /* Hexadecimal Armour\n \n A message is encoded in Hexadecimal armour by expressing its\n bytes as a hexadecimal string which is prefixed by a sentinel\n of "?HX?" and suffixed by "?H", then broken into lines no\n longer than maxLineLength. Armoured messages use lower case\n letters for digits with decimal values of 0 through 15, but\n either upper or lower case letters are accepted when decoding\n a message. The hexadecimal to byte array interconversion\n routines in aes.js do most of the heavy lifting here. */\n \n var hexSentinel = "?HX?", hexEndSentinel = "?H";\n \n // Encode byte array in hexadecimal armour\n \n function armour_hex(b) {\n var h = hexSentinel + byteArrayToHex(b) + hexEndSentinel;\n var t = "";\n while (h.length > maxLineLength) {\n//dump("h.length", h.length);\n t += h.substring(0, maxLineLength) + "\sn";\n h = h.substring(maxLineLength, h.length);\n }\n//dump("h.final_length", h.length);\n t += h + "\sn";\n return t;\n }\n \n /* Decode string in hexadecimal armour to byte array. If the\n string supplied contains a start and/or end sentinel,\n only characters within the sentinels will be decoded.\n Non-hexadecimal digits are silently ignored, which\n automatically handles line breaks. We might want to\n diagnose invalid characters as opposed to ignoring them. */\n \n function disarm_hex(s) {\n var hexDigits = "0123456789abcdefABCDEF";\n var hs = "", i;\n \n // Extract hexadecimal data between sentinels, if present\n \n if ((i = s.indexOf(hexSentinel)) >= 0) {\n s = s.substring(i + hexSentinel.length, s.length);\n }\n if ((i = s.indexOf(hexEndSentinel)) >= 0) {\n s = s.substring(0, i);\n }\n \n // Assemble string of valid hexadecimal digits\n \n for (i = 0; i < s.length; i++) {\n var c = s.charAt(i);\n if (hexDigits.indexOf(c) >= 0) {\n hs += c;\n }\n }\n//dump("hs", hs);\n return hexToByteArray(hs);\n }\n\n /* Codegroup Armour\n \n Codegroup armour encodes a byte string into a sequence of five\n letter code groups like spies used in the good old days. The\n first group of a message is always "ZZZZZ" and the last "YYYYY";\n the decoding process ignores any text outside these start and\n end sentinels. Bytes are encoded as two letters in the range\n "A" to "X", each encoding four bits of the byte. Encoding uses\n a pseudorandomly generated base letter and wraps around modulo\n 24 to spread encoded letters evenly through the alphabet. (This\n refinement is purely aesthetic; the base letter sequence is\n identical for all messages and adds no security. If the message\n does not fill an even number of five letter groups, the last\n group is padded to five letters with "Z" characters, which are\n ignored when decoding. */\n \n var acgcl, acgt, acgg;\n \n // Output next codegroup, flushing current line if it's full\n \n function armour_cg_outgroup() {\n if (acgcl.length > maxLineLength) {\n acgt += acgcl + "\sn";\n acgcl = "";\n }\n if (acgcl.length > 0) {\n acgcl += " ";\n }\n acgcl += acgg;\n acgg = "";\n }\n \n /* Add a letter to the current codegroup, emitting it when\n it reaches five letters. */\n \n function armour_cg_outletter(l) {\n if (acgg.length >= 5) {\n armour_cg_outgroup();\n }\n acgg += l;\n }\n \n var codegroupSentinel = "ZZZZZ";\n \n function armour_codegroup(b) {\n var charBase = ("A").charCodeAt(0);\n \n acgcl = codegroupSentinel;\n acgt = "";\n acgg = "";\n \n var cgrng = new LEcuyer(0xbadf00d);\n for (i = 0; i < b.length; i++) {\n var r = cgrng.nextInt(23);\n armour_cg_outletter(String.fromCharCode(charBase + ((((b[i] >> 4) & 0xF)) + r) % 24));\n r = cgrng.nextInt(23);\n armour_cg_outletter(String.fromCharCode(charBase + ((((b[i] & 0xF)) + r) % 24)));\n }\n delete cgrng;\n \n // Generate nulls to fill final codegroup if required\n \n while (acgg.length < 5) {\n armour_cg_outletter("Z");\n }\n armour_cg_outgroup();\n \n // Append terminator group\n \n acgg = "YYYYY";\n armour_cg_outgroup();\n \n // Flush last line\n \n acgt += acgcl + "\sn";\n \n return acgt;\n }\n \n var dcgs, dcgi;\n \n /* Obtain next "significant" character from message. Characters\n other than letters are silently ignored; both lower and upper\n case letters are accepted. */\n \n function disarm_cg_insig() {\n while (dcgi < dcgs.length) {\n var c = dcgs.charAt(dcgi++).toUpperCase();\n if ((c >= "A") && (c <= "Z")) {\n//dump("c", c);\n return c;\n }\n }\n return "";\n }\n \n // Decode a message in codegroup armour\n \n function disarm_codegroup(s) {\n var b = new Array();\n var nz = 0, ba, bal = 0, c;\n \n dcgs = s;\n dcgi = 0;\n \n // Search for initial group of "ZZZZZ"\n \n while (nz < 5) {\n c = disarm_cg_insig();\n \n if (c == "Z") {\n nz++;\n } else if (c == "") {\n nz = 0;\n break;\n } else {\n nz = 0;\n }\n }\n \n if (nz == 0) {\n alert("No codegroup starting symbol found in message.");\n return "";\n }\n \n /* Decode letter pairs from successive groups\n and assemble into bytes. */\n \n var charBase = ("A").charCodeAt(0); \n var cgrng = new LEcuyer(0xbadf00d);\n for (nz = 0; nz < 2; ) {\n c = disarm_cg_insig();\n//dump("c", c);\n \n if ((c == "Y") || (c == "")) {\n break;\n } else if (c != "Z") {\n var r = cgrng.nextInt(23);\n var n = c.charCodeAt(0) - charBase;\n n = (n + (24 - r)) % 24;\n//dump("n", n);\n if (nz == 0) {\n ba = (n << 4);\n nz++;\n } else {\n ba |= n;\n b[bal++] = ba;\n nz = 0;\n }\n }\n }\n delete cgrng;\n \n /* Ponder how we escaped from the decoder loop and\n issue any requisite warnings. */\n \n var kbo = " Attempting decoding with data received.";\n if (nz != 0) {\n alert("Codegroup data truncated." + kbo);\n } else {\n if (c == "Y") {\n nz = 1;\n while (nz < 5) {\n c = disarm_cg_insig();\n if (c != "Y") {\n break;\n }\n nz++;\n }\n if (nz != 5) {\n alert("Codegroup end group incomplete." + kbo);\n }\n } else {\n alert("Codegroup end group missing." + kbo);\n }\n }\n \n return b;\n }\n \n /* Base64 Armour\n \n Base64 armour encodes a byte array as described in RFC 1341. Sequences\n of three bytes are encoded into groups of four characters from a set\n of 64 consisting of the upper and lower case letters, decimal digits,\n and the special characters "+" and "/". If the input is not a multiple\n of three characters, the end of the message is padded with one or two\n "=" characters to indicate its actual length. We prefix the armoured\n message with "?b64" and append "?64b" to the end; if one or both\n of these sentinels are present, text outside them is ignored. You can\n suppress the generation of sentinels in armour by setting base64addsent\n false before calling armour_base64. */\n \n \n var base64code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",\n base64sent = "?b64", base64esent = "?64b", base64addsent = true;\n \n function armour_base64(b) {\n var b64t = "";\n var b64l = base64addsent ? base64sent : "";\n \n var i;\n for (i = 0; i <= b.length - 3; i += 3) {\n if ((b64l.length + 4) > maxLineLength) {\n b64t += b64l + "\sn";\n b64l = "";\n }\n b64l += base64code.charAt(b[i] >> 2);\n b64l += base64code.charAt(((b[i] & 3) << 4) | (b[i + 1] >> 4));\n b64l += base64code.charAt(((b[i + 1] & 0xF) << 2) | (b[i + 2] >> 6));\n b64l += base64code.charAt(b[i + 2] & 0x3F);\n }\n \n//dump("b.length", b.length); dump("i", i); dump("(b.length - i)", (b.length - i));\n if ((b.length - i) == 1) {\n b64l += base64code.charAt(b[i] >> 2);\n b64l += base64code.charAt(((b[i] & 3) << 4));\n b64l += "==";\n } else if ((b.length - i) == 2) {\n b64l += base64code.charAt(b[i] >> 2);\n b64l += base64code.charAt(((b[i] & 3) << 4) | (b[i + 1] >> 4));\n b64l += base64code.charAt(((b[i + 1] & 0xF) << 2));\n b64l += "=";\n }\n\n if ((b64l.length + 4) > maxLineLength) {\n b64t += b64l + "\sn";\n b64l = "";\n }\n if (base64addsent) {\n b64l += base64esent;\n }\n b64t += b64l + "\sn";\n return b64t;\n }\n \n function disarm_base64(s) {\n var b = new Array();\n var i = 0, j, c, shortgroup = 0, n = 0;\n var d = new Array();\n \n if ((j = s.indexOf(base64sent)) >= 0) {\n s = s.substring(j + base64sent.length, s.length);\n }\n if ((j = s.indexOf(base64esent)) >= 0) {\n s = s.substring(0, j);\n }\n \n /* Ignore any non-base64 characters before the encoded\n data stream and skip the type sentinel if present. */\n \n while (i < s.length) {\n if (base64code.indexOf(s.charAt(i)) != -1) {\n break;\n }\n i++;\n }\n \n /* Decode the base64 data stream. The decoder is\n terminated by the end of the input string or\n the occurrence of the explicit end sentinel. */\n \n while (i < s.length) {\n for (j = 0; j < 4; ) {\n if (i >= s.length) {\n if (j > 0) {\n alert("Base64 cipher text truncated.");\n return b;\n }\n break;\n }\n c = base64code.indexOf(s.charAt(i));\n if (c >= 0) {\n d[j++] = c;\n } else if (s.charAt(i) == "=") {\n d[j++] = 0;\n shortgroup++;\n } else if (s.substring(i, i + base64esent.length) == base64esent) {\n//dump("s.substring(i, i + base64esent.length)", s.substring(i, i + base64esent.length));\n//dump("esent", i);\n i = s.length;\n continue;\n } else {\n//dump("s.substring(i, i + base64esent.length)", s.substring(i, i + base64esent.length));\n//dump("usent", i);\n // Might improve diagnosis of improper character in else clause here\n }\n i++;\n }\n//dump("d0", d[0]); dump("d1", d[1]); dump("d2", d[2]); dump("d3", d[3]); \n//dump("shortgroup", shortgroup);\n//dump("n", n);\n if (j == 4) {\n b[n++] = ((d[0] << 2) | (d[1] >> 4)) & 0xFF;\n if (shortgroup < 2) {\n b[n++] = ((d[1] << 4) | (d[2] >> 2)) & 0xFF;\n//dump("(d[1] << 4) | (d[2] >> 2)", (d[1] << 4) | (d[2] >> 2));\n if (shortgroup < 1) {\n b[n++] = ((d[2] << 6) | d[3]) & 0xFF;\n }\n }\n }\n }\n return b;\n }\n\n // Entropy collection utilities\n\n /* Start by declaring static storage and initialise\n the entropy vector from the time we come through\n here. */\n \n var entropyData = new Array(); // Collected entropy data\n var edlen = 0; // Keyboard array data length\n \n addEntropyTime(); // Start entropy collection with page load time\n ce(); // Roll milliseconds into initial entropy\n\n // Add a byte to the entropy vector\n \n function addEntropyByte(b) {\n entropyData[edlen++] = b;\n }\n \n /* Capture entropy. When the user presses a key or performs\n various other events for which we can request\n notification, add the time in 255ths of a second to the\n entropyData array. The name of the function is short\n so it doesn't bloat the form object declarations in\n which it appears in various "onXXX" events. */\n \n function ce() {\n addEntropyByte(Math.floor((((new Date).getMilliseconds()) * 255) / 999));\n }\n \n // Add a 32 bit quantity to the entropy vector\n \n function addEntropy32(w) {\n var i;\n \n for (i = 0; i < 4; i++) {\n addEntropyByte(w & 0xFF);\n w >>= 8;\n }\n }\n \n /* Add the current time and date (milliseconds since the epoch,\n truncated to 32 bits) to the entropy vector. */\n \n function addEntropyTime() {\n addEntropy32((new Date()).getTime());\n }\n\n /* Start collection of entropy from mouse movements. The\n argument specifies the number of entropy items to be\n obtained from mouse motion, after which mouse motion\n will be ignored. Note that you can re-enable mouse\n motion collection at any time if not already underway. */\n \n var mouseMotionCollect = 0;\n var oldMoveHandler; // For saving and restoring mouse move handler in IE4\n \n function mouseMotionEntropy(maxsamp) {\n if (mouseMotionCollect <= 0) {\n mouseMotionCollect = maxsamp;\n if ((document.implementation.hasFeature("Events", "2.0")) &&\n document.addEventListener) {\n // Browser supports Document Object Model (DOM) 2 events\n document.addEventListener("mousemove", mouseMoveEntropy, false);\n } else {\n if (document.attachEvent) {\n // Internet Explorer 5 and above event model\n document.attachEvent("onmousemove", mouseMoveEntropy);\n } else {\n // Internet Explorer 4 event model\n oldMoveHandler = document.onmousemove;\n document.onmousemove = mouseMoveEntropy;\n }\n }\n//dump("Mouse enable", mouseMotionCollect);\n }\n }\n \n /* Collect entropy from mouse motion events. Note that\n this is craftily coded to work with either DOM2 or Internet\n Explorer style events. Note that we don't use every successive\n mouse movement event. Instead, we XOR the three bytes collected\n from the mouse and use that to determine how many subsequent\n mouse movements we ignore before capturing the next one. */\n \n var mouseEntropyTime = 0; // Delay counter for mouse entropy collection\n \n function mouseMoveEntropy(e) {\n if (!e) {\n e = window.event; // Internet Explorer event model\n }\n if (mouseMotionCollect > 0) {\n if (mouseEntropyTime-- <= 0) {\n addEntropyByte(e.screenX & 0xFF);\n addEntropyByte(e.screenY & 0xFF);\n ce();\n mouseMotionCollect--;\n mouseEntropyTime = (entropyData[edlen - 3] ^ entropyData[edlen - 2] ^\n entropyData[edlen - 1]) % 19;\n//dump("Mouse Move", byteArrayToHex(entropyData.slice(-3)));\n }\n if (mouseMotionCollect <= 0) {\n if (document.removeEventListener) {\n document.removeEventListener("mousemove", mouseMoveEntropy, false);\n } else if (document.detachEvent) {\n document.detachEvent("onmousemove", mouseMoveEntropy);\n } else {\n document.onmousemove = oldMoveHandler;\n }\n//dump("Spung!", 0);\n }\n }\n } \n \n /* Compute a 32 byte key value from the entropy vector.\n We compute the value by taking the MD5 sum of the even\n and odd bytes respectively of the entropy vector, then\n concatenating the two MD5 sums. */\n \n function keyFromEntropy() {\n var i, k = new Array(32);\n \n if (edlen == 0) {\n alert("Blooie! Entropy vector void at call to keyFromEntropy.");\n }\n//dump("Entropy bytes", edlen);\n\n md5_init();\n for (i = 0; i < edlen; i += 2) {\n md5_update(entropyData[i]);\n }\n md5_finish();\n for (i = 0; i < 16; i++) {\n k[i] = digestBits[i];\n }\n\n md5_init();\n for (i = 1; i < edlen; i += 2) {\n md5_update(entropyData[i]);\n }\n md5_finish();\n for (i = 0; i < 16; i++) {\n k[i + 16] = digestBits[i];\n }\n \n//dump("keyFromEntropy", byteArrayToHex(k));\n return k;\n }\n/*\n * md5.jvs 1.0b 27/06/96\n *\n * Javascript implementation of the RSA Data Security, Inc. MD5\n * Message-Digest Algorithm.\n *\n * Copyright (c) 1996 Henri Torgemane. All Rights Reserved.\n *\n * Permission to use, copy, modify, and distribute this software\n * and its documentation for any purposes and without\n * fee is hereby granted provided that this copyright notice\n * appears in all copies. \n *\n * Of course, this soft is provided "as is" without express or implied\n * warranty of any kind.\n\n This version contains some trivial reformatting modifications\n by John Walker.\n\n */\n\nfunction array(n) {\n for (i = 0; i < n; i++) {\n this[i] = 0;\n }\n this.length = n;\n}\n\n/* Some basic logical functions had to be rewritten because of a bug in\n * Javascript.. Just try to compute 0xffffffff >> 4 with it..\n * Of course, these functions are slower than the original would be, but\n * at least, they work!\n */\n\nfunction integer(n) {\n return n % (0xffffffff + 1);\n}\n\nfunction shr(a, b) {\n a = integer(a);\n b = integer(b);\n if (a - 0x80000000 >= 0) {\n a = a % 0x80000000;\n a >>= b;\n a += 0x40000000 >> (b - 1);\n } else {\n a >>= b;\n }\n return a;\n}\n\nfunction shl1(a) {\n a = a % 0x80000000;\n if (a & 0x40000000 == 0x40000000) {\n a -= 0x40000000; \n a *= 2;\n a += 0x80000000;\n } else {\n a *= 2;\n }\n return a;\n}\n\nfunction shl(a, b) {\n a = integer(a);\n b = integer(b);\n for (var i = 0; i < b; i++) {\n a = shl1(a);\n }\n return a;\n}\n\nfunction and(a, b) {\n a = integer(a);\n b = integer(b);\n var t1 = a - 0x80000000;\n var t2 = b - 0x80000000;\n if (t1 >= 0) {\n if (t2 >= 0) {\n return ((t1 & t2) + 0x80000000);\n } else {\n return (t1 & b);\n }\n } else {\n if (t2 >= 0) {\n return (a & t2);\n } else {\n return (a & b); \n }\n }\n}\n\nfunction or(a, b) {\n a = integer(a);\n b = integer(b);\n var t1 = a - 0x80000000;\n var t2 = b - 0x80000000;\n if (t1 >= 0) {\n if (t2 >= 0) {\n return ((t1 | t2) + 0x80000000);\n } else {\n return ((t1 | b) + 0x80000000);\n }\n } else {\n if (t2 >= 0) {\n return ((a | t2) + 0x80000000);\n } else {\n return (a | b); \n }\n }\n}\n\nfunction xor(a, b) {\n a = integer(a);\n b = integer(b);\n var t1 = a - 0x80000000;\n var t2 = b - 0x80000000;\n if (t1 >= 0) {\n if (t2 >= 0) {\n return (t1 ^ t2);\n } else {\n return ((t1 ^ b) + 0x80000000);\n }\n } else {\n if (t2 >= 0) {\n return ((a ^ t2) + 0x80000000);\n } else {\n return (a ^ b); \n }\n }\n}\n\nfunction not(a) {\n a = integer(a);\n return 0xffffffff - a;\n}\n\n/* Here begin the real algorithm */\n\nvar state = new array(4); \nvar count = new array(2);\n count[0] = 0;\n count[1] = 0; \nvar buffer = new array(64); \nvar transformBuffer = new array(16); \nvar digestBits = new array(16);\n\nvar S11 = 7;\nvar S12 = 12;\nvar S13 = 17;\nvar S14 = 22;\nvar S21 = 5;\nvar S22 = 9;\nvar S23 = 14;\nvar S24 = 20;\nvar S31 = 4;\nvar S32 = 11;\nvar S33 = 16;\nvar S34 = 23;\nvar S41 = 6;\nvar S42 = 10;\nvar S43 = 15;\nvar S44 = 21;\n\nfunction F(x, y, z) {\n return or(and(x, y), and(not(x), z));\n}\n\nfunction G(x, y, z) {\n return or(and(x, z), and(y, not(z)));\n}\n\nfunction H(x, y, z) {\n return xor(xor(x, y), z);\n}\n\nfunction I(x, y, z) {\n return xor(y ,or(x , not(z)));\n}\n\nfunction rotateLeft(a, n) {\n return or(shl(a, n), (shr(a, (32 - n))));\n}\n\nfunction FF(a, b, c, d, x, s, ac) {\n a = a + F(b, c, d) + x + ac;\n a = rotateLeft(a, s);\n a = a + b;\n return a;\n}\n\nfunction GG(a, b, c, d, x, s, ac) {\n a = a + G(b, c, d) + x + ac;\n a = rotateLeft(a, s);\n a = a + b;\n return a;\n}\n\nfunction HH(a, b, c, d, x, s, ac) {\n a = a + H(b, c, d) + x + ac;\n a = rotateLeft(a, s);\n a = a + b;\n return a;\n}\n\nfunction II(a, b, c, d, x, s, ac) {\n a = a + I(b, c, d) + x + ac;\n a = rotateLeft(a, s);\n a = a + b;\n return a;\n}\n\nfunction transform(buf, offset) { \n var a = 0, b = 0, c = 0, d = 0; \n var x = transformBuffer;\n \n a = state[0];\n b = state[1];\n c = state[2];\n d = state[3];\n \n for (i = 0; i < 16; i++) {\n x[i] = and(buf[i * 4 + offset], 0xFF);\n for (j = 1; j < 4; j++) {\n x[i] += shl(and(buf[i * 4 + j + offset] ,0xFF), j * 8);\n }\n }\n\n /* Round 1 */\n a = FF( a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */\n d = FF( d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */\n c = FF( c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */\n b = FF( b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */\n a = FF( a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */\n d = FF( d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */\n c = FF( c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */\n b = FF( b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */\n a = FF( a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */\n d = FF( d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */\n c = FF( c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */\n b = FF( b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */\n a = FF( a, b, c, d, x[12], S11, 0x6b901122); /* 13 */\n d = FF( d, a, b, c, x[13], S12, 0xfd987193); /* 14 */\n c = FF( c, d, a, b, x[14], S13, 0xa679438e); /* 15 */\n b = FF( b, c, d, a, x[15], S14, 0x49b40821); /* 16 */\n\n /* Round 2 */\n a = GG( a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */\n d = GG( d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */\n c = GG( c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */\n b = GG( b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */\n a = GG( a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */\n d = GG( d, a, b, c, x[10], S22, 0x2441453); /* 22 */\n c = GG( c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */\n b = GG( b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */\n a = GG( a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */\n d = GG( d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */\n c = GG( c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */\n b = GG( b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */\n a = GG( a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */\n d = GG( d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */\n c = GG( c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */\n b = GG( b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */\n\n /* Round 3 */\n a = HH( a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */\n d = HH( d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */\n c = HH( c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */\n b = HH( b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */\n a = HH( a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */\n d = HH( d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */\n c = HH( c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */\n b = HH( b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */\n a = HH( a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */\n d = HH( d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */\n c = HH( c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */\n b = HH( b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */\n a = HH( a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */\n d = HH( d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */\n c = HH( c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */\n b = HH( b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */\n\n /* Round 4 */\n a = II( a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */\n d = II( d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */\n c = II( c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */\n b = II( b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */\n a = II( a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */\n d = II( d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */\n c = II( c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */\n b = II( b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */\n a = II( a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */\n d = II( d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */\n c = II( c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */\n b = II( b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */\n a = II( a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */\n d = II( d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */\n c = II( c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */\n b = II( b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */\n\n state[0] += a;\n state[1] += b;\n state[2] += c;\n state[3] += d;\n\n}\n\nfunction md5_init() {\n count[0] = count[1] = 0;\n state[0] = 0x67452301;\n state[1] = 0xefcdab89;\n state[2] = 0x98badcfe;\n state[3] = 0x10325476;\n for (i = 0; i < digestBits.length; i++) {\n digestBits[i] = 0;\n }\n}\n\nfunction md5_update(b) { \n var index, i;\n \n index = and(shr(count[0],3) , 0x3F);\n if (count[0] < 0xFFFFFFFF - 7) {\n count[0] += 8;\n } else {\n count[1]++;\n count[0] -= 0xFFFFFFFF + 1;\n count[0] += 8;\n }\n buffer[index] = and(b, 0xff);\n if (index >= 63) {\n transform(buffer, 0);\n }\n}\n\nfunction md5_finish() {\n var bits = new array(8);\n var padding; \n var i = 0, index = 0, padLen = 0;\n\n for (i = 0; i < 4; i++) {\n bits[i] = and(shr(count[0], (i * 8)), 0xFF);\n }\n for (i = 0; i < 4; i++) {\n bits[i + 4] = and(shr(count[1], (i * 8)), 0xFF);\n }\n index = and(shr(count[0], 3), 0x3F);\n padLen = (index < 56) ? (56 - index) : (120 - index);\n padding = new array(64); \n padding[0] = 0x80;\n for (i = 0; i < padLen; i++) {\n md5_update(padding[i]);\n }\n for (i = 0; i < 8; i++) {\n md5_update(bits[i]);\n }\n\n for (i = 0; i < 4; i++) {\n for (j = 0; j < 4; j++) {\n digestBits[i * 4 + j] = and(shr(state[i], (j * 8)) , 0xFF);\n }\n } \n}\n\n/* End of the MD5 algorithm */\n\n// END SJR\n
#tiddlerNotes .title {color: #F00;border-bottom:2px solid red}\ndiv[tags~="todo"].viewer {background-color: #F9F9F0; }\n\n#popup {background-color: #DCDCDC; color: #F90;border-right: 2px solid #FBFBFB; border-bottom: 2px solid #FBFBFB}\n#popup a {color: #F90;background-color: #DCDCDC}\n#popup a:hover {background-color: #F90;color: #FFF}\n#popup hr { color:#FFF}\n\nul { margin-left: 10px; padding-left: 0; list-style: none; }\nli { padding-left: 14px; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAJCAMAAAA4jZ0cAAAACXBIWXMAAAsTAAALEwEAmpwYAAADAFBMVEXchhTcihzkjhzkkhzslhzkkiTsmiT0niT0niz0oiT8oiz8piz8rjT8sjT8ujT8wjz82kz84kz88lz89lz////sv/QS9SxFBvMS9XAS9ExFNyAS9bjs3sgS9XQS9aTqReQS9GhFNyBGniLqReQS9FDkFY+tE5gABAEAAADumqxyFEG6q80S9HTjr6FyFEGtE5gABAEAAADumqwABAHpWmQS9JTifi3/DAOtE5gABAEAAADumqwAAAES9eRFOAT/DAOtE5gABAEAAADumqz0by8S9OAAAWQAAAAAAAATU8gS9sjjhwgS9oQBI7P0b50S9OAAAA8AAAAAAAAAAAAAAZAAAAAAAABhAE1sAHJ0AGUAAHQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAD7fmT4MUj///8S9yT8rhUTB6gAABES93QAAAAAAAHjwk4S9YQAAT8AAAEAAIQS9eTh6Hl5EroAAIQAAABMAT8AAAEAARIS99TpNUwS99TpNUzI0NT0TfYUk7gAAkwSAAAAAAB6FQhMAT96FQgTj9gS9wh2deABI7MAAAAAAAAAAAIAAAEAAAAAAAAAAADI0NT0TfYUk7gAAAAAAADiAZwAAAAAAAEAAAIAAAABI7P0TVT0ZL4BI7P0TVT0ZL6AgIAS9nziAY8BI7MAAAES9sj0S1ABI7P0cEL3sIAAQAAKCkb0VhoKCkYS9sj0S1ABI7MAJwoS9zTjhu0KAADI0NT0TfYUk7gAAA8AAAAAAAAAAAAAAZAAAAAAAABhAE1sAHJ0AGUAAHQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAHpXvytE5gS9zhz6DXI0NT0TfYUk7jI0NQS9zhz6DvI0NT0TfYUk7gAAAEKF0gS+AByITGtE5gS94gAAA8Uk7jkF2AAAADhvugAAAAAAAIS+FAAAAAAAAAAAAFJhE0AAAEAAAQOK7oBI7MAAAAAAAAAAADchhTchhS5nyqtAAAAFXRSTlP//////////////////////////wAr2X3qAAAARElEQVR42h2LQRLAIAgDQaooAxYZ/v/WYk/ZySaQqsKjJ2xTmYMQNns4PwhmcsI7lBKJePFCNdRgz9qsX5ms+0qi1io+e0gC3TYSp4cAAAAASUVORK5CYII=);background-repeat: no-repeat;background-position: 0 3px;}\n\n.button {color: #F90;}\n.button:active {background-color: #FFF;color: #F90;}\n.button:hover {background-color: #F90;color: #FFF;}\n\n.toolbar a {color: #F90;}\n.toolbar a:active {background-color: #FFF;color: #F90;}\n.toolbar a:hover {background-color: #F90;color: #FFF;}\n\n.toolbar {position:relative;top:19px;left:-1px;border: 0px; background-color:transparent; color:#000; height:16px;padding-top:2px;margin-left:200px;padding-right:0}\n\nhr { border: none; border-top: dotted 1px #777; height: 1px; color: #777;margin: 7px 0;} \n\n.tiddler .button {color: #F90;}\n.tiddler .button:active {background-color: #FFF;color: #F90;}\n.tiddler .button:hover {background-color: #F90;color: #FFF;}\n.tiddler .tiddlyLink {text-align:left;color:#F90;}\n.tiddler .tiddlyLink:hover {background-color:#F90;color: #fff;}\n.tiddler .externalLink:hover {background-color:#F90;color: #fff; text-decoration: none;}\n.tiddler .externalLink{color: #F9C;text-decoration: underline;}\n\n.tiddler {\nbackground: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAABbCAMAAAAoXweDAAADAFBMVEUAAAD////+/v79/f38/Pz7+/v6+vr5+fn4+Pj39/f29vb19fX09PTz8/Py8vLx8fHw8PDv7+/u7u7t7e3s7Ozr6+vq6urp6eno6Ojn5+fm5ubl5eX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjeV9AAAAcklEQVRIie3KSRKCQBAAsEFRARcQWVT+/0++kCr74KFzTtlI+ef2JcHtQ4LbmwS3lWhbiLaZBLeJaHsRbSPR9iTaBqKtJ9oepNyJthvRdiXaOqKtJdoaou1CgtuZaDsRbTUJbkcS3A4kuFUkW7Zs2X5pO8hWjs3oEtOqAAAAAElFTkSuQmCC) repeat-x;background-position: 0 15px;\n}\n\n#messageArea {background-color: #FBFBFB; color: #000; border:1px solid #DCDCDC}\n#messageArea a:link, #messageArea a:visited {color: #F90;}\n#messageArea a:hover {color: #FFF;background-color: #F90;}\n#messageArea a:active {color: #F90;}\n\n#mainMenu {border: 0px solid #555;text-align:left;background-color:#FBFBFB;padding-top:0px;color:#F90;font-size: 9pt;\n}\n\n#mainMenu .button {color: #F90;}\n#mainMenu .button:active {background-color: #FFF;color: #F90;}\n#mainMenu .button:hover {background-color: #E7920E;color: #FFF;}\n#mainMenu h1 { font-size:11pt;}\n#mainMenu h2 { font-size:10pt;}\n#mainMenu .tiddlyLink {text-align:left;color: #F90;}\n#mainMenu .tiddlyLink:hover {background-color: #F90;color: #fff;}\n#mainMenu .externalLink:hover {background-color: #F90;color: #fff; text-decoration: none}\n#mainMenu .externalLink{color: #F90;text-decoration: underline}\n\n #titleLine {color: #F90; background-color: #F9F9F0; padding: 5px;padding-top:15px;border-bottom:1px solid #EEE}\n#titleLine .tiddlyLink {color: #F90;}\n body {\n font: 13px/125% "Lucida Grande", "Trebuchet MS", "Bitstream Vera Sans", Verdana, Helvetica, sans-serif;\n }\n.editor textarea {height:300px;background-color:#F2F2F2;}\n.editor input {background-color:#DCDCDC;}\n.title {font-size: 10pt; font-weight: bold; background-color:transparent; color:#F90;display:inline;margin:0px;padding-left:0px;padding-right:30px;}\n.viewer h1,h2,h3,h4,h5,h6 {border-bottom:2px solid #EEE;background-color: transparent; color:#F90;text-align:left}\n.viewer{margin-left:-12px;margin-right:-12px;padding:5px;padding-top:12px;border: 0px;background-color:#transparent}\n.viewer table {border-collapse: collapse;border: 2px solid #303030;font-size: 11px;margin: 5px;}\n.viewer th {background: #DEDEDE;border: 1px solid #aaa;color:#000;padding: 3px;}\n.viewer td {border: 1px solid #aaa;padding: 3px;}\n.viewer caption {padding: 3px;}\n.viewer hr { border: none; border-top: dotted 1px #777; height: 1px; color: #777;margin: 7px 0;} \n.viewer pre {font-size: 8pt;border:1px solid #CBCBCB; margin:5px;padding: 2px;color:#123;background-color: #FBFBFB}\n.viewer code {background: #FBFBFB;color:#123;}\n.viewer input {border: 0px solid black;background-color:#F2F2F2; color:#F90;}\n.viewer .button {color: #F90;background-color: #FFF}\n.viewer .button:active {background-color: #FFF;color: #F90;}\n.viewer .button:hover {background-color: #F90;color: #FFF;}\n.viewer blockquote {background-color:#FBFBFB; border-left:2px solid #DCDCDC}\n.viewer a.tiddlyLink {text-align:left;color:#F90;}\n.viewer a.tiddlyLink:hover {background-color:#F90;color: #fff;}\n.viewer a.externalLink{color: #F90;background-color:transparent;text-decoration: underline}\n.viewer a.externalLink:hover {background-color: #F90;color: #fff; text-decoration: none}\n.viewer a.tabSelected {color: #000;font-weight: bold;background-color: #DCDCDC;position: relative;top: 0px;}\n.viewer a.tabUnselected {font-style:italic;color: #000;background-color: #EEE;top: -2px;}\n.viewer a.tabSelected:hover {color: #FFF;background-color: #D15E00;}\n.viewer a.tabUnselected:hover {color: #FFF;background-color: #D15E00;}\n.viewer .tabContents {color: #FF9900;background-color: #DCDCDC}\n.viewer .tabContents span {font-weight: bold;}\n.viewer .tabContents .tiddlyLink {color: #000;}\n.viewer .tabContents .tiddlyLink:hover {color: #FFF;background-color: #D15E00;}\n.viewer .tabContents .button {color: #FFF;background-color: #D15E00;}\n.viewer .tabContents .button:active {background-color: #FFF;color: #D15E00;}\n.viewer .tabContents .button:hover {background-color: #F90;color: #FFF;}\n.viewer .tabContents #popup {background-color: #D15E00; color: #FFF;border-right: 2px solid #BCBCBC; border-bottom: 2px solid #BCBCBC;}\n.viewer .tabContents #popup a {color: #FFF; background-color:transparent}\n.viewer .tabContents hr{color: #FFF;}\n.viewer .tabContents #popup a:hover {background-color: #F90;color: #FFF;}\n\n.sparkline {background-color: transparent;border: none;}\n.sparktick {background-color: #F90;outline: 0;}\n\n#sidebar {float: right; width: 16em;color: #000;font-size: 8pt;}\n#sidebar input { border: 0px solid black;background-color:#F2F2F2; color:#F90;}\n\n#sidebar a {color: #F90;}\n#sidebar a:active {background-color: #FFF;color: #F90;}\n#sidebar a:hover {background-color: #F90;color: #FFF;}\n\n#sidebarOptions {padding-top: 0.5em;background-color: #FBFBFB;color:#000;}\n#sidebarOptions .button {color: #F90;}\n#sidebarOptions .button:active {background-color: #FFF;color: #D15E00;}\n#sidebarOptions .button:hover {background-color: #F90;color: #FFF;}\n\n#sidebarOptions .sliderPanel {background-color:#DCDCDC; }\n#sidebarOptions .sliderPanel A {color: #D15E00;}\n#sidebarOptions .sliderPanel A:active {color: #FFF;background-color: #D15E00;}\n#sidebarOptions .sliderPanel A:hover {color: #FFF;background-color: #F90;}\n\n.sidebarSubHeading {font-size: 7pt;color: #FBFBFB;}\n\n#sidebarTabs ul { list-style: none; margin-left: 3px;}\n#sidebarTabs li { background-image: none;padding-left: 5px;}\n#sidebarTabs a {color: #D15E00;}\n#sidebarTabs a:hover {color: #FFF;background-color: #D15E00;}\n#sidebarTabs a:active {color: #000;background-color: #D15E00;}\n#sidebarTabs { background-color: transparent}\n#sidebarTabs .tabSelected {color: #000;font-weight: bold;background-color: #DCDCDC;position: relative;top: 0px;}\n#sidebarTabs .tabUnselected {font-style:italic;color: #000;background-color: #EEE;top: -2px;}\n#sidebarTabs .tabContents {color: #FF9900;background-color: #DCDCDC}\n#sidebarTabs .tabContents span {font-weight: bold;}\n#sidebarTabs .tabContents .tiddlyLink {color: #000;}\n#sidebarTabs .tabContents .tiddlyLink:hover {color: #FFF;background-color: #D15E00;}\n#sidebarTabs .txtMoreTab .tabSelected {color: #FFF;background-color: #F90;}\n#sidebarTabs .txtMoreTab .tabUnselected {font-weight: normal;font-style:italic;color: #FFF;background-color: #D15E00;}\n#sidebarTabs .txtMoreTab .tabContents { color: #000;background-color: #F90;}\n#sidebarTabs .txtMoreTab .tabContents .tiddlyLink {color: #FFF;}\n#sidebarTabs .tabContents .button {color: #FFF;}\n#sidebarTabs .tabContents .button:active {background-color: #FFF;color: #D15E00;}\n#sidebarTabs .tabContents .button:hover {background-color: #F90;color: #FFF;}\n#sidebarTabs .tabContents #popup {background-color: #D15E00; color: #FFF;border-right: 2px solid #BCBCBC; border-bottom: 2px solid #BCBCBC;}\n#sidebarTabs .tabContents #popup a {color: #FFF; background-color:transparent}\n#sidebarTabs .tabContents hr{color: #FFF;}\n#sidebarTabs .tabContents #popup a:hover {background-color: #F90;color: #FFF;}
Stylesheets included here are:\n<<listTags stylesheets title *>>
<<toolbarClose>><<toolbarCloseOthers>><<toolbarCollapse>><<toolbarEdit>><<toolbarPermalink>><<toolbarReferences>><<toolbarDecrypt>>
<<toolbarDone>><<toolbarCancel>><<toolbarDelete>><<toolbarDuplicate>><<toolbarEditDecrypt>><<toolbarEncrypt>>
<<tagCloud>>
<<calendar thismonth>>\n----\n[[Welcome to YATWA|Welcome to YATWA version 2]]\n[[Recent Changes]]\n[[Plugins]]\n[[StyleSheets]]\n[[What's next?]]\n[[Downloading]]\n[[How to Upgrade]]\n[[Usage]]\n\n<<newTiddler>>\n<<newJournal "DD MMM YYYY">>\n\n----\n<<tagCloud>>
// //''Name:'' ToolbarCreation plugin\n// //''Author:'' Alan Hechts\n\n// //''Please note that I am posting this tiddler for demo purposes only. I haven't fully released the code as I'm awaiting some upcoming changes to ~TiddlyWiki.''\n\n// //''This tiddler demonstrates how you can add, remove & rearrange toolbar buttons using a macro approach. This tiddler (the one you are reading now) is the only "required" addition to ~TiddlyWiki 1.2.28 to allow a customizable toolbar.''\n\n// //''By replacing the createTiddlerToolbar function in the hard code and creating new macros that emulate each toolbar button, you can now add or rearrange both the editing and viewing toolbars. Folks, it's just a matter of time before you can have one toolbar set for editors and one for web viewers!''\n\n// //''To create your own toolbars (you can even try it live on this website), simply edit the two new tiddlers, called EditorToolbar and ViewerToolbar (no special tags are necessary for either of these tiddlers). Then use the following macro references to add buttons in the order that you desire:''\n\n// //''Viewing toolbar:'' <<toolbarClose>> <<toolbarEdit>> <<toolbarCollapse>> <<toolbarCloseOthers>> <<toolbarPermalink>> <<toolbarReferences>> \n// //''Editing Toolbar:'' <<toolbarDone>> <<toolbarCancel>> <<toolbarSpellCheck>> <<toolbarDuplicate>> <<toolbarDelete>> <<toolbarEditHelp>>\n// //''Note: these buttons will not work properly from within tiddlers, they will only work when displayed in the toolbar area.''\n\n// // ''Code Section''\n\n// //''Macro Declarations'' (some repeated from the original code)\nconfig.macros.toolbarClose = {};\nconfig.macros.toolbarEdit = {};\nconfig.macros.toolbarPermalink = {};\nconfig.macros.toolbarReferences = {};\nconfig.macros.toolbarDone = {};\nconfig.macros.toolbarCancel = {};\nconfig.macros.toolbarDelete = {};\n\n// //''Steve's additions''\nconfig.macros.toolbarEncrypt = {};\nconfig.macros.toolbarDecrypt = {};\nconfig.macros.toolbarEditDecrypt = {};\n\n\n// //''Corresponding Macro functions''\nconfig.macros.toolbarClose.handler = function(place)\n{\n lingo = config.views.wikified;\n createTiddlyButton(place,lingo.toolbarClose.text,lingo.toolbarClose.tooltip,onClickToolbarClose,null,null,"toolbarClose");\n}\n\nconfig.macros.toolbarEdit.handler = function(place,macroName,params)\n{\n lingo = config.views.wikified;\n createTiddlyButton(place,lingo.toolbarEdit.text,lingo.toolbarEdit.tooltip,onClickToolbarEdit);\n}\n\nconfig.macros.toolbarPermalink.handler = function(place,macroName,params)\n{\n lingo = config.views.wikified;\n createTiddlyButton(place,lingo.toolbarPermalink.text,lingo.toolbarPermalink.tooltip,onClickToolbarPermaLink);\n}\n\nconfig.macros.toolbarReferences.handler = function(place,macroName,params)\n{\n lingo = config.views.wikified;\n createTiddlyButton(place,lingo.toolbarReferences.text,lingo.toolbarReferences.tooltip,onClickToolbarReferences);\n}\n\nconfig.macros.toolbarDone.handler = function(place,macroName,params)\n{\n lingo = config.views.editor;\n createTiddlyButton(place,lingo.toolbarDone.text,lingo.toolbarDone.tooltip,onClickToolbarSave);\n}\n\nconfig.macros.toolbarCancel.handler = function(place,macroName,params)\n{\n lingo = config.views.editor;\n createTiddlyButton(place,lingo.toolbarCancel.text,lingo.toolbarCancel.tooltip,onClickToolbarUndo);\n}\n\nconfig.macros.toolbarDelete.handler = function(place,macroName,params)\n{\n lingo = config.views.editor;\n createTiddlyButton(place,lingo.toolbarDelete.text,lingo.toolbarDelete.tooltip,onClickToolbarDelete);\n}\n\n// //(These shouldn't be here, but IE fails if they aren't there must be some kind of ordering problem)\nfunction onClickToolbarEncrypt(e)\n{\n if (!e) var e = window.event;\n if(encryptKey == "")\n encryptChangePassword();\n var title = this.parentNode.id.substr(7);\n var newBody = document.getElementById("editorBody" + title).value;\n newBody = encryptContents(newBody);\n document.getElementById("editorBody" + title).value = newBody;\n}\n\nfunction onClickToolbarEditDecrypt(e)\n{\n if (!e) var e = window.event;\n if(encryptKey == "")\n encryptChangePassword();\n var title = this.parentNode.id.substr(7);\n var newBody = document.getElementById("editorBody" + title).value;\n newBody = decryptContents(newBody);\n document.getElementById("editorBody" + title).value = newBody;\n}\n\nfunction onClickToolbarDecrypt(e)\n{\n if (!e) var e = window.event;\n if(encryptKey == "")\n encryptChangePassword();\n\n var title = this.parentNode.id.substr(7);\n var theBody = document.getElementById("body" + title);\n var theViewer = document.getElementById("viewer" + title);\n if(theViewer)\n theViewer.parentNode.removeChild(theViewer);\n var theViewer = createTiddlyElement(theBody,"div","viewer" + title,"viewer",null);\n\n var newText = store.getTiddlerText(title);\n newText = decryptContents(newText);\n wikify(newText,theViewer,false,false);\n}\n\nconfig.macros.toolbarEncrypt.handler = function(place,macroName,params)\n{\n lingo = config.views.editor;\n createTiddlyButton(place,lingo.toolbarEncrypt.text,lingo.toolbarEncrypt.tooltip,onClickToolbarEncrypt);\n}\n\nconfig.macros.toolbarEditDecrypt.handler = function(place,macroName,params)\n{\n lingo = config.views.editor;\n createTiddlyButton(place,lingo.toolbarDecrypt.text,lingo.toolbarDecrypt.tooltip,onClickToolbarEditDecrypt);\n}\n\nconfig.macros.toolbarDecrypt.handler = function(place,macroName,params)\n{\n lingo = config.views.wikified;\n createTiddlyButton(place,lingo.toolbarDecrypt.text,lingo.toolbarDecrypt.tooltip,onClickToolbarDecrypt);\n}\n\n// //''Replaced TW functions''\nwindow.createTiddlerToolbar = function createTiddlerToolbar(title,isEditor)\n{\n var theToolbar = document.getElementById("toolbar" + title);\n if(theToolbar)\n {\n removeChildren(theToolbar);\n if(isEditor)\n {\n // Editor toolbar\n wikify(store.getTiddlerText("EditorToolbar"),theToolbar,null,null);\n }\n else\n {\n // Viewer toolbar\n wikify(store.getTiddlerText("ViewerToolbar"),theToolbar,null,null);\n }\n }\n}\n\n// //''Shadowed tiddlers (in case they don't yet exist)''\nconfig.shadowTiddlers.ViewerToolbar = "<<toolbarClose>> <<toolbarEdit>> <<toolbarCollapse>> <<toolbarCloseOthers>> <<toolbarPermalink>> <<toolbarReferences>>";\nconfig.shadowTiddlers.EditorToolbar = "<<toolbarDone>> <<toolbarCancel>> <<toolbarSpellCheck>> <<toolbarDuplicate>> <<toolbarDelete>> <<toolbarEditHelp>>";\nconfig.shadowTiddlers.EditingHelp = "Click on each topic below to see formatting instructions and examples:\sn<<listTags formatting title *>>";\n\n// // Function to dynamically handle changes to the special toolbar tiddlers\nfunction refreshToolbars()\n{\n clearMessage();\n var place = document.getElementById("tiddlerDisplay");\n var tiddler = place.firstChild;\n var nextTiddler;\n while(tiddler)\n {\n nextTiddler = tiddler.nextSibling;\n if(tiddler.id)\n if(tiddler.id.substr(0,7) == "tiddler")\n {\n var title = tiddler.id.substr(7);\n createTiddlerToolbar(title,false)\n }\n tiddler = nextTiddler;\n }\n}\n\n// // Additional notifications for toolbar layout changes\nstore.addNotification("ViewerToolbar",function(){refreshToolbars()});\nstore.addNotification("EditorToolbar",function(){refreshToolbars()});\n\n\n
* Added Clint Checkett's tagCloud macro\n* Added Eric Shullman's SinglePageMode plugin\n* Corrected the attribution of the ToolbarCreation plugin\n* Tweaked the calendar plugin to include CSS styles for a calendar inside MainMenu\n* Included a MoveMessageArea" plugin to put the message are at the top right of the browser window, out of the way.
Moving the message area might have avoided the need for this. I'll re-evaluate this item in a while.\n
// //''Name:'' InsertSmiley\n// //''Version:'' <<getversion smiley>> (<<getversiondate smiley "DD MMM YYYY">>)\n// //''Author:'' AlanHecht\n// //''Type:'' [[Macro|Macros]]\n\n// //''Description:'' Inserts a small smiley graphic at the location of the macro and does not require any external graphics. The method used should work on most current browser platforms.\n\n// //''Syntax:'' << {{{smiley ;-)}}}>>\n// //Examples: <<smiley>> <<smiley :-(>> <<smiley ;-)>> <<smiley :-|>> <<smiley :-D>>\n\n// //''Directions:'' <<tiddler MacroDirections>>\n\n// //''Notes:'' A regular smiley <<smiley>> will be displayed if no smiley string is provided. Most smileys will work with or without the "nose" -- e.g. {{{;-)}}} is the same as {{{;)}}}\n\n// //''Revision History:''\n// // v0.1.0 (20 July 2005): initial release\n// // v0.1.1 (20 July 2005): << {{{smiley}}}>> with no parameter displays a standard smiley\n\n// //''Code section:''\nversion.extensions.smiley = {major: 0, minor: 1, revision: 1, date: new Date("Jul 20, 2005")};\nconfig.macros.smiley = {}\nconfig.macros.smiley.handler = function(place,macroName,params)\n{\n var palette = ["transparent","#000000","#1a1507","#352e18","#464646","#666666","#a3141e","#b06b63","#cc9900","#dd9030","#dddddd","#e89d00","#edc32a","#f3cb3c","#fdf201","#fdf526","#ff3149","#ffac00","#ffbf06","#ffc846","#ffcc66","#ffd758","#ffdd01","#ffea7b","#ffed55","#ffffff"];\n var data = params;\n var imageMap = null;\n if(!data[0] || data[0] == ":-)" || data[0] == ":)")\n imageMap = "aaaaabbbbbaaaaaaaabdtyyvtdbaaaaabnyxxxxxujbaaabmyyffyffuujbaadyyyeeyeetttdabppppddyddpmmlbbwoooooooowsrlbbwwpooooowwmrlbbwwboooowwwbllbbwwwboooowbrllbacwwwbbbbbrllcaablswwwwsrrlibaaablsssrrllibaaaaabcrrlllcbaaaaaaaabbbbbaaaaa";\n else if(data[0] == ":-(" || data[0] == ":(")\n imageMap = "aaaaabbbbbaaaaaaaabdtyyvtdbaaaaabnyxxxxxujbaaabmyyyyyyyuujbaadyyyeeyeetttdabppppddyddpmmlbbwoooooooowsrlbbwwpooooowwmrlbbwwoooooowwrllbbwwwwbbbbbsrllbacwwbwwwwsbllcaablswwwwsrrlibaaablsssrrllibaaaaabcrrlllcbaaaaaaaabbbbbaaaaa";\n else if(data[0] == ";-)" || data[0] == ";)")\n imageMap = "aaaaabbbbbaaaaaaaabdtyyvtdbaaaaabnyxxxxxujbaaabmyyxxxxxuujbaadyyyxxxeetttdabppphddyddpmmlbbwoooooooowsrlbbwwpooooowwmrlbbwwboooowwwbllbbwwwboooowbrllbacwwwbbbbbrllcaablswwwwsrrlibaaablsssrrllibaaaaabcrrlllcbaaaaaaaabbbbbaaaaa";\n else if(data[0] == ":-|" || data[0] == ":|")\n imageMap = "aaaaabbbbbaaaaaaaabdtyyvtdbaaaaabnyxxxxxujbaaabmyyffyffuujbaadyyyeeyeetttdabppppddyddpmmlbbwoooooooowsrlbbwwpooooowwmrlbbwwoooooowwrllbbwwwwbbbbbsrllbacwwwwwwwsrllcaablswwwwsrrlibaaablsssrrllibaaaaabcrrlllcbaaaaaaaabbbbbaaaaa";\n else if(data[0] == ":-D" || data[0] == ":D")\n imageMap = "aaaaabbbbbaaaaaaaabdtyyvtdbaaaaabnyxxxxxujbaaabmyyeeyeeuujbaadyyyeeyeetttdabppppyyyyypmmlbbwbbbbbbbbbbblbbwbkzzzzzzzkbwbbwbfzzzzzzzfbwbbwbkzzzzzzzkbwbacwbkzzzzzkblcaablsbkzzzkblibaaablsbbbbblibaaaaabcrrlllcbaaaaaaaabbbbbaaaaa";\n else\n createTiddlyElement(place,"span",null,"errorNoSuchMacro","unknown smiley");\n if(imageMap)\n {\n var box = createTiddlyElement(place,"span",null,"smiley",String.fromCharCode(160));\n box.style.position = "relative";\n box.style.width = "15px";\n box.style.height = "15px";\n box.style.marginLeft = "1px";\n box.style.marginRight = "1px";\n box.style.paddingRight = "12px";\n box.style.verticalAlign = "top";\n\n //now divide into 15x15 grid and create each pixel\n // rows\n for(r=0; r<15; r++)\n {\n // columns\n for(c=0; c<15; c++)\n {\n //create each pixel with the correct background\n var pix = document.createElement("img");\n pix.className = "smileyPixel";\n pix.style.position = "absolute";\n pix.border = 0;\n pix.style.top = r + "px";\n pix.style.left = c + "px";\n pix.style.width = "1px";\n pix.style.height = "1px";\n pix.style.backgroundColor = palette[imageMap.charCodeAt((r*15)+c)-97];\n pix.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";\n box.appendChild(pix);\n }\n }\n }\n}\n
* This at least needs the browsing capabilities of jscalendar.\n* Nicer formatting, especially when embedded in MainMenu\n* A better way of specifying holidays\n* A mechanism for specifying the first day of the week\n* Make days with existing tiddlers more visible\n* Add the ability to create tiddlers for week numbers\n* Integrate with the reminder plugin
// //''Name:'' Collapse plugin\n// //''Author:'' Alan Hechts\n\n// // __Macro for the toolbar button__ \nconfig.views.wikified.toolbarCollapse = {text: "collapse", tooltip: "Collapse this tiddler", toggleText: "expand", toggleTooltip: "Expand this tiddler"};\n\nconfig.macros.toolbarCollapse = {};\n\nconfig.macros.toolbarCollapse.handler = function(place,macroName,params)\n{\n lingo = config.views.wikified;\n createTiddlyButton(place,lingo.toolbarCollapse.text,lingo.toolbarCollapse.tooltip,onClickToolbarCollapse);\n}\n\n// //__Event handler on toolbar button press__\nfunction onClickToolbarCollapse(e)\n{\n if (!e) var e = window.event;\n title = this.parentNode.id.substr(7);\n if(title)\n {\n var viewerStatus = document.getElementById("viewer" + title).style.display\n var displayStyle;\n var buttonText;\n var buttonTooltip;\n var lingo = config.views\n lingo = lingo.wikified;\n if(viewerStatus == "none")\n {\n displayStyle = "block";\n buttonText = lingo.toolbarCollapse.text;\n buttonTooltip = lingo.toolbarCollapse.tooltip;\n }\n else\n {\n displayStyle = "none";\n buttonText = lingo.toolbarCollapse.toggleText;\n buttonTooltip = lingo.toolbarCollapse.toggleTooltip;\n }\n document.getElementById("viewer" + title).style.display = displayStyle; \n document.getElementById("footer" + title).style.display = displayStyle; \n this.innerHTML = buttonText;\n this.title = buttonTooltip;\n }\n}\n
// //''Name:'' Duplicate plugin\n// //''Author:'' Alan Hechts\n\nconfig.views.editor.toolbarDuplicate = {text: "duplicate", tooltip: "Duplicate this tiddler", suffix: "Copy"};\n\nconfig.macros.toolbarDuplicate = {};\n\nconfig.macros.toolbarDuplicate.handler = function(place,macroName,params)\n{\n lingo = config.views.editor;\n createTiddlyButton(place,lingo.toolbarDuplicate.text,lingo.toolbarDuplicate.tooltip,onClickToolbarDuplicate);\n}\n\nfunction onClickToolbarDuplicate()\n{\n clearMessage();\n var lingo = config.views\n lingo = lingo.editor;\n var thisSrc = document.getElementById(this.parentNode.id);\n var thisTiddler = this.parentNode.id.substr(7);\n var dupTitle = thisTiddler + lingo.toolbarDuplicate.suffix;\n var dupBody = document.getElementById("editorBody" + thisTiddler).value;\n var dupTags = document.getElementById("editorTags" + thisTiddler).value;\n displayTiddler(thisSrc,dupTitle,2,null,null,false);\n document.getElementById("editorBody" + dupTitle).value = dupBody;\n document.getElementById("editorTags" + dupTitle).value = dupTags;\n // If you want the original tiddler to close completely after you click 'duplicate,' then remove the slashes at the start of the next line\n //closeTiddler(thisTiddler,false);\n}\n
Jeremy Ruston is a technologist based in London. He does consultancy work through my company [[Osmosoft|http://www.osmosoft.com]], as well as pursuing some independent projects like TiddlyWiki. He can be reached at {{{jeremy (at) osmosoft (dot) com}}}, and he regularly reads and replies to messages on the TiddlyWiki GoogleGroups.
A TiddlyWiki is like a blog because it's divided up into neat little chunks, but it encourages you to read it by hyperlinking rather than sequentially: if you like, a non-linear blog analogue that binds the individual microcontent items into a cohesive whole. I think that TiddlyWiki represents a novel medium for writing, and will promote its own distinctive WritingStyle. This is the ThirdVersion of TiddlyWiki, which adds several NewFeatures. There are also several TiddlyWikiAdaptations by other developers based on earlier versions.\n\nTiddlyWiki is being developed by JeremyRushton, and can be found here: http://www.tiddlywiki.com.
// //''Name:'' FAQ List\n// //''Version:'' <<getversion faqlist>> (<<getversiondate faqlist "DD MMM YYYY">>)\n// //''Author:'' AlanHecht\n// //''Type:'' [[Macro|Macros]]\n\n// //''Description:'' FAQ List lets you compile a list of Frequently Asked Questions and present them in a cascading style for the viewer. Each question is turned into a link that will toggle the view of the answer text. The list can be compiled either from all tiddlers containing a certain tag or from a single tiddler that contains all the needed questions and answers.\n\n// //''Syntax:'' << {{{ faqlist mode source sortBy hrSeparator }}} >>\n// // ''faqlist:'' the macro call (required)\n// // ''mode:'' either "byTag" or "byTitle" (required)\n// // ''source:'' the associated tag or tiddler title (required)\n// // ''sortBy:'' if byTag, sort can be "title," "modifier," "modified." If byTitle, sort can be "question" and will reorder the questions in alphabetical order. (this parameter is optional; use "null" if you don't want a sort order, but want to use "hr" as the last paramter)\n// // ''hrSeparator:'' if "hr" is included at the end of the call string, each question/answer set will be separated by a horizontal rule.\n// //Examples: (edit these two tiddlers to see the syntax used for each)\n// // • [[FAQ Method One]]\n// // • [[FAQ Method Two]]\n\n// //''Directions:'' <<tiddler StartupBehaviorDirections>> <<tiddler MacroDirections>>\n\n// //''Notes:'' If you choose to use byTitle mode where the entire set of questions/answers comes from a single tiddler, the syntax for the tiddler content is as follows:\n// // • Each question must be a single line (i.e. no hard returns) but can wrap as needed\n// // • The answer to a question begins on the next line after the question and can be as long as needed. It can also include hard returns as part of the answer text, but it cannot include empty lines (i.e. an empty line is the result of pressing enter twice).\n// // • Each question/answer set must be seperated by two hard returns (i.e. must have a single, blank line between them.\n// // Refer to [[FAQ Tiddler Sample]] for an example.\n\n// //''Known Issues:'' If a user clicks too quickly to toggle a FAQ entry on/off, they will go into tiddler edit mode. This should be corrected in the future by allowing web-hosted versions of the faq to disable double-clicking.\n\n// //''Revision History:''\n// // v0.1.0 (01 August 2005): initial release\n\n// //''Code section:''\nversion.extensions.faqlist = {major: 0, minor: 1, revision: 0, date: new Date(2005,07,01)};\nconfig.macros.faqlist = {\n bulletCollapse: ">",\n bulletExpand: "∨",\n expandButton: {title: "Expand All", tooltip: "Open all items for reading"},\n collapseButton: {title: "Collapse All", tooltip: "Close all items"}\n};\nconfig.macros.faqlist.handler = function(place,macroName,params)\n{\n lingo = config.macros.faqlist;\n var mode = params[0].toLowerCase();\n var list = [];\n switch(mode)\n {\n case "bytag":\n var tagged = store.getTaggedTiddlers(params[1], params[2]);\n for(t=0; t<tagged.length; t++)\n {\n var title = tagged[t].title;\n list[t] = [title,store.getTiddlerText(title)];\n }\n var subTitle = store.tiddlers[title].getSubtitle();\n break;\n case "bytitle":\n var faqText = store.getTiddlerText(params[1]);\n var faqItems = faqText.split("\sn\sn");\n if(params[2] == "question")\n faqItems.sort();\n for(t=0; t<faqItems.length; t++)\n {\n list[t] = [faqItems[t].substring(0,faqItems[t].indexOf("\sn")),faqItems[t].substring(faqItems[t].indexOf("\sn")+1)];\n }\n var subTitle = null;\n break;\n }\n \n var faqHeading = place.appendChild(document.createElement("span"));\n faqHeading.appendChild(createTiddlyButton(faqHeading,lingo.expandButton.title,lingo.expandButton.tooltip,faqExpandAll));\n faqHeading.appendChild(createTiddlyButton(faqHeading,lingo.collapseButton.title,lingo.collapseButton.tooltip,faqCollapseAll));\n faqHeading.appendChild(document.createElement("p"));\n var faqBody = place.appendChild(document.createElement("span"));\n for(t=0; t<list.length; t++)\n {\n var title = list[t][0];\n\n var content = "<<<\sn" + list[t][1] + "\sn<<<";\n var theClass = "tiddlyLinkExisting tiddlyLink";\n var itemHeading = faqBody.appendChild(document.createElement("span"));\n itemHeading.appendChild(document.createTextNode(config.macros.faqlist.bulletCollapse + " "));\n createTiddlyButton(itemHeading,title,subTitle,faqToggleThis,theClass);\n var itemBody = faqBody.appendChild(document.createElement("span"));\n itemBody.style.display = "none";\n itemBody.className = "itemBody";\n wikify(content,itemBody,null,null);\n faqBody.appendChild(itemBody);\n faqBody.appendChild(document.createElement("p"));\n if(params[3] == "hr")\n faqBody.appendChild(document.createElement("hr"));\n }\n}\n\nfunction faqToggleThis(e)\n{\n var content = this.parentNode.nextSibling;\n var shown = content.style.display;\n if(shown == "none")\n {\n content.style.display = "inline";\n this.previousSibling.nodeValue = config.macros.faqlist.bulletExpand + " ";\n }\n else\n {\n content.style.display = "none";\n this.previousSibling.nodeValue = config.macros.faqlist.bulletCollapse + " ";\n }\n}\n\nfunction faqExpandAll()\n{\n for(t=0; t<this.parentNode.nextSibling.childNodes.length; t++)\n {\n item = this.parentNode.nextSibling.childNodes[t];\n if(item.className == "itemBody")\n {\n item.style.display = "inline";\n item.previousSibling.childNodes[0].nodeValue = config.macros.faqlist.bulletExpand + " ";\n }\n }\n}\n\nfunction faqCollapseAll()\n{\n for(t=0; t<this.parentNode.nextSibling.childNodes.length; t++)\n {\n item = this.parentNode.nextSibling.childNodes[t];\n if(item.className == "itemBody")\n {\n item.style.display = "none";\n item.previousSibling.childNodes[0].nodeValue = config.macros.faqlist.bulletCollapse + " ";\n }\n }\n}\n
// //''Name:'' Calendar plugin\n// //''Version:'' <<getversion closeOthers>> (<<getversiondate closeOthers "DD MMM YYYY">>)\n// //''Author:'' SteveRumsby\n// //''Requires:'' ToolbarCreationPlugin\n\n// //''Description:'' Works with the ToolbarCreationPlugin to add a "close others" button to the tiddler toolbar. When clicked, this button will close any other open tiddlers, unless they are being edited. To use, put the macro << {{{toolbarCloseOthers}}} >> at an appropriate place in the ViewerToolbar and/or EditorToolbar tiddlers.\n\n// //''Code section:''\nversion.extensions.closeOthers = { major: 1, minor: 0, revision: 0, date: new Date(2005, 07, 16)};\n\nconfig.macros.toolbarCloseOthers = {};\nconfig.views.wikified["toolbarCloseOthers"] = { text: "close others", tooltip: "Close other tiddlers"};\n\nconfig.macros.toolbarCloseOthers = {};\nconfig.macros.toolbarCloseOthers.handler = function(place,macroName,params)\n{\n lingo = config.views.wikified;\n createTiddlyButton(place,lingo.toolbarCloseOthers.text,lingo.toolbarCloseOthers.tooltip,onClickToolbarCloseOthers);\n}\n\n// //__Event handler for clicking on toolbar close others button__\nfunction onClickToolbarCloseOthers(e)\n{\n if (!e) var e = window.event;\n clearMessage();\n if(this.parentNode.id)\n closeAllBut(this.parentNode.id.substr(7));\n}\n\nfunction closeAllBut(keeptitle)\n{\n clearMessage();\n var place = document.getElementById("tiddlerDisplay");\n var tiddler = place.firstChild;\n var nextTiddler;\n while(tiddler)\n {\n nextTiddler = tiddler.nextSibling;\n if(tiddler.id)\n if(tiddler.id.substr(0,7) == "tiddler")\n {\n var title = tiddler.id.substr(7);\n if(title != keeptitle && !document.getElementById("editor" + title))\n place.removeChild(tiddler);\n }\n tiddler = nextTiddler;\n }\n}\n
// Eric Shulman - ELS Design Studios\n// SelectStylesheet Plug-in for TiddlyWiki version 1.2.31 or above\nversion.extensions.selectStylesheet = {major: 3, minor: 0, revision: 0, date: new Date(2005,7,14)};\n\n// set to FALSE to disable status message output when stylesheets are applied\nvar verbose=false;\n\n// IE needs explicit global scoping for functions/vars called from browser events\nwindow.onChangeSelectStylesheet=onChangeSelectStylesheet;\nwindow.refreshSelectStylesheet=refreshSelectStylesheet;\nwindow.applyStylesheets=applyStylesheets;\n\n// remove default built-in named notification for "StyleSheet"\nstore.namedNotifications["StyleSheet"]=null;\n\n// hijack refreshStyles handler\nwindow.refreshStyles=applyStylesheets;\n\n// load stylesheets+overlays and set up named notifications\napplyStylesheets();\n\n// define macro rendering handler\nconfig.macros.selectStylesheet = { };\nconfig.macros.selectStylesheet.handler = function(place,macroName,params) {\n setStylesheet(".selectStylesheet {width:100%;font-size:8pt;margin:0em}","selectStylesheetPlugin");\n var theList=createTiddlyElement(place,"select",null,"selectStylesheet",null);\n theList.onchange=onChangeSelectStylesheet;\n theList.size=1;\n theList.autosize=1;\n theList.overlaysOnly=false;\n if (params[0] && (params[0]=="overlays")) { theList.overlaysOnly=true; params.shift(); }\n if (params[0] && (params[0]=="size:auto")) { theList.autosize=0; params.shift(); }\n if (params[0] && (params[0].substr(0,5)=="size:")) theList.autosize=(params.shift()).substr(5);\n if (params[0] && (params[0].substr(0,6)=="width:")) theList.style.width=(params.shift()).substr(6);\n theList.extraStyles=params;\n if (!store.blanketNotifications.find(refreshSelectStylesheet))\n store.addNotification(null,refreshSelectStylesheet);\n refreshSelectStylesheet();\n}\n\nfunction onChangeSelectStylesheet()\n{\n if (this.value!="")\n {\n var theExtraCookie="txtStyleSheet";\n if (this.options[this.selectedIndex].extra)\n theExtraCookie+=this.options[this.selectedIndex].extra;\n var theExtraSheet=((this.value=="[default]")?"":this.value);\n config.options[theExtraCookie]=theExtraSheet;\n saveOptionCookie(theExtraCookie);\n applyStylesheets();\n }\n // if selection is a stylesheet, top heading or overlay heading, update the list display\n if ((this.value!="")||(this.selectedIndex==0)||this.options[this.selectedIndex].extra)\n refreshSelectStylesheet();\n return;\n}\n\nfunction getElementsByClass(classname)\n{\n var arr=new Array();\n var count=0;\n var all=document.all? document.all : document.getElementsByTagName("*");\n for (i=0; i<all.length; i++)\n if (all[i].className==classname)\n arr[count++]=all[i];\n return arr;\n}\n\nfunction refreshSelectStylesheet()\n{\n var sp=String.fromCharCode(160);\n // for all instances of the selectStylesheet control\n var allStyleLists=getElementsByClass("selectStylesheet");\n for (var k=0; k<allStyleLists.length; k++)\n {\n var theList=allStyleLists[k];\n // save current selection\n var theSelected = theList.options[0];\n if (theList.selectedIndex!=-1) theSelected = theList.options[theList.selectedIndex];\n // clear current list contents\n while (theList.length > 0) { theList.options[0] = null; }\n theList.selectedIndex=-1;\n // fill the stylesheet list\n var count=0;\n if (!theList.overlaysOnly)\n {\n // prompt text\n theList.options[count++] =\n new Option("select a stylesheet:","",false,false);\n // option: built-in CSS (no custom stylesheet)\n var prefix = (config.options.txtStyleSheet=="[none]")?">":(sp+sp);\n theList.options[count++] = new Option(prefix+sp+"[none]","[none]",false,false);\n // option: default "StyleSheet" CSS tiddler (if any)\n if (store.tiddlers["StyleSheet"]!=undefined)\n {\n var prefix = (config.options.txtStyleSheet=="StyleSheet")?">":(sp+sp);\n theList.options[count++] = new Option(prefix+sp+"[default]","StyleSheet",false,false);\n }\n // options: CSS tiddlers tagged with "stylesheets" (excluding default "StyleSheet" tiddler)\n var theSheets=store.getTaggedTiddlers("stylesheets");\n for (var i=0; i<theSheets.length; i++)\n {\n var theTitle=theSheets[i].title;\n if (theTitle=="StyleSheet") continue;\n prefix = (theTitle==config.options.txtStyleSheet)?">":(sp+sp);\n theList.options[count] = new Option(prefix+sp+theTitle,theTitle,false,false);\n theList.options[count++].extra = theList.extraStyles[t];\n }\n }\n // optional "overlay" stylesheets (grouped by tag name)\n theList.extraIndex=count; // list index where extra styles begin\n if (theList.extraStyles.length>1)\n theList.options[count++] =\n new Option("overlay extra stylesheets:","",false,false);\n for (var t=0; t<theList.extraStyles.length; t++)\n {\n var theExtraSheet=config.options["txtStyleSheet"+theList.extraStyles[t]];\n var showSection=(theSelected && (theSelected.extra==theList.extraStyles[t]));\n showSection |= (theList.overlaysOnly && (theList.extraStyles.length==1));\n // section heading ("+ tagname: sheetname")\n var theHeading="+ "+theList.extraStyles[t];\n if (theExtraSheet && (theExtraSheet!="") && (!showSection))\n theHeading=theHeading+": "+theExtraSheet;\n theList.options[count] = new Option(theHeading,"",false,false);\n theList.options[count++].extra = theList.extraStyles[t];\n // only show overlay stylesheet choices if this branch is selected\n if (showSection)\n {\n // option: use default CSS (disable overlay - displayed only when an overlay is in use)\n if (theExtraSheet && (theExtraSheet!=""))\n {\n theList.options[count] = new Option(sp+sp+sp+"[default]","[default]",false,false);\n theList.options[count++].extra = theList.extraStyles[t];\n }\n // options: CSS tiddlers tagged with this 'extra style' tag\n var theSheets=store.getTaggedTiddlers(theList.extraStyles[t]);\n for (var i=0; i<theSheets.length; i++)\n {\n var theTitle=theSheets[i].title;\n prefix = (theTitle==theExtraSheet)?">":(sp+sp);\n theList.options[count] = new Option(prefix+sp+theTitle,theTitle,false,false);\n theList.options[count++].extra = theList.extraStyles[t];\n }\n }\n }\n // set the listbox selection\n theList.selectedIndex=-1; // start with nothing selected\n if (theSelected) // then restore the previous selection (if any)\n {\n if (theSelected.extra && ((theSelected.value=="")||(theSelected.value=="[default]")))\n { // overlay header or [default], select section heading by matching extra\n for (var t=0; t<theList.length; t++)\n if (theList.options[t].extra==theSelected.extra)\n { theList.selectedIndex=t; break; }\n }\n else if (theSelected.value!="") // non-heading... restore by matching value\n theList.value = theSelected.value;\n }\n if (theList.selectedIndex==-1) // if no selection, default to current stylesheet in use\n for (var t=0; t<theList.extraIndex; t++) \n if (theList.options[t].text.substr(0,1)==">")\n { theList.selectedIndex=t; break; }\n if (theList.selectedIndex==-1) // if still no selection, default to first item\n theList.selectedIndex=0;\n theList.size=(theList.autosize<1)?theList.options.length:theList.autosize; // autosize as appropriate\n } // end of "for all instances"\n}\n\nfunction applyStylesheets()\n{\n // define pattern to match executable <<tiddlername>> references embedded in CSS text\n var codeTiddlerRegExp = new RegExp("(?:<<([^>]+)>>)","mg");\n\n // first, make sure the requested stylesheet exists, fallback if not...\n var theSheet=config.options.txtStyleSheet;\n if (theSheet==undefined)\n theSheet="StyleSheet";\n if ((theSheet!="[none]") && (store.tiddlers[theSheet]==undefined))\n theSheet="StyleSheet"\n if (store.tiddlers[theSheet]==undefined)\n theSheet='[none]';\n config.options.txtStyleSheet=theSheet;\n\n // then, assemble the CSS from primary plus overlay stylesheets \n var theCSS = "";\n // get the primary stylesheet CSS\n var msg="primary stylesheet: '%0'";\n if (verbose) { clearMessage(); displayMessage(msg.format([theSheet])); }\n var theNotify = store.namedNotifications[theSheet];\n theCSS += (theSheet=='[none]')?"":store.getRecursiveTiddlerText(theSheet,"");\n if (theSheet!='[none]')\n // add notification for stylesheet changes (only if notify not already set)\n if (!theNotify || (theNotify.find(refreshStyles)==null))\n store.addNotification(theSheet,refreshStyles);\n // get the overlay CSS stylesheets (all config.options[] starting with 'txtStyleSheet' )\n for (var t in config.options) if ((t.substr(0,13)=="txtStyleSheet") && (t.substr(13)!=""))\n {\n var msg="overlay stylesheet: %0='%1'";\n if (verbose && (config.options[t]!=""))\n displayMessage(msg.format([t.substr(13),config.options[t]]));\n var theExtraSheet = config.options[t];\n var theNotify = store.namedNotifications[theExtraSheet];\n theCSS += store.getRecursiveTiddlerText(theExtraSheet,"");\n if (theExtraSheet && (theExtraSheet!=""))\n // add notification for stylesheet changes (only if notify not already set)\n if (!theNotify || (theNotify.find(refreshStyles)==null))\n store.addNotification(theExtraSheet,refreshStyles);\n }\n\n // next, execute any embedded <<tiddlername>> references\n do {\n var match = codeTiddlerRegExp.exec(theCSS);\n if(match && match[1])\n {\n var msg="stylesheet macro: '%0'";\n if (verbose) displayMessage(msg.format([match[1]]));\n var msg="error in '%0': %1";\n try { window.eval(store.getTiddlerText(match[1])); }\n catch(e) { displayMessage(msg.format([match[1],e.toString()])); }\n }\n } while(match);\n\n // finally, apply the styles, filtering out any embedded tiddler references\n setStylesheet(theCSS.replace(codeTiddlerRegExp,""));\n}\n
// Eric Shulman - ELS Design Studios\n// Import Tiddlers Plug-in for TiddlyWiki version 1.2.25 or above\n\n// define macro "importTiddlers" to render controls\nversion.extensions.importTiddlers = {major: 1, minor: 0, revision: 2, date: new Date(2005,6,27)};\nconfig.macros.importTiddlers = {\n label: "import tiddlers", prompt: "Copy selected tiddlers from another document"\n};\n\nconfig.macros.importTiddlers.css = '\s\n#importPanel {\s\n display: none;\s\n background-color: #eeeeaa;\s\n position:absolute; z-index:11; width:25em; left:-28em; top:3em;\s\n padding: 0.5em; margin:0em;\s\n border:1px solid black; border-bottom-width: 3px; border-right-width: 3px;\s\n font-size: 7pt;\s\n}\s\n#importPanel input { width: 100%; margin: 1px; font-size:8pt; }\s\n#importPanel select { width: 100%; margin: 1px; font-size:8pt; }\s\n#importPanel .importButton { padding: 0em; margin: 0px; font-size:8pt; }\s\n#importPanel .importListButton { padding:0em 0.25em 0em 0.25em; color: #000000; }\s\n#importAskPanel { display:none; margin:0.5em 0em 0em 0em; }\s\n';\n\nconfig.macros.importTiddlers.html = '\s\n<div id="importPanel">\s\nimport from source document:\s\n<input type="file" id="fileImportSource" size=31\s\n onKeyUp="window.importSource=this.value"\s\n onChange="window.importSource=this.value; onClickImportButton(this)">\s\n<span style="float:left; padding:1px; white-space:nowrap">\s\n <input type=checkbox id="chkImportDiffsOnly" checked style="height:1em; width:auto"\s\n onClick="window.importDiffsOnly=this.checked; refreshImportList();">show differences only\s\n</span>\s\n<span style="float:right; padding:1px; white-space:nowrap">\s\n <a href="JavaScript:;" id="importSmaller" class="importListButton"\s\n onclick="onClickImportButton(this)" title="reduce list size">–</a>\s\n <a href="JavaScript:;" id="importLarger" class="importListButton"\s\n onclick="onClickImportButton(this)" title="increase list size">+</a>\s\n <a href="JavaScript:;" id="importMaximize" class="importListButton"\s\n onclick="onClickImportButton(this)" title="maximize/restore list size">=</a>\s\n</span>\s\n<select id="importList" size=1 multiple\s\n onchange="setTimeout(\s'refreshImportList(\s'+this.selectedIndex+\s')\s',1)">\s\n <!-- NOTE: delay refresh so list is updated AFTER onchange event is handled -->\s\n</select>\s\nadd tags:\s\n<input type=text id="txtImportTags" size=15 onKeyUp="window.importTags=this.value" autocomplete=off>\s\n<div align=center>\s\n <input type=button id="importOpen" class="importButton" style="width:23%" value="open"\s\n onclick="onClickImportButton(this)">\s\n <input type=button id="importSelectAll" class="importButton" style="width:23%" value="select all"\s\n onclick="onClickImportButton(this)">\s\n <input type=button id="importStart" class="importButton" style="width:23%" value="import"\s\n onclick="onClickImportButton(this)">\s\n <input type=button id="importClose" class="importButton" style="width:23%" value="close"\s\n onclick="onClickImportButton(this)">\s\n</div>\s\n<div id="importAskPanel">\s\n tiddler already exists:\s\n <input type=text id="importNewTitle" size=15 autocomplete=off">\s\n <div align=center>\s\n <input type=button id="importSkip" class="importButton" style="width:23%" value="skip"\s\n onclick="onClickImportButton(this)">\s\n <input type=button id="importRename" class="importButton" style="width:23%" value="rename"\s\n onclick="onClickImportButton(this)">\s\n <input type=button id="importMerge" class="importButton" style="width:23%" value="merge"\s\n onclick="onClickImportButton(this)">\s\n <input type=button id="importReplace" class="importButton" style="width:23%" value="replace"\s\n onclick="onClickImportButton(this)">\s\n </div>\s\n</div>\s\n</div>\s\n<!-- hidden frame for remote page load -->\s\n<span style="position:absolute; display:none;">\s\n<iframe name="importFrame" id="importFrame" src="" height=0 width=0></iframe>\s\n</span>\s\n';\n\nconfig.macros.importTiddlers.handler = function(place,macroName,params) {\n createTiddlyButton(place,this.label,this.prompt,onClickImportMenu);\n setStylesheet(config.macros.importTiddlers.css,"importTiddlers");\n var newspan=createTiddlyElement(place,"span",null,null,null)\n newspan.innerHTML=config.macros.importTiddlers.html;\n store.addNotification(null,refreshImportList); // refresh listbox after every tiddler change\n}\n\n// IE needs explicit global scoping for functions/vars called from browser events\nwindow.refreshImportList=refreshImportList;\nwindow.onClickImportButton=onClickImportButton;\nwindow.getImportedTiddlers=getImportedTiddlers;\nwindow.importSource=""; // path/filename or URL of document to import\nwindow.importedTiddlers; // hash-indexed array of tiddlers from other document\nwindow.importTags=""; // text of tags added to imported tiddlers\n\nwindow.importListSize=10; // # of lines to show in imported tiddler list\nwindow.importDiffsOnly=true; // show differences option (toggle)\nwindow.importIndex=0; // current processing index in import list\n\n// Import menu item (show/hide import panel)\nfunction onClickImportMenu(e)\n{\n if (!e) var e = window.event;\n var thePanel = document.getElementById("importPanel");\n if (thePanel==undefined) return;\n var isOpen = thePanel.style.display=="block";\n if(config.options.chkAnimate)\n anim.startAnimating(new Slider(thePanel,!isOpen,e.shiftKey || e.altKey,"none"));\n else\n thePanel.style.display = isOpen ? "none" : "block" ;\n e.cancelBubble = true;\n if (e.stopPropagation) e.stopPropagation();\n return(false);\n}\n\nfunction onClickImportButton(which)\n{\n // DEBUG alert(which.id);\n var theList = document.getElementById('importList');\n if (!theList) return;\n var thePanel = document.getElementById('importPanel');\n var theAskPanel = document.getElementById('importAskPanel');\n var theNewTitle = document.getElementById('importNewTitle');\n switch (which.id)\n {\n case 'fileImportSource':\n case 'importOpen': // load import source into hidden frame\n importReport(); // if an import was in progress, generate a report\n window.importedTiddlers=null; // clear the imported tiddler buffer\n refreshImportList(); // reset/resize the listbox\n if (window.importSource=="") break;\n try\n {\n // Load document into hidden iframe so we can read it's DOM\n // set timeout for 1 second and return to browser processing, so it has\n // some time to finish loading the document before we try to read the storeArea\n var url=window.importSource;\n if (url.charAt(1)==":") url="file://"+url; // fixup pc local filename\n window.frames['importFrame'].location.href=url;\n setTimeout('getImportedTiddlers()',1000);\n }\n catch(e)\n {\n clearMessage();\n displayMessage("Error opening "+window.importSource+": " + ((e.message)?e.message:e));\n }\n break;\n case 'importSelectAll': // select all tiddler list items (i.e., not headings)\n importReport(); // if an import was in progress, generate a report\n for (var t = 0; t < theList.options.length; t++)\n theList.options[t].selected=(theList.options[t].value!="");\n break;\n case 'importStart': // initiate the import processing\n importReport(); // if an import was in progress, generate a report\n window.importIndex=0;\n window.importIndex=importTiddlers(0);\n importStopped();\n break;\n case 'importClose': // unload imported tiddlers or hide the import control panel\n // if imported tiddlers not loaded, close the import control panel\n if (!window.importedTiddlers) { thePanel.style.display='none'; break; }\n importReport(); // if an import was in progress, generate a report\n window.importedTiddlers=null; // clear the imported tiddler buffer\n refreshImportList(); // reset/resize the listbox\n break;\n case 'importSkip': // don't import the tiddler\n var theItem = theList.options[window.importIndex];\n for (var j=0;j<window.importedTiddlers.length;j++)\n if (window.importedTiddlers[j].title==theItem.value) break;\n var theImported = window.importedTiddlers[j];\n theImported.status='skipped after asking'; // mark item as skipped\n theAskPanel.style.display='none';\n window.importIndex=importTiddlers(window.importIndex+1); // resume with NEXT item\n importStopped();\n break;\n case 'importRename': // change name of imported tiddler\n var theItem = theList.options[window.importIndex];\n for (var j=0;j<window.importedTiddlers.length;j++)\n if (window.importedTiddlers[j].title==theItem.value) break;\n var theImported = window.importedTiddlers[j];\n theImported.status = 'renamed from '+theImported.title; // mark item as renamed\n theImported.set(theNewTitle.value,null,null,null,null); // change the tiddler title\n theItem.value = theNewTitle.value; // change the listbox item text\n theItem.text = theNewTitle.value; // change the listbox item text\n theAskPanel.style.display='none';\n window.importIndex=importTiddlers(window.importIndex); // resume with THIS item\n importStopped();\n break;\n case 'importMerge': // join existing and imported tiddler content\n var theItem = theList.options[window.importIndex];\n for (var j=0;j<window.importedTiddlers.length;j++)\n if (window.importedTiddlers[j].title==theItem.value) break;\n var theImported = window.importedTiddlers[j];\n var theExisting = store.tiddlers[theItem.value];\n var theText = theExisting.text+'\sn----\sn^^merged from: [['+window.importSource+'#'+theItem.value+'|'+window.importSource+'#'+theItem.value+']]^^\sn^^'+theImported.modified.toLocaleString()+' by '+theImported.modifier+'^^\sn'+theImported.text;\n var theDate = new Date();\n var theTags = theExisting.getTags()+' '+theImported.getTags();\n theImported.set(null,theText,null,theDate,theTags);\n theImported.status = 'merged with '+theExisting.title; // mark item as merged\n theImported.status += ' - '+theExisting.modified.formatString("MM/DD/YYYY hh:mm:ss");\n theImported.status += ' by '+theExisting.modifier;\n theAskPanel.style.display='none';\n window.importIndex=importTiddlers(window.importIndex); // resume with this item\n importStopped();\n break;\n case 'importReplace': // substitute imported tiddler for existing tiddler\n var theItem = theList.options[window.importIndex];\n for (var j=0;j<window.importedTiddlers.length;j++)\n if (window.importedTiddlers[j].title==theItem.value) break;\n var theImported = window.importedTiddlers[j];\n var theExisting = store.tiddlers[theItem.value];\n theImported.status = 'replaces '+theExisting.title; // mark item for replace\n theImported.status += ' - '+theExisting.modified.formatString("MM/DD/YYYY hh:mm:ss");\n theImported.status += ' by '+theExisting.modifier;\n theAskPanel.style.display='none';\n window.importIndex=importTiddlers(window.importIndex); // resume with THIS item\n importStopped();\n break;\n case 'importSmaller': // decrease current listbox size, minimum=5\n if (theList.options.length==1) break;\n theList.size-=(theList.size>5)?1:0;\n window.importListSize=theList.size;\n break;\n case 'importLarger': // increase current listbox size, maximum=number of items in list\n if (theList.options.length==1) break;\n theList.size+=(theList.size<theList.options.length)?1:0;\n window.importListSize=theList.size;\n break;\n case 'importMaximize': // toggle listbox size between current and maximum\n if (theList.options.length==1) break;\n theList.size=(theList.size==theList.options.length)?window.importListSize:theList.options.length;\n break;\n }\n}\n\nfunction getImportedTiddlers()\n{\n try\n {\n // make sure document has valid tiddler store area\n var importDocument = window.frames['importFrame'].document;\n if (!importDocument)\n { throw("could not get file contents from importFrame"); }\n var importStoreArea = importDocument.getElementById("storeArea");\n if (!importStoreArea || !(importStore=importStoreArea.childNodes) || (importStore.length==0))\n { throw("no tiddlers found in file"); }\n importStoreArea.normalize();\n var link=unescape(window.frames['importFrame'].location.href).replace(/\s\s/g,"/")\n clearMessage();\n displayMessage('read '+importStoreArea.innerHTML.length+' bytes from ',link);\n }\n catch(e)\n {\n clearMessage();\n displayMessage("Error reading "+window.importSource+": " + ((e.message)?e.message:e));\n }\n window.importedTiddlers = new Array();\n for(var t = 0; t < importStore.length; t++)\n {\n var e = importStore[t];\n var title = null;\n if(e.getAttribute)\n title = e.getAttribute("tiddler");\n if(!title && e.id && (e.id.substr(0,5) == "store"))\n title = e.id.substr(5);\n if(title && title != "")\n {\n var theImported = new Tiddler();\n theImported.loadFromDiv(e,title);\n window.importedTiddlers.push(theImported);\n }\n }\n refreshImportList();\n}\n\nfunction importStopped()\n{\n var theList = document.getElementById('importList');\n var theNewTitle = document.getElementById('importNewTitle');\n if (!theList) return;\n if (window.importIndex==-1)\n importReport(); // import finished... generate the report\n else\n {\n // DEBUG alert('import stopped at: '+window.importIndex);\n // import collision... show the ask panel and set the title edit field\n document.getElementById('importAskPanel').style.display='block';\n theNewTitle.value=theList.options[window.importIndex].value;\n }\n}\n\nfunction refreshImportList(selectedIndex)\n{\n var theList = document.getElementById("importList");\n if (!theList) return;\n // if nothing to show, reset list content and size\n if (!window.importedTiddlers) \n {\n while (theList.length > 0) { theList.options[0] = null; }\n theList.options[0]=new Option('please open a document...',"",false,false);\n theList.size=1; // show one line only\n return;\n }\n // get the sort order\n if (!selectedIndex) selectedIndex=0;\n if (selectedIndex==0) importSortBy='title'; // heading\n if (selectedIndex==1) importSortBy='title';\n if (selectedIndex==2) importSortBy='modified';\n if (selectedIndex>2) return; // heading or tiddler item, no refresh needed\n // get the alphasorted list of tiddlers (optionally, filter out unchanged tiddlers)\n var tiddlers = [];\n\n // don't import tiddler if title/date/time match (i.e., no changes)\n for (t=0;t<window.importedTiddlers.length;t++)\n {\n if ( window.importDiffsOnly\n && store.tiddlers[window.importedTiddlers[t].title]\n && (window.importedTiddlers[t].modified-store.tiddlers[window.importedTiddlers[t].title].modified==0))\n continue;\n tiddlers.push(window.importedTiddlers[t]);\n }\n tiddlers.sort(function (a,b) {if(a['title'] == b['title']) return(0); else return (a['title'] < b['title']) ? -1 : +1; });\n // clear current list contents\n while (theList.length > 0) { theList.options[0] = null; }\n // add heading and control items to list\n var i=0;\n var indent=String.fromCharCode(160)+String.fromCharCode(160);\n theList.options[i++]=new Option('Select tiddlers to import',"",false,false);\n theList.options[i++]=new Option(((importSortBy=="title" )?">":indent)+' [by title]',"",false,false);\n theList.options[i++]=new Option(((importSortBy=="modified")?">":indent)+' [by date]',"",false,false);\n theList.options[i++]=new Option(tiddlers.length+' tiddler'+((tiddlers.length!=1)?'s are ':' is ')+(window.importDiffsOnly?'different':'in the document'),"",false,false);\n // output the tiddler list\n switch(importSortBy)\n {\n case "title":\n for(var t = 0; t < tiddlers.length; t++)\n theList.options[i++] = new Option(tiddlers[t].title,tiddlers[t].title,false,false);\n break;\n case "modified":\n // sort descending for newest date first\n tiddlers.sort(function (a,b) {if(a['modified'] == b['modified']) return(0); else return (a['modified'] > b['modified']) ? -1 : +1; });\n var lastSection = "";\n for(var t = 0; t < tiddlers.length; t++)\n {\n var tiddler = tiddlers[t];\n var theSection = tiddler.modified.toLocaleDateString();\n if (theSection != lastSection)\n {\n theList.options[i++] = new Option(theSection,"",false,false);\n lastSection = theSection;\n }\n theList.options[i++] = new Option(indent+indent+tiddler.title,tiddler.title,false,false);\n }\n break;\n }\n theList.selectedIndex=selectedIndex; // select current control item\n if (theList.size<window.importListSize)\n theList.size=window.importListSize;\n if (theList.size>theList.options.length)\n theList.size=theList.options.length;\n}\n\nfunction importTiddlers(startIndex)\n{\n if (!window.importedTiddlers) return -1;\n\n var theList = document.getElementById('importList');\n if (!theList) return;\n // if starting new import, reset import status flags\n if (startIndex==0)\n for (var t=0;t<window.importedTiddlers.length;t++)\n window.importedTiddlers[t].status="";\n for (var i=startIndex; i<theList.options.length; i++)\n {\n // if list item is not selected or is a heading (i.e., has no value), skip it\n if ((!theList.options[i].selected) || ((t=theList.options[i].value)==""))\n continue;\n for (var j=0;j<window.importedTiddlers.length;j++)\n if (window.importedTiddlers[j].title==t) break;\n var theImported = window.importedTiddlers[j];\n var theExisting = store.tiddlers[theImported.title];\n // don't import the "ImportedTiddlers" history from the other document...\n if (theImported.title=='ImportedTiddlers')\n continue;\n // don't import tiddler if title/date/time match (i.e., no changes)\n if (theExisting && ((theImported.modified-theExisting.modified)==0))\n continue;\n // if tiddler exists and import not marked for replace or merge, stop importing\n if (theExisting && (theImported.status.substr(0,7)!="replace") && (theImported.status.substr(0,5)!="merge"))\n return i;\n // append importation tags (if any)\n if (window.importTags!="")\n theImported.set(null,null,null,null,theImported.getTags()+' '+window.importTags)\n // set the status to 'added' (if not already set by the 'ask the user' UI)\n theImported.status=(theImported.status=="")?'added':theImported.status;\n // do the import!\n store.tiddlers[theImported.title] = theImported;\n store.dirty=true;\n }\n return(-1); // signals that we really finished the entire list\n}\n\nfunction importReport()\n{\n\n if (!window.importedTiddlers) return;\n // DEBUG alert('importReport: start');\n\n // if import was not completed, the Ask panel will still be open... close it now.\n document.getElementById('importAskPanel').style.display='none'; \n // get the alphasorted list of tiddlers\n var tiddlers = window.importedTiddlers;\n window.importedTiddlers.sort(function (a,b) {if(a['title'] == b['title']) return(0); else return (a['title'] < b['title']) ? -1 : +1; });\n // gather the statistics\n var count=window.importedTiddlers.length; var added=0; var replaced=0; var renamed=0; var skipped=0; var merged=0;\n for (var t=0; t<count; t++)\n if (window.importedTiddlers[t].status)\n {\n if (window.importedTiddlers[t].status=='added') added++;\n if (window.importedTiddlers[t].status.substr(0,7)=='skipped') skipped++;\n if (window.importedTiddlers[t].status.substr(0,6)=='rename') renamed++;\n if (window.importedTiddlers[t].status.substr(0,7)=='replace') replaced++;\n if (window.importedTiddlers[t].status.substr(0,6)=='merged') merged++;\n }\n var omitted=count-(added+replaced+renamed+skipped+merged);\n // DEBUG alert('stats done: '+count+' total, '+added+' added, '+skipped+' skipped, '+renamed+' renamed, '+replaced+' replaced, '+merged+' merged');\n // skip the report if nothing was imported\n if (added+replaced+renamed+merged==0) return;\n // quick message area summary report\n clearMessage();\n displayMessage((added+replaced+renamed+merged)+' of '+count+' tiddler'+((count!=1)?'s':"")+' imported from ',window.importSource)\n // create the report tiddler (if not already present)\n var tiddler = store.tiddlers['ImportedTiddlers'];\n if (!tiddler) // create new report tiddler if it doesn't exist\n {\n tiddler = new Tiddler();\n tiddler.title = 'ImportedTiddlers';\n tiddler.text = "";\n }\n // format the report header\n var now = new Date();\n newText = "";\n newText += "On "+now.toLocaleString()+", "+config.options.txtUserName+" ";\n newText += "imported tiddlers from ["+"["+window.importSource+"|"+window.importSource+"]"+"]:\sn";\n newText += "<"+"<"+"<\sn";\n newText += "Out of "+count+" tiddler"+((count!=1)?"s ":" ")+" in "+window.importSource+":\sn";\n if (added+renamed>0)\n newText += (added+renamed)+" new tiddler"+(((added+renamed)!=1)?"s were":" was")+" added to your document.\sn";\n if (merged>0)\n newText += merged+" tiddler"+((merged!=1)?"s were":" was")+" merged with "+((merged!=1)?"":"an ")+"existing tiddler"+((merged!=1)?"s":"")+".\sn"; \n if (replaced>0)\n newText += replaced+" existing tiddler"+((replaced!=1)?"s were":" was")+" replaced.\sn"; \n if (skipped>0)\n newText += skipped+" tiddler"+((skipped!=1)?"s were":" was")+" skipped after asking.\sn"; \n if (omitted>0)\n newText += omitted+" tiddler"+((omitted!=1)?"s":"")+((omitted!=1)?" were":" was")+" unchanged/not selected, and "+((omitted!=1)?"were":"was")+" not imported.\sn";\n if (window.importTags!="")\n newText += "imported tiddlers were tagged with: \s""+window.importTags+"\s"\sn";\n // output the tiddler detail and reset status flags\n for (var t=0; t<count; t++)\n if (window.importedTiddlers[t].status!="")\n {\n newText += "#["+"["+window.importedTiddlers[t].title+"]"+"]";\n newText += ((window.importedTiddlers[t].status!="added")?("\sn^"+"^"+window.importedTiddlers[t].status+"^"+"^"):"")+"\sn";\n window.importedTiddlers[t].status="";\n }\n newText += "<"+"<"+"<\sn";\n // update the ImportedTiddlers content and show the tiddler\n tiddler.text = newText+((tiddler.text!="")?'----\sn':"")+tiddler.text;\n tiddler.modifier = config.options.txtUserName;\n tiddler.modified = new Date();\n store.tiddlers[tiddler.title] = tiddler;\n displayTiddler(document.getElementById('sidebar'),"ImportedTiddlers",1,null,null,false);\n // update the page display\n store.notifyAll();\n}
// //''Name:'' SinglePageMode Plug-in for TiddlyWiki version 1.2.31 or above\n// //''Version:'' <<getversion SinglePageMode>> (<<getversiondate SinglePageMode "DD MMM YYYY">>)\n// //''Author:'' Eric Shulman - ELS Design Studios\n\nversion.extensions.SinglePageMode= {major: 1, minor: 0, revision: 0, date: new Date(2005,7,13)};\n\nif (config.options.chkSinglePageMode==undefined) config.options.chkSinglePageMode=false;\nconfig.shadowTiddlers.AdvancedOptions += "\sn<<option chkSinglePageMode>> Display one tiddler at a time";\n\nwindow.coreDisplayTiddler=window.displayTiddler;\nwindow.displayTiddler = function(src,title,state,highlightText,highlightCaseSensitive,animate,slowly)\n{\n if (config.options.chkSinglePageMode) closeAllTiddlers();\n coreDisplayTiddler(src,title,state,highlightText,highlightCaseSensitive,animate,slowly);\n}\n\n
// //''Name:'' tagCloud plugin\n// //''Version:'' <<getversion tagCloud>> (<<getversiondate tagCloud "DD MMM YYYY">>)\n// //''Author:'' ClintChecketts\n\n// //''Syntax:'' << {{{tagCloud //tags//}}} >>\n// //Any //tags// listed as arguments are omitted from the cloud.\n\n// //''Code section''\nversion.extensions.tagCloud = {major: 0, minor: 2, revision: 0, date: new Date(2005,7,16)};\n\nconfig.macros.tagCloud = {noTags: "No tag cloud created because there are no tags."};\n\nconfig.macros.tagCloud.handler = function(place,macroName,params) {\n \nvar tagCloudWrapper = createTiddlyElement(place,"div",null,"tagCloud",null);\n\nvar tags = store.getTags();\nvar tagsNoParams = new Array();\nfor (t=0; t<tags.length; t++) {\n var keepTag = true;\n for (p=0;p<params.length; p++) if (tags[t][0] == params[p]) tags[t][0] = "";\n// if (keepTag) tagsNoParams.push(tags[t][0]);\n}\n//tags = tagsNoParams;\n\n\n if(tags.length == 0) \n createTiddlyElement(tagCloudWrapper,"span",null,null,this.noTags);\n //Findout the maximum number of tags\n var mostTags = 0;\n for (t=0; t<tags.length; t++) {\n if (tags[t][1] > mostTags) mostTags = tags[t][1];\n }\n //divide the mostTags into 4 segments for the 4 different tagCloud sizes\n var tagSegment = mostTags / 4;\n\n for (t=0; t<tags.length; t++) {\n var tagCloudElement = createTiddlyElement(tagCloudWrapper,"span",null,null,null);\n tagCloudWrapper.appendChild(document.createTextNode(" "));\n var theTag = createTiddlyButton(tagCloudElement,tags[t][0],this.tooltip + tags[t][0],onClickTag,"tagCloudtag tagCloud" + (Math.round(tags[t][1]/tagSegment)+1));\n theTag.setAttribute("tag",tags[t][0]);\n }\n\n};\n\nsetStylesheet(".tagCloud li{height: 1.8em; float:left; margin: 3px; list-style: none;}.tagCloud1{font-size: 1.2em;}.tagCloud2{font-size: 1.4em;}.tagCloud3{font-size: 1.6em;}.tagCloud4{font-size: 1.8em;}.tagCloud5{font-size: 1.8em;font-weight: bold;}.clearer{clear:left;}#mainMenu .tagCloud{ font-size: .5em; margin: 0; padding: 0; font-weight: bold; } #mainMenu .tagCloudtag:hover{ text-decoration: underline; }","tagCloudsStyles");
// //''Name:'' Calendar plugin\n// //''Version:'' <<getversion listTags>> (<<getversiondate listTags "DD MMM YYYY">>)\n// //''Author:'' SteveRumsby\n\n// //''Syntax:''\n// //<< {{{listTags tag //sort// //prefix//}}} >>\n\n// //''Description:''\n// //Generate a list of tiddlers tagged with the given tag.\n// //If both //sort// and //prefix// are omitted the list is sorted in increasing order of title, with one tiddler per line.\n// //If //sort// is specified the list is sorted in increasing order of the given tiddler property. Possible properties are: title. modified, modifier.\n// //If //prefix// is specified the given string is inserted before the tiddler title. The insertion happens before the text is wikified. This can be used to generated bulleted or numbered lists.\n\n// //''Examples:''\n// //<< {{{listTags usage}}} >> - generate a plain list of all tiddlers tagged with tag //usage//, sorted by title\n// //<< {{{listTags usage modified}}} >> - the same list, with most recently modified tiddlers last\n// //<< {{{listTags usage title #}}} >> - generate a numbered list if tiddlers tagged with //usage//, sorted by title\n\n// //''Code section:''\nversion.extensions.listTags = {major: 0, minor: 1, revision: 0, date: new Date(2005, 6,16)};\n\nconfig.macros.listTags = {\ntext: "Hello"\n};\n\nconfig.macros.listTags.handler = function(place,macroName,params)\n{\n var tagged = store.getTaggedTiddlers(params[0], params[1]);\n var string = "";\n for(var r=0;r<tagged.length;r++)\n {\n if(params[2]) string = string + params[2] + " ";\n string = string + "[[" + tagged[r].title + "]]\sn";\n }\n wikify(string, place, null, null);\n}
// //''Name:'' MoveMessageArea plugin\n// //''Version:'' <<getversion moveMessageArea>> (<<getversiondate moveMessageArea "DD MMM YYYY">>)\n// //''Author:'' SteveRumsby\n\n// //''Description:'' Adds appropriate CSS styles to move the message area to the top right of the browser window, out of the way. Also sets the height of the titleLine to match a typical 3-line message from AutoSave. Messages generated for other reasons may include more or fewer lines. If this causes a problem, tweak the height to suit!\n\nversion.extensions.moveMessageArea= { major: 0, minor: 1, revision: 0, date: new Date(2005, 07, 15)};\n\nsetStylesheet("#messageArea{ position: absolute; top: 0; right:0;} #titleLine { height: 4em; }", "moveMessageArea");\n\n
// //''Name:'' UntaggedTiddlers plugin\n// //''Version:'' <<getversion untaggedTiddlers>> (<<getversiondate untaggedTiddlers "DD MMM YYYY">>)\n// //''Author:'' SteveRumsby\n\n// //''Code section:''\nversion.extensions.untaggedTiddlers = {major: 0, minor: 1, revision: 0, date: new Date(2005, 6,16)};\n\nconfig.macros.list["untagged"] = {prompt: "Tiddlers that are not tagged"};\n\nconfig.macros.list.untagged.handler = function(params)\n{\n//displayMessage("Building list of untagged tiddlers");\n var results = [];\n for(var t in store.tiddlers) {\n var tiddler = store.tiddlers[t];\n if(tiddler.getTags() == "")\n results.push(t);\n }\n results.sort();\n return results;\n}
* Upgraded to TW 1.2.32
version.extensions.yatwa = { major: 2, minor: 0, revision: 2, date: new Date(2005, 7, 18))};
(Yet Another TiddlyWiki Adaptation)
I've christened this version 2 because it is a collection of pure plugins in a vanilla TiddlyWiki 1.2.31 code base. This is the first version of YATWA that has no changes to the code - all enhancements are in the form of systemConfig tiddlers. As a result of this change there is some functionality missing in this version compared to previous versions. Specifically:\n* sortable tables\n* checkboxes\n* supression of the auto save messages\n* folded search results\n\nI plan to work on providing these as pure plugins, but some may need to wait for enhancements to the core TiddlyWiki code.\n\nSo what //is// included? \n* [[Plugins]]\n* StyleSheets\n
// //''Name:'' Shorten Tab Links plugin\n// //''Author:'' SimonBaird\n\n// ---------------------------------------------------------------------------------\n// shorten names in tabs\n\nwindow.createTiddlyLink_orig_mptw_shortnames = window.createTiddlyLink;\n\nwindow.createTiddlyLink = function(place,title,includeText) {\n\n // first create the button using the standard create function\n // this will survive upgrades better than the my old way which\n // was to replace the entire function\n var btn = createTiddlyLink_orig_mptw_shortnames(place,title,includeText);\n\n // use this trick to check if we are in a sidebar\n if (btn.parentNode.className && btn.parentNode.className == "tabContents") {\n // we must be in a sidebar\n // so lets do our thing\n\n var trimAt = 20; // tweak this if you want longer or shorter\n \n // check if we need to trim\n if (title.length > trimAt) {\n shortTitle = title.substring(0,trimAt).trim(); // why doesn't this trim seem to work???\n // wouldn't need this bit if the trim worked.\n while (shortTitle.substr(shortTitle.length-1) == " ") {\n shortTitle = shortTitle.substr(0,shortTitle.length-1);\n }\n removeChildren(btn); // btn is an a element and only has one child, the text node\n btn.appendChild(document.createTextNode(shortTitle+"...")); // cool.\n }\n }\n return btn;\n}\n
config.options["defaultLeadTime"] = 6000;\nconfig.macros["reminder"] = {};\nconfig.macros["showReminders"] = {};\nconfig.macros["displayTiddlersWithReminders"] = {};\n//config.options["defaultReminderMessage"] = "DIFF: TITLE on DATE ANNIVERSARY";\nconfig.options["defaultReminderMessage"] = "DIFF: DATE ANNIVERSARY";\nconfig.options["defaultAnniversaryMessage"] = "(DIFF)";\n\nconfig.macros.showReminders.handler = function(place,macroName,params)\n{\n var now = new Date().getMidnight();\n var paramHash = {};\n var type = "";\n var num = 0;\n var leadtime = 14;\n var paramHash = getParamsForReminder(params);\n var bProvidedDate = (paramHash["year"] != null) || (paramHash["month"] != null) || (paramHash["day"] != null) || (paramHash["dayofweek"] != null)\n if (paramHash["leadtime"] != null)\n {\n leadtime = paramHash["leadtime"];\n if (bProvidedDate)\n//If they've entered a day, we need to make sure to find it. We'll reset the leadtime a few lines down.\n paramHash["leadtime"] = 10000\n }\n var matchedDate = now;\n if (bProvidedDate)\n{\n matchedDate = findDateForReminder(paramHash); \n}\n\n var arr = findTiddlersWithReminders(matchedDate, leadtime, paramHash["tag"], paramHash["limit"]);\n for (j = 0; j < arr.length; j++)\n {\n var mess = getReminderMessageForDisplay(arr[j]["diff"], arr[j]["params"], arr[j]["matchedDate"]);\n if (paramHash["nolinks"] == null)\n mess += " -- ";\n createTiddlyElement(place,"span",null,null, mess);\n if (paramHash["nolinks"] == null)\n createTiddlyLink(place, arr[j]["tiddler"], arr[j]["tiddler"]);\n place.appendChild(document.createElement("br"));\n }\n \n}\n\n\nconfig.macros.displayTiddlersWithReminders.handler = function(place,macroName,params)\n{\n var now = new Date().getMidnight();\n var paramHash = {};\n var type = "";\n var num = 0;\n var leadtime = 14;\n var paramHash = getParamsForReminder(params);\n var bProvidedDate = (paramHash["year"] != null) || (paramHash["month"] != null) || (paramHash["day"] != null) || (paramHash["dayofweek"] != null)\n if (paramHash["leadtime"] != null)\n {\n leadtime = paramHash["leadtime"];\n if (bProvidedDate)\n//If they've entered a day, we need to make sure to find it. We'll reset the leadtime a few lines down.\n paramHash["leadtime"] = 10000\n }\n var matchedDate = now;\n if (bProvidedDate)\n {\n matchedDate = findDateForReminder(paramHash); \n }\n\n var arr = findTiddlersWithReminders(matchedDate, leadtime, paramHash["tag"], paramHash["limit"]);\n for (j = 0; j < arr.length; j++)\n {\n displayTiddler(null,arr[j]["tiddler"],0,null,false,false,false)\n }\n}\n\nconfig.macros.reminder.handler = function(place,macroName,params)\n{\n var dateHash = getParamsForReminder(params);\n if (dateHash["hidden"] != null)\n return;\n var matchedDate = findDateForReminder(dateHash);\n var leadTime = dateHash["leadtime"];\n if (leadTime == null)\n leadTime = config.options["defaultLeadTime"]; \n\n if (matchedDate != null)\n {\n var diff = matchedDate.getDifferenceInDays(new Date())\n createTiddlyElement(place,"span",null,null, getReminderMessageForDisplay(diff, dateHash, matchedDate));\n }\n else\n createTiddlyElement(place,"span",null,null, "Couldn't find a match for " + dateHash["title"] + " in the next " + leadTime + " days.");\n}\n\nDate.prototype.getMidnight = function()\n{\n return Date.convertFromYYYYMMDDHHMM("" + this.getFullYear() + String.zeroPad(this.getMonth()+1,2) + String.zeroPad(this.getDate(),2) + "0000");\n}\n// Add the specified number of days to a date.\nDate.prototype.addDays = function(numberOfDays)\n{\n return(new Date(this.getTime() + (86400000 * numberOfDays)));\n}\n// Add the specified number of days to a date.\nDate.prototype.getDifferenceInDays = function(otherDate)\n{\n return Math.floor((this.getMidnight().getTime() - otherDate.getMidnight().getTime()) / 86400000);\n \n}\n\nfindTiddlersWithReminders = function(baseDate, leadtime, tags, limit)\n{\n var matches = store.search("reminder",false,false,"title","excludeSearch");\n var structureRegExp = new RegExp(structurePatterns,"mg");\n var arr = [];\n for(var t=matches.length-1; t>=0; t--)\n {\n if (tags != null)\n {\n var bHasTag = false;\n for(var t2=0; t2<matches[t].tags.length; t2++)\n {\n if (matches[t].tags[t2] == tags)\n {\n bHasTag = true;\n break;\n }\n }\n if (! bHasTag)\n continue;\n }\n\n var targetText = matches[t].text;\n do {\n // Get the next formatting match\n var formatMatch = structureRegExp.exec(targetText);\n var matchPos = formatMatch ? formatMatch.index : targetText.length;\n var level;\n var theBlockquote;\n if(formatMatch)\n {\n if (formatMatch[14] != null && formatMatch[14].toLowerCase() == "reminder")\n {\n //Find the matching date.\n var params = formatMatch[15].readMacroParams();\n var dateHash = getParamsForReminder(params);\n\n if (limit != null || dateHash["leadtime"] == null)\n dateHash["leadtime"] = leadtime;\n \n\n var matchedDate = findDateForReminder(dateHash, baseDate);\n if (matchedDate != null)\n {\n var hash = {};\n var diff = matchedDate.getDifferenceInDays(baseDate)\n hash["diff"] = diff;\n hash["matchedDate"] = matchedDate;\n hash["params"] = dateHash;\n hash["tiddler"] = matches[t].title;\n hash["tags"] = matches[t].tags;\n arr.pushUnique(hash);\n }\n }\n }\n }while(formatMatch);\n }\n arr.sort(function (a,b) {if(a["diff"] == b["diff"]) return(0); else return (a["diff"] < b["diff"]) ? -1 : +1; });\n return arr;\n}\ngetReminderMessageForDisplay = function(diff, params, matchedDate)\n{\n var anniversaryString = "";\n var reminderTitle = params["title"];\n\n if (reminderTitle == null)\n reminderTitle = "Untitled Reminder";\n\n else if (reminderTitle[0] == "\s"" && reminderTitle[reminderTitle.length -1] == "\s"")\n reminderTitle = reminderTitle.substr(1, reminderTitle.length - 2);\n if (params["firstyear"] != null)\n anniversaryString = config.options["defaultAnniversaryMessage"].replace("DIFF", (matchedDate.getFullYear() - params["firstyear"]));\n var mess = "";\n if (diff == 0)\n diffString = "Today";\n else if (diff == 1)\n diffString = "Tomorrow";\n else\n diffString = diff + " days";\n mess = config.options["defaultReminderMessage"].replace("DIFF", diffString).replace("TITLE", reminderTitle).replace("DATE", matchedDate.formatString("DDD MMM DD, YYYY")).replace("ANNIVERSARY", anniversaryString);\n return mess;\n}\ngetParamsForReminder = function(params)\n{\n var dateHash = {};\n var type = "";\n var num = 0;\n var title = "";\n for(var t=0; t<params.length; t++)\n {\n type = params[t].split(":")[0].toLowerCase();\n if (type != "title" && type != "tag")\n num = parseInt(params[t].split(":")[1]);\n else if (type == "nolinks" || type == "limit" || type == "hidden")\n num = 1;\n else\n {\n title = params[t].split(":")[1];\n while (title[0] == '"' && title[title.length - 1] != '"')\n title += " " + params[++t];\n num = title;\n }\n dateHash[type] = num;\n }\n //date is synonymous with day\n if (dateHash["day"] == null)\n dateHash["day"] = dateHash["date"];\n return dateHash;\n}\nfindDateForReminder = function( dateHash, baseDate)\n{\n if (baseDate == null)\n baseDate = new Date().getMidnight();\n var leadTime = dateHash["leadtime"];\n if (leadTime == null)\n leadTime = config.options["defaultLeadTime"]; \n var matchedDate = baseDate.findMatch(dateHash, leadTime);\n if (matchedDate != null)\n {\n var newMatchedDate = matchedDate;\n if (dateHash["recurdays"] != null)\n {\n while (newMatchedDate.getTime() < baseDate.getTime())\n {\n newMatchedDate = newMatchedDate.addDays(dateHash["recurdays"]);\n }\n }\n else if (dateHash["offsetyear"] != null \n || dateHash["offsetmonth"] != null\n || dateHash["offsetday"] != null\n || dateHash["offsetdayofweek"] != null)\n {\n dateHash["year"] = dateHash["offsetyear"];\n dateHash["month"] = dateHash["offsetmonth"];\n dateHash["day"] = dateHash["offsetday"];\n dateHash["dayofweek"] = dateHash["offsetdayofweek"];\n newMatchedDate = matchedDate.findMatch(dateHash, leadTime);\n }\n var diff2 = newMatchedDate.getDifferenceInDays(baseDate);\n if (diff2 >= 0 && diff2 <= leadTime)\n return newMatchedDate;\n }\n return null;\n}\n// Add the specified number of days to a date.\nDate.prototype.findMatch = function(dateHash, leadTime)\n{\n var bSpecifiedYear = (dateHash["year"] != null);\n var bSpecifiedMonth = (dateHash["month"] != null);\n var bSpecifiedDay = (dateHash["day"] != null);\n var bSpecifiedDayOfWeek = (dateHash["dayofweek"] != null);\n if (bSpecifiedYear && bSpecifiedMonth && bSpecifiedDay)\n return Date.convertFromYYYYMMDDHHMM("" + dateHash["year"] + String.zeroPad(dateHash["month"],2) + String.zeroPad(dateHash["day"],2) + "0000");\n var bMatchedYear = !bSpecifiedYear;\n var bMatchedMonth = !bSpecifiedMonth;\n var bMatchedDay = !bSpecifiedDay;\n var bMatchedDayOfWeek = !bSpecifiedDayOfWeek;\n var searchInterval = 1;\n if (bSpecifiedDayOfWeek && dateHash["dayofweek"] < 0)\n {\n dateHash["dayofweek"] = dateHash["dayofweek"] * -1;\n searchInterval = -1;\n }\n if (bSpecifiedDay && bSpecifiedMonth && !bSpecifiedYear && !bSpecifiedDayOfWeek)\n {\n //Shortcut -- First try this year. If it's too small, try next year.\n var tmpMidnight = this.getMidnight();\n var tmpDate = Date.convertFromYYYYMMDDHHMM("" + this.getFullYear() + String.zeroPad(dateHash["month"],2) + String.zeroPad(dateHash["day"],2) + "0000");\n if (tmpDate.getTime() < tmpMidnight.getTime())\n tmpDate = Date.convertFromYYYYMMDDHHMM("" + (this.getFullYear() + 1) + String.zeroPad(dateHash["month"],2) + String.zeroPad(dateHash["day"],2) + "0000");\n var diff2 = tmpDate.getDifferenceInDays(tmpMidnight);\n if (diff2 <= leadTime && diff2 >= 0)\n return tmpDate;\n else\n return null;\n }\n for (i = 0; i <= leadTime; i+=searchInterval)\n {\n var newDate = this.addDays(i);\n if (bSpecifiedYear)\n bMatchedYear = ((dateHash["year"] - 1900) == newDate.getYear());\n if (bSpecifiedMonth)\n bMatchedMonth = ((dateHash["month"] - 1) == newDate.getMonth() );\n if (bSpecifiedDay)\n bMatchedDay = (dateHash["day"] == newDate.getDate());\n if (bSpecifiedDayOfWeek)\n bMatchedDayOfWeek = (dateHash["dayofweek"] == newDate.getDay());\n\n if (bMatchedYear && bMatchedMonth && bMatchedDay && bMatchedDayOfWeek)\n return newDate;\n }\n}\n\n// Convert a date to UTC YYYYMMDD string format\nDate.prototype.convertToYYYYMMDD = function()\n{\n return(String.zeroPad(this.getFullYear(),4) + String.zeroPad(this.getMonth()+1,2) + String.zeroPad(this.getDate(),2));\n}\n\n\n
Type the text for '26/08/2005'
!!Calendar plugin v0.2\nIf the Reminder macros are present, clicking on a date produces a pop-up containing:\n* The clicked date, as a header\n* A "new reminder" button, which creates a new tiddler with the date as a title\n* A list of tiddlers with a reminder for that date, if any\n\nIf Reminder macros are not present, clicking on a date simply displays the appropriate tiddler as before.\n\nStill to do:\n* When creating a new reminder, pre-populate the new tiddler with an appropriate invocation of the reminder macro\n* Find a better way of getting the date in onClickCalenderDate, so that the tiddler date format can be changeable again\n* Pop-ups for calendars displayed in tiddlers appear in the wrong place (a calendar in MainMenu is fine)\n* Sort out all the CSS - it is a mess
// //''Name:'' Calendar plugin\n// //''Version:'' <<getversion calendar>> (<<getversiondate calendar "DD MMM YYYY">>)\n// //''Author:'' SteveRumsby\n\n// //''Syntax:'' \n// //<< {{{calendar}}} >> or << {{{calendar //year//}}} >> or << {{{calendar //year month//}}} >> or << {{{calendar thismonth}}} >>\n\n// //''Description:'' \n// //The first form produces an full-year calendar for the current year. The second produces a full-year calendar for the given year. The third produces a single month calendar for the given month and year. The fourth form produces a single month calendar for the current month.\n// // Weekends and holidays are highlighted (see below for how to specify holdays).\n\n// //''Todo:''\n// //* Improve the formatting, especially when included in MainMenu\n// //* Find a better way of specifying holidays. It would be good to support calculated dates (e.g. Easter), and dates for different countries.\n// //* Add browsing facilities like jscalendar has\n// //* Highlight "today", if visible...\n// //* Integrate with the ReminderMacros\n\n// //''Configuration:''\n// //Modify this section to change the text displayed for the month and day names, to a different language for example. You can also change the format of the tiddler names linked to from each date, and the colours used.\n\nconfig.macros.calendar = {};\n\nconfig.macros.calendar.monthnames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];\nconfig.macros.calendar.daynames = ["M", "T", "W", "T", "F", "S", "S"];\n\nconfig.macros.calendar.weekendbg = "#c0c0c0";\nconfig.macros.calendar.monthbg = "#e0e0e0";\nconfig.macros.calendar.holidaybg = "#ffc0c0";\n\n// //''Code section:''\n// (you should not need to alter anything below here)//\n\nconfig.macros.calendar.tiddlerformat = "0DD/0MM/YYYY"; // This used to be changeable - for now, it isn't// <<smiley :-(>> \n\nversion.extensions.calendar = { major: 0, minor: 2, revision: 0, date: new Date(2005, 07, 21)};\nconfig.macros.calendar.monthdays = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n\nconfig.macros.calendar.holidays = [ "01/01", "25/12", "03/01/2005", "02/05/2005", "30/05/2005", "29/08/2005" ];\n\nfunction calendarIsHoliday(date)\n{\n var longHoliday = date.formatString("0DD/0MM/YYYY");\n var shortHoliday = date.formatString("0DD/0MM");\n\n for(var i = 0; i < config.macros.calendar.holidays.length; i++) {\n if(config.macros.calendar.holidays[i] == longHoliday || config.macros.calendar.holidays[i] == shortHoliday) {\n return true;\n }\n }\n return false;\n}\n\nconfig.macros.calendar.handler = function(place,macroName,params)\n{\n var calendar = createTiddlyElement(place, "table", null, "calendar", null);\n\n if(params[0] == "thismonth") {\n var today = new Date();\n createCalendarOneMonth(calendar, today.getYear()+1900, today.getMonth());\n } else {\n var year;\n if(params[0]) {\n year = params[0];\n } else {\n year = (new Date()).getYear() + 1900;\n }\n\n if(params[1]) {\n var month = params[1] -1;\n createCalendarOneMonth(calendar, year, month);\n } else {\n createCalendarYear(calendar, year);\n }\n }\n}\n\nfunction createCalendarOneMonth(calendar, year, mon)\n{\n var row = createTiddlyElement(calendar, "tr", null, null, null);\n createCalendarMonthHeader(row, config.macros.calendar.monthnames[mon] + " " + year, true);\n row = createTiddlyElement(calendar, "tr", null, null, null);\n createCalendarDayHeader(row, 1);\n createCalendarDayRowsSingle(calendar, year, mon);\n}\n\n\nfunction createCalendarMonth(calendar, year, mon)\n{\n var row = createTiddlyElement(calendar, "tr", null, null, null);\n createCalendarMonthHeader(row, config.macros.calendar.monthnames[mon] + " " + year, false);\n row = createTiddlyElement(calendar, "tr", null, null, null);\n createCalendarDayHeader(row, 1);\n createCalendarDayRowsSingle(calendar, year, mon);\n}\n\nfunction createCalendarYear(calendar, year)\n{\n var row;\n\n row = createTiddlyElement(calendar, "tr", null, null, null);\n var yearHeader = createTiddlyElement(row, "td", null, "calendarYear", year);\n yearHeader.align = "center";\n yearHeader.setAttribute("colSpan", 21);\n\n createCalendarMonthRow(calendar, year, 0);\n createCalendarMonthRow(calendar, year, 3);\n createCalendarMonthRow(calendar, year, 6);\n createCalendarMonthRow(calendar, year, 9);\n}\n\nfunction createCalendarMonthRow(cal, year, mon)\n{\n var row = createTiddlyElement(cal, "tr", null, null, null);\n createCalendarMonthHeader(row, config.macros.calendar.monthnames[mon]);\n createCalendarMonthHeader(row, config.macros.calendar.monthnames[mon+1]);\n createCalendarMonthHeader(row, config.macros.calendar.monthnames[mon+2]);\n row = createTiddlyElement(cal, "tr", null, null, null);\n createCalendarDayHeader(row, 3);\n createCalendarDayRows(cal, year, mon);\n}\n\nfunction createCalendarMonthHeader(row, name, nav)\n{\n var month;\n if(nav) {\n var back = createTiddlyElement(row, "td", null, null, null);\n createTiddlyButton(back, "<", "Back", onClickCalendarBack)\n back.align = "center";\n back.style.background = config.macros.calendar.monthbg; \n month = createTiddlyElement(row, "td", null, "calendarMonthname", name)\n month.setAttribute("colSpan", 5);\n var fwd = createTiddlyElement(row, "td", null, null, null);\n createTiddlyButton(fwd, ">", "Fwd", onClickCalendarFwd)\n fwd.align = "center";\n fwd.style.background = config.macros.calendar.monthbg; \n } else {\n month = createTiddlyElement(row, "td", null, "calendarMonthname", name)\n month.setAttribute("colSpan", 7);\n }\n month.align = "center";\n month.style.background = config.macros.calendar.monthbg;\n}\n\nfunction onClickCalendarBack(e)\n{\n\n}\n\nfunction onClickCalendarFwd(e)\n{\n\n}\n\nfunction createCalendarDayHeader(row, num)\n{\n var cell;\n for(var i = 0; i < num; i++) {\n for(var j = 0; j < 7; j++) {\n cell = createTiddlyElement(row, "td", null, null, config.macros.calendar.daynames[j]);\n if(j > 4) cell.style.background = config.macros.calendar.weekendbg;\n }\n }\n}\n\nfunction createCalendarDays(row, col, first, max, year, mon)\n{\n var i;\n for(i = 0; i < col; i++) {\n createTiddlyElement(row, "td", null, null, null);\n }\n var day = first;\n for(i = col; i < 7; i++) {\n var daycell = createTiddlyElement(row, "td", null, null, null);\n if(i > 4) daycell.style.background = config.macros.calendar.weekendbg;\n if(day > 0 && day <= max) {\n var celldate = new Date(year, mon, day);\n var title = celldate.formatString(config.macros.calendar.tiddlerformat);\n if(calendarIsHoliday(celldate)) {\n daycell.style.background = config.macros.calendar.holidaybg;\n }\n if(window.findTiddlersWithReminders == null) {\n var link = createTiddlyLink(daycell, title, false);\n link.appendChild(document.createTextNode(day));\n } else {\n var button = createTiddlyButton(daycell, day, title, onClickCalendarDate);\n }\n }\n day++;\n }\n}\n\n// //We've clicked on a day in a calendar - create a suitable pop-up of options.\n// //The pop-up should contain:\n// // * a link to create a new entry for that date\n// // * a link to create a new reminder for that date\n// // * an <hr>\n// // * the list of reminders for that date\nfunction onClickCalendarDate(e)\n{\n var button = this;\n var date = button.getAttribute("title");\n var dat = new Date(date.substr(6,4), date.substr(3,2)-1, date.substr(0, 2));\n\n date = dat.formatString(config.macros.calendar.tiddlerformat);\n var popup = createTiddlerPopup(this);\n popup.appendChild(document.createTextNode(date));\n var newReminder = function() {\n var t = store.tiddlers[date];\n displayTiddler(null, date, 2, null, null, false, false);\n if(t) {\n document.getElementById("editorBody" + date).value += "\sn<<reminder day:" + dat.getDate() +\n " month:" + (dat.getMonth()+1) +\n " year:" + (dat.getYear()+1900) + " title: >>";\n } else {\n document.getElementById("editorBody" + date).value = "<<reminder day:" + dat.getDate() +\n " month:" + (dat.getMonth()+1) +\n " year:" + (dat.getYear()+1900) + " title: >>";\n }\n };\n var link = createTiddlyButton(popup, "New reminder", null, newReminder); \n popup.appendChild(document.createElement("hr"));\n\n var t = findTiddlersWithReminders(dat, 0, null, null);\n for(var i = 0; i < t.length; i++) {\n link = createTiddlyLink(popup, t[i].tiddler, false);\n link.appendChild(document.createTextNode(t[i].tiddler));\n }\n\n}\n\nfunction calendarMaxDays(year, mon)\n{\n var max = config.macros.calendar.monthdays[mon];\n if(mon == 1 && (year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0)) {\n max++;\n }\n return max;\n}\n\nfunction createCalendarDayRows(cal, year, mon)\n{\n var row = createTiddlyElement(cal, "tr", null, null, null);\n\n var first1 = (new Date(year, mon, 1)).getDay() -1;\n if(first1 < 0) first1 = 6;\n var day1 = -first1 + 1;\n var first2 = (new Date(year, mon+1, 1)).getDay() -1;\n if(first2 < 0) first2 = 6;\n var day2 = -first2 + 1;\n var first3 = (new Date(year, mon+2, 1)).getDay() -1;\n if(first3 < 0) first3 = 6;\n var day3 = -first3 + 1;\n\n var max1 = calendarMaxDays(year, mon);\n var max2 = calendarMaxDays(year, mon+1);\n var max3 = calendarMaxDays(year, mon+2);\n\n while(day1 <= max1 || day2 <= max2 || day3 <= max3) {\n row = createTiddlyElement(cal, "tr", null, null, null);\n createCalendarDays(row, 0, day1, max1, year, mon); day1 += 7;\n createCalendarDays(row, 0, day2, max2, year, mon+1); day2 += 7;\n createCalendarDays(row, 0, day3, max3, year, mon+2); day3 += 7;\n }\n}\n\nfunction createCalendarDayRowsSingle(cal, year, mon)\n{\n var row = createTiddlyElement(cal, "tr", null, null, null);\n\n var first1 = (new Date(year, mon, 1)).getDay() -1;\n if(first1 < 0) first1 = 6;\n var day1 = -first1 + 1;\n var max1 = calendarMaxDays(year, mon);\n\n while(day1 <= max1) {\n row = createTiddlyElement(cal, "tr", null, null, null);\n createCalendarDays(row, 0, day1, max1, year, mon); day1 += 7;\n }\n}\n\nsetStylesheet("#mainMenu table, th, tr, td {font-size:10pt;}", "calendarStyles");
<<calendar 2005>>
// //''Name:'' Save Changes To DAV plugin\n// //''Version:'' <<getversion saveChangesToDAV>> (<<getversiondate calendar "DD MMM YYYY">>)\n// //''Depends on:'' YATWA http://www.rumsby.org/yatwa/\n// //''Author:'' PeterSuschlik <peter-tiddly //at// suschlik //dot// de>\n\n// //''Syntax:'' \n// //<< {{{saveChangesToDAV}}} >>\n\n// //''Description:'' \n// //This plugin allows you to upload your changes to a webserver via WebDAV (at the moment only the methods {{{GET}}} and {{{PUT}}} are implemented)\n// //It should be add to SideBarOptions.\n// //Addionally, add << {{{option txtDAVURL 50}}} >> to AdvancedOptions.\n\n// //''WebDAV Apache Setup Example''\n// // Wiki-URL: http://{{{host}}}/wiki/\n// // DAV-URL: http://{{{host}}}/wiki/dav/index.html\n// // * setup WebDAV for {{{host}}} as usual\n// // * symlink /wiki/index.html to /wiki/dav/index.html\n\n// //''Notes on XMLHttpRequest restrictions''\n// //Due to security reasons there are some restrictions on connection to a webserver via XMLHttpRequest\n// //The wiki and the upload WebDAV directory must live on the same host\n\n// //''TODO''\n// // * some documentation/comments\n\n\n// //''Configuration:''\n// //Modify {{{txtDAVURL}}} option at AdvancedOptions.\n// //For setup see above.\n\n// //''Code section:''\n// (you should not need to alter anything below here)//\n\n/*\n{{{\n*/\n\nfunction isHttp() {\n return document.location.toString().search(/https?:\s/\s//) != -1;\n}\n\nfunction DAVSaver() {\n this.uploading = false;\n}\n\nDAVSaver.prototype = {\n xmlhttprequest: function() {\n try {\n return new XMLHttpRequest();\n return new ActiveXObject("Msxml2.XMLHTTP");\n return new ActiveXObject("Microsoft.XMLHTTP");\n } catch(e) {}\n alert("Could not construct XmlHttpRequest Object!");\n },\n reset: function() {\n this.uploading = false;\n return null;\n },\n loadLocal: function() {\n var originalPath = document.location.toString();\n var hashPos = originalPath.indexOf("#");\n if(hashPos != -1) originalPath = originalPath.substr(0,hashPos);\n var localPath;\n if(originalPath.charAt(9) == ":") // pc local file\n localPath = unescape(originalPath.substr(8)).replace(new RegExp("/","g"),"\s\s");\n else if(originalPath.indexOf("file://///") == 0) // FireFox pc network file\n localPath = "\s\s\s\s" + unescape(originalPath.substr(10)).replace(new RegExp("/","g"),"\s\s");\n else if(originalPath.indexOf("file:///") == 0) // mac/unix local file\n localPath = unescape(originalPath.substr(7));\n else if(originalPath.indexOf("file:/") == 0) // mac/unix local file\n localPath = unescape(originalPath.substr(5));\n else // pc network file\n localPath = "\s\s\s\s" + unescape(originalPath.substr(7)).replace(new RegExp("/","g"),"\s\s");\n displayMessage('Loading locally: ' + localPath, localPath);\n var original = loadFile(localPath);\n if (original == null) {\n displayMessage('Loading locally failed: ' + localPath, localPath);\n return;\n }\n this.doUpload(original);\n },\n loadRemote: function() {\n var xml = this.xmlhttprequest();\n xml._uploader = this;\n displayMessage('Loading remotely: ' + this.url, this.url);\n xml.onreadystatechange = function() {\n if (xml.readyState != 3)\n displayMessage("Download-State " + xml.readyState);\n if (xml.readyState == 4) {\n if (xml.status == 200) {\n displayMessage('Downloaded ' + xml.responseText.length + ' bytes');\n xml._uploader.doUpload(xml.responseText);\n } else {\n displayMessage('Upload failed ' + xml.status, xml._uploader.url);1\n xml._uploader.reset();\n }\n }\n }\n xml.open('GET', this.url, true);\n xml.send('');\n },\n loadAndUpload: function() {\n if (isHttp()) {\n this.loadRemote();\n } else {\n this.loadLocal();\n }\n },\n upload: function() {\n if (readOnly) return;\n if (this.uploading) {\n displayMessage("Upload in progress - please wait");\n return;\n }\n this.url = config.options['txtDAVURL'];\n if (this.url == null || this.url == "") {\n alert("No DAV URL specified in AdvancedOptions!\sn\sn" +\n"Maybe you need to add the following line to AdvancedOptions:\sn" +\n"DAV-URL <<option txtDAVURL 50>>");\n return;\n }\n this.uploading = true;\n this.loadAndUpload();\n },\n doUpload: function(content) {\n if (content == null) return;\n content = this.reviseStore(content);\n displayMessage("Uploading " + content.length + " bytes to " + this.url);\n var xml = this.xmlhttprequest();\n xml._uploader = this;\n xml.onreadystatechange = function() {\n displayMessage("Upload-State " + xml.readyState);\n if (xml.readyState == 4) {\n if (xml.status == 201 || xml.status == 204) {\n displayMessage("Uploaded", this.url);\n } else {\n displayMessage("Upload failed " + xml.status, xml._uploader.url);\n }\n xml._uploader.reset();\n }\n }\n if (!isHttp()) {\n netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");\n }\n xml.open('PUT', this.url, true);\n xml.send(content);\n },\n reviseStore: function(original) {\n // Locate the storeArea div's\n var posOpeningDiv = original.indexOf(startSaveArea);\n var posClosingDiv = original.lastIndexOf(endSaveArea);\n if((posOpeningDiv == -1) || (posClosingDiv == -1)) {\n alert(config.messages.invalidFileError.format([localPath]));\n return;\n }\n var revised = original.substr(0,posOpeningDiv + startSaveArea.length) + \n convertUnicodeToUTF8(allTiddlersAsHtml()) + "\sn\st\st" +\n original.substr(posClosingDiv);\n var newSiteTitle = store.getTiddlerText("SiteTitle","TiddlyWiki").htmlEncode();\n revised = revised.replace(new RegExp("<title>[^<]*</title>", "im"),"<title>"+ newSiteTitle +"</title>");\n return revised;\n },\n onClick: function() {\n clearMessage();\n this.upload();\n },\n}\nvar davSaver = new DAVSaver();\n\nversion.extensions.saveChangesToDAV = {major: 0, minor: 2, revision: 1, date: new Date(2005,09,09)};\n\nif (isHttp() && (config.options['txtDAVURL'] == null || config.options['txtDAVURL'] == "")) {\n config.options['txtDAVURL'] = document.location.href;\n}\n\nconfig.macros.saveChangesToDAV = {\n label: "save to dav",\n prompt: "Save all tiddlers to create a new TiddlyWiki to DAV"\n}\n\nconfig.macros.saveChangesToDAV.handler = function(place) {\n if(!readOnly)\n createTiddlyButton(place,this.label,this.prompt, function() { davSaver.onClick() });\n}\n\n/** Override */\n\nconfig.macros.option.handler = function(place,macroName,params)\n{\n var opt = params[0];\n if(config.options[opt] == undefined)\n return;\n var size = params[1] || 15; // configure size\n var c;\n switch(opt.substr(0,3))\n {\n case "txt":\n c = document.createElement("input");\n c.onkeyup = this.onChangeOption;\n c.setAttribute("option",opt);\n c.size = size; // configure size\n c.value = config.options[opt];\n place.appendChild(c);\n break;\n case "chk":\n c = document.createElement("input");\n c.setAttribute("type","checkbox");\n c.onclick = this.onChangeOption;\n c.setAttribute("option",opt);\n c.checked = config.options[opt];\n place.appendChild(c);\n break;\n }\n}\n\nfunction convertUnicodeToUTF8(s)\n{\n if(saveUsingSafari)\n return s;\n/* This does not work remotely!\n else if(window.Components)\n return mozConvertUnicodeToUTF8(s);\n*/\n else\n return manualConvertUnicodeToUTF8(s);\n}\n\n/*\n}}}\n*/
<<search>><<closeAll>><<permaview>><<importTiddlers>><<saveChanges>><<saveChangesToDAV>><<slider chkSliderOptionsPanel OptionsPanel options 'Change TiddlyWiki advanced options'>>
fasel
<<option chkOpenInNewWindow>> OpenLinksInNewWindow\n<<option chkSaveEmptyTemplate>> SaveEmptyTemplate\n <<option chkSinglePageMode>> SinglePageMode\nDAV-URL: <<option txtDAVURL 50>>