<!--{{{-->
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml'/>
<!--}}}-->
Background: #fff
Foreground: #000
PrimaryPale: #8cf
PrimaryLight: #18f
PrimaryMid: #04b
PrimaryDark: #014
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
/*{{{*/
body {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

hr {height:1px;}

a {text-decoration:none;}

dt {font-weight:bold;}

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

.txtOptionInput {width:11em;}

#contentWrapper .chkOptionInput {border:0;}

.externalLink {text-decoration:underline;}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

----
Also see AdvancedOptions
<<importTiddlers>>
In Socialtext Unplugged, the selected pages of your Socialtext workspace are displayed as individual "tiddlers" on the page. When the mouse passes over a tiddler a short toolbar menu appears at the top right. Use the commands here to manipulate that particular tiddler: notably closing and editting it. (You can double click on a tiddler as a shortcut to directly enter edit mode).

Over on the right hand side of the window are commands that affect the entire page, in particular "close all" which can be useful to clear the decks when many tiddlers are open at once.

The user is encouraged to ensure that they can SaveChanges before embarking on widespread editing.
Welcome to Socialtext Unplugged. This is a specially designed web page that you can use to view and edit your Socialtext content without having to be online to your Socialtext server.

There are three steps to using Socialtext Unplugged:
* First, learn how to SaveChanges to your local hard drive. This keeps your work safe even if you close your browser or have to reboot your computer
* Secondly, find out how to BrowseAndEdit your content while it is unplugged
* Thirdly, when you can reconnect to your Socialtext server, you can SyncChanges to save your unplugged changes to the server so that other people can see them too

You should also check your system meets the SystemRequirements.
Socialtext Unplugged lets you browse and edit your content while you're offline. When you make a change you need to SaveChanges to save the change to your local hard drive, before later performing a SyncChanges to synchronise the change back to the server.

The procedure for SaveChanges is slightly different for different browsers:
* SavingOnInternetExplorer
* SavingOnFireFox
* SavingOnSafari
* SavingOnOpera
You can save changes with any version of FireFox, and also many other browsers in the FireFox family, such as Camino on the Mac and MiniMo on mobile devices. The procedure is:
# Click the button labelled 'save changes' over in the right hand sidebar
# If prompted with an "Internet Security" dialog as follows, click the checkbox labelled "Remember this decision" and then the "Allow" button
## "A script from "file://" is requesting enhanced capabilities that are UNSAFE and could be used to compromise your machine or data..."
# You should then see a message at the top right of the window saying "Main TiddlyWiki file saved"
If you accidentally //deny// permission instead, you may need to UnravelFireFoxPermissions.
You can save changes with Internet Explorer versions 6 and 7, but not the earlier versions. The procedure is:
# Click the button labelled 'save changes' over in the right hand sidebar
# If prompted as follows, click "Yes":
## "An ActiveX control on this page might be unsafe to interact with other parts of the page. Do you want to allow this interaction?"
# You should then see a message at the top right of the window saying "Main TiddlyWiki file saved"
Note that there is currently [[a bug|http://trac.tiddlywiki.org/tiddlywiki/ticket/39]] that prevents Internet Explorer from saving correctly if you have specified a backup directory in AdvancedOptions.
To SaveChanges on Opera, see the instructions for using the TiddlySaver Java applet.
To SaveChanges on Safari, see the instructions for using the TiddlySaver Java applet.
<<search>><<closeAll>><<permaview>><<newTiddler 'New Tiddler' fields:'server.host:"https://saturn.ffzg.hr%2C%20saturn.ffzg.hr:443" server.workspace:"rot13" wikiformat:socialtext'>><<newJournal 'DD MMM YYYY' fields:'server.host:"https://saturn.ffzg.hr%2C%20saturn.ffzg.hr:443" server.workspace:"rot13" wikiformat:socialtext'>><<saveChanges>><<backstage sync>><<slider chkSliderOptionsPanel OptionsPanel 'options »' 'Change TiddlyWiki advanced options'>>
Dobrica Pavlinušić's random unstructured stuff
Socialtext Unplugged
https://saturn.ffzg.hr/rot13/
[[SocialtextScreenStyle]]
[[SocialtextStyleOverrides]]
[[Styles HorizontalMainMenu]]
<<sync>>
@@The user interface for synchronization is not finalized@@
To synchronize your changes back to the Socialtext server:
# click on [[Sync]] in the right-hand sidebar
<<tabs txtMoreTab Orphans 'Orphaned tiddlers' TabMoreOrphans Shadowed 'Shadowed tiddlers' TabMoreShadowed>>
Under FireFox, you can run into problems if you accidentally click 'Deny' on the permission request dialog, and have selected //Remember this decision//.

To reverse the effects, first locate the file {{{prefs.js}}} in your FireFox profile directory. Under Windows you'll find it at something like {{{C:\Documents and Settings\Jeremy\Application Data\Mozilla\Firefox\Profiles\o3dhupu6.default\prefs.js}}}, where {{{Jeremy}}} is the name of your windows profile and {{{o3dhupu6}}} will be a similar string of gobbledegook. On the Mac it'll be at {{{~/Library/Application Support/Firefox/Profiles/o3dhupu6.default/prefs.js}}} and on most versions of Linux, at {{{~/.mozilla/firefox/o3dhupu6.default/prefs.js}}}.

Open the file in a text editor and find the line {{{user_pref("capability.principal.codebase.p0.denied", "UniversalXPConnect");}}} and simply replace the word {{{denied}}} with {{{granted}}}.
//(Thanks to JonScully for figuring out this fix)//
<!--{{{-->
<div class='toolbar' macro='toolbar closeTiddler closeOthers +editTiddler references > fields syncing jump'></div>
<div class='workspace' id='st-page-wiki-title' macro='view socialtext.workspace'></div>
<div class='title' id='st-page-titletext' macro='view title'></div>
<div class='subtitle'>
Created on <span macro='view created date [[MMM DD, 0hh:0mm]]'></span>.
Updated by <span macro='view modifier link'></span>
on <span macro='view modified date [[MMM DD, 0hh:0mm]]'></span></div>
<div class='tagging' macro='tagging'></div>
<div class='tagged' macro='tags'></span></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<!--}}}-->
/***
To use, add {{{[[Styles HorizontalMainMenu]]}}} to your StyleSheet tiddler.
See http://www.w3schools.com/css/css_colors.asp for a color chart.
***/
/*{{{*/
#mainMenu {position:relative;left:auto;width:auto;text-align:left;line-height:normal;padding 0em 1em 0em 1em;font-size:normal;}
#mainMenu br {display:none;}
#mainMenu {background:#336699;}
#mainMenu {padding:2px;}
#mainMenu .button, #mainMenu .tiddlyLink {padding-left:0.5em;padding-right:0.5em;color:white;font-size:115%;}

#displayArea {
	margin-top:0;margin-right:20em;margin-bottom:0;margin-left:1em;
	padding-top:.1em;padding-bottom:.1em;
}
/*}}}*/
|''Type:''|socialtext|
|''URL:''|https://saturn.ffzg.hr%2C%20saturn.ffzg.hr:443 |
|''Workspace:''|rot13|
|''WorkspaceList:''||
|''Description:''|Dobrica Pavlinušić's random unstructured stuff|
The TiddlySaver Java applet allows TiddlyWiki from a {{{file://}}} URL to save changes Safari, Opera and other browsers.

It is a small file named [["TiddlySaver.jar"|TiddlySaver.jar]] that must be placed in the same directory as your TiddlyWiki file. Before you can use it, you need to give it the necessary privileges by editting your {{{.java.policy}}} file.

For Windows, the file will be at {{{C:\Documents and Settings\your-user-name\.java.policy}}}. Add the following lines (substituting the directory of your TiddlyWiki file as appropriate):
{{{
grant codeBase "file:${user.home}/My Documents/tiddlywiki-folder/*" {
  permission java.io.FilePermission "${user.home}${/}My Documents${/}tiddlywiki-folder${/}*", "read,write";
};
}}}
On Mac OS X, the file is found at {{{/Users/your-user-name/.java.policy}}}:
{{{
grant codeBase "file:${user.home}/Documents/tiddlywiki-folder/*" {
  permission java.io.FilePermission "${user.home}${/}Documents${/}tiddlywiki-folder${/}*", "read,write";
};
}}}
It can be tricky creating files whose name starts with a period, so you can use this [[pre-built .java.policy file|.java.policy]]. The same file is suitable for Macs too, just edit it and delete the "My " bit, leaving just "Documents". Make sure you save it in the right place for each operating system!

If you have trouble setting up the permissions correctly, you can try granting broader permissions to the applet like this:

{{{
grant codeBase "file://localhost/home/users/Desktop/
TiddlySaver.jar"
 { permission java.security.AllPermission; };
}}}

Note that there is currently [[a bug|http://trac.tiddlywiki.org/ticket/172]] that prevents TiddlySaver from working if you have specified a backup directory in AdvancedOptions.
/***
|''Name:''|SocialtextLocaleOverrides|
|''Description:''|Text changes for Socialtext|
***/

//{{{
merge(config.views.wikified.tag,{
	labelNoTags: "No Tags",
	labelTags: "Tags"});

merge(config.commands.references,{
	text: "incoming links",
	tooltip: "Show tiddlers that link to this one",
	popupNone: "No incoming links"});
//}}}
/***
|''Name:''|SocialtextTweaksPlugin|
|''Description:''|Allows changes to be synchronised with a Socialtext server|
|''Source:''|http://stunplugged.tiddlywiki.com/#SocialtextTweaksPlugin|
|''Author:''|JeremyRuston (jeremy (at) osmosoft (dot) com)|
|''Version:''|1.0.2|
|''Date:''|Jun 15, 2006|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev|
|''License:''|[[BSD open source license]]|
|''~CoreVersion:''|2.2|

Make minor configuration tweaks specific to Socialtext Unplugged
***/

//{{{
// Ensure that the SocialtextTweaksPlugin is only installed once.
if(!version.extensions.SocialtextTweaksPlugin) {
version.extensions.SocialtextTweaksPlugin = {installed:true};
// Check version number of core code
if(version.major < 2 || (version.major == 2 && version.minor < 2))
	{alertAndThrow("SocialtextTweaksPlugin requires TiddlyWiki 2.2 or later.");}

merge(config.defaultCustomFields,{
	wikiformat:'socialtext',
	'server.host':'https://saturn.ffzg.hr%2C%20saturn.ffzg.hr:443'
});

config.options.chkSinglePageMode = true;
config.options.chkEnableAnimations = true;

} // end of "install only once"
//}}}
/***
|''Name:''|SocialtextFormatterPlugin|
|''Description:''|Allows Tiddlers to use [[Socialtext|http://www.socialtext.com/]] text formatting|
|''Author:''|Martin Budden (mjbudden (at) gmail (dot) com)|
|''Source:''|http://www.martinswiki.com/#SocialtextFormatterPlugin|
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/formatters/SocialtextFormatterPlugin.js|
|''Version:''|0.9.4|
|''Date:''|Jan 21, 2007|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev|
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|''~CoreVersion:''|2.1.0|

This is the SocialtextFormatterPlugin, which allows you to insert Socialtext formated text into a TiddlyWiki.

The aim is not to fully emulate Socialtext, but to allow you to work with Socialtext content off-line and then resync the content with your Socialtext wiki later on, with the expectation that only minor edits will be required.

To use Socialtext format in a Tiddler, tag the Tiddler with SocialtextFormat or set the tiddler's {{{wikiformat}}} extended field to {{{socialtext}}}

Please report any defects you find at http://groups.google.co.uk/group/TiddlyWikiDev
***/

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

if(version.major < 2 || (version.major == 2 && version.minor < 1))
	{alertAndThrow('SocialtextFormatterPlugin requires TiddlyWiki 2.1 or later.');}

SocialtextFormatter = {}; // 'namespace' for local functions

wikify = function(source,output,highlightRegExp,tiddler)
{
	if(source && source != '') {
		var w = new Wikifier(source,getParser(tiddler),highlightRegExp,tiddler);
		var out = output;
		if(tiddler && (tiddler.isTagged(config.parsers.socialtextFormatter.formatTag) || (tiddler.fields.wikiformat==config.parsers.socialtextFormatter.format)) ) {
			var d1 = createTiddlyElement(output,'div','content-display-body','content-section-visible');
			var d2 = createTiddlyElement(d1,'div','wikipage');
			out = createTiddlyElement(d2,'div',null,'wiki');
		}
		var time1,time0 = new Date();
		w.subWikifyUnterm(out);
		if(tiddler && config.options.chkDisplayInstrumentation) {
			time1 = new Date();
			var t = tiddler ? tiddler.title : source.substr(0,10);
			displayMessage("Wikify '"+t+"' in " + (time1-time0) + " ms");
		}
	}
};

stDebug = function(out,str)
{
	createTiddlyText(out,str.replace(/\n/mg,'\\n').replace(/\r/mg,'RR'));
	createTiddlyElement(out,'br');
};

SocialtextFormatter.Tiddler_changed = Tiddler.prototype.changed;
Tiddler.prototype.changed = function()
{
	if((this.fields.wikiformat==config.parsers.socialtextFormatter.format) || this.isTagged(config.parsers.socialtextFormatter.formatTag)) {
		// update the links array, by checking for Socialtext format links
		this.links = [];
		var tiddlerLinkRegExp = /(?:\"(.*?)\" ?)?\[([^\]]*?)\]/mg;
		tiddlerLinkRegExp.lastIndex = 0;
		var match = tiddlerLinkRegExp.exec(this.text);
		while(match) {
			var link = match[2];
			this.links.pushUnique(link);
			match = tiddlerLinkRegExp.exec(this.text);
		}
	}/* else {
		return SocialtextFormatter.Tiddler_changed.apply(this,arguments);
	}*/
	this.linksUpdated = true;
};

SocialtextFormatter.wafl = function(w)
{
	this.lookaheadRegExp.lastIndex = w.matchStart;
	var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
	if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
		var lm2 = lookaheadMatch[2];
		switch(lookaheadMatch[1]) {
		case 'image':
			var img = createTiddlyElement(w.output,'img');
			img.src = w.tiddler.title + '/' + lm2;
			createTiddlyText(img,lm2);
			break;
		case 'file':
			var s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
			var a = createTiddlyElement(s,'a');
			a.href = w.tiddler.title + '/' + lm2;
			createTiddlyText(a,lm2);
			break;
		case 'link':
			s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
			a = createTiddlyElement(s,'a');
			var t = w.tiddler ? w.tiddler.title + ':' : '';
			a.setAttribute('href','#' + t + lm2);
			a.title = 'section link';
			createTiddlyText(a,lm2);
			break;
		case 'weblog':
			s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
			var text = lm2;
			var link = 'Weblog: ' + lm2;
			createTiddlyText(createTiddlyLink(s,link,false,null,w.isStatic),text);
			break;
		case 'section':
			a = createTiddlyElement(w.output,'a');// drop anchor
			t = w.tiddler ? w.tiddler.title + ':' : '';
			a.setAttribute('name',t + lm2);
			break;
		case 'date':
			createTiddlyText(w.output,lm2);
			break;
		case 'user':
			var oldSource = w.source;
			w.source = lm2;
			w.nextMatch = 0;
			w.subWikifyUnterm(w.output);
			w.source = oldSource;
			break;
// Shortcut expansions - not strictly syntax
		case 'google':
			s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
			a = createExternalLink(s,'http://www.google.com/search?q='+lm2);
			createTiddlyText(a,lm2);
			break;
		case 'fedex':
			s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
			a = createExternalLink(s,'http://www.fedex.com/Tracking?tracknumbers='+lm2);
			createTiddlyText(a,lm2);
			break;
		case 'map':
			s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
			a = createExternalLink(s,'http://maps.google.com/maps?q='+lm2);
			createTiddlyText(a,lm2);
			break;
		case 'wikipedia':
			s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
			a = createExternalLink(s,'http://en.wikipedia.org/wiki/'+lm2);
			createTiddlyText(a,lm2);
			break;
		case 'rt':
			s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
			a = createExternalLink(s,'http://rt.socialtext.net/Ticket/Display.html?id='+lm2);
			createTiddlyText(a,lm2);
			break;
		case 'stcal':
			s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
			a = createExternalLink(s,'https://calendar.socialtext.net:445/view_t.php?timeb=1&id=3&date='+lm2);
			createTiddlyText(a,lm2);
			break;
		case 'svn':
			s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
			a = createExternalLink(s,'https://repo.socialtext.net/listing.php?rev='+lm2+'sc=1');
			createTiddlyText(a,lm2);
			break;
		default:
			w.outputText(w.output,w.matchStart,w.nextMatch);
			return;
		}
		w.nextMatch = this.lookaheadRegExp.lastIndex;
	} else {
		w.outputText(w.output,w.matchStart,w.nextMatch);
	}
};

SocialtextFormatter.presence = function(w)
{
	this.lookaheadRegExp.lastIndex = w.matchStart;
	var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
	if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
		var p = lookaheadMatch[1];
		var text = lookaheadMatch[2];
		var link;
		var src;
		if(p=='aim') {
			link = 'aim:goim?screenname=' + text + '&message=hello';
			src = 'http://big.oscar.aol.com/sleepleft?on_url=http://www.aim.com/remote/gr/MNB_online.gif&amp;off_url=http://www.aim.com/remote/gr/MNB_offline.gif';
		} else if(p=='yahoo'||p=='ymsgr') {
			link = 'ymsgr:sendIM?'+text;
			src = 'http://opi.yahoo.com/online?u=chrislondonbridge&f=.gif';
		} else if(p=='skype'||p=='callto') {
			link = 'callto:'+text;
			src = 'http://goodies.skype.com/graphics/skypeme_btn_small_green.gif';
		} else if(p=='asap') {
			link = 'http://asap2.convoq.com/AsapLinks/Meet.aspx?l='+text;
			src = 'http://asap2.convoq.com/AsapLinks/Presence.aspx?l='+text;
		}
		var s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
		var a = createExternalLink(s,link);
		var img = createTiddlyElement(a,'img');
		createTiddlyText(a,text);
		img.src = src;
		img.border='0';
		img.alt = '(' + lookaheadMatch[1] + ')';
		if(p=='aim') {
			img.width='11'; img.height='13';
		}
		w.nextMatch = this.lookaheadRegExp.lastIndex;
	}
};

config.formatterHelpers.singleCharFormat = function(w)
{
	this.lookaheadRegExp.lastIndex = w.matchStart;
	var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
	if(lookaheadMatch && lookaheadMatch.index == w.matchStart && lookaheadMatch[0].substr(lookaheadMatch[0].length-2,1) != ' ') {
		w.subWikifyTerm(createTiddlyElement(w.output,this.element),this.termRegExp);
	} else {
		w.outputText(w.output,w.matchStart,w.nextMatch);
	}
};

config.socialtext = {};
config.socialtext.formatters = [
{
	name: 'socialtextHeading',
	match: '^\\^{1,6} ?',
	termRegExp: /(\n+)/mg,
	handler: function(w)
	{
		var len = w.matchText.trim().length;
		var e = createTiddlyElement(w.output,'h' + len);
		var a = createTiddlyElement(e,'a');// drop anchor
		var t = w.tiddler ? w.tiddler.title + ':' : '';
		len = w.source.substr(w.nextMatch).indexOf('\n');
		a.setAttribute('name',t+w.source.substr(w.nextMatch,len));
		w.subWikifyTerm(e,this.termRegExp);
	}
},

{
	name: 'socialtextTable',
	match: '^\\|(?:(?:.|\n)*)\\|$',
	lookaheadRegExp: /^\|(?:(?:.|\n)*)\|$/mg,
	cellRegExp: /(?:\|(?:[^\|]*)\|)(\n|$)?/mg,
	cellTermRegExp: /((?:\x20*)\|)/mg,
	handler: function(w)
	{
		var table = createTiddlyElement(w.output,'table');
		var rowContainer = createTiddlyElement(table,'tbody');
		var prevColumns = [];
		w.nextMatch = w.matchStart;
		this.lookaheadRegExp.lastIndex = w.nextMatch;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		while(lookaheadMatch && lookaheadMatch.index == w.nextMatch) {
			var r = this.rowHandler(w,createTiddlyElement(rowContainer,'tr'),prevColumns);
			if(!r) {
				w.nextMatch++;
				break;
			}
			this.lookaheadRegExp.lastIndex = w.nextMatch;
			lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		}
	},
	rowHandler: function(w,e,prevColumns)
	{
		this.cellRegExp.lastIndex = w.nextMatch;
		var cellMatch = this.cellRegExp.exec(w.source);
		while(cellMatch && cellMatch.index == w.nextMatch) {
			w.nextMatch++;
			var cell = createTiddlyElement(e,'td');
			w.subWikifyTerm(cell,this.cellTermRegExp);
			if(cellMatch[1]) {
				// End of row
				w.nextMatch = this.cellRegExp.lastIndex;
				return true;
			}
			// Cell
			w.nextMatch--;
			this.cellRegExp.lastIndex = w.nextMatch;
			cellMatch = this.cellRegExp.exec(w.source);
		}
		return false;
	}
},

{
	name: 'socialtextList',
	match: '^[\\*#]+ ',
	lookaheadRegExp: /^([\*#])+ /mg,
	termRegExp: /(\n+)/mg,
	handler: function(w)
	{
		var stack = [w.output];
		var currLevel = 0, currType = null;
		var itemType = 'li';
		w.nextMatch = w.matchStart;
		this.lookaheadRegExp.lastIndex = w.nextMatch;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		while(lookaheadMatch && lookaheadMatch.index == w.nextMatch) {
			var listType = lookaheadMatch[1] == '*' ? 'ul' : 'ol';
			var listLevel = lookaheadMatch[0].length;
			w.nextMatch += listLevel;
			if(listLevel > currLevel) {
				for(var i=currLevel; i<listLevel; i++) {
					stack.push(createTiddlyElement(stack[stack.length-1],listType));
				}
			} else if(listLevel < currLevel) {
				for(i=currLevel; i>listLevel; i--) {
					stack.pop();
				}
			} else if(listLevel == currLevel && listType != currType) {
				stack.pop();
				stack.push(createTiddlyElement(stack[stack.length-1],listType));
			}
			currLevel = listLevel;
			currType = listType;
			var e = createTiddlyElement(stack[stack.length-1],itemType);
			w.subWikifyTerm(e,this.termRegExp);
			this.lookaheadRegExp.lastIndex = w.nextMatch;
			lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		}
	}
},

{
	name: 'socialtextQuoteByLine',
	match: '^>+',
	lookaheadRegExp: /^>+/mg,
	termRegExp: /(\n)/mg,
	element: 'blockquote',
	handler: function(w)
	{
		var stack = [w.output];
		var currLevel = 0;
		var newLevel = w.matchLength;
		var i;
		do {
			if(newLevel > currLevel) {
				for(i=currLevel; i<newLevel; i++) {
					stack.push(createTiddlyElement(stack[stack.length-1],this.element));
				}
			} else if(newLevel < currLevel) {
				for(i=currLevel; i>newLevel; i--) {
					stack.pop();
				}
			}
			currLevel = newLevel;
			w.subWikifyTerm(stack[stack.length-1],this.termRegExp);
			createTiddlyElement(stack[stack.length-1],'br');
			this.lookaheadRegExp.lastIndex = w.nextMatch;
			var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
			var matched = lookaheadMatch && lookaheadMatch.index == w.nextMatch;
			if(matched) {
				newLevel = lookaheadMatch[0].length;
				w.nextMatch += newLevel;
			}
		} while(matched);
	}
},

{
	name: 'socialtextRule',
	match: '^----+$\\n+',
	handler: function(w)
	{
		createTiddlyElement(w.output,'hr');
	}
},

{
	name: 'socialtextPreformatted',
	match: '^\\.pre\\s*\\n',
	lookaheadRegExp: /^.pre\s*\n((?:.|\n)*?)\n.pre\s*\n/mg,
	element: 'pre',
	handler: config.formatterHelpers.enclosedTextHelper
},

{
	name: 'socialtextHtml',
	match: '^\\.html',
	lookaheadRegExp: /\.html((?:.|\n)*?)\.html/mg,
	handler: function(w)
	{
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
			createTiddlyElement(w.output,'span').innerHTML = lookaheadMatch[1];
			w.nextMatch = this.lookaheadRegExp.lastIndex;
		}
	}
},

{
	name: 'macro',
	match: '<<',
	lookaheadRegExp: /<<([^>\s]+)(?:\s*)((?:[^>]|(?:>(?!>)))*)>>/mg,
	handler: function(w)
	{
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart && lookaheadMatch[1]) {
			w.nextMatch = this.lookaheadRegExp.lastIndex;
			invokeMacro(w.output,lookaheadMatch[1],lookaheadMatch[2],w,w.tiddler);
		}
	}
},

{
	name: 'socialtextExplicitLink',
	match: '(?:".*?" ?)?\\[',
	lookaheadRegExp: /(?:\"(.*?)\" ?)?\[([^\]]*?)\]/mg,
	handler: function(w)
	{
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
			var link = lookaheadMatch[2];
			var text = lookaheadMatch[1] ? lookaheadMatch[1] : link;
			createTiddlyText(createTiddlyLink(w.output,link,false,null,w.isStatic,w.tiddler),text);
			w.nextMatch = this.lookaheadRegExp.lastIndex;
		}
	}
},

{
	name: 'socialtextExternalLink',
	match: '(?:".*?" ?)?<[a-z]{2,8}:',
	lookaheadRegExp: /(?:\"(.*?)\" ?)?<([a-z]{2,8}:.*?)>/mg,
	imgRegExp: /\.(?:gif|ico|jpg|png)/g,
	handler: function(w)
	{
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
			var link = lookaheadMatch[2];
			var text = lookaheadMatch[1] ? lookaheadMatch[1] : link;
			this.imgRegExp.lastIndex = 0;
			if(this.imgRegExp.exec(link)) {
				var img = createTiddlyElement(w.output,'img');
				if(lookaheadMatch[1]) {
					img.title = text;
				}
				img.alt = text;
				img.src = link;
			} else {
				createTiddlyText(createExternalLink(w.output,link),text);
			}
			w.nextMatch = this.lookaheadRegExp.lastIndex;
		}
	}
},

{
	name: 'socialtextUrlLink',
	match: config.textPrimitives.urlPattern,
	handler: function(w)
	{
		w.outputText(createExternalLink(w.output,w.matchText),w.matchStart,w.nextMatch);
	}
},

{
	name: 'socialtextBold',
	match: '\\*(?![\\s\\*])',
	lookaheadRegExp: /\*(?!\s)(?:.*?)(?!\s)\*(?=[$\s\|\._\-,])/mg,
	termRegExp: /((?!\s)\*(?=[$\s\|\.\-_,]))/mg,
	element: 'strong',
	handler: config.formatterHelpers.singleCharFormat
},

{
	name: 'socialtextItalic',
	match: '_(?![\\s_])',
	lookaheadRegExp: /_(?!\s)(?:.*?)(?!\s)_(?=[$\s\|\.\*\-,])/mg,
	termRegExp: /((?!\s)_(?=[$\s\|\.\*\-,]))/mg,
	element: 'em',
	handler: config.formatterHelpers.singleCharFormat
},

{
	name: 'socialtextStrike',
	match: '-(?![\\s\\-])',
	lookaheadRegExp: /-(?!\s)(?:.*?)(?!\s)-(?=[$\s\|\.\*_,])/mg,
	termRegExp: /((?!\s)-(?=[$\s\|\.\*_,]))/mg,
	element: 'del',
	handler: config.formatterHelpers.singleCharFormat
},

{
	name: 'socialtextMonoSpaced',
	match: '`(?![\\s`])',
	lookaheadRegExp: /`(?!\s)(?:.*?)(?!\s)`(?=[$\s\.\*\-_,])/mg,
	termRegExp: /((?!\s)`(?=[$\s\.\*\-_,]))/mg,
	element: 'tt',
	handler: config.formatterHelpers.singleCharFormat
},

{
	name: 'socialtextParagraph',
	match: '\\n{2,}',
	handler: function(w)
	{
		createTiddlyElement(w.output,'p');
	}
},

{
	name: 'socialtextLineBreak',
	match: '\\n',
	handler: function(w)
	{
		createTiddlyElement(w.output,'br');
	}
},

{
	name: 'socialtextNoWiki',
	match: '\\{\\{',
	lookaheadRegExp: /\{\{((?:.|\n)*?)\}\}/mg,
	element: 'span',
	handler: config.formatterHelpers.enclosedTextHelper
},

{
	name: 'socialtextTrademark',
	match: '\\{tm\\}',
	handler: function(w)
	{
		createTiddlyElement(w.output,'span').innerHTML = '&trade;';
	}
},

{
	name: 'socialtextWafl',
	match: '\\{(?:[a-z]{2,16}): ?.*?\\}',
	lookaheadRegExp: /\{([a-z]{2,16}): ?(.*?)\}/mg,
	handler: SocialtextFormatter.wafl
},

{
	name: 'socialtextPresence',
	match: '(?:aim|yahoo|ymsgr|skype|callto|asap):\\w+',
	lookaheadRegExp: /(aim|yahoo|ymsgr|skype|callto|asap):(\w+)/mg,
	handler: SocialtextFormatter.presence
},

{
	name: 'socialtextMailTo',
	match: '[\\w\.]+@[\\w]+\.[\\w\.]+',
	lookaheadRegExp: /([\w\.]+@[\w]+\.[\w\.]+)/mg,
	handler: function(w)
	{
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
			var text = lookaheadMatch[1];
			createTiddlyText(createExternalLink(w.output,'mailto:'+text),text);
			w.nextMatch = this.lookaheadRegExp.lastIndex;
		}
	}
},

{
	name: 'socialtextHtmlEntitiesEncoding',
	match: '&#?[a-zA-Z0-9]{2,8};',
	handler: function(w)
	{
		createTiddlyElement(w.output,'span').innerHTML = w.matchText;
	}
}
];

config.parsers.socialtextFormatter = new Formatter(config.socialtext.formatters);
config.parsers.socialtextFormatter.format = 'socialtext';
config.parsers.socialtextFormatter.formatTag = 'SocialtextFormat';

} // end of 'install only once'
//}}}
/***
|''Name:''|SocialtextAdaptorPlugin|
|''Description:''|Adaptor for moving and converting data to and from Socialtext Wikis|
|''Author:''|Martin Budden (mjbudden (at) gmail (dot) com) and JeremyRuston (jeremy (at) osmosoft (dot) com)|
|''Source:''|http://www.martinswiki.com/#SocialtextAdaptorPlugin|
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/adaptors/SocialtextAdaptorPlugin.js|
|''Version:''|0.5.1|
|''Date:''|Feb 25, 2007|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev|
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|''~CoreVersion:''|2.2.0|

Socialtext REST documentation is at:
http://www.eu.socialtext.net/st-rest-docs/index.cgi?socialtext_rest_documentation

***/

//{{{
if(!version.extensions.SocialtextAdaptorPlugin) {
version.extensions.SocialtextAdaptorPlugin = {installed:true};

function SocialtextAdaptor()
{
	this.host = null;
	this.workspace = null;
	return this;
}

SocialtextAdaptor.mimeType = 'text/x.socialtext-wiki';
SocialtextAdaptor.serverType = 'socialtext';
SocialtextAdaptor.serverParsingErrorMessage = "Error parsing result from server";
SocialtextAdaptor.errorInFunctionMessage = "Error in function SocialtextAdaptor.%0";

SocialtextAdaptor.prototype.setContext = function(context,userParams,callback)
{
	if(!context) context = {};
	context.userParams = userParams;
	if(callback) context.callback = callback;
	context.adaptor = this;
	if(!context.host)
		context.host = this.host;
	if(!context.workspace && this.workspace)
		context.workspace = this.workspace;
	return context;
};

SocialtextAdaptor.doHttpGET = function(uri,callback,params,headers,data,contentType,username,password)
{
	return doHttp('GET',uri,data,contentType,username,password,callback,params,headers);
};

SocialtextAdaptor.doHttpPOST = function(uri,callback,params,headers,data,contentType,username,password)
{
	return doHttp('POST',uri,data,contentType,username,password,callback,params,headers);
};

SocialtextAdaptor.fullHostName = function(host)
{
	if(!host)
		return '';
	if(!host.match(/:\/\//))
		host = 'http://' + host;
	if(host.substr(host.length-1) != '/')
		host = host + '/';
	return host;
};

SocialtextAdaptor.minHostName = function(host)
{
	return host ? host.replace(/^http:\/\//,'').replace(/\/$/,'') : '';
};

// Convert a page title to the normalized form used in uris
SocialtextAdaptor.normalizedTitle = function(title)
{
	var n = title.toLowerCase();
	n = n.replace(/\s/g,'_').replace(/\//g,'_').replace(/\./g,'_').replace(/:/g,'').replace(/\?/g,'');
	if(n.charAt(0)=='_')
		n = n.substr(1);
	return String(n);
};

// Convert a Socialtext date in YYYY-MM-DD hh:mm format into a JavaScript Date object
SocialtextAdaptor.dateFromEditTime = function(editTime)
{
	var dt = editTime;
	return new Date(Date.UTC(dt.substr(0,4),dt.substr(5,2)-1,dt.substr(8,2),dt.substr(11,2),dt.substr(14,2)));
};

SocialtextAdaptor.prototype.openHost = function(host,context,userParams,callback)
{
	this.host = SocialtextAdaptor.fullHostName(host);
	context = this.setContext(context,userParams,callback);
	if(context.callback) {
		context.status = true;
		window.setTimeout(function() {callback(context,userParams);},0);
	}
	return true;
};

SocialtextAdaptor.prototype.openWorkspace = function(workspace,context,userParams,callback)
{
	this.workspace = workspace;
	context = this.setContext(context,userParams,callback);
	if(context.callback) {
		context.status = true;
		window.setTimeout(function() {callback(context,userParams);},0);
	}
	return true;
};


SocialtextAdaptor.prototype.getWorkspaceList = function(context,userParams,callback)
{
	context = this.setContext(context,userParams,callback);
	var uriTemplate = '%0data/workspaces';
	var uri = uriTemplate.format([context.host]);
	var req = SocialtextAdaptor.doHttpGET(uri,SocialtextAdaptor.getWorkspaceListCallback,context,{'accept':'application/json'});
	return typeof req == 'string' ? req : true;
};

SocialtextAdaptor.getWorkspaceListCallback = function(status,context,responseText,uri,xhr)
{
	context.status = false;
	context.statusText = SocialtextAdaptor.errorInFunctionMessage.format(['getWorkspaceListCallback']);
	if(status) {
		try {
			eval('var info=' + responseText);
		} catch (ex) {
			context.statusText = exceptionText(ex,SocialtextAdaptor.serverParsingErrorMessage);
			if(context.callback)
				context.callback(context,context.userParams);
			return;
		}
		var list = [];
		for(var i=0; i<info.length; i++) {
			var item = {
				title:info[i].title,
				name:info[i].name,
				modified:SocialtextAdaptor.dateFromEditTime(info[i].modified_time)
				};
			list.push(item);
		}
		context.workspaces = list;
		context.status = true;
	} else {
		context.statusText = xhr.statusText;
	}
	if(context.callback)
		context.callback(context,context.userParams);
};

SocialtextAdaptor.prototype.getTiddlerList = function(context,userParams,callback)
{
	context = this.setContext(context,userParams,callback);
	var uriTemplate = '%0data/workspaces/%1/pages?order=newest';//!! ? or ;
	var uri = uriTemplate.format([context.host,context.workspace]);
	var req = SocialtextAdaptor.doHttpGET(uri,SocialtextAdaptor.getTiddlerListCallback,context,{'accept':'application/json'});
	return typeof req == 'string' ? req : true;
};


SocialtextAdaptor.getTiddlerListCallback = function(status,context,responseText,uri,xhr)
{
	context.status = false;
	context.statusText = SocialtextAdaptor.errorInFunctionMessage.format(['getTiddlerListCallback']);
	if(status) {
		try {
			eval('var info=' + responseText);
		} catch (ex) {
			context.statusText = exceptionText(ex,SocialtextAdaptor.serverParsingErrorMessage);
			if(context.callback)
				context.callback(context,context.userParams);
			return;
		}
		var list = [];
		for(var i=0; i<info.length; i++) {
			var tiddler = new Tiddler(info[i].name);
			tiddler.modified = SocialtextAdaptor.dateFromEditTime(info[i].last_edit_time);
			tiddler.modifier = info[i].last_editor;
			tiddler.tags = info[i].tags;
			tiddler.fields['server.page.id'] = info[i].page_id;
			tiddler.fields['server.page.name'] = info[i].name;
			tiddler.fields['server.page.revision'] = String(info[i].revision_id);
			list.push(tiddler);
		}
		context.tiddlers = list;
		context.status = true;
	} else {
		context.statusText = xhr.statusText;
	}
	if(context.callback)
		context.callback(context,context.userParams);
};

SocialtextAdaptor.prototype.generateTiddlerInfo = function(tiddler)
{
	var info = {};
	var host = this && this.host ? this.host : SocialtextAdaptor.fullHostName(tiddler.fields['server.host']);
	var workspace = this && this.workspace ? this.workspace : tiddler.fields['server.workspace'];
	uriTemplate = '%0%1/index.cgi?%2';
	info.uri = uriTemplate.format([host,workspace,SocialtextAdaptor.normalizedTitle(tiddler.title)]);
	return info;
};

SocialtextAdaptor.prototype.getTiddler = function(title,context,userParams,callback)
{
	return this.getTiddlerRevision(title,null,context,userParams,callback);
};

SocialtextAdaptor.prototype.getTiddlerRevision = function(title,revision,context,userParams,callback)
{
	context = this.setContext(context,userParams,callback);

	// request the page in json format to get the page attributes
	if(revision) {
		var uriTemplate = '%0data/workspaces/%1/pages/%2/revisions/%3';
		context.revision = revision;
	} else {
		uriTemplate = '%0data/workspaces/%1/pages/%2';
		context.revision = null;
	}
	uri = uriTemplate.format([context.host,context.workspace,SocialtextAdaptor.normalizedTitle(title),revision]);

	context.tiddler = new Tiddler(title);
	context.tiddler.fields.wikiformat = 'socialtext';
	context.tiddler.fields['server.host'] = SocialtextAdaptor.minHostName(context.host);
	context.tiddler.fields['server.workspace'] = context.workspace;
	var req = SocialtextAdaptor.doHttpGET(uri,SocialtextAdaptor.getTiddlerCallback,context,{'accept':'application/json'});
	return typeof req == 'string' ? req : true;
};


SocialtextAdaptor.getTiddlerCallback = function(status,context,responseText,uri,xhr)
{
	context.status = false;
	context.statusText = SocialtextAdaptor.errorInFunctionMessage.format(['getTiddlerCallback']);
	if(status) {
		try {
			eval('var info=' + responseText);
			context.tiddler.tags = info.tags;
			context.tiddler.fields['server.page.id'] = info.page_id;
			context.tiddler.fields['server.page.name'] = info.name;
			context.tiddler.fields['server.page.revision'] = String(info.revision_id);
			context.tiddler.modifier = info.last_editor;
			context.tiddler.modified = SocialtextAdaptor.dateFromEditTime(info.last_edit_time);
		} catch (ex) {
			context.statusText = exceptionText(ex,SocialtextAdaptor.serverParsingErrorMessage);
			if(context.callback)
				context.callback(context,context.userParams);
			return;
		}
		context.status = true;
	} else {
		context.statusText = xhr.statusText;
		if(context.callback)
			context.callback(context,context.userParams);
		return;
	}
	var uriTemplate = context.revision ? '%0data/workspaces/%1/pages/%2/revisions/%3' : '%0data/workspaces/%1/pages/%2';
	var host = SocialtextAdaptor.fullHostName(context.tiddler.fields['server.host']);
	var workspace = context.workspace ? context.workspace : context.tiddler.fields['server.workspace'];
	uri = uriTemplate.format([host,workspace,SocialtextAdaptor.normalizedTitle(context.tiddler.title),context.revision]);
	var req = SocialtextAdaptor.doHttpGET(uri,SocialtextAdaptor.getTiddlerCallback2,context,{'accept':SocialtextAdaptor.mimeType});
};

SocialtextAdaptor.getTiddlerCallback2 = function(status,context,responseText,uri,xhr)
{
	context.tiddler.text = responseText;
	if(status) {
		context.status = true;
	} else {
		context.status = false;
		context.statusText = xhr.statusText;
	}
	if(context.callback)
		context.callback(context,context.userParams);
};

SocialtextAdaptor.prototype.getTiddlerRevisionList = function(title,limit,context,userParams,callback)
{
	context = this.setContext(context,userParams,callback);

	var uriTemplate = '%0data/workspaces/%1/pages/%2/revisions?accept=application/json';
	if(!limit)
		limit = 5;
	var uri = uriTemplate.format([context.host,context.workspace,SocialtextAdaptor.normalizedTitle(title),limit]);

	var req = SocialtextAdaptor.doHttpGET(uri,SocialtextAdaptor.getTiddlerRevisionListCallback,context);
	return typeof req == 'string' ? req : true;
};

SocialtextAdaptor.getTiddlerRevisionListCallback = function(status,context,responseText,uri,xhr)
{
	context.status = false;
	if(status) {
		var content = null;
		try {
			eval('var info=' + responseText);
		} catch (ex) {
			context.statusText = exceptionText(ex,SocialtextAdaptor.serverParsingErrorMessage);
			if(context.callback)
				context.callback(context,context.userParams);
			return;
		}
		list = [];
		for(var i=0; i<info.length; i++) {
			var tiddler = new Tiddler(info[i].name);
			tiddler.modified = SocialtextAdaptor.dateFromEditTime(info[i].last_edit_time);
			tiddler.modifier = info[i].last_editor;
			tiddler.tags = info[i].tags;
			tiddler.fields['server.page.id'] = info[i].page_id;
			tiddler.fields['server.page.name'] = info[i].name;
			tiddler.fields['server.page.revision'] = info[i].revision_id;
			list.push(tiddler);
		}
		var sortField = 'server.page.revision';
		list.sort(function(a,b) {return a.fields[sortField] < b.fields[sortField] ? +1 : (a.fields[sortField] == b.fields[sortField] ? 0 : -1);});
		context.revisions = list;
		context.status = true;
	} else {
		context.statusText = xhr.statusText;
	}
	if(context.callback)
		context.callback(context,context.userParams);
};

SocialtextAdaptor.prototype.putTiddler = function(tiddler,context,userParams,callback)
{
	context = this.setContext(context,userParams,callback);
	context.tiddler = tiddler;
	context.title = tiddler.title;
	var uriTemplate = '%0data/workspaces/%1/pages/%2';
	var host = context.host ? context.host : SocialtextAdaptor.fullHostName(tiddler.fields['server.host']);
	var workspace = context.workspace ? context.workspace : tiddler.fields['server.workspace'];
	var uri = uriTemplate.format([host,workspace,tiddler.title,tiddler.text]);
	//var req = doHttp('POST',uri,tiddler.text,SocialtextAdaptor.mimeType,null,null,SocialtextAdaptor.putTiddlerCallback,context,{"X-Http-Method": "PUT"});
	var req = SocialtextAdaptor.doHttpPOST(uri,SocialtextAdaptor.putTiddlerCallback,context,{"X-Http-Method": "PUT"},tiddler.text,SocialtextAdaptor.mimeType);
	return typeof req == 'string' ? req : true;
};

SocialtextAdaptor.putTiddlerCallback = function(status,context,responseText,uri,xhr)
{
	if(status) {
		context.status = true;
	} else {
		context.status = false;
		context.statusText = xhr.statusText;
	}
	if(context.callback)
		context.callback(context,context.userParams);
};

SocialtextAdaptor.prototype.close = function()
{
	return true;
};

config.adaptors[SocialtextAdaptor.serverType] = SocialtextAdaptor;
} //# end of 'install only once'
//}}}
/***
SocialtextStyleOverrides
***/

/*{{{*/
.headerShadow {padding: 2em 0em .5em 1em;}
.headerForeground {padding: 2em 0em .5em 1em;}

#st-page-wiki-title {
	font-size: 80%;
}
.subtitle {
	font-style: italic;
	font-size 80%;
}

/* from #st-tags */
.tagged {
	border-color: #bbeebb;
	background-color: #f4fff4;
}

.tagged .listTitle {
	color: #595;
	font-weight: bold;
}

.tagged .button {
	color: #000;
}

.selected .tagged {
	background-color: ColorPalette::TertiaryLight;
	border: 1px solid ColorPalette::TertiaryMid;
}

/* from #st-incoming-links */
.tagging {
	border-color: #ebb;
	background-color: #fff4f4;
}

.tagging .listTitle {
	color: #b78;
	font-weight: bold;
}

.tagging .button {
	color: #999;
}

.selected .tagging {
	background-color: ColorPalette::TertiaryLight;
	border: 1px solid ColorPalette::TertiaryMid;
}

.tiddler {/* Tiddler body */
	border:1px solid #ccc;
	margin:0.5em;
	background:#fff;
	padding:0.5em;
}

.viewer blockquote {border-left: 0px solid}

.tiddlyLinkNonExisting {
	font-style: italic;
	border-bottom: 1px dashed;
}

.editor input, .editor textarea {
	background: #ffd;
	border-style: solid;
	border-color: #888 #ccc #ccc #888;
	border-width: 2px;
}

.tabContents {white-space: nowrap;}

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

#sidebar {
	position: absolute;
	right: 3px;
	width: 21em;
	font-size: .9em;
}

#sidebarOptions .button {
	border-color: #eee;
}

#sidebarTabs .tabContents {
	width: 20em;
	overflow: hidden;
}

.viewer tt {
	font-size: 1.2em;
	line-height: 1.4em;
}

ul {list-style-type: square;}
ul ul {list-style-type: circle;}

ol {list-style-type: decimal;}
ol ol {list-style-type: decimal;}
ol ol ol {list-style-type: decimal;}
ol ol ol ol {list-style-type: decimal;}
ol ol ol ol ol {list-style-type: decimal;}
ol ol ol ol ol ol {list-style-type: decimal;}

/*}}}*/
/***
SocialtextScreenStyle
http://www.eu.socialtext.net/static/2.0.0.1/css/st/screen.css
***/

/*{{{*/
body {
	font-family: Arial, sans-serif;
	color: #000;
	background: #eee;
	margin: 0;
}

/* Wiki Navigation */

.st-wiki-nav {
	clear: both;
	margin-left: 10px;
	margin-right: 10px;
}
.st-wiki-nav-content {
	background: url('../../images/st/wiki-nav/solid.gif') repeat-x left bottom;
	margin-left: 24px;
	margin-right: 24px;
	padding-top: 3px;
	min-height: 24px;
}
* html .st-wiki-nav-content {
	padding-bottom: 3px;
	height: 24px;
}

.st-wiki-nav-right {
	background: url('../../images/st/wiki-nav/right-round.gif') no-repeat bottom right;
}

.st-wiki-nav-left {
	background: url('../../images/st/wiki-nav/left-round.gif') no-repeat bottom left;
}

#st-home {
	float: left;
	margin-right: 60px;
	padding-top: 2px;
}

#st-home-link {
	color: white;
	text-decoration: none;
	font-weight: bold;
	font-family: Helvetica, sans-serif;
	font-size: 90%;
}

#st-editing-prefix-container {
	border-collapse: collapse;
	width: 100%;
	padding: 0px;
	margin: 0px;
	margin-bottom: -20px;
}

#st-editing-prefix-container tr td {
	margin: 0px;
	padding: 0px;
}

#st-editing-title {
	color: black;
	background-color: white;
	text-decoration: none;
	font-weight: bold;
	font-family: Helvetica, sans-serif;
	font-size: 90%;
	margin-bottom: 0.4em;
}

#st-wiki-title-invite {
	font-size: 50%;
	font-family: Helvetica, sans-serif;
}

#st-wiki-title-central-page-link {
	font-size: 50%;
	font-family: Helvetica, sans-serif;
}

#st-wiki-title-invite a {
	color: #00f;
}

#st-wiki-logo {
	text-align: center;
	clear: both;
}

#st-wiki-logo-image {
}

.st-wiki-nav-actions {
	float: right;
	color: black;
	font-size: 75%;
	padding-top: 3px;
}

.st-wiki-nav-actions a {
	padding: 2px;
	color: white;
	text-decoration: none;
	font-family: Helvetica, sans-serif;
}

/* Wiki Subnav */

#st-wiki-subnav {
	margin-top: 2px;
	font-size: 70%;
	font-weight: bold;
	font-family: Helvetica, sans-serif;
	color: #888;
}

#st-wiki-subnav a {
	padding: 2px;
	color: #008;
	text-decoration: none;
}

#st-wiki-subnav-right {
	float: right;
	margin-right: 6em;
}

#st-wiki-subnav-left {
	float: left;
	margin-left: 6em;
}
* html #st-wiki-subnav-left {
	margin-left: 3em;
}

/* Wiki Navigation Search Bar */

#st-search-form {
	margin: 0;
	padding: 0;
	padding-top: 1px;
}

#st-search-form .button-table {
	float: left;
	font-size: 79%;
	font-weight: bold;
	margin-left: 5px;
	margin-top: 1px;
}

#st-search-form #st-search-term {
	float: left;
	font-size: 60%;
}

/* Content Outline */

#st-content-border, #st-edit-border {
	position: relative;
	clear: both;
	margin-left: 3px;
	margin-right: 2px;
	margin-bottom: 0px;
	margin-top: 0px;
	border-bottom: 1px solid #eee;
}

#st-content-border-left, #st-edit-border-left {
	background: url('../../images/st/page-shadow/left.gif') left top repeat-y;
	position: relative;
}

#st-content-border-right, #st-edit-border-right {
	background: url('../../images/st/page-shadow/right.gif') right top repeat-y;
	position: relative;
}

#st-content-border-top, #st-edit-border-top {
	position: relative;
	background: url('../../images/st/page-shadow/top.gif') left top repeat-x;
}

#st-content-border-bottom, #st-edit-border-bottom {
	background: url('../../images/st/page-shadow/bottom.gif') left bottom repeat-x;
	position: relative;
}

#st-content-border-left-top, #st-edit-border-left-top {
	background: url('../../images/st/page-shadow/left-top.gif') left top no-repeat;
	position: relative;
}
#st-content-border-right-top, #st-edit-border-right-top {
	background: url('../../images/st/page-shadow/right-top.gif') right top no-repeat;
	position: relative;
}

#st-content-border-left-bottom, #st-edit-border-left-bottom {
	background: url('../../images/st/page-shadow/left-bottom.gif') left bottom no-repeat;
	position: relative;
}

#st-content-border-right-bottom, #st-edit-border-right-bottom {
	background: url('../../images/st/page-shadow/right-bottom.gif') right bottom no-repeat;
	padding-top: 5px;
	padding-bottom: 9px;
	position: relative;
}

* html #st-content-border-right-bottom, * html #st-edit-border-right-bottom {
	padding-top: 4px;
	padding-left: 7px;
	padding-right: 8px;
	position: relative;
}

.st-content-width-controller {
	width: 100%;
	position: relative;
	border-collapse: collapse;
}
.st-content-width-controller td {
	vertical-align: top;
}
.st-content {
	position: relative;
	background-color: white;
	margin-top: 0px;
	margin-left: 7px;
	margin-right: 8px;
	margin-bottom: -1px;
	border-left: 1px dotted #80a9f3;
	border-right: 1px dotted #80a9f3;
	border: 1px solid #80a9f3;
	padding: 6px 12px 12px 12px;
}
* html .st-content {
	margin-top: 0px;
	margin-left: 0px;
	margin-right: 0px;
}

/* This textarea is only for Safari. However, if we use display:none; here Safari ignores the .value operation in JS */
#st-raw-wikitext-textarea {
	width:1px;
	height:1px;
	margin:0;
	padding:0;
}

/* Action Buttons */
.button-table, .button-table tr td {
	border-collapse: collapse;
	margin: 0;
	padding: 0;
}
.button-rounded {
	background: url('../../images/st/grey-button/left-top-rounded.png') top left no-repeat;
	margin: 0;
}
.button-rounded-right-top {
	background: url('../../images/st/grey-button/right-top-rounded.png') top right no-repeat;
	margin: 0;
}
.button-rounded-left-bottom {
	background: url('../../images/st/grey-button/left-bottom-rounded.png') bottom left no-repeat;
	margin: 0;
}
.button-rounded-right-bottom {
	background: url('../../images/st/grey-button/right-bottom-rounded.png') bottom right no-repeat;
	margin: 0;
}
.button-straight {
	background: url('../../images/st/grey-button/left-top-straight.png') top left no-repeat;
	margin: 0;
}
.button-straight-right-top {
	background: url('../../images/st/grey-button/right-top-straight.png') top right no-repeat;
	margin: 0;
}
.button-straight-left-bottom {
	background: url('../../images/st/grey-button/left-bottom-straight.png') bottom left no-repeat;
	margin: 0;
}
.button-straight-right-bottom {
	background: url('../../images/st/grey-button/right-bottom-straight.png') bottom right no-repeat;
	margin: 0;
}
.button-content {
	font-size: 90%;
}
.button-content a {
	display: block;
	padding: 2px;
	padding-left: 10px;
	padding-right: 10px;
	font-family: Helvetica, Verdana, sans-serif;
	font-weight: bold;
	text-decoration: none;
	color: black;
}

.button-content input.submit {
	border: 0px;
	padding: 2px;
	padding-left: 10px;
	padding-right: 10px;
	font-family: Helvetica, Verdana, sans-serif;
	font-weight: bold;
	text-decoration: none;
	color: black;
	background-color: transparent;
}

/* Personal Homepage */

#st-homepage {
	background: white url('../../images/st/homepage/blue-fade.gif') top left no-repeat;
}

#st-homepage-layout {
	margin-top: 15px;
	clear: both;
	width: 100%;
	border-collapse: collapse;
}

#st-homepage-layout tr td.st-homepage-layout-cell {
	padding: 5px;
	vertical-align: top;
}

#st-homepage-layout-dashboard {
	width: 50%
}

#st-homepage-layout-notes {
	width: 50%;
}

#st-homepage-notes, #st-homepage-dashboard {
	text-align: left;
	width: 95%;
}

#st-user-greeting, #st-wiki-title {
	font-family: Helvetica, Verdana, sans-serif;
	font-size: 150%;
}
#st-wiki-title {
	margin-left: 5px;
}

#st-user-greeting {
	position: relative;
	text-align: right;
	float: right;
}

#st-group-notes-content, #st-personal-notes-content {
}

.st-homepage-section {
	margin-bottom: 15px;
}

#st-homepage-notes .st-homepage-section {
	background-color: white;
	border: 1px solid #aaa;
	padding: 15px;
}

.st-homepage-section-title {
	font-size: 110%;
	font-family: Helvetica, Verdana, sans-serif;
}

#st-homepage-notes .st-homepage-section-title {
	color: #aaa;
	text-decoration: underline;
}

.st-homepage-notes-edit-link {
	background: url('../../images/st/homepage/edit-icon.gif') no-repeat left top;
	display: block;
	text-indent: -2000px;
	height: 13px;
	width: 36px;
	text-decoration: none;
	padding:0;
}
* html .st-homepage-notes-edit-link {
	border:1px solid white;
}

.st-homepage-notes-edit {
	font-family: Verdana, sans-serif;
	font-size: 65%;
	float: right;
}

.st-homepage-notes-content {
	font-size: 85%;
	margin-top: 10px;
	padding-top: 0px;
	padding-bottom: 0px;
	font-family: Verdana, Helvetica, sans-serif;
}

#st-dyk {
	border-color: #cca !important;
	background-color: #ffe !important;
}

#st-dyk-title {
	color: #e4a020 !important;
	text-decoration: none !important;
}


/* Homepage Simple List */

#st-whats-new-title-link {
	background: url('../../images/st/homepage/icon-28-pages.gif') no-repeat left top;
}
#st-watchlist-title-link {
	background: url('../../images/st/homepage/icon-28-star.gif') no-repeat left top;
}
#st-wikis-title-link {
	background: url('../../images/st/homepage/icon-28-group.gif') no-repeat left top;
}
.st-homepage-simplelist-title-link {
	display: block;
	padding-left: 32px;
	min-height: 32px;
}
* html .st-homepage-simplelist-title-link {
	height: 32px;
}

.st-homepage-simplelist-title {
}

.st-homepage-simplelist-table {
	margin-left: 25px;
	border: 1px dashed #ddd;
	border-collapse: collapse;
	font-family: Verdana, Helvetica, sans-serif;
	font-size: 80%;
	width: 95%;
}

.st-homepage-simplelist-table td {
	padding: 2px;
}

.st-homepage-simplelist-table tr.st-homepage-simplelist-row-odd {
	background-color: #f3f7f7;
}

.st-homepage-simplelist-table tr.st-homepage-simplelist-row-even {
	background-color: white;
}

.st-homepage-simplelist-table a {
	color: #4f55dd;
	text-decoration: none;
}

.st-homepage-simplelist-table a:visited {
	color: #551a8b;
}

.st-homepage-simplelist-subleft {
	font-size: 80%;
	margin-left: 1em;
	color: #666;
}

.st-homepage-simplelist-right {
	width: 20%;
}

.st-homepage-simplelist-subright {
	font-size: 80%;
	color: #666;
}

.st-homepage-simplelist {
}

.st-homepage-simplelist-header {
	min-height: 35px;
}

.st-homepage-simplelist-header .button-table {
	float: right;
	margin-right: 15px;
	font-size: 95%;
}

.st-homepage-simplelist-header .button-table .button-content {
	padding: 1px;
}

.st-homepage-whatsnew-author, .st-homepage-whatsnew-date {
	color: #555;
}
.st-homepage-whatsnew-attribution {
	padding-left: 1em;
	font-size: 80%;
	color: #aaa;
}

/* Homepage Wikis List */

#st-wikis-title {
}

/* Data and Templates */

.st-jst-template, .st-json {
	display: none;
}

/* Page Sidebox Common Styles */

#st-page-boxes-toggle {
	position: relative;
	float: right;
	text-align: right;
	font-family: Verdana, Arial, sans-serif;
	font-weight: bold;
	font-size: 80%;
	margin-bottom: 0.7em;
}

#st-page-boxes-toggle-link {
	text-decoration: none;
}

#st-page-boxes-underlay {
	float: right;
	margin-top: -10px;
	margin-right: 10px;
	background: white;
	z-index: 198;
	clear: both;
	margin-left: 15px;
}
* html #st-page-boxes-underlay {
	margin-right: 4px;
}
#st-page-boxes {
	background: inherit;
	position: absolute;
	right: 23px;
	z-index: 199;
	margin-top: 15px;
	margin-left: 20px;
}
#st-page-boxes, #st-page-boxes-underlay {
	width: 225px;
	/* padding-left: 15px; */ /* Gives the white border effect, cwest dislikes it. */
}

.st-page-box {
	border: 1px solid black;
	padding: 5px;
	font-family: Verdana, Helvetica, sans-serif;
	font-size: 80%;
	margin-top: 15px;
}

.st-page-box-title {
	font-family: Helvetica, Verdana, sans-serif;
	font-weight: bold;
	margin-bottom: 10px;
}

.st-page-box-listing {
	margin: 0;
	padding: 0;
}

.st-page-box-listing-entry {
	display: block;
}

.st-page-boxes-nobacklinks {
	font-family: Verdana, Helvetica, sans-serif;
	font-size: 90%;
	color: #888;
}

.st-page-box-first {
	margin-top: 0px;
}

/* Page Display */

#st-page-content {
	clear: left;
	margin-top: 6px;
	margin-bottom: 0;
	padding-bottom: 0;
}

#st-page-content, #st-page-content td {
	font-family: Verdana, Helvetica, sans-serif;
	font-size: 90%;
}

#st-page-wiki-title {
	font-family: Helvetica, Verdana, sans-serif;
	font-size: 65%;
	font-weight: bold;
	color: #aaa;
	margin-bottom: 0.2em;
	margin-top: 0.1em;
	padding-top: 0;
}

#wiki {
	margin: 0;
	padding: 0;
}

#st-page-title {
}

#st-page-titletext, .st-page-title {
	font-family: Helvetica, Verdana, sans-serif;
	font-size: 150%;
	font-weight: bold;
	color: #888;
	border-bottom: 1px solid #888;
}

#st-newpage-pagename-edit {
	font-family: inherit;
	font-size: inherit;
	font-weight: inherit;
	color: #000;
	border: 1px solid black;
	padding-left: 0.3em;
	background-color: #ffd;
}

#st-page-details {
	font-style: italic;
	font-size: 75%;
	font-family: Georgia, serif;
	margin: 6px 10px 0 10px;
}

#st-page-details-feed-icon {
	vertical-align: middle;
	border: none;
}

#st-page-stats {
	float: right;
	vertical-align: middle;
}

#st-attribution {
	float: left;
	margin-bottom: 10px;
}

#st-page-editing-wysiwyg {
	background: #ffd;
	border-style: solid;
	border-color: #888 #ccc #ccc #888;
	border-width: 2px;
	width: 100%;
}

#st-page-editing-toolbar {
	margin-left: -6px;
	overflow: hidden;
	float: left;
	height: 25px;
}

#wikiwyg_wikitext_textarea {
	margin-top: 4px;
	background: #ffd;
	border-style: solid;
	border-color: #888 #ccc #ccc #888;
	border-width: 2px;
	width: 100%;
	font-family: monospace;
}

#st-page-maincontent {
}

#st-page-editing, #wikiwyg_wikitext_textarea {
}

#st-page-editing-pagebody-decoy, #st-page-editing-wysiwyg {
	display: none;
}

#st-editing-tools-edit {
	display: none;
}

#st-mode-wysiwyg-button
{
	font-size: 70%;
	margin-left: 4em;
}

#st-mode-wikitext-button
{
	font-size: 70%;
}

#st-edit-tips
{
	font-size: 70%;
}

.wikiwyg_button {
	background: #FFFFFF;
	border: 1px solid #FFFFFF;
	cursor: pointer;
	width: 20px;
	height: 20px;
	vertical-align: bottom;
}

.wikiwyg_button:hover {
	border: 1px outset;
}

.wikiwyg_button:active {
	border: 1px inset;
}

#wikiwyg_toolbar {
	display: none;
}

/* Sidebox Pagetools: Revisions, Watchlist */
#st-side-box-pagetools {
	border-collapse: collapse;
}

#st-rewind-norevisions {
	font-family: Helvetica, Arial, sans-serif;
	font-size: 11px;
	color: #777;
	text-decoration: none;
}

#st-side-box-pagetools a {
	font-family: Helvetica, Arial, sans-serif;
	font-size: 11px;
	color: #555;
	text-decoration: none;
}

/* Page View Tags/Incoming Links Sidebox */

#st-tags {
	background: #f4fff4;
	border-color: #bbeebb;
	color: #999;
}

#st-tags-title {
	color: #595;
}

#st-tags-addlink, #st-tags-addbutton {
	font-weight: bold;
}

#st-tags-listing {
	margin-bottom: 5px;
}

#st-tags-addinput, #st-tags-message, #st-tags-suggestion {
	display: none;
}

#st-tags-deletemessage {
	font-size: 90%;
	color: #555;
	display: none;
	margin-top: 0.5em;
	margin-bottom: 0.5em;
}

#st-tags-suggestion {
	margin-top: 2px;
}

.st-tags-level1 {
	font-size: 90%;
}

.st-tags-level2 {
	font-size: 100%;
}

.st-tags-level3 {
	font-size: 110%;
}

.st-tags-level4 {
	font-size: 120%;
}

.st-tags-level5 {
	font-size: 130%;
}

.st-tags-tagline .st-tags-tagdelete {
	text-decoration: none;
	color: #ccc;
}

.st-tags-tagline a {
	text-decoration: none;
	color: #444;
}

#st-tags-field {
	width: 95%;
}

#st-incoming-links {
	border-color: #ebb;
	background-color: #fff4f4;
}

#st-incoming-links-title {
	color: #b78;
}

#st-attachments {
	border-color: #bbe;
	background-color: #f4f4ff;
}

#st-attachments-uploadbutton, #st-attachments-managebutton {

}
#st-attachments-buttons-uploadbutton {
	margin: 0px;
	padding: 0px;
	padding-left: 2px;
}
#st-attachments-buttons-managebutton {
	margin: 0px;
	padding: 0px;
	padding-right: 2px;
}

#st-attachments-buttons td {
	padding-right: 3px;
	font-size: 99%;
}

#st-attachments-buttons {
	border-collapse: collapse;
	margin: 0px;
	padding: 0px;
	margin-top: 5px;
}

#st-attachments-title {
	color: #77b;
}

.st-attachments-line {
	width:100%;
	overflow:hidden;
}

/* Actions Bar */

#st-actions-bar-spacer {
	clear:both;
	height:0.5em;
	overflow:hidden;
}

#st-actions-bar-spacer-clear {
	clear:both;
	height:1px;
	overflow:hidden;
}


#st-actions-bar, #st-editing-tools-bar {
	margin-left: 30px !important;
	margin-right: 30px !important;
}

/* Footer */
#st-footer {
	margin-top: -8px;
	margin-bottom: 5px;
	clear: both;
}

/* Socialtext Attribution */

#st-socialtext-attribution {
	clear: both;
	text-align: center;
	font-size: 80%;
	font-family: Helvetica, sans-serif;
}

#st-socialtext-attribution-link {
	text-decoration: none;
}

#st-socialtext-attribution-image {
	border: 0;
}


/* Page Actions */

#st-edit-button-border-left-middle, #st-login-to-edit-button-border-left-middle {
	background: url('../../images/st/button-blue/left-middle.gif') left top repeat-y;
}
#st-edit-button-border-right-middle, #st-login-to-edit-button-border-right-middle {
	background: url('../../images/st/button-blue/right-middle.gif') right top repeat-y;
}

#st-edit-button-border-left-top, #st-login-to-edit-button-border-left-top {
	background: url('../../images/st/button-blue/left-top.gif') left top no-repeat;
}
#st-edit-button-border-right-top, #st-login-to-edit-button-border-right-top {
	background: url('../../images/st/button-blue/right-top.gif') right top no-repeat;
}

#st-edit-button-border-left-bottom, #st-login-to-edit-button-border-left-bottom {
	background: url('../../images/st/button-blue/left-bottom.gif') left bottom no-repeat;
}

#st-edit-button-border-right-bottom, #st-login-to-edit-button-border-right-bottom {
	background: url('../../images/st/button-blue/right-bottom.gif') right bottom no-repeat;
}

#st-edit-button-link, #st-login-to-edit-button-link {
}

#st-comment-button-border-left-middle {
	background: url('../../images/st/button-purple/left-middle.gif') left top repeat-y;
}

#st-comment-button-border-right-middle {
	background: url('../../images/st/button-purple/right-middle.gif') right top repeat-y;
}

#st-comment-button-border-left-top {
	background: url('../../images/st/button-purple/left-top.gif') left top no-repeat;
}

#st-comment-button-border-right-top {
	background: url('../../images/st/button-purple/right-top.gif') right top no-repeat;
}

#st-comment-button-border-left-bottom {
	background: url('../../images/st/button-purple/left-bottom.gif') left bottom no-repeat;
}

#st-comment-button-border-right-bottom {
	background: url('../../images/st/button-purple/right-bottom.gif') right bottom no-repeat;
}

#st-comment-button-link {
}

#st-save-button-border-left-middle {
	background: url('../../images/st/button-green/left-middle.gif') left top repeat-y;
}
#st-save-button-border-right-middle {
	background: url('../../images/st/button-green/right-middle.gif') right top repeat-y;
}

#st-save-button-border-left-top {
	background: url('../../images/st/button-green/left-top.gif') left top no-repeat;
}
#st-save-button-border-right-top {
	background: url('../../images/st/button-green/right-top.gif') right top no-repeat;
}

#st-save-button-border-left-bottom {
	background: url('../../images/st/button-green/left-bottom.gif') left bottom no-repeat;
}

#st-save-button-border-right-bottom {
	background: url('../../images/st/button-green/right-bottom.gif') right bottom no-repeat;
}

#st-save-button-link {
}

#st-preview-button-border-left-middle {
	background: url('../../images/st/button-gold/left-middle.gif') left top repeat-y;
}
#st-preview-button-border-right-middle {
	background: url('../../images/st/button-gold/right-middle.gif') right top repeat-y;
}

#st-preview-button-border-left-top {
	background: url('../../images/st/button-gold/left-top.gif') left top no-repeat;
}
#st-preview-button-border-right-top {
	background: url('../../images/st/button-gold/right-top.gif') right top no-repeat;
}

#st-preview-button-border-left-bottom {
	background: url('../../images/st/button-gold/left-bottom.gif') left bottom no-repeat;
}

#st-preview-button-border-right-bottom {
	background: url('../../images/st/button-gold/right-bottom.gif') right bottom no-repeat;
}

#st-preview-button-link {
}

#st-cancel-button-border-left-middle {
	background: url('../../images/st/button-crimson/left-middle.gif') left top repeat-y;
}
#st-cancel-button-border-right-middle {
	background: url('../../images/st/button-crimson/right-middle.gif') right top repeat-y;
}

#st-cancel-button-border-left-top {
	background: url('../../images/st/button-crimson/left-top.gif') left top no-repeat;
}
#st-cancel-button-border-right-top {
	background: url('../../images/st/button-crimson/right-top.gif') right top no-repeat;
}

#st-cancel-button-border-left-bottom {
	background: url('../../images/st/button-crimson/left-bottom.gif') left bottom no-repeat;
}

#st-cancel-button-border-right-bottom {
	background: url('../../images/st/button-crimson/right-bottom.gif') right bottom no-repeat;
}

#st-cancel-button-link {
}

#st-edit-more-button-border-left-middle {
	background: url('../../images/st/button-blue/left-middle.gif') left top repeat-y;
}
#st-edit-more-button-border-right-middle {
	background: url('../../images/st/button-blue/right-middle.gif') right top repeat-y;
}

#st-edit-more-button-border-left-top {
	background: url('../../images/st/button-blue/left-top.gif') left top no-repeat;
}
#st-edit-more-button-border-right-top {
	background: url('../../images/st/button-blue/right-top.gif') right top no-repeat;
}

#st-edit-more-button-border-left-bottom {
	background: url('../../images/st/button-blue/left-bottom.gif') left bottom no-repeat;
}

#st-edit-more-button-border-right-bottom {
	background: url('../../images/st/button-blue/right-bottom.gif') right bottom no-repeat;
}

#st-edit-more-button-link {
}

.st-page-action-button-link {
	min-height: 24px;
	min-width: 100px;
	text-align: center;
	font-family: Helvetica, Verdana, sans-serif;
	font-size: 90%;
	text-decoration: none;
	color: #fff;
	font-weight: bold;
	display: block;
	padding-top: 8px;
	padding-bottom: 0px;
	margin-bottom: -3px;
	width: 100%;
	margin-left: -2px;
}
* html .st-page-action-button-link {
	padding-top: 5px;
	padding-bottom: 0px;
	height: 24px;
}

.st-page-action-button {
	float: left;
	margin: 0;
	padding: 0;
	margin-right: 10px;
	min-height: 20px;
	border-collapse: collapse;
	width: 100px;
}

/* Attach File Interface */

#st-attachments-attachinterface {
	font-family: Helvetica, sans-serif;
	font-size: 90%;
	display: none;
	position: fixed;
	left: 0px;
	top: 0px;
	width: 100%;
	height: 100%;
	z-index: 2000;
	background-image: url('../../images/st/popup/bg.png');
}
#st-attachments-manageinterface {
	font-family: Helvetica, sans-serif;
	font-size: 90%;
	display: none;
	position: absolute;
	left: 0px;
	top: 0px;
	width: 100%;
	height: 100%;
	z-index: 2000;
	background-image: url('../../images/st/popup/bg.png');
}

* html #st-attachments-attachinterface {
	background-image: none;
}
* html #st-attachments-manageinterface {
	background-image: none;
}
* html .popup-overlay {
	background-image: url('../../images/st/popup/bg.png');
	background-color: #000;
	opacity: .70;
	position: absolute;
	left: 0px;
	top: 0px;
	width: 100%;
	height: 100%;
	z-index: 2001;
}

#st-attachments-attach-interface {
	z-index: 2002;
	background-color: #fff;
	color: #000;
	border: 4px solid #ccc;
	padding: 1em;
	width: 520px;
	margin-left: auto;
	margin-right: auto;
	margin-top: 10%;
	position: absolute;
	top: 0px;
}

* html #st-attachments-attach-interface {
}

#st-attachments-attach-formtarget {
	width: 0px;
	height: 0px;
	border: 0;
	padding: 0;
	margin: 0;
}

#st-attachments-attach-message {
	font-size: 90%;
	font-family: Verdana, Arial, Helvetica, Sans-Serif;
}

#st-attachments-attach-title {
	font-weight: bold;
	font-size: 120%;
}

#st-attachments-attach-close {
	float: right;
	margin-top: 6px;
}

#st-attachments-attach-uploadbutton {
	float: right;
	margin-right: 6px;
	margin-top: 6px;
	padding-bottom: 0;
}

#st-attachments-attach-fileprompt {
	margin: 0.2em 0 0.4em 0;
	padding-bottom: 0px;
}

#st-attachments-attach-submit {
	font-size: 90%;
	font-weight: bold;
}

#st-attachments-attach-filename {
	font-size: 90%;
}

#st-attachments-attach-uploadmessage {
	font-weight: bold;
	margin-bottom: 1em;
	display: none;
}

#st-attachments-attach-error {
	font-weight: bold;
	color: #f00;
	margin-bottom: 1em;
	display: none;
}

#st-attachments-attach-list {
	display: none;
	color: #666;
	font-size: 90%;
	margin-top: 1em;
	margin-bottom: 1em;
	border-top: 1px solid #4949BA;
	border-bottom: 1px solid #4949BA;
	background-color: #F5F5F5;
	padding: 3px;
}

.st-attachments-attach-listlabel {
	font-size: 90%;
	color: #4949BA;
}

/* Queue File Dialog */

#st-attachmentsqueue-interface {
	font-family: Helvetica, sans-serif;
	font-size: 90%;
	display: none;
	position: fixed;
	left: 0px;
	top: 0px;
	width: 100%;
	height: 100%;
	background-image: url('../../images/st/popup/bg.png'); /* Don't forget IE hack for ship! */
	z-index: 2000;
}

* html #st-attachmentsqueue-interface {
	background-image: none;
}

#st-attachmentsqueue-dialog {
	z-index: 2002;
	background-color: #fff;
	color: #000;
	border: 4px solid #ccc;
	padding: 1em;
	width: 530px;
	margin-left: auto;
	margin-right: auto;
	margin-top: 10%;
	position: absolute;
	top: 0px;
}

* html #st-attachmentsqueue-dialog {
}

#st-attachmentsqueue-fileprompt {
	margin-bottom: 0.4em;
	margin-top: 0;
	padding-bottom: 0;
}

#st-attachmentsqueue-title {
	font-weight: bold;
	font-size: 120%;
}

#st-attachmentsqueue-close {
	float: right;
	margin-top: 6px;
}

#st-attachmentsqueue-uploadbutton {
	float: right;
	margin-right: 6px;
	margin-top: 6px;
	padding-bottom: 0;
}

#st-attachmentsqueue-submit {
	font-size: 90%;
}

#st-attachmentsqueue-filename {
	font-size: 90%;
}

#st-attachmentsqueue-message {
	font-size: 90%;
	font-family: Verdana, Arial, Helvetica, Sans-Serif;
}

#st-attachmentsqueue-uploadmessage {
	font-weight: bold;
	margin-bottom: 1em;
	display: none;
}

#st-attachmentsqueue-error {
	font-weight: bold;
	color: #f00;
	margin-bottom: 1em;
	display: none;
}

#st-attachmentsqueue-list {
	display: none;
	color: #666;
	font-size: 90%;
	margin-top: 1em;
	margin-bottom: 1em;
	border-top: 1px solid #4949BA;
	border-bottom: 1px solid #4949BA;
	background-color: #F5F5F5;
	padding: 3px;
}

.st-attachmentsqueue-listlabel {
	font-size: 90%;
	color: #4949BA;
}

/* Lists */

tr.st-trbg-even, tr.st-trbg-even td{
	background-color: #f3f7f7;
}

tr.w-st-even-row, tr.w-st-even-row td {
	background-color: #f3f7f7;
}

.query-results-header-title, .query-results-header-last-edit-by {
	text-align: left;
}


.query-results-row-revisions {
	text-align: right;
}

.query-results-content {
	font-size: 85%;
	border-collapse: collapse;
	border: 1px dashed #ddd;
	border-left: 1px solid #ddd;
	border-right: 1px solid #ddd;
}

.query-results-row {
	border-collapse: collapse;
	border: 1px dashed #ddd;
	border-left: 1px solid #ddd;
	border-right: 1px solid #ddd;
}

.query-results-row a {
	text-decoration: underline;
	color: #00f;
}

.query-results-row td {
	font-family: Verdana;
	padding: 0.3em;
	border-left: 1px dashed #ddd;
	border-right: 1px dashed #ddd;
	border-top: 1px solid #ddd;
	border-bottom: 1px solid #ddd;
}

.query-results-header-row {
	border-collapse: collapse;
	border: 1px dashed #ddd;
	border-left: 1px solid #ddd;
	border-right: 1px solid #ddd;
}

.query-results-header-row a {
	text-decoration: underline;
	color: #00f;
}

.query-results-header-row th {
	font-family: Helvetica;
	padding: 0.3em;
	border-left: 1px dashed #ddd;
	border-right: 1px dashed #ddd;
	border-top: 1px solid #ddd;
	border-bottom: 1px solid #ddd;
}

div.st-actionbutton {
	float: left;
}

div#deleteme-st-actions-bar {
	clear: both;
	margin: 0.8em 20px 0.2em auto;
	padding: 0;
}

/* Manage File Interface */



#st-attachments-manage-interface {
	z-index: 2002;
	background-color: #fff;
	color: #000;
	border: 4px solid #ccc;
	padding: 1em;
	width: 520px;
	margin-left: auto;
	margin-right: auto;
	margin-top: 10%;
	position: absolute;
	top: 0px;
}

#st-attachments-manage-filetable {
	height: 150px;
	margin: 0;
	padding: 0;
	width: 100%;
	overflow: auto;
	border: 1px solid #ccc;
}

#st-attachments-manage-filelisting tbody td {
	font-size: 90%;
}
#st-attachments-manage-filelisting {
	width: 100%;
	border-collapse: collapse;
	border: 0;
	margin: 0;
	padding: 0;
}

#st-attachments-manage-fileheader {
	background: #ccc;
	font-weight: bold;
	border-bottom: 1px black solid;
}

#st-attachments-manage-close {
	float: right;
	margin-top: 3px;
	margin-right: -2px;
	font-weight: bold;
}

#st-attachments-manage-delete {
	margin-top: 3px;
	float: left;
	font-weight: bold;
}

.st-attachments-manage-filerow {
	border-bottom: 1px solid #ccc;
}

.row-odd {
	background-color: #eee;
}

.row-even {
	background-color: #fff;
}

.row-on {
	background-color: #009 !important;
	color: white !important;
}

.row-on a {
	color: #fff !important;
}

#st-attachments-manage-deletemessage {
	color: red;
}

/* Page tools icons */

#st-pagetools-print {
	background: url('../../images/st/pagetools/print.gif')
	left center no-repeat;
}

#st-pagetools-email {
	background: url('../../images/st/pagetools/email.gif')
	left center no-repeat;
}

#st-pagetools-tools {
	background: url('../../images/st/pagetools/tools.gif')
	left center no-repeat;
}

/*
 #st-pagetools-watch {
	background: url('../../images/st/pagetools/watch-blue.gif')
	left center no-repeat;
}
*/


/* *********** Settings *********** */

#st-settings-pane {
}
* html #settings-pane { font-size: 85%;}

.settings-start-table {
}
* html .settings-start-table { font-size: 90%;}

#st-settings-select {
	padding: 0px 10px 10px 10px;
	vertical-align: top;
	width: 1px;

	background-color: #eff1ec;
	border: none;
}

#st-settings-section {
	padding: 0px 10px 10px 10px;
	vertical-align: top;
}

.settings-top-header {
	margin-top: 1em;
	font-weight: bold;
	width: 15em;
}

.settings-header {
	margin-top: 1em;
	font-weight: bold;
}

.settings-selections {
	padding: 0px 0px 0px 20px;
	line-height: 1.5em;
}

.settings-selections a:visited, .settings-selections a:active {
	color: #0000ff;
}

.settings-link {
	clear: both;
	display: block;
}

.settings-section-left {
	text-align: right;
}

.settings-label {
	font-weight: bold;
}

.settings-help {
	color: #888;
}

.settings-comment {
}

.users-invite-message {
	padding: 0.5em 0.5em 0.5em 2em;
	background-color: #eee;
	/* This seems necessary to fix an IE bug that sometimes
		causes the text in this div to be invisible */
	z-index: 1000;
}

.workspace-entry-header {
	margin-top: .5em;
	font-weight: bold;
}

.workspace-entry {
	margin-left: 3em;
}

.workspace-entry-p {
	margin-top: .5em;
	margin-bottom: .75em;
}

.workspace-subentry {
	font-style: italic;
	font-weight: bold;
	margin-left: 1.5em;
}

.preferences-td {
	padding:.5em 0 1.5em 0;
}

.preferences-query {
	text-align: left;
}

.preference-radio {
	background-color: #cec;
}
.user-settings-listall-headings td {
	background-color: #eff3ef;
}

#st-settings-save {
	padding-bottom: 0.5em;
}

.standard-button-cancel {
	font-weight: bold;
	background-color: #71004b;

	border-left: 1px solid #aaa;
	border-top: 1px solid #aaa;
	border-bottom: 2px solid #333;
	border-right: 2px solid #333;
	color: #f4f3b9;
	width: 8em;
}

.standard-button-submit {
	font-weight: bold;
	background-color: #656084;

	border-left: 1px solid #aaa;
	border-top: 1px solid #aaa;
	border-bottom: 2px solid #333;
	border-right: 2px solid #333;
	color: #f4f3b9;
	width: 8em;
}

#st-settings {
	font-family: Verdana, Arial, Helvetica, Sans-Serif;
	font-size: 90%;
}


/* Listview Tabs */


#st-listview a:visited {
	color: #551a8b;
}
#st-listview-tabs ul {
	display: block;
	list-style: none outside;
	margin: 0 0 0 4em;
	padding: 0;
	font-family: Helvetica, Arial, Sans-serif;
	font-size: 80%;
}

#st-listview-tabs li {
	display: block;
	float: left;
	margin: 0 0.8em 0 0;
	padding: 3px 0.6em 0 0.6em;
	border: 1px solid #d8d8d8;
	border-bottom: 1px solid rgb(128, 169, 243);
	background-color: #f4f4f4;
	position: relative;
	bottom: -2px;
}

#st-listview-tabs li.spacer {
	margin: 0 0.8em 0 2em;
}

#st-listview-tabs a {
	color: #bbb;
	text-decoration: none;
}

#st-listview-tabs li.selected {
	background-color: #fff !important;
	border: 1px solid rgb(128, 169, 243) !important;
	border-bottom: 1px solid #fff !important;
	font-weight: bold !important;
}

#st-listview-tabs li.selected a {
	color: #000 !important;
}

/* Category List Display */

#st-category-display-links {
	margin-bottom: 1em;
	font-size: 90%;
}

#st-tag-listbody {
	font-family: Helvetica, Verdana, sans-serif;
}

/* Attachments List Display */

#st-attachments-list-body table.button-table {
	margin-top: 0.1em;
	font-size: 80%;
}


/* ********** PageTools Menu ************** */

div#st-editing-tools {
	float: left;
}

div#st-pagetools {
	z-index: 300;
	font-family: Helvetica, Verdana, sans-serif;
	font-size: 10px;
	float: right;
	margin: 18px 0 0 0em;
	color: #000;
	vertical-align: bottom;
	position: relative;
}

#st-pagetools a {
	text-decoration: none;
	color: black;
	padding-left: 17px;
}

#st-pagetools span {
	color: inherit;
	padding-left: 17px;
	vertical-align: top;
}

#st-pagetools span.st-watchlist-link {
	color: inherit;
	vertical-align: top;
}

.st-watchlist-link {
	cursor: pointer;
}

div#st-pagetools ul.level2 {
	z-index: 300;
	margin: 0;
	padding: 0;
	background: white;
	border: 1px solid #CCC;
	border-width: 0 1px;
}

div#st-pagetools li {
	position: relative;
	list-style: none;
	margin: 0;
	float: left;
	width: 7em;
	line-height: 11px;
}

div#st-pagetools ul ul li:hover {
	background: #BFE2FF;
}

div#st-pagetools li a {
	display: block;
	text-decoration: none;
}

div#st-pagetools>ul a {
	width: auto;
}

div#st-pagetools ul ul {
	position: absolute;
	width: auto;
	display: none;
}

div#st-pagetools ul ul li {
	line-height: 1.5em;
/*	width: 100%; */
	width: 14em;
}

.first {
	border-top: 1px solid #CCC;
}

.separator {
	border-bottom: 1px solid #CCC;
}

div#st-pagetools ul ul li a {
	border-bottom: 1px solid #CCC;
	padding-left: 15px;
	padding-right: 3px;
	margin-right: 3px;
	border: 0px;
}

div#st-pagetools li.submenu li.submenu:hover {
	z-index: 300;
	background-color: #BFE2FF;
}

div#st-pagetools ul.level1 li.submenu:hover ul.level2 {
	display:block;
}

div#st-pagetools ul.level2 {
	top: 1.0em;
	left: -9.5em;
}

/*

=head2 Revision List Display

Change these styles to update the page revision list.

*/

#st-revision-list-table {
	border-collapse: collapse;
	font-size: 85%;
	color: #000;
}

.st-page-title-decorator {
	color: #C80000;
}

.st-revision-header-emphasis {
	color: #C80000;
}

.st-revision-list-compare-button-row {
}

.st-revision-list-compare-button-cell {
	padding-top: 0.3em;
	text-align: center;
}

.st-revision-list-compare-button {
}

#st-revision-list-header-row {
}

#st-revision-list-header-select {
	padding: 6px 2px 2px 2px;
	text-align: center;
}

#st-revision-list-header-revision {
	padding: 6px 2px 2px 2px;
	text-align: left;
}

#st-revision-list-header-edited-by {
	padding: 6px 2px 2px 2px;
	text-align: center;
}

#st-revision-list-header-date {
	padding: 6px 2px 2px 2px;
	text-align: center;
}

.st-revision-list-row {
	border-collapse: collapse;
	border: 1px dashed #ddd;
	border-left: 1px solid #ddd;
	border-right: 1px solid #ddd;
}

.st-revision-list-row td {
	font-family: Verdana;
	padding: 0.3em;
	border-left: 1px dashed #ddd;
	border-right: 1px dashed #ddd;
	border-top: 1px solid #ddd;
	border-bottom: 1px solid #ddd;
}

.st-revision-list-row-select {
	padding: 3px 0 2px 0;
	text-align: center;
}

.st-revision-list-row-select-old {
}

.st-revision-list-row-select-new {
}

.st-revision-list-row-revision {
}

.st-revision-list-row-revision-link {
}

.st-revision-list-row-edited-by {
}

.st-revision-list-row-date {
}

/* Revision Menu */

#st-pagetools.st-revision-view-bar {
	float: left;
}

ul.st-revision-menu {
	list-style: none;
	margin: 0;
	padding: 0.2em;
	font-size: 80%;
}

ul.st-revision-menu li {
	float: left;
	padding: 0 0.4em 0 0.4em;
	border-right: thin solid #000000;
}

ul.st-revision-menu li.st-last {
	border-right: none;
}

#st-restore-revision-button {
	font-size: 80%;
}

/*

=head2 Revision Compare Display

When comparing two revisions of a page, these styles apply.

*/

#st-revision-compare-table {
	background-color: #f0f0f0;
}

#st-revision-compare-table td {
	background-color: white;
}

.st-revision-compare-old {
	background-color: #fdd;
	text-decoration: line-through;
}
.st-revision-compare-new {
	background-color: #dfd;
	font-weight: bold;
}

/* Weblog View */

#st-weblog {
	padding: 0;
}

#st-content-weblog-display-width-controller {
}
#st-content-weblog-display-width-controller-nav {
	width: 230px;
	margin-left: 15px;
	border-left: 5px solid #ddd;
	margin-top: -1px;
}

#st-weblog-content {
	font-family: Verdana, Helvetica, sans-serif;
	margin-top: -1px;
	margin-bottom: -1px;
	border-top: 1px solid #80a9f3;
	border-bottom: 1px solid #80a9f3;
}

#st-weblog-title {
	font-family: 'Trebuchet MS', Verdana, Helvetica, sans-serif;
	font-family: 'Times New Roman', serif;
	background-color: #80a9f3;
	color: #fff;
	font-size: 150%;
	font-weight: bold;
	padding: 0.2em;
	padding-left: 1em;
}

#st-weblog-wikititle {
	font-family: Helvetica, Verdana, sans-serif;
	font-style: italic;
	font-size: 40%;
	color: #fff;
	margin-bottom: 0.2em;
	margin-top: 0.1em;
	padding-top: 0;
}

#st-weblog-titletext {
	font-family: Helvetica, Verdana, sans-serif;
	font-weight: bold;
	color: #fff;
}

div.st-weblog-entry {
	margin-top: 0.2em;
	margin-bottom: 4.8em;
	padding: 0 1.5em 0 1.5em;
}

.st-page-title {
	clear: both;
}

div.st-weblog-entrytitle span.text {
	font-family: Helvetica, Verdana, sans-serif;
	font-size: 150%;
	font-weight: bold;
	color: #000;
}

.st-weblog-entrycontent {
	font-family: Verdana, Helvetica, sans-serif;
	font-size: 90%;
	border-bottom: 1px solid #888;
}

.st-weblog-byline {
	float: left;
	text-align: left;
	font-style: italic;
	font-size: 70%;
	font-family: Verdana, Helvetica, sans-serif;
}

.st-weblog-post-links {
	float: right;
	text-align: right;
	font-size: 70%;
	font-family: Verdana, Helvetica, sans-serif;
}

#st-weblog-archives, #st-weblog-navigation {
	position: relative;
	float: right;
	width: 230px;
}

#st-weblog-archives {
	margin-top: 15px;
	clear: right;
}

#st-weblog-archives-title, #st-weblog-navigation-title {
	margin-left: 15px;
	font-family: Helvetica, sans-serif;
	font-size: 95%;
	font-weight: bold;
	color: #999;
	border-bottom: 2px solid #f99;
	padding-bottom: 5px;
	padding-top: 5px;
	margin-bottom: 5px;
}

#st-weblog-navigation-content {
	margin-left: 15px;
	font-size: 80%;
}

#st-weblog-archives ul {
	margin: 0;
	padding: 0;
}

#st-weblog-archives ul li {
	/* list-type: none; */
	display: block;
	font-size: 80%;
	font-family: Helvetica, sans-serif;
	padding-left: 15px;
}

#st-weblog-newpost {
	padding: 0.5em 0.7em 0.3em 0.3em;
}

#st-weblog-newpost-button {
}

#st-weblog-actionbar-chooseweblog {
	float: right;
}

#st-weblog-postbyemail {
	font-size: 70%;
	font-family: Verdana, Helvetica, sans-serif;
	color: #def;
	padding-top: 0.4em;
}

#st-weblog-postbyemail-link {
	color: #00c;
}

.st-weblog-chooseprompt {
	font-size: 90%;
	font-family: Verdana, Helvetica, sans-serif;
	padding-right: 0.2em;
	color: #000;
}

.st-spacer {
	padding-right: 0.1em;
	padding-left: 0.1em;
}

.st-weblog-preventries {
	padding-bottom: 20px;
	clear: both;
}
.st-weblog-nextentries {
	clear: both;
}

div.st-weblog-entrynav {
	margin-top: 0.2em;
	margin-bottom: 1.8em;
	padding: 0;
}

span.st-weblog-previousentries, span.st-weblog-nextentries {
	font-size: 90%;
	font-family: Verdana, Helvetica, sans-serif;
	padding-left: 1em;
}

/* ******* Page Stats ******** */

#st-usagereport-navbar {
	font-size: 80%;
	padding: 0;
	margin: 0;
}

#st-usagereport-date {
	font-weight: bold;
	margin-top: 1em;
}

#st-page-usagereport h1 {
	font-size: 1.3em;
	font-weight: bold;
	margin-top: 1.2em;
	margin-bottom: 0.3em;
}

#st-page-usagereport h2 {
	font-size: 1.1em;
	font-weight: bold;
	margin-top: 0.8em;
	margin-bottom: 0.3em;
}

/* New Page */
#st-newpage-save, #st-newpage-duplicate {
	display: none;
	position: fixed;
	left: 0px;
	top: 0px;
	width: 100%;
	height: 100%;
	background: url('../../images/st/popup/bg.png'); /* Don't forget IE hack for ship! */
	z-index: 2000;
}

#st-newpage-save-interface {
	background-color: #fff;
	color: #000;
	border: 4px solid #ccc;
	padding: 0.5em;
	width: 450px;
	margin-left: auto;
	margin-right: auto;
	margin-top: 10%;
	position:absolute;
	top:0px;
	z-index:2003;
}

#st-newpage-duplicate-interface {
	background-color: #fff;
	color: #000;
	border: 4px solid #ccc;
	padding: 0.5em;
	width: 530px;
	margin-left: auto;
	margin-right: auto;
	margin-top: 10%;
	position:absolute;
	top:0px;
	z-index:2003;
}

#st-newpage-save-title, #st-newpage-duplicate-title {
	margin: 0;
	padding: 0;
	font-weight: bold;
	font-family: Helvetica, sans-serif;
	font-size: 100%;
}

#st-newpage-save-prompt, #st-newpage-duplicate-prompt {
	font-family: Helvetica, sans-serif;
	font-size: 90%;
	margin-bottom: 0.4em;
}

#st-newpage-save-buttons, #st-newpage-duplicate-buttons {
	margin-top: 0.8em;
	text-align: right;
}

.st-newpage-duplicate-option {
	font-family: Helvetica, sans-serif;
	font-size: 90%;
	margin: 0;
	padding: 0;
}

#st-newpage-duplicate-pagename {
	font-size: 90%;
}

.st-newpage-duplicate-emphasis {
	background-color: #FFFF00;
	font-weight: bold;
}

#st-newpage-save-field-pagename {
	margin-bottom: 0;
	margin-top: 0.2em;
	padding-bottom: 0;
	font-size: 90%;
}

#st-newpage-save-tip {
	margin-bottom: 0;
	margin-top: 1.2em;
	padding-bottom: 0;
	font-size: 75%;
	color: #888;
}

/* Wikitext Styling */

.wiki {
}

.wiki hr {
	margin-top: .4em;
	margin-bottom: .4em;
}

.wiki .short-rule {
	width: 25%;
}

.wiki .medium-rule {
	width: 50%
}

.wiki ul,
.wiki ol,
.wiki blockquote {
	margin-left: 2em;
	padding-left: 0em;
}

.wiki table {
	border-collapse: collapse;
}

.wiki td {
	border: 1px;
	border-style: solid;
	padding: .2em;
	vertical-align: top;
}

.wiki h1,
.wiki h2,
.wiki h3,
.wiki h4,
.wiki h5,
.wiki h6 {
	font-weight: bold;
	font-style: normal;
	margin-top: 0.1em;
	margin-bottom: 8px;
}

.wiki h1 {font-size: 200%;}
.wiki h2 {font-size: 170%;}
.wiki h3 {font-size: 145%;}
.wiki h4 {font-size: 125%;}
.wiki h5 {font-size: 110%;}
.wiki h6 {font-size: 100%;}

.wiki pre {
	background-color: #eee; /* XXX */
	margin-left: 1em;
	margin-right: 1em;
	padding: .2em;
}

.wiki .incipient {
	text-decoration: none;
	border-bottom: 1px dashed;
}

.wiki-include-title {
	background-color: #ccccff;
}

.wiki .wiki {
	position: relative;
	background-color: #ddddff;
	border: 1px solid #ccccff;
	padding: 3px;
}

.wafl_existence_error {
	color: rgb(200,0,0);
	border-bottom: 0.2em dashed rgb(200,0,0);
}

#st-edit-mode-container {
}

#st-edit-mode-view {
}

#st-page-editing-uploadbutton {
	z-index: 1500;
	float: left;
}

/* Comment UI */


body#st-commentui {
	background: #ffffff;
}

#st-commentui-container {
}

#st-commentui-container a:visited,
#st-commentui-container a:active {
	color: #00f;
}

#st-commentui-notetop {
}

#st-commentui-controls {
}

#st-commentui-savelink {
	background-color: #fffebd;
}

#st-commentui-cancellink {
}

#st-commentui-customfield {
}

#st-commentui-customfield .customfield-label {
}

#st-commentui-customfield .customfield-input {
}

#st-commentui-textarea {
	padding: 0;
	border-style: inset;
	border-width: thin;
	background-color: #ffd;
	color: black;
	width: 99%;
	height: 150px;
}

/*

=head2 Send Page by Email

Styles for the 'Send Page by Email' popup, accessed from the 'Email' dropdown
menu on the page bar.

*/

#email-page {
	background: #ffffff;
	font-size: 80%;
}

.email-page-row {
	clear: both;
}

.email-page-row-label {
	font-weight: bold;
	float: left;
	width: 5em;
	margin-left: 1.2em;
	margin-right: 1.2em;
	text-align: right;
}

.email-page-row-content {
	float: left;
	padding-bottom: 1.2em;
}

.email-page-user-select-column {
	float: left;
	padding-right: 1.2em;
	width: 14em;
}

#email-page-user-select-column-center {
	width: 10em;
}

.email-page-user-select-label {
	text-align: center;
}

#email-page-user-select-add-label {
	padding-top: 1em;
}

.email-page-user-select-button-group {
	padding-bottom: 2em;
}

.email-page-input {
	width: 120px;
	clear: both;
	display: block;
}


.email-page-select {
	width: 175px;
	font-size: x-small;
}

#email-page-error-message {
	text-align: center;
}

#email-page-buttons-container {
	clear: both;
}

#email-page-buttons {
	text-align: center;
}

.email-page-input-new {
	width: 175px;
}

/* System Status, Red with icon */

#st-system-status-alert {
	clear: both;
	width: 50%;
	margin-left: 25%;
	margin-top: 10px;
	padding: 5px;
	color: #c00;
	font-weight: bold;
	font-size: 80%;
	background: transparent url('../../images/st/system-message/important-note.gif') no-repeat 5px center;
	padding-left: 60px;
	min-height: 38px;
}
* html #st-system-status-alert {
	height: 38px;
}

/* System Status, Green */

#st-system-status {
	clear: both;
	text-align:center;
	width: 80%;
	margin-left: 10%;
	padding: 8px 0 3px 0;
	color: #0a0;
	font-family: Arial, Helvetica, sans-serif;
	font-size: 80%;
}

.socialtextLogo {
	text-align: center;
}
/*}}}*/
/***
|''Name:''|SparklinePlugin|
|''Description:''|Sparklines macro|
***/
//{{{
if(!version.extensions.SparklinePlugin) {
version.extensions.SparklinePlugin = {installed:true};

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

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


}
//}}}
/***
|''Name:''|CryptoFunctionsPlugin|
|''Description:''|Support for cryptographic functions|
***/
//{{{
if(!version.extensions.CryptoFunctionsPlugin) {
version.extensions.CryptoFunctionsPlugin = {installed:true};

//--
//-- Crypto functions and associated conversion routines
//--

// Crypto "namespace"
function Crypto() {}

// Convert a string to an array of big-endian 32-bit words
Crypto.strToBe32s = function(str)
{
	var be = Array();
	var len = Math.floor(str.length/4);
	var i, j;
	for(i=0, j=0; i<len; i++, j+=4) {
		be[i] = ((str.charCodeAt(j)&0xff) << 24)|((str.charCodeAt(j+1)&0xff) << 16)|((str.charCodeAt(j+2)&0xff) << 8)|(str.charCodeAt(j+3)&0xff);
	}
	while (j<str.length) {
		be[j>>2] |= (str.charCodeAt(j)&0xff)<<(24-(j*8)%32);
		j++;
	}
	return be;
};

// Convert an array of big-endian 32-bit words to a string
Crypto.be32sToStr = function(be)
{
	var str = "";
	for(var i=0;i<be.length*32;i+=8)
		str += String.fromCharCode((be[i>>5]>>>(24-i%32)) & 0xff);
	return str;
};

// Convert an array of big-endian 32-bit words to a hex string
Crypto.be32sToHex = function(be)
{
	var hex = "0123456789ABCDEF";
	var str = "";
	for(var i=0;i<be.length*4;i++)
		str += hex.charAt((be[i>>2]>>((3-i%4)*8+4))&0xF) + hex.charAt((be[i>>2]>>((3-i%4)*8))&0xF);
	return str;
};

// Return, in hex, the SHA-1 hash of a string
Crypto.hexSha1Str = function(str)
{
	return Crypto.be32sToHex(Crypto.sha1Str(str));
};

// Return the SHA-1 hash of a string
Crypto.sha1Str = function(str)
{
	return Crypto.sha1(Crypto.strToBe32s(str),str.length);
};

// Calculate the SHA-1 hash of an array of blen bytes of big-endian 32-bit words
Crypto.sha1 = function(x,blen)
{
	// Add 32-bit integers, wrapping at 32 bits
	add32 = function(a,b)
	{
		var lsw = (a&0xFFFF)+(b&0xFFFF);
		var msw = (a>>16)+(b>>16)+(lsw>>16);
		return (msw<<16)|(lsw&0xFFFF);
	};
	// Add five 32-bit integers, wrapping at 32 bits
	add32x5 = function(a,b,c,d,e)
	{
		var lsw = (a&0xFFFF)+(b&0xFFFF)+(c&0xFFFF)+(d&0xFFFF)+(e&0xFFFF);
		var msw = (a>>16)+(b>>16)+(c>>16)+(d>>16)+(e>>16)+(lsw>>16);
		return (msw<<16)|(lsw&0xFFFF);
	};
	// Bitwise rotate left a 32-bit integer by 1 bit
	rol32 = function(n)
	{
		return (n>>>31)|(n<<1);
	};

	var len = blen*8;
	// Append padding so length in bits is 448 mod 512
	x[len>>5] |= 0x80 << (24-len%32);
	// Append length
	x[((len+64>>9)<<4)+15] = len;
	var w = Array(80);

	var k1 = 0x5A827999;
	var k2 = 0x6ED9EBA1;
	var k3 = 0x8F1BBCDC;
	var k4 = 0xCA62C1D6;

	var h0 = 0x67452301;
	var h1 = 0xEFCDAB89;
	var h2 = 0x98BADCFE;
	var h3 = 0x10325476;
	var h4 = 0xC3D2E1F0;

	for(var i=0;i<x.length;i+=16) {
		var j,t;
		var a = h0;
		var b = h1;
		var c = h2;
		var d = h3;
		var e = h4;
		for(j = 0;j<16;j++) {
			w[j] = x[i+j];
			t = add32x5(e,(a>>>27)|(a<<5),d^(b&(c^d)),w[j],k1);
			e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
		}
		for(j=16;j<20;j++) {
			w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
			t = add32x5(e,(a>>>27)|(a<<5),d^(b&(c^d)),w[j],k1);
			e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
		}
		for(j=20;j<40;j++) {
			w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
			t = add32x5(e,(a>>>27)|(a<<5),b^c^d,w[j],k2);
			e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
		}
		for(j=40;j<60;j++) {
			w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
			t = add32x5(e,(a>>>27)|(a<<5),(b&c)|(d&(b|c)),w[j],k3);
			e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
		}
		for(j=60;j<80;j++) {
			w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
			t = add32x5(e,(a>>>27)|(a<<5),b^c^d,w[j],k4);
			e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
		}

		h0 = add32(h0,a);
		h1 = add32(h1,b);
		h2 = add32(h2,c);
		h3 = add32(h3,d);
		h4 = add32(h4,e);
	}
	return Array(h0,h1,h2,h3,h4);
};


}
//}}}
/***
|''Name:''|DeprecatedFunctionsPlugin|
|''Description:''|Support for deprecated functions removed from core|
***/
//{{{
if(!version.extensions.DeprecatedFunctionsPlugin) {
version.extensions.DeprecatedFunctionsPlugin = {installed:true};

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

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

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

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

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

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

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

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

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

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

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

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

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

}
//}}}
This is the home page for Dobrica Pavlinušić's random unstructured stuff.

Welcome to my new unsorted stuff site. If you are here to "learn about rot13"<http://en.wikipedia.org/wiki/ROT13> this might not be the right place.

If you are, however looking latest and/or unsorted snippets which didn't made to "my homepage"<http://www.rot13.org/~dpavlin/> or "blog"<http://blog.rot13.org/> you might be on right place.

| {search: category: projects} | {search: category: howto} | {recent_changes: rot13} |

{fetchrss: http://blog.rot13.org/index.xml}
https://www.raspberrypi.com/documentation/microcontrollers/rp2040.html

^ python

https://datasheets.raspberrypi.com/pico/getting-started-with-pico.pdf

^ 1.8TFT

ST7755

pinout of connector, rp2040 pins

VCC
GND
CS 17 SPI0 CSn
RESET 16 SPI0 MISO
A0 20 
SDA 19 SPI0 MOSI
SCK 18 SPI0 SCK
LED

https://github.com/boochow/MicroPython-ST7735

.pre
spi = SPI(0, baudrate=20000000, polarity=0, phase=0, sck=Pin(18), mosi=Pin(19), miso=Pin(16))
tft=TFT(spi,20,16,17)
.pre
{toc: }

{file: dove-bootlog.txt}

Xtreme PC LXD8541

Chip PC Linux-based Thinx OS

Product Specifications Xtreme PC LXD8541

Processor • Marvell Dove, Armada 510 800MHZ https://www.kernel.org/doc/html/v5.14/arm/marvell.html#dove-family-application-processor

Memory • 1GB, DDR3 @ 800MHz

Mass Storage • 2GB, High reliability eMMC NAND flash • Optional externally accessed MicroSD slot

Display Support • One DVI-I port
• Display Data Control (DDC) for automatic setting of resolution and refresh rate

Resolutions • Single: Up to 1920x1200 Pixels @ true color (32 bit)
• Dual: Up to 1920x1080 Pixels @ true color (24 bit)

Video Player • Various video codecs, including: DivX HD, H.264 (MPEG4), WMV9/VC1
• Up to 1080p local browser Flash support

Audio Support • High Definition Audio Codec
• Stereo Audio Output - 3 mm (1/8 inch) Audio-Out Jack; 16-bit Stereo, 96KHz

sample rate
• Microphone Input - 3 mm (1/8 inch), 8 bit
• Software volume / mute control

Input / Output ports • 6 x USB 2.0 ports (2 front, 4 back)

^ serial

https://forum.doozan.com/read.php?2,67954,76099#msg-76099

 Koen Re: Debian on Chip PC LXD8941 January 04, 2019 02:33PM

Inside there is both a 4 pin and a 6 pin header. The 4 pin is the UART connection. With the power button towards you and the DVI connection away from you the connections are as follows: GND, TX, RX, VCC (from left to right).

^ kernel

Linux Kernel 6.6.2 MVEBU package and Debian armhf rootfs

https://forum.doozan.com/read.php?2,32146

.pre
mkfs.ext3 -L rootfs /dev/sda1
mount /dev/sda1 /mnt/sda1/
cd /mnt/sda1/
tar xvf /nuc/armada/Debian-6.6.2-mvebu-tld-1-rootfs-bodhi.tar.bz2
.pre

3. Create uImage with DTB appended.

.pre
root@nuc:/mnt/sda1# cd boot/
root@nuc:/mnt/sda1/boot# cp -a uImage uImage.orig
root@nuc:/mnt/sda1/boot# cp -a zImage-6.6.2-mvebu-tld-1 zImage.fdt
root@nuc:/mnt/sda1/boot# cat dts/dove-chip-lxd8941.dtb >> zImage.fdt
root@nuc:/mnt/sda1/boot# mkimage -A arm -O linux -T kernel -C none -a 0x00008000 -e 0x00008000 -n Linux-6.6.2-mvebu-tld-1 -d zImage.fdt uImage
Image Name:   Linux-6.6.2-mvebu-tld-1
Created:      Tue Dec 19 18:00:34 2023
Image Type:   ARM Linux Kernel Image (uncompressed)
Data Size:    5193798 Bytes = 5072.07 KiB = 4.95 MiB
Load Address: 00008000
Entry Point:  00008000
.pre

insert usb stick into back 4 usb ports, front 2 won't find storage device on usb

abort u-boot over serial and issue boot from usb:

.pre
setenv bootargs console=ttyS0,115200 root=LABEL=rootfs rootdelay=10 ${mtdparts} earlyprintk=serial
usb start; ext2load usb 0:1 0x3000000 /boot/uImage; ext2load usb 0:1 0x4000000 /boot/uInitrd
bootm 0x3000000 0x4000000
.pre

^ video output

DRM and framebuffer are not currently (as of 6.6) supported in upstream kernel according to messages at
forum, but dove-chip-lxd8941.dts doesn't include lcd power and dove-hp-t5335z.dts does.

Let's try to boot with this dts but this does not work.

^ u-boot enviroment

^^ fw_printenv

.pre
root@dove:~# cat /etc/fw_env.config
# MTD device name       Device offset   Env. size       Flash sector size       Number of sectors
/dev/mtd1 0x000000 0x010000
.pre

^^ setup boot from usb

.pre
root@dove:~# fw_setenv bootusb 'setenv bootargs console=ttyS0,115200 root=LABEL=rootfs rootdelay=10 ${mtdparts} earlyprintk=serial ; usb start; ext2load usb 0:1 0x3000000 /boot/uImage; ext2load usb 0:1 0x4000000 /boot/uInitrd ; bootm 0x3000000 0x4000000'

root@dove:~# fw_printenv bootcmd
bootcmd=run bootmmc
root@dove:~# fw_setenv bootcmd bootusb
.pre

fw_setenv this doesn't work from booted debian system, re-try over serial on u-boot prompt:

.pre
MIC>> printenv usbboot
usbboot=usb start; sleep 3; ext2load usb 0:1 0x2000000 /boot/uImage; run usbargs;bootm 0x2000000
MIC>> setenv usbboot 'setenv bootargs console=ttyS0,115200 root=LABEL=rootfs rootdelay=10 ${mtdparts} earlyprintk=serial ; usb start; ext2load usb 0:1 0x3000000 /boot/uImage; ext2load usb 0:1 0x4000000 /boot/uInitrd ; bootm 0x3000000 0x4000000'
MIC>> printenv usbboot
usbboot=setenv bootargs console=ttyS0,115200 root=LABEL=rootfs rootdelay=10 ${mtdparts} earlyprintk=serial ; usb start; ext2load usb 0:1 0x3000000 /boot/uImage; ext2load usb 0:1 0x4000000 /boot/uInitrd ; bootm 0x3000000 0x4000000
MIC>> saveenv
Saving Environment to SPI Flash...
Erasing 0xc0000 - 0xd0000:      [Done]
Writing to SPI flash:           [Done]

MIC>> setenv bootcmd run usbboot
MIC>> saveenv
Saving Environment to SPI Flash...
Erasing 0xc0000 - 0xd0000:      [Done]
Writing to SPI flash:           [Done]

.pre

^ power button

seemes like it's on gpio 25

.pre
apt install gpiod

root@dove:/home/dpavlin# gpioget 0 0 1 2 3 4 5 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
1 0 1 1 0 0 0 0 1 1 1 0 1 0 0 0 0 1 0 1 0 0 0 0 0 0
root@dove:/home/dpavlin# gpioget 0 0 1 2 3 4 5 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
1 0 1 1 0 0 0 0 1 1 1 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0

root@dove:/home/dpavlin# gpiomon 0 25
event: FALLING EDGE offset: 25 timestamp: [    1466.369262333]
event: FALLING EDGE offset: 25 timestamp: [    1466.632278096]
event:  RISING EDGE offset: 25 timestamp: [    1467.188375662]
event:  RISING EDGE offset: 25 timestamp: [    1468.390585489]
event: FALLING EDGE offset: 25 timestamp: [    1470.143645190]
event:  RISING EDGE offset: 25 timestamp: [    1471.752436499]
event: FALLING EDGE offset: 25 timestamp: [    1473.233499601]
event:  RISING EDGE offset: 25 timestamp: [    1474.560678725]
.pre
^ PICKit 2

^^ pk2cmd

.pre
pi@rpi2 ~ $ git clone https://github.com/psmay/pk2cmd
pi@rpi2 ~ $ cd pk2cmd/pk2cmd
pi@rpi2 ~/pk2cmd/pk2cmd $ make linux

pi@rpi2 ~/pk2cmd/pk2cmd $ ./pk2cmd -P
Auto-Detect: Found part PIC16F684.

# power on target from pickit 2
pi@rpi2 ~/pk2cmd/pk2cmd $ ./pk2cmd -PPIC16F684 -T
.pre

^^ serial

https://github.com/majenkotech/pk2serial
Codename 	grouper
Vendor: 	Google
Type: 	Tablet
Also known as: 	grouper
Platform: 	NVIDIA Tegra 3
CPU: 	1.3 GHz quad-core Cortex A9
GPU: 	Nvidia GeForce ULP
RAM: 	1 GB
Bluetooth: 	3.0
Wi-Fi: 	802.11 b/g/n 2.4GHz
GSM freq: 	not supported
LTE freq: 	not supported
Main camera: 	1.2 MP
Secondary camera: 	not supported
Peripherals: 	accelerometer / gyroscope / proximity sensor / digital compass / GPS / magnometer / microphone / NF

https://www.unlegacy-android.org/projects/unlegacy-android/wiki/Grouper_info

^ PostmarketOS

^^ compile

.pre
dpavlin@klin:/klin/pmos/pmbootstrap$ pmbootstrap install --android-recovery-zip

pmbootstrap flasher --method=adb sideload
.pre

To make pmbootstrap flasher work, I have to issue `adb kill-server` on my normal terminal console so that postmarketos
chroot can start new adb to flash device.

^^ desktop network config

.pre
dpavlin@klin:/klin/pmos/pmbootstrap$ grep -A3 usb0 /etc/network/interfaces
allow-hotplug usb0
iface usb0 inet static
# postmarket os
	address 172.16.42.2
	netmask 255.255.255.0

dpavlin@klin:/klin/pmos/pmbootstrap$ grep -A5 pmos ~/.ssh/config
Host pmos
    HostName 172.16.42.1
    UserKnownHostsFile /dev/null
    StrictHostKeyChecking=no
.pre

^^ reboot-mode to reboot into recovery

https://gitlab.com/postmarketOS/pmaports/-/merge_requests/442

^ pogo pins

Top ground.

Bottom +5 volts.
{toc: }

^ links

* http://www.esp8266.com/
* https://github.com/esp8266/esp8266-wiki/wiki
* http://www.electrodragon.com/w/Wi07c
* https://nurdspace.nl/ESP8266

* Documentation, tools, firmwares https://onedrive.live.com/?cid=C4DDF72E6EEA3826&id=C4DDF72E6EEA3826%21631

* https://github.com/esp8266/arduino
* https://github.com/igrr/esptool-ck (with reset support)

* http://tim.jagenberg.info/2015/01/18/low-power-esp8266/

{image: module_v2.png}

* all IO is 3.3V (3.6V max)
* CH_PD i chip-enable and has to be connected to VCC (3.3V)
* RST, GPIO0, GPIO2 should be pulled up to VCC for normal operation (GPIO0 at minumum!)
* GPIO0 pull to ground for firmware update
* make sure that 3.3V VCC power supply can support 300-400mA or there *WILL* be problems!

^ serial port

baud rate 115200

.pre
AT+GMR
00160901

OK

AT+RST

OK

 ets Jan  8 2013,rst cause:4, boot mode:(3,7)

wdt reset
load 0x40100000, len 24444, room 16 
tail 12
chksum 0xe0
ho 0 tail 12 room 4
load 0x3ffe8000, len 3168, room 12 
tail 4
chksum 0x93
load 0x3ffe8c60, len 4956, room 4 
tail 8
chksum 0xbd
csum 0xbd

ready

.pre

^ ESP-201

http://www.banggood.com/ESP8266-ESP-201-Remote-Serial-Port-WIFI-Transceiver-Wireless-Module-p-964288.html

{image: ESP8266-ESP-201-pin-reference-v01.png}

from http://smarpl.com/content/esp8266-esp-201-module-first-impressions

* http://jas-hacks.blogspot.com/2015/04/iot-esp8266-esp-201-cc1110-xrf.html

> One quirk with the ESP-201 is that is IO15 has to be grounded for the device to function. To flash the device IO00 has to be grounded.

.pre
AT+RST

OK

 ets Jan  8 2013,rst cause:4, boot mode:(3,7)

wdt reset
load 0x40100000, len 212, room 16 
tail 4
chksum 0x5e
load 0x3ffe8000, len 788, room 4 
tail 0
chksum 0x1c
load 0x3ffe8314, len 72, room 8 
tail 0
chksum 0x55
csum 0x55
jump to user1

.pre

modify flash for dio instead of qio: http://smarpl.com/content/esp8266-esp-201-module-freeing-gpio9-and-gpio10

^ nodemcu

* https://github.com/nodemcu/nodemcu-firmware
* https://github.com/nodemcu/nodemcu-firmware/wiki/nodemcu_api_en

^^ esptool.py

.pre
dpavlin@x200:/rest/cvs/esptool$ git remote -v
origin  https://github.com/themadinventor/esptool (fetch)
origin  https://github.com/themadinventor/esptool (push)

dpavlin@x200:/rest/cvs/esptool$ ./esptool.py --port /dev/ttyUSB2 read_mac
Connecting...
MAC: 18:fe:34:a0:38:72
.pre

^^ flash firmware

.pre
dpavlin@blue:/opt/Espressif/esptool$ ./esptool.py read_mac
Connecting...
MAC: 18:fe:34:a0:38:72
dpavlin@blue:/opt/Espressif/esptool$ ./esptool.py --port /dev/ttyUSB0 write_flash 0x00000 ../nodemcu-firmware/pre_build/latest/nodemcu_latest.bin 
Connecting...
Erasing flash...
Writing at 0x00010800... (17 %) 
.pre

Get latest build from https://github.com/nodemcu/nodemcu-firmware/releases

.pre
dpavlin@x200:/rest/cvs/esptool$ ./esptool.py --port /dev/ttyUSB2 write_flash 0x00000 ./nodemcu_float_0.9.6-dev_20150406.bin

dpavlin@x200:/rest/cvs/esptool$ microcom -p /dev/ttyUSB2 -s 9600
connected to /dev/ttyUSB2
Escape character: Ctrl-\
Type the escape character followed by c to get to the menu or q to quit

> node.restart()

NodeMCU 0.9.6 build 20150406  powered by Lua 5.1.4
lua: cannot open init.lua
> 
.pre

^^ build from source

For latest features, you might want to rebuild software from github source

.pre
dpavlin@x200:/rest/cvs$ git clone https://github.com/pfalcon/esp-open-sdk.git

dpavlin@x200:/rest/cvs/esp-open-sdk$ export PATH=/rest/cvs/esp-open-sdk/xtensa-lx106-elf/bin:$PATH




git clone https://github.com/nodemcu/nodemcu-firmware.git
cd nodemcu-firmware

dpavlin@x200:/rest/cvs/nodemcu-firmware$ git checkout -b dev origin/dev
Branch dev set up to track remote branch dev from origin.
Switched to a new branch 'dev'


make

# check that device is in boot loader mode

dpavlin@x200:/rest/cvs/nodemcu-firmware$ ../esptool/esptool.py --port /dev/ttyUSB1 read_mac
Connecting...
MAC: 18:fe:34:99:f2:83

# flash new firmware

dpavlin@x200:/rest/cvs/nodemcu-firmware$ make flash ESPPORT=/dev/ttyUSB1
make -C ./app flash
make[1]: Entering directory '/rest/cvs/nodemcu-firmware/app'
../tools/esptool.py --port /dev/ttyUSB1 write_flash 0x00000 ../bin/0x00000.bin 0x10000 ../bin/0x10000.bin
Connecting...
Erasing flash...
Writing at 0x0000c500... (100 %)
Erasing flash...
Writing at 0x00068c00... (100 %)

Leaving...
make[1]: Leaving directory '/rest/cvs/nodemcu-firmware/app'

.pre

^^ A library for the Microchip MCP3021 A/D converter for use with the ESP8266.

https://github.com/AllAboutEE/ESP8266-MCP3021-Library

^ nodemcu-uploader

.pre
dpavlin@x200:/rest/cvs$ git clone https://github.com/kmpm/nodemcu-uploader
dpavlin@x200:/rest/cvs/nodemcu-uploader$ ./nodemcu-uploader.py --port /dev/ttyUSB2 --baud 9600 file list
Listing files
for key,value in pairs(file.list()) do print(key,value) end
> 
.pre

^ OpenOCD JTAG

https://github.com/projectgus/openocd

http://www.esp8266.com/viewtopic.php?f=9&t=1871#p11157

| JTAG Signal | ESP8266 GPIO Pin | JTAG Pin (standard 20 pin connector) |
| TMS | 14 | 7 |
| TDI | 12 | 5 |
| TCK | 13 | 9 |
| TDO | 15 | 13 |
| RST | RST | 15 |

verified on https://visualgdb.com/tutorials/esp8266/nodemcu/jtag/

^ ESP8266 as wireless JTAG Programmer

https://github.com/emard/wifi_jtag

^ WIFI

* https://github.com/kripthor/WiFiBeaconJam

^ software serial

* C library https://github.com/plieningerweb/esp8266-software-uart
* Arduino https://github.com/plerup/espsoftwareserial

^ Sonoff

https://www.itead.cc/sonoff-wifi-wireless-switch.html
http://wiki.iteadstudio.com/Sonoff
https://github.com/arendst/Sonoff-MQTT-OTA

^^ pinout

My sonoff is early model, with just 4 pins (instead of 5)

1 - VCC
2 - RX
3 - TX
4 - GND

^ Programming

* https://tech.scargill.net/a-flashing-esp-chips-surprise/

use *dio* not *qio* to fix checksum errors

^^ CH340 USB to ESP8266 ESP-01 Wifi Module Adapter

It doesn't have GPIO0 connected to ground, so flashing doesn't work!

http://www.esp8266.com/wiki/doku.php?id=all-in-one-esp-usb-converter

^ ESP-01S DHT11 board

* https://github.com/IOT-MCU/ESP-01S-DHT11-v1.0

.pre
#define DHTTYPE DHT11
#define DHTPIN  2
DHT dht(DHTPIN, DHTTYPE, 11);
.pre

^^ adding IR led

Button is connected to RST, and if you want to add IR led (with transistor and resistor) it seems that only
way to make it work is to connect it to RX pin (gpio3). For more info see my blog post: https://blog.rot13.org/2019/08/emulate-ir-remote-for-tv-or-hvac-from-command-line-using-tasmota.html

^ KEYESTUDIO ESP8266 ESP-12F CH340G WiFi Module Board for Arduino NodeMcu

https://www.keyestudio.com/products/new-keyeastudio-nodemcu-lua-esp8266-esp-12f-wifi-module-1m-usb-cable-development-board-compatible-with-networking

{image: keyes-esp8266-pinout.jpg}
Up: [Workspace Tour - Table of Contents]
Back: [How do I make links?]

Visit the *dashboard* and click on the *New Page* Button. You will see a new page to edit. Change the name of the page by editing the title in the field on top. Put the text of the page in the larger space below. Click the green *Save* button.
>> http:base/images/docs/Create-New-Page.png

You can also create a new page by making a link on an existing page. While editing, select the text to link and click on http:base/images/wikiwyg_icons/link.gif in the toolbar. You can also put the name of the page you wish to create in square brackets, like this: *{{[Title of New Page]}}*.

After saving, the link will appear with a dashed underline, which means the link refers to page that does not exist. Whenever you click on a dashed link, you can create the missing page.

To practice, try making a new page with your name as a title using either method.

[Congratulations! You know how to use a workspace]
{toc: }

https://github.com/raphaelbs/esp32-cam-ai-thinker/blob/master/docs/about-esp32-cam.md

^ connection, flashing

connected to pl2303 serial

| pl2303 | esp32cam |
| 3v3 | not connected |
| rxd | UnR |
| rxd | UOT |
| gnd | GND |
| 5v | 5V |

{image: ESP32-CAM-pinout-new.png}

To program the board, I userd jumper to jump GPIO0 with GND pin next to it.

https://github.com/raphaelbs/esp32-cam-ai-thinker/blob/master/docs/esp32cam-pin-notes.md

^^ spi

SDI = IO12

SDO = IO13

SCK = IO14

CS = IO15

^ improved example app

https://github.com/easytarget/esp32-cam-webserver

.pre
   cp myconfig.sample.h myconfig.h
   vi myconfig.h
dpavlin@nuc:/nuc/esp32/esp32-cam-webserver$ platformio run

dpavlin@nuc:/nuc/esp32/esp32-cam-webserver$ pio run -t upload --upload-port /dev/ttyUSB2
"/home/dpavlin/.platformio/penv/bin/python" "/home/dpavlin/.platformio/packages/tool-esptoolpy/esptool.py" \
--chip esp32 --port "/dev/ttyUSB3" --baud 460800 --before default_reset --after hard_reset \
write_flash -z --flash_mode dio --flash_freq 40m --flash_size detect \
0x1000 /home/dpavlin/.platformio/packages/framework-arduinoespressif32/tools/sdk/bin/bootloader_dio_40m.bin \
0x8000 /nuc/esp32/esp32-cam-webserver/.pio/build/esp32cam/partitions.bin \
0xe000 /home/dpavlin/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin \
0x10000 .pio/build/esp32cam/firmware.bin
.pre

^ timelapse

* https://bitluni.net/esp32camtimelapse
* https://github.com/bitluni/ESP32CamTimeLapse

^ ocr on device

https://github.com/jomjol/AI-on-the-edge-device

https://github.com/jomjol/AI-on-the-edge-device/wiki/Installation

Remove glue from lens (very hard, using sharp knife), and rotate lens by 45 degrees until
picture is sharp (I had to use pliers to do this).

.pre
dpavlin@nuc:/nuc/esp32/AI-on-the-edge-device$ vi sd-card/wlan.ini

dpavlin@nuc:/nuc/esp32/AI-on-the-edge-device/code$ pio run

dpavlin@nuc:/nuc/esp32/AI-on-the-edge-device/code$ pio run -v -t upload --upload-port /dev/ttyUSB3

"/home/dpavlin/.platformio/penv/bin/python" "/home/dpavlin/.platformio/packages/tool-esptoolpy/esptool.py" \
--chip esp32 --port "/dev/ttyUSB3" --baud 460800 --before default_reset --after hard_reset \
write_flash -z --flash_mode dio --flash_freq 40m --flash_size detect \
0x1000 /nuc/esp32/AI-on-the-edge-device/code/.pio/build/esp32cam/bootloader.bin \
0x8000 /nuc/esp32/AI-on-the-edge-device/code/.pio/build/esp32cam/partitions.bin \
0xd000 /nuc/esp32/AI-on-the-edge-device/code/.pio/build/esp32cam/ota_data_initial.bin \
0x10000 .pio/build/esp32cam/firmware.bin

# original flashing instructions
esptool write_flash 0x01000 bootloader.bin 0x08000 partitions.bin 0x10000 firmware.bin

# download raw picture
wget 192.168.3.112/img_tmp/raw.jpg

.pre

----

^ old, obsolete problems

It seems that my module is usually known as AI thinker variant. It has terrible picture which starts with huge green bias.

It also doesn't work for me in resolutions below 1024x768 (in current esp32 example as of 2019-08-02).

Plugging it into external 5V power supply did not helped much.

----

To solve green tint, I just left esp32cam module plugged in whole day and night. I guess that image sensor got discharged during night, but next day picture was fine.

Problem with image resolution was fixed by updating to more recent version of ESP32 support for Arduino (as of 2020-04-20 it works fine)

^ [Home Assistant]

https://jamesachambers.com/cheap-esp32-cam-home-assistant-esphome-camera-guide/

.pre
esphome:
  name: esp32cam
  friendly_name: esp32cam

esp32:
  board: esp32cam
  framework:
    type: arduino

# Enable logging
logger:
  level: VERBOSE
  tx_buffer_size: 256

# Enable Home Assistant API
api:
  encryption:
    key: "MsJJJiDv9FTjZ1w8dfoy3Z8cQWjGOsk0m4Wgge0B+8w="
  services:  # change camera parameters on-the-fly
  - service: camera_set_param
    variables:
      name: string
      value: int
    then:
      - lambda: |-
          bool state_return = false;
          if (("contrast" == name) && (value >= -2) && (value <= 2)) { id(espcam).set_contrast(value); state_return = true; }
          if (("brightness" == name) && (value >= -2) && (value <= 2)) { id(espcam).set_brightness(value); state_return = true; }
          if (("saturation" == name) && (value >= -2) && (value <= 2)) { id(espcam).set_saturation(value); state_return = true; }
          if (("special_effect" == name) && (value >= 0U) && (value <= 6U)) { id(espcam).set_special_effect((esphome::esp32_camera::ESP32SpecialEffect)value); state_return = true; }
          if (("aec_mode" == name) && (value >= 0U) && (value <= 1U)) { id(espcam).set_aec_mode((esphome::esp32_camera::ESP32GainControlMode)value); state_return = true; }
          if (("aec2" == name) && (value >= 0U) && (value <= 1U)) { id(espcam).set_aec2(value); state_return = true; }
          if (("ae_level" == name) && (value >= -2) && (value <= 2)) { id(espcam).set_ae_level(value); state_return = true; }
          if (("aec_value" == name) && (value >= 0U) && (value <= 1200U)) { id(espcam).set_aec_value(value); state_return = true; }
          if (("agc_mode" == name) && (value >= 0U) && (value <= 1U)) { id(espcam).set_agc_mode((esphome::esp32_camera::ESP32GainControlMode)value); state_return = true; }
          if (("agc_value" == name) && (value >= 0U) && (value <= 30U)) { id(espcam).set_agc_value(value); state_return = true; }
          if (("agc_gain_ceiling" == name) && (value >= 0U) && (value <= 6U)) { id(espcam).set_agc_gain_ceiling((esphome::esp32_camera::ESP32AgcGainCeiling)value); state_return = true; }
          if (("wb_mode" == name) && (value >= 0U) && (value <= 4U)) { id(espcam).set_wb_mode((esphome::esp32_camera::ESP32WhiteBalanceMode)value); state_return = true; }
          if (("test_pattern" == name) && (value >= 0U) && (value <= 1U)) { id(espcam).set_test_pattern(value); state_return = true; }
          if (true == state_return) {
            id(espcam).update_camera_parameters();
          }
          else {
            ESP_LOGW("esp32_camera_set_param", "Error in name or data range");
          }

ota:
  password: "09e4b58a1d186b8b33d100548f33d796"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  power_save_mode: none

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esp32Cam Fallback Hotspot"
    password: "GTIKgjitx2Re"

captive_portal:

# Example configuration entry
esp32_camera:
  id: espcam
  name: esp-cam
  external_clock:
    pin: GPIO0
    frequency: 20MHz
  i2c_pins:
    sda: GPIO26
    scl: GPIO27
  data_pins: [GPIO5, GPIO18, GPIO19, GPIO21, GPIO36, GPIO39, GPIO34, GPIO35]
  vsync_pin: GPIO25
  href_pin: GPIO23
  pixel_clock_pin: GPIO22
  power_down_pin: GPIO32

  resolution: 800x600
  jpeg_quality: 10  # max. 63
  max_framerate: 1.0fps
  idle_framerate: 0.2fps
  vertical_flip: true
  horizontal_mirror: false
  brightness: 2 # -2 to 2
  contrast: 1 # -2 to 2
  special_effect: none
  # exposure settings
  aec_mode: auto
  aec2: false
  ae_level: 0
  aec_value: 300
  # gain settings
  agc_mode: auto
  agc_gain_ceiling: 2x
  agc_value: 0
  # white balance setting
  wb_mode: auto
output:
# white LED
  - platform: ledc
    channel: 2
    pin: GPIO4
    id: espCamLED
# red status light
  - platform: gpio
    pin:
      number: GPIO33
      inverted: True
    id: gpio_33
light:
  - platform: monochromatic
    output: espCamLED
    name: esp-cam light
  - platform: binary
    output: gpio_33
    name: esp-cam led
switch:
  - platform: restart
    name: esp-cam restart
binary_sensor:
  - platform: status
    name: esp-cam status
.pre
* http://sdr.osmocom.org/trac/wiki/rtl-sdr
* http://rtl-entropy.org/

{toc: }

^ calibration

https://github.com/steve-m/kalibrate-rtl

.pre
dpavlin@nuc:/nuc/kalibrate-rtl$ ./src/kal -s GSM900
Found 1 device(s):
  0:  Terratec T Stick PLUS

Using device 0: Terratec T Stick PLUS
Found Elonics E4000 tuner
Exact sample rate is: 270833.002142 Hz
kal: Scanning for GSM-900 base stations.
GSM-900:
        chan: 53 (945.6MHz - 14.311kHz) power: 873627.18
        chan: 61 (947.2MHz - 14.203kHz) power: 5086424.19
        chan: 69 (948.8MHz - 14.217kHz) power: 925674.55
        chan: 82 (951.4MHz - 14.368kHz) power: 1267065.47
        chan: 89 (952.8MHz - 14.430kHz) power: 914349.18
        chan: 99 (954.8MHz - 14.352kHz) power: 902132.81
        chan: 105 (956.0MHz - 14.380kHz)        power: 990434.19
        chan: 108 (956.6MHz - 14.350kHz)        power: 2682914.97

dpavlin@nuc:/nuc/kalibrate-rtl$ ./src/kal -c 61
Found 1 device(s):
  0:  Terratec T Stick PLUS

Using device 0: Terratec T Stick PLUS
Found Elonics E4000 tuner
Exact sample rate is: 270833.002142 Hz
kal: Calculating clock frequency offset.
Using GSM-900 channel 61 (947.2MHz)
average         [min, max]      (range, stddev)
- 14.238kHz             [-14257, -14220]        (37, 8.682419)
overruns: 0
not found: 0
average absolute error: 15.032 ppm



dpavlin@nuc:/nuc/kalibrate-rtl$ ./src/kal -c 61
Found 2 device(s):
  0:  Generic RTL2832U OEM
  1:  Terratec T Stick PLUS

Using device 0: Generic RTL2832U OEM
Found Fitipower FC0012 tuner
Exact sample rate is: 270833.002142 Hz
kal: Calculating clock frequency offset.
Using GSM-900 channel 61 (947.2MHz)
average         [min, max]      (range, stddev)
- 36.021kHz             [-36032, -36011]        (21, 5.899949)
overruns: 0
not found: 0
average absolute error: 38.028 ppm


.pre

^ DVB-T Digital TV Receiver USB Dongle w/ FM / Remote Control / Antenna - Black

http://dx.com/p/dvb-t-digital-tv-receiver-usb-dongle-w-fm-remote-control-antenna-black-149928

.pre
dpavlin@blue:~$ lsusb | grep DVB
Bus 001 Device 007: ID 0bda:2838 Realtek Semiconductor Corp. RTL2838 DVB-T

dpavlin@blue:~$ sudo rtl_test -t
[sudo] password for dpavlin: 
Found 1 device(s):
  0:  ezcap USB 2.0 DVB-T/DAB/FM dongle

Using device 0: ezcap USB 2.0 DVB-T/DAB/FM dongle
Found Rafael Micro R820T tuner
Supported gain values (29): 0.0 0.9 1.4 2.7 3.7 7.7 8.7 12.5 14.4 15.7 16.6 19.7 20.7 22.9 25.4 28.0 29.7 32.8 33.8 36.4 37.2 38.6 40.2 42.1 43.4 43.9 44.5 48.0 49.6 
No E4000 tuner found, aborting.


dpavlin@blue:/blue/rtl-sdr/rtl-sdr/build$ sudo rtl_tcp 
Found 1 device(s).
Found Rafael Micro R820T tuner
Using ezcap USB 2.0 DVB-T/DAB/FM dongle
Tuned to 100000000 Hz.
listening...
Use the device argument 'rtl_tcp=127.0.0.1:1234' in OsmoSDR (gr-osmosdr) source
to receive samples in GRC and control rtl_tcp parameters (frequency, gain, ...).
.pre

^ E4000+2832U USB DVB-T TV Receiver Stick

http://dx.com/p/e4000-2832u-usb-dvb-t-tv-receiver-stick-white-black-172105

.pre
dpavlin@blue:~$ rtl_test -t
Found 1 device(s):
  0:  Terratec T Stick PLUS

Using device 0: Terratec T Stick PLUS
Found Elonics E4000 tuner
Supported gain values (14): -1.0 1.5 4.0 6.5 9.0 11.5 14.0 16.5 19.0 21.5 24.0 29.0 34.0 42.0 
Benchmarking E4000 PLL...
[E4K] PLL not locked for 52000000 Hz!
[E4K] PLL not locked for 2227000000 Hz!
[E4K] PLL not locked for 1114000000 Hz!
[E4K] PLL not locked for 1274000000 Hz!
E4K range: 53 to 2226 MHz
E4K L-band gap: 1114 to 1274 MHz
.pre

^ Hama 53176

* FC0013 tuner

{image: Hama1.jpg}

{image: hama2.jpg}

{image: hama3.jpg}

^ TV LV5TDLX

* FC0012 tuner

{image: LV51.jpg}
{image: LV52.jpg}
{image: LV53.jpg}
{image: ch340g-3v3.png}

{image: ch340g-5v.png}

Some of those serial dongles (I have one which is intended for esp01) have been configured for 5V operation instead of 3.3V.

You can check that by measuring RX and TX while plugged in in USB and if they are more than 3.3V your dongle is not really
3.3V.
{image: VINDRIKTNING-schema.jpg}

See also [Ikea zigbee]

^ VINDRIKTNING

air quality sensor

https://github.com/dzurishome/esphome-ikea-vindriktning

Control LEDS https://github.com/Hypfer/esp8266-vindriktning-particle-sensor/issues/18
{toc}

^ GONGJUE 8018LCD

* http://www.banggood.com/8018LCD-220V-450-Degree-LCD-Adjustable-Electronic-Heat-Hot-Air-Gun-p-970060.html

* https://www.youtube.com/watch?v=XsxOuK5ZzRI

^^ schematics

{image: schema_GJ_8018LCD.JPG}

^^ board

{image: board_GJ-8018LCD.png}

{file: Sprint-Layout60_Viewer.exe}

{file: HGunCJ8018LCD_ZRN.lay6}

* http://imgur.com/a/yyhHi


^ ideas for upgrade with mcu controll

* Arduino based hot air, similar to what we need: https://www.instructables.com/id/Cheap-Hot-Air-Station-With-Arduino/
* Alternative firmware for different station: https://github.com/madworm/Youyue-858D-plus
From: Gélineau, Samuel - Montreal
Date: Thu, 1 Nov 2007 17:31:54 -0400

----

Hi,

Your svn2cvs testsuite failed on my machine, and I had to fix both the testsuite and the perl script. I assume it must have worked for you the last time you ran your testsuite, and I have no clue why. I`m using CVS 1.12.9.

.pre
 > cd svn2cvs/src
.pre

Running ./test.sh, the first abnormal behaviour I notice is at svn commit 14, "remove everything":

.pre
 ...
 + svn rm $svnco/dir/*
 D /dev/shm/test-svn-co/dir/bar
 D /dev/shm/test-svn-co/dir/baz
 D /dev/shm/test-svn-co/dir/keep
 D /dev/shm/test-svn-co/dir/keep-dir
 D /dev/shm/test-svn-co/dir/l1/bar
 D /dev/shm/test-svn-co/dir/l1/baz
 D /dev/shm/test-svn-co/dir/l1/l2/bar
 D /dev/shm/test-svn-co/dir/l1/l2/baz
 D /dev/shm/test-svn-co/dir/l1/l2/l3/bar
 D /dev/shm/test-svn-co/dir/l1/l2/l3/baz
 D /dev/shm/test-svn-co/dir/l1/l2/l3
 D /dev/shm/test-svn-co/dir/l1/l2
 D /dev/shm/test-svn-co/dir/l1
 D /dev/shm/test-svn-co/dir/skip_add
 D /dev/shm/test-svn-co/dir/with space
 + svn revert $svnco/dir/keep $svnco/dir/keep-dir/keep
 Reverted '/dev/shm/test-svn-co/dir/keep'
 Skipped '/dev/shm/test-svn-co/dir/keep-dir/keep'
 + svn commit -m 'remove everything' $svnco
 Deleting /dev/shm/test-svn-co/dir/bar
 Deleting /dev/shm/test-svn-co/dir/baz
 Deleting /dev/shm/test-svn-co/dir/keep-dir
 Deleting /dev/shm/test-svn-co/dir/l1
 Deleting /dev/shm/test-svn-co/dir/skip_add
 Deleting /dev/shm/test-svn-co/dir/with space

 Committed revision 14.
 ...
.pre

The interesting lines are:

.pre
 Skipped '/dev/shm/test-svn-co/dir/keep-dir/keep'
 ...
 Deleting /dev/shm/test-svn-co/dir/keep-dir
.pre

It`s obvious from the "svn revert" line that you never intended keep-dir to be deleted, yet it does gets deleted. I`m using svn 1.3.1 (r19032).

This time, the fix is in the testsuite itself:

.pre
 --- svn2cvs/src/test.sh 2007-11-01 19:41:19.000000000 +0000
 +++ svn2cvs/src/test.sh 2007-11-01 19:49:37.000000000 +0000
 @@ -145,7 +145,7 @@
 test

 svn rm $svn_co/dir/* || exit
 -svn revert $svn_co/dir/keep $svn_co/dir/keep-dir/keep
 +svn revert $svn_co/dir/keep $svn_co/dir/keep-dir{,/keep}
 svn commit -m "remove everything" $svn_co || exit

 test
.pre

The relevant commit in the new testsuite now runs as follows:

.pre
 ...
 + svn rm $svnco/dir/*
 D /dev/shm/test-svn-co/dir/bar
 D /dev/shm/test-svn-co/dir/baz
 D /dev/shm/test-svn-co/dir/keep
 D /dev/shm/test-svn-co/dir/keep-dir
 D /dev/shm/test-svn-co/dir/l1/bar
 D /dev/shm/test-svn-co/dir/l1/baz
 D /dev/shm/test-svn-co/dir/l1/l2/bar
 D /dev/shm/test-svn-co/dir/l1/l2/baz
 D /dev/shm/test-svn-co/dir/l1/l2/l3/bar
 D /dev/shm/test-svn-co/dir/l1/l2/l3/baz
 D /dev/shm/test-svn-co/dir/l1/l2/l3
 D /dev/shm/test-svn-co/dir/l1/l2
 D /dev/shm/test-svn-co/dir/l1
 D /dev/shm/test-svn-co/dir/skip_add
 D /dev/shm/test-svn-co/dir/with space
 + svn revert $svnco/dir/keep $svnco/dir/keep-dir $svnco/dir/keep-dir/keep
 Reverted '/dev/shm/test-svn-co/dir/keep'
 Reverted '/dev/shm/test-svn-co/dir/keep-dir'
 Skipped '/dev/shm/test-svn-co/dir/keep-dir/keep'
 + svn commit -m 'remove everything' $svnco
 Deleting /dev/shm/test-svn-co/dir/bar
 Deleting /dev/shm/test-svn-co/dir/baz
 Deleting /dev/shm/test-svn-co/dir/l1
 Deleting /dev/shm/test-svn-co/dir/skip_add
 Deleting /dev/shm/test-svn-co/dir/with space

 Committed revision 14.
 ...
.pre

This time, the "skip" is legitimate. The testsuite still fails, though:

.pre
 ...
 + diff -x '.svn*' -x CVS -urw $svnco/dir/ $cvsco/dir/
 Only in /dev/shm/test-cvs-co//dir/: l1
 Only in /dev/shm/test-cvs-co//dir/: with space
 + exit
.pre

It again failed at this problematic last commit, "remove everything":

.pre
 ...
 Starting after revision 13
 ## svn export --force -q -r 14 file:///dev/shm/test-svn-rep//dir /tmp/checkoutGGpuy/dir
 NOTICE: using /dir as directory for svn

 -------------------------------------------------------------------------------
 r 14| gelineaus | 2007-11-01T20:22:39.115442Z

 remove everything
 svn2cvs: D /dir/bar
 #### remove file: bar at ./svn2cvs.pl line 402.
 ## cvs -f -d /dev/shm/test-cvs-rep/ delete 'bar'
 cvs remove: scheduling `bar' for removal
 cvs remove: use `cvs commit' to remove this file permanently
 ## cvs -f -d /dev/shm/test-cvs-rep/ commit -m 'remove everything' 'bar'
 /dev/shm/test-cvs-rep/dir/bar,v <-- bar
 new revision: delete; previous revision: 1.1
 svn2cvs: D /dir/with space
 WARNING: with space is not present in CVS, skipping...
 svn2cvs: D /dir/baz
 #### remove file: baz at ./svn2cvs.pl line 402.
 ## cvs -f -d /dev/shm/test-cvs-rep/ delete 'baz'
 cvs remove: scheduling `baz' for removal
 cvs remove: use `cvs commit' to remove this file permanently
 ## cvs -f -d /dev/shm/test-cvs-rep/ commit -m 'remove everything' 'baz'
 /dev/shm/test-cvs-rep/dir/baz,v <-- baz
 new revision: delete; previous revision: 1.1
 svn2cvs: D /dir/l1
 WARNING: l1 is not present in CVS, skipping...
 svn2cvs: D /dir/skip_add
 #### remove file: skip_add at ./svn2cvs.pl line 402.
 ## cvs -f -d /dev/shm/test-cvs-rep/ delete 'skip_add'
 cvs remove: scheduling `skip_add' for removal
 cvs remove: use `cvs commit' to remove this file permanently
 ## cvs -f -d /dev/shm/test-cvs-rep/ commit -m 'remove everything' 'skip_add'
 /dev/shm/test-cvs-rep/dir/skip_add,v <-- skip_add
 new revision: delete; previous revision: 1.1
 commit ignored, no files
 subversion revision 14 commited to CVS
 /dev/shm/test-cvs-rep/dir/.svnrev,v <-- .svnrev
 new revision: 1.15; previous revision: 1.14
 + update_all
 + update_svn
 + svn update /dev/shm/test-svn-co/
 At revision 14.
 + update_cvs
 + cd /dev/shm/test-cvs-co/
 + cvs -f update -d dir
 cvs update: Updating dir
 U dir/.svnrev
 cvs update: `dir/bar' is no longer in the repository
 cvs update: `dir/baz' is no longer in the repository
 cvs update: `dir/skip_add' is no longer in the repository
 cvs update: Updating dir/keep-dir
 cvs update: Updating dir/l1
 cvs update: Updating dir/l1/l2
 cvs update: Updating dir/l1/l2/l3
 cvs update: Updating dir/with space
 + cd-
 + diff -x '.svn*' -x CVS -urw /dev/shm/test-svn-co//dir/ /dev/shm/test-cvs-co//dir/
 Only in /dev/shm/test-cvs-co//dir/: l1
 Only in /dev/shm/test-cvs-co//dir/: with space
 + exit
.pre

The relevant lines are:

.pre
 ...
 svn2cvs: D /dir/with space
 WARNING: with space is not present in CVS, skipping...
 ...
 svn2cvs: D /dir/l1
 WARNING: l1 is not present in CVS, skipping...
 ...
 Only in /dev/shm/test-cvs-co//dir/: l1
 Only in /dev/shm/test-cvs-co//dir/: with space
 + exit
.pre

In other words, svn2cvs.pl cannot see directories and refuses to remove them. This is because of the in_entries() function, which does not consider lines describing directories. Here`s the fix:

.pre
 --- svn2cvs/src/svn2cvs.pl 2007-11-01 20:21:22.000000000 +0000
 +++ svn2cvs/src/svn2cvs.pl 2007-11-01 20:36:52.000000000 +0000
 @@ -263,6 +263,7 @@ sub in_entries($) {
 			|| return 0; #die "no entries file: $dir/CVS/Entries";
 		while (<$fh>) {
 			return 1 if (m{^/$file/});
 +			return 1 if (m{^D/$file/});
 		}
 		close($fh);
 		return 0;
.pre

But the problematic last commit _still_ fails:

.pre
 Starting after revision 13
 ## svn export --force -q -r 14 file:///dev/shm/test-svn-rep//dir /tmp/checkout1jkCl/dir
 NOTICE: using /dir as directory for svn

 -------------------------------------------------------------------------------
 r 14| gelineaus | 2007-11-01T20:53:32.113268Z

 remove everything
 svn2cvs: D /dir/bar
 #### remove file: bar at ./svn2cvs.pl line 403.
 ## cvs -f -d /dev/shm/test-cvs-rep/ delete 'bar'
 cvs remove: scheduling `bar' for removal
 cvs remove: use `cvs commit' to remove this file permanently
 ## cvs -f -d /dev/shm/test-cvs-rep/ commit -m 'remove everything' 'bar'
 /dev/shm/test-cvs-rep/dir/bar,v <-- bar
 new revision: delete; previous revision: 1.1
 svn2cvs: D /dir/with space
 #### remove directory: with space at ./svn2cvs.pl line 383.
 #### entries(with space) => at ./svn2cvs.pl line 249.
 ## cvs -f -d /dev/shm/test-cvs-rep/ delete 'with space'
 cvs remove: Removing with space
 ## cvs -f -d /dev/shm/test-cvs-rep/ commit -m 'remove everything' 'with space'
 cvs commit: Examining with space
 ## cvs -f -d /dev/shm/test-cvs-rep/ update -dP .
 cvs update: Updating .
 cvs update: Updating keep-dir
 cvs update: Updating l1
 cvs update: Updating l1/l2
 cvs update: Updating l1/l2/l3
 cvs update: Updating with space
 svn2cvs: D /dir/baz
 #### remove file: baz at ./svn2cvs.pl line 403.
 ## cvs -f -d /dev/shm/test-cvs-rep/ delete 'baz'
 cvs remove: scheduling `baz' for removal
 cvs remove: use `cvs commit' to remove this file permanently
 ## cvs -f -d /dev/shm/test-cvs-rep/ commit -m 'remove everything' 'baz'
 /dev/shm/test-cvs-rep/dir/baz,v <-- baz
 new revision: delete; previous revision: 1.1
 svn2cvs: D /dir/l1
 #### remove directory: l1 at ./svn2cvs.pl line 383.
 #### entries recurse into: l1/l2 at ./svn2cvs.pl line 239, <$fh> line 3.
 #### entries recurse into: l1/l2/l3 at ./svn2cvs.pl line 239, <> line 3.
 #### entries(l1/l2/l3) => bar|baz at ./svn2cvs.pl line 249.
 #### entries(l1/l2) => bar|baz|l3/bar|l3/baz|l3 at ./svn2cvs.pl line 249.
 #### entries(l1) => bar|baz|l2/bar|l2/baz|l2/l3/bar|l2/l3/baz|l2/l3|l2 at ./svn2cvs.pl line 249.
 ## cvs -f -d /dev/shm/test-cvs-rep/ delete 'l1/bar'
 cvs remove: scheduling `l1/bar' for removal
 cvs remove: use `cvs commit' to remove this file permanently
 ## cvs -f -d /dev/shm/test-cvs-rep/ commit -m 'remove everything' 'l1/bar'
 /dev/shm/test-cvs-rep/dir/l1/bar,v <-- bar
 new revision: delete; previous revision: 1.1
 ## cvs -f -d /dev/shm/test-cvs-rep/ delete 'l1/baz'
 cvs remove: scheduling `l1/baz' for removal
 cvs remove: use `cvs commit' to remove this file permanently
 ## cvs -f -d /dev/shm/test-cvs-rep/ commit -m 'remove everything' 'l1/baz'
 /dev/shm/test-cvs-rep/dir/l1/baz,v <-- baz
 new revision: delete; previous revision: 1.1
 ## cvs -f -d /dev/shm/test-cvs-rep/ delete 'l1/l2/bar'
 cvs remove: scheduling `l1/l2/bar' for removal
 cvs remove: use `cvs commit' to remove this file permanently
 ## cvs -f -d /dev/shm/test-cvs-rep/ commit -m 'remove everything' 'l1/l2/bar'
 /dev/shm/test-cvs-rep/dir/l1/l2/bar,v <-- bar
 new revision: delete; previous revision: 1.2
 ## cvs -f -d /dev/shm/test-cvs-rep/ delete 'l1/l2/baz'
 cvs remove: scheduling `l1/l2/baz' for removal
 cvs remove: use `cvs commit' to remove this file permanently
 ## cvs -f -d /dev/shm/test-cvs-rep/ commit -m 'remove everything' 'l1/l2/baz'
 /dev/shm/test-cvs-rep/dir/l1/l2/baz,v <-- baz
 new revision: delete; previous revision: 1.2
 ## cvs -f -d /dev/shm/test-cvs-rep/ delete 'l1/l2/l3/bar'
 cvs remove: scheduling `l1/l2/l3/bar' for removal
 cvs remove: use `cvs commit' to remove this file permanently
 ## cvs -f -d /dev/shm/test-cvs-rep/ commit -m 'remove everything' 'l1/l2/l3/bar'
 /dev/shm/test-cvs-rep/dir/l1/l2/l3/bar,v <-- bar
 new revision: delete; previous revision: 1.3
 ## cvs -f -d /dev/shm/test-cvs-rep/ delete 'l1/l2/l3/baz'
 cvs remove: scheduling `l1/l2/l3/baz' for removal
 cvs remove: use `cvs commit' to remove this file permanently
 ## cvs -f -d /dev/shm/test-cvs-rep/ commit -m 'remove everything' 'l1/l2/l3/baz'
 /dev/shm/test-cvs-rep/dir/l1/l2/l3/baz,v <-- baz
 new revision: delete; previous revision: 1.3
 ## cvs -f -d /dev/shm/test-cvs-rep/ delete 'l1/l2/l3'
 cvs remove: Removing l1/l2/l3
 ## cvs -f -d /dev/shm/test-cvs-rep/ commit -m 'remove everything' 'l1/l2/l3'
 cvs commit: Examining l1/l2/l3
 ## cvs -f -d /dev/shm/test-cvs-rep/ delete 'l1/l2'
 cvs remove: Removing l1/l2
 cvs remove: Removing l1/l2/l3
 ## cvs -f -d /dev/shm/test-cvs-rep/ commit -m 'remove everything' 'l1/l2'
 cvs commit: Examining l1/l2
 cvs commit: Examining l1/l2/l3
 ## cvs -f -d /dev/shm/test-cvs-rep/ delete 'l1'
 cvs remove: Removing l1
 cvs remove: Removing l1/l2
 cvs remove: Removing l1/l2/l3
 ## cvs -f -d /dev/shm/test-cvs-rep/ commit -m 'remove everything' 'l1'
 cvs commit: Examining l1
 cvs commit: Examining l1/l2
 cvs commit: Examining l1/l2/l3
 ## cvs -f -d /dev/shm/test-cvs-rep/ update -dP .
 cvs update: Updating .
 cvs update: Updating keep-dir
 cvs update: Updating l1
 cvs update: Updating l1/l2
 cvs update: Updating l1/l2/l3
 cvs update: Updating with space
 svn2cvs: D /dir/skip_add
 #### remove file: skip_add at ./svn2cvs.pl line 403.
 ## cvs -f -d /dev/shm/test-cvs-rep/ delete 'skip_add'
 cvs remove: scheduling `skip_add' for removal
 cvs remove: use `cvs commit' to remove this file permanently
 ## cvs -f -d /dev/shm/test-cvs-rep/ commit -m 'remove everything' 'skip_add'
 /dev/shm/test-cvs-rep/dir/skip_add,v <-- skip_add
 new revision: delete; previous revision: 1.1
 commit ignored, no files
 subversion revision 14 commited to CVS
 /dev/shm/test-cvs-rep/dir/.svnrev,v <-- .svnrev
 new revision: 1.15; previous revision: 1.14
 + update_all
 + update_svn
 + svn update /dev/shm/test-svn-co/
 At revision 14.
 + update_cvs
 + cd /dev/shm/test-cvs-co/
 + cvs -f update -d dir
 cvs update: Updating dir
 U dir/.svnrev
 cvs update: `dir/bar' is no longer in the repository
 cvs update: `dir/baz' is no longer in the repository
 cvs update: `dir/skip_add' is no longer in the repository
 cvs update: Updating dir/keep-dir
 cvs update: Updating dir/l1
 cvs update: `dir/l1/bar' is no longer in the repository
 cvs update: `dir/l1/baz' is no longer in the repository
 cvs update: Updating dir/l1/l2
 cvs update: `dir/l1/l2/bar' is no longer in the repository
 cvs update: `dir/l1/l2/baz' is no longer in the repository
 cvs update: Updating dir/l1/l2/l3
 cvs update: `dir/l1/l2/l3/bar' is no longer in the repository
 cvs update: `dir/l1/l2/l3/baz' is no longer in the repository
 cvs update: Updating dir/with space
 + cd-
 + diff -x '.svn*' -x CVS -urw /dev/shm/test-svn-co//dir/ /dev/shm/test-cvs-co//dir/
 Only in /dev/shm/test-cvs-co//dir/: l1
 Only in /dev/shm/test-cvs-co//dir/: with space
 + exit
.pre

The relevant lines are:

.pre
 ...
 svn2cvs: D /dir/with space
 ## cvs -f -d /dev/shm/test-cvs-rep/ delete 'with space'
 cvs remove: Removing with space
 ## cvs -f -d /dev/shm/test-cvs-rep/ commit -m 'remove everything' 'with space'
 ...
 ## cvs -f -d /dev/shm/test-cvs-rep/ delete 'l1'
 cvs remove: Removing l1
 cvs remove: Removing l1/l2
 cvs remove: Removing l1/l2/l3
 ## cvs -f -d /dev/shm/test-cvs-rep/ commit -m 'remove everything' 'l1'
 ...
 Only in /dev/shm/test-cvs-co//dir/: l1
 Only in /dev/shm/test-cvs-co//dir/: with space
 + exit
.pre

Thus cvs was asked to delete the directories, but didn`t. This is no surprise, since CVS was _designed_ not to remove directories. From the CVS manual:

> 7.3 Removing directories

> In concept, removing directories is somewhat similar to removing files--you want the directory to not exist in your current working directories, but you also want to be able to retrieve old releases in which the directory existed.

> The way that you remove a directory is to remove all the files in it. You don't remove the directory itself; there is no way to do that. Instead you specify the '-P' option to cvs update or cvs checkout, which will cause CVS to remove empty directories from working directories. (Note that cvs export always removes empty directories.) Probably the best way to do this is to always specify '-P'; if you want an empty directory then put a dummy file (for example '.keepme') in it to prevent '-P' from removing it.

> Note that '-P' is implied by the '-r' or '-D' options of checkout. This way, CVS will be able to correctly create the directory or not depending on whether the particular version you are checking out contains any files in that directory.

Thus the fix would be to automatically add a ".keepme" file upon directory creation, and to removed it (along with the other files in the directory) upon directory deletion. The testsuite also needs to be updated to use the "-P" flag. Thus, my last patch:

.pre
 diff -r -uprN svn2cvs/src/svn2cvs.pl svn2cvs/src/svn2cvs.pl
 --- svn2cvs/src/svn2cvs.pl 2007-11-01 20:36:52.000000000 +0000
 +++ svn2cvs/src/svn2cvs.pl 2007-11-01 21:06:04.000000000 +0000
 @@ -104,7 +104,8 @@ sub add_dir($$) {
 		next if in_entries($curr_dir);
 		next if ( -e "$curr_dir/CVS" );

 +		log_system( "touch '$curr_dir/.keepme'", "creation of .keepme file (to keep $curr_dir alive in CVS) failed" );
 -		log_system( "$cvs add '$curr_dir'", "cvs add of $curr_dir failed" );
 +		log_system( "$cvs add '$curr_dir' '$curr_dir/.keepme'", "cvs add of $curr_dir failed" );
 	}
 }

 diff -r -uprN svn2cvs/src/test.sh svn2cvs/src/test.sh
 --- svn2cvs/src/test.sh 2007-11-01 20:36:32.000000000 +0000
 +++ svn2cvs/src/test.sh 2007-11-01 21:06:39.000000000 +0000
 @@ -52,13 +52,13 @@ cd- || exit

 rm -Rf $cvs_co || exit
 mkdir $cvs_co || exit
 -cd $cvs_co && cvs -f co dir && cd- || exit
 +cd $cvs_co && cvs -f co -P dir && cd- || exit

 function svn2cvs() {
 	./svn2cvs.pl file://$svn_rep/dir $cvs_rep dir || exit
 }
 function update_cvs() {
 -	cd $cvs_co && cvs -f update -d dir && cd- || exit
 +	cd $cvs_co && cvs -f update -P -d dir && cd- || exit
 }
 function update_svn() {
 	svn update $svn_co || exit
 @@ -70,7 +70,7 @@ function update_all() {
 function test() {
 	svn2cvs
 	update_all
- 	diff -x .svn\* -x CVS -urw $svn_co/dir/ $cvs_co/dir/ || exit
 +	diff -x .svn\* -x CVS -x '\.keep' -urw $svn_co/dir/ $cvs_co/dir/ || exit
 }

 svn2cvs
.pre

And now the problematic test finally passes.

Hoping to be useful,

* Samuel Gélineau

----

This is one of best bug reports I ever received or actually read :-) It seems that "other projects also appriciate bug reports"<http://dev.eclipse.org/mhonarc/lists/aspectj-announce/msg00055.html> like:

* https://bugs.eclipse.org/bugs/show_bug.cgi?id=96111
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=98320
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=98592
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=99168
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=99228
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=100227
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=100260
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=102212
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=102357
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=104024
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=105181
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=106630
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=106634
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=106874
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=107059
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=107858
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=107898
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=108014
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=104046
{toc: }

This page documents my attempt to install Seaside as loadbalanced configuration with multiple squeak images under OpenVZ

^ Create VE

.pre
# download template
root@mljac:~# cd /var/lib/vz/template/cache
root@mljac:~# wget http://download.openvz.org/template/precreated/contrib/debian-5.0-i386-minimal.tar.gz

root@mljac:~# vzctl create 1001 --ostemplate debian-5.0-i386-minimal --ipadd 10.0.0.1 --hostname gw.rot13.org

# configure
root@mljac:~# vzctl set 1011 --nameserver 192.168.1.2 --save
.pre

Use something like {file: vz-nat.sh} to configure NAT on your OpenVZ machine.

^ Seaside

.pre
# dependencies

root@seaside:/srv# apt-get install unzip

root@seaside:/srv# wget -nd -nH http://www.seaside.st/distributions/Seaside-2.8.3.app.zip
root@seaside:/srv# unzip Seaside-2.8.3.app.zip 
Archive:  Seaside-2.8.3.app.zip

root@seaside:/srv# ln -s Seaside-2.8-578.app seaside


Adding new group `squeak' (1000) ...
Adding new user `squeak' (1000) with group `squeak' ...
Not creating home directory `/home/squeak'.

root@seaside:/srv# chown -R squeak:squeak Seaside-2.8-578.app/
.pre

^^ Startup

{file: Seaside.sh} - use something like this script to start headless squeak.

Actual `-headless` option didn't seem to work for me

^ Front-end HTTP proxy

{include: [nginx]}

^ Monitoring

We will be using "monit"<http://mmonit.com/monit/>, light-weight process monitor written in C to monitor servers on our virtual machine. It will do startup of our services, monitor load and report alerts.

For it to work, we need to have a script which will start/stop squeak.

Use following configuration: {file: monitrc}

Also install following two shells scripts in `/srv' so that monit can call them to start or stop services

* {file: seaside.sh}
* {file: nginx.sh}

.pre
# check syntax
root@seaside:~# /etc/init.d/monit syntax
Control file syntax OK
.pre

And you are rady to go.

* "monit@squeak1"<http://seaside.rot13.org:2812/> to view current server status

^^ Test

open "http://hostname:8080/seaside/"<http://seaside.rot13.org:8080/seaside/> to test seaside

^ More info

* http://onsmalltalk.com/scaling-seaside-more-advanced-load-balancing-and-publishing
* http://blog.blobworks.com/2008/12/16/squeak-in-jail/

* https://bytesmith.seework.com

.pre
{weblog_list: }
.pre
> "Pencil"<http://www.les-stooges.org/pascal/pencil/> is an animation/drawing software for Mac OS X and Windows. It lets you create traditional hand-drawn animation (cartoon) using both bitmap and vector graphics. Pencil is free and open source.

I wanted to run it under Linux (without "wine"<http://winehq.org>) so I tried to compile:

^ Get mac version of source

.pre
wget http://www.les-stooges.org/pascal/pencil/contents/Download/pencil-0.4.2b-mac-src.tgz
tar xvfz pencil-0.4.2b-mac-src.tgz
cd pencil-0.4.2b-mac-src
.pre

^ Use local version of ming library

Edit `pencil.pro` and change `LIBS` to:

.pre
LIBS += -lming
.pre

and remove binary verison of `libming.a` with:

.pre
rm lib/libming.a
.pre

You will also have to comment out one line in `src/interface/editor.cpp`

.pre
		updateMaxFrame();
//		object->exportMovie(1, maxFrame, view, exportSize, filePath, fps);
		return true;
.pre

^ Build it

Create `Makefile` and build project:

.pre
qmake-qt4
make
.pre

All required changes to source are also available as single diff file: {file: pencil-0.4.2b-linux.diff}

{image: pencil-linux.png}

^ Related

After compiling it, I went to Google and searched for `exportMovie` (it's easy once you *know* what to do :-) and found "following blog post"<http://www.blendernation.com/2007/06/03/pencil-2d-animation-software/> which had reference to same fix for compilation (I didn't need `-lungif` to make it work)
DSO Shell

https://gr33nonline.wordpress.com/2019/06/15/dso-150-hacks/

^ DSO-150

^^ toshi firmware with improvements

https://jyetech.com/forum/viewtopic.php?f=19&t=1206#p4057

^^ free software firmware

https://github.com/michar71/Open-DSO-150

display problem: https://www.stm32duino.com/viewtopic.php?f=7&t=276&p=1794&hilit=dso138#p1794
{toc: }

^ Links

^^ Implementations

* http://code.sixapart.com/trac/gearman
* http://gearman.org/

^^ Documentation

* protocol: http://gearman.org/index.php?id=protocol
* HTTP: http://oddments.org/?p=68

^ Cookbook

{fetchrss: http://sysadmin-cookbook.rot13.org/rss/gearman.xml full}
Disconnect receiver dongle and move finger on touchpad

.pre
dpavlin@blue:/blue-zfs/MSP430/goodfet/client$ ./goodfet.nrf sniffmacs | tee /dev/shm/keyboard
Holding autotune on 2402 MHz
sync,mac,r5,r6
'aa,bffffdea01,02,0f' looks valid       1       0.00094
'aa,bffffdea01,02,0f' looks valid       2       0.00187
'aa,bffffdea01,02,0f' looks valid       3       0.00143
'55,5ffffef500,02,0f' looks valid       1       0.00047
'55,5ffffef500,02,0f' looks valid       2       0.00084
'aa,bffffdea01,02,0f' looks valid       4       0.00154
'aa,bffffdea01,02,0f' looks valid       5       0.00182
'aa,bffffdea01,02,0f' looks valid       6       0.00202
'55,5ffffef500,02,0f' looks valid       3       0.00094

dpavlin@x200:/rest/cvs/goodfet/client$ ./goodfet.nrf tune aa,bffffdea01,02,0f

dpavlin@blue:/blue-zfs/MSP430/goodfet/client$ ./goodfet.nrf sniff
Listening as bffffdea01 on 2402 MHz           
 cc af f7 bf ff 1f e0 19 54 3b 9f 2d 2d c4 d4 1d 6a 96 d5 16 93 2a 95 b6 2b 74 d4 aa 85 72 91 41
 cc ef f7 bc fe 7f e0 19 46 c2 5e b0 c2 5a 54 a5 48 cd 42 2c d8 99 dd 19 7a aa a5 85 4a 84 55 15
 cc 2f f7 bd 42 5f e0 19 4c bf be dc d5 69 ab 19 55 8e 95 4f 8f 66 ed ac a7 d2 b6 8d d1 1b 8b 2a
 cc 6f f7 a2 62 ff e0 19 58 26 9e 32 25 20 82 0b 56 d5 12 54 3a a6 bd 5f 7d 75 ed fd 14 b2 4b 48
 cc af f7 a2 7f 9f e0 19 5b 61 5d bf 1a 62 50 b6 a9 14 b8 d9 d2 1a 52 11 0a 25 4d aa a8 dc 85 1a
 cc ef f7 bf 1d 9f e0 19 53 1f 14 a5 14 54 c3 a2 14 d1 84 59 25 56 09 08 77 55 4a 22 ce ad 56 91
.pre
This page tries to describe protocol used by CAME automatic gates

^ Information on internet

* Came code finder http://www.electronika.fr/blog/?p=1064
* decoding signals http://www.electronika.fr/blog/?p=777

^ RBE4RC

http://www.cameuk.com/camenew/tech-docs/03_Remotes%20and%20receivers/RB%20Receiver%20(needs%20AF%20card)/RBE4rc_119RS71/S71v2_GB.pdf

* ATOMO four-channel AM 433.92 MHz frequency Rolling Code Receiver

^ KeeLoq

* http://www.pittnerovi.com/jiri/hobby/electronics/keeloq/
.pre
Bus 003 Device 002: ID 093a:2600 Pixart Imaging, Inc. Typhoon Easycam USB 330K (newer)/Typhoon Easycam USB 2.0 VGA 1.3M/Sansun SN-508
.pre

* http://moinejf.free.fr/
* http://moinejf.free.fr/svv.c

.pre
dpavlin@t61p:~$ grep gcc svv.c 
gcc -Wall svv.c -o svv $(pkg-config gtk+-2.0 --cflags --libs) -lv4lconvert

dpavlin@t61p:~$ sh -c "`grep gcc svv.c`"
dpavlin@t61p:~$ ./svv 
raw pixfmt: PJPG 640x480
pixfmt: RGB3 640x480
mmap method
.pre