<!--{{{-->
<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");

}
//}}}
Amlogic Quad-core A55
RAM: 4GB
ROM: 64GB
WIFI: 2.4/5Ghz
2A@5V DC

F3X S905X3

{toc: }

internal photos:

https://fccid.io/2AVBM-A95XF3AIR/Internal-Photos/Internal-photos-4583382.pdf

^ armbian

https://www.armbian.com/amlogic-s9xx-tv-box/

boot from sd card doesn't work, button is hidden inside phone connector, and is very stiff.

^^ scdard

.pre
dpavlin@nuc:~$ sudo fdisk -l /dev/mmcblk0
Disk /dev/mmcblk0: 14.88 GiB, 15978201088 bytes, 31207424 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x2a327079

Device         Boot   Start     End Sectors  Size Id Type
/dev/mmcblk0p1         8192 1056767 1048576  512M ea Linux extended boot
/dev/mmcblk0p2      1056768 4218879 3162112  1.5G 83 Linux


dpavlin@nuc:~$ sudo mount /dev/mmcblk0p1 /tmp/a95x-boot/
[Tue Sep  2 19:53:40 2025] mmc0: cannot verify signal voltage switch
dpavlin@nuc:~$ cd /tmp/a95x-boot/
dpavlin@nuc:/tmp/a95x-boot$ [Tue Sep  2 19:53:50 2025] mmc0: cannot verify signal voltage switch

dpavlin@nuc:/tmp/a95x-boot$ ls
[Tue Sep  2 19:53:54 2025] mmc0: cannot verify signal voltage switch
aml_autoscript                  dtb              initrd.img-6.12.43-current-meson64  u-boot-s905x2-s922     uInitrd
boot.bmp                        emmc_autoscript  s905_autoscript                     u-boot-s905x3
build-u-boot                    extlinux         System.map-6.12.43-current-meson64  u-boot-s905x3-ugoosx3
config-6.12.43-current-meson64  Image            u-boot-s905                         u-boot-s905x-s912

root@nuc:/tmp/a95x-boot/extlinux# ls -al ../dtb/amlogic/*x3*
-rwxr-xr-x 1 root root 40278 Aug 22 05:10 ../dtb/amlogic/meson-gxl-s905w-tx3-mini.dtb
-rwxr-xr-x 1 root root 77285 Aug 22 05:10 ../dtb/amlogic/meson-sm1-ugoos-x3.dtb

root@nuc:/tmp/a95x-boot/extlinux# vi extlinux.conf

root@nuc:/tmp/a95x-boot# cp  u-boot-s905x3-ugoosx3 u-boot.ext


.pre

^ dead

device draws only 70mA from 5.2V 2A power supply (verified using [DPS5005]).

<https://photos.google.com/photo/AF1QipMGlbI49ukEsx0OgqaPwIROT3cjvUe-7qfEOt3>-

^ LED display

this device has interesting DVD-like LED display with HT1628 DVD driver chip and some transistors (maybe level shifters since chip is 5V ?)

https://photos.google.com/photo/AF1QipOfJtafYiOvS0QW2uX-rFwruJ3wCz7pZtsZ6qNq

^ LED strip

https://photos.google.com/photo/AF1QipMqXN8R4eBN2uQCzwUvn2ZtoBKnsJgQAE1ctr9J

it has three wire led strip of 15 leds (ws2812 meybe?) with three wires and SOIC8 chip on it.

^ serial

4 pins on bottom of board

1. GND (pin marked with square on board)
2. TX
3. RX
4. 3V3 (?)

serial output:

.pre
SM1:BL:511f6b:81ca2f;FEAT:B2F839B2:202B2060;POC:F;RCY:0;EMMC:0;READ:0;CHK:1F;READ:0;CHK:1F;READ:0;CHK:1F;SD?:20000;USB:8;
LOOP:1;EMMC:0;READ:0;CHK:1F;READ:0;CHK:1F;READ:0;CHK:1F;SD?:20000;USB:8;
LOOP:2;EMMC:0;READ:0;CHK:1F;READ:0;CHK:1F;READ:0;CHK:1F;SD?:20000;USB:8;
LOOP:3;EMMC:0;READ:0;CHK:1F;READ:0;CHK:1F;READ:0;CHK:1F;SD?:20000;USB:8;
LOOP:4;EMMC:0;READ:0;CHK:1F;READ:0;CHK:1F;READ:0;CHK:1F;SD?:20000;USB:8;
LOOP:5;EMMC:0;READ:0;CHK:1F;READ:0;CHK:1F;READ:0;CHK:1F;SD?:20000;USB:8;
LOOP:6;EMMC:0;READ:0;CHK:1F;READ:0;CHK:1F;READ:0;CHK:1F;SD?:20000;USB:8;
.pre

with sd card inserted

.pre
SM1:BL:511f6b:81ca2f;FEAT:B2F839B2:202B2060;POC:F;RCY:0;EMMC:0;READ:0;CHK:1F;READ:0;CHK:1F;READ:0;CHK:1F;SD?:0;SD:0;READ:0;CHK:1F;USB:8;
LOOP:1;EMMC:0;READ:0;CHK:1F;READ:0;CHK:1F;READ:0;CHK:1F;SD?:0;SD:0;READ:0;CHK:1F;USB:8;
LOOP:2;EMMC:0;READ:0;CHK:1F;READ:0;CHK:1F;READ:0;CHK:1F;SD?:0;SD:0;READ:0;CHK:1F;USB:8;
LOOP:3;EMMC:0;READ:0;CHK:1F;READ:0;CHK:1F;READ:0;CHK:1F;SD?:0;SD:0;READ:0;CHK:1F;USB:8;
LOOP:4;EMMC:0;READ:0;CHK:1F;READ:0;CHK:1F;READ:0;CHK:1F;SD?:0;SD:0;READ:0;CHK:1F;USB:8;
SM1:BL:511f6b:81ca2f;FEAT:B2F839B2:202B2060;POC:F;RCY:0;EMMC:0;READ:0;CHK:1F;READ:0;CHK:1F;READ:0;CHK:1F;SD?:0;SD:0;READ:0;CHK:1F;USB:8;
SM1:BL:511f6b:81ca2f;FEAT:B2F839B2:202B2060;POC:F;RCY:0;EMMC:0;READ:0;CHK:1F;READ:0;CHK:1F;READ:0;CHK:1F;SD?:0;SD:0;READ:0;CHK:1F;USB:8;
.pre

^ u-boot

https://github.com/hexdump0815/u-boot-misc/blob/master/readme.gxy

^ usb boot

https://github.com/superna9999/pyamlboot/tree/master

^ soc bypass

https://fredericb.info/2016/10/amlogic-s905-soc-bypassing-not-so.html

^ android image unpack in search for bootloader

.pre
dpavlin@nuc:/nuc/amlogic/utils$ git remote -v
origin	https://github.com/khadas/utils.git (fetch)
origin	https://github.com/khadas/utils.git (push)


dpavlin@nuc:/nuc/amlogic/utils$ ./aml_image_v2_packer -d ~/Downloads/a95x/A95X_F3_AIR_20191024senk.img A95X_F3_AIR_20191024senk
[Msg]Image package version 0x2
[Msg]Unpack item [USB         ,              DDR] to (A95X_F3_AIR_20191024senk/DDR.USB) size:1330032 bytes
[Msg]Unpack item [USB         ,          DDR_ENC] to (A95X_F3_AIR_20191024senk/DDR_ENC.USB) size:65536 bytes
[Msg]Backup item [USB         ,            UBOOT] backItemId[0][USB, DDR]
[Msg]Unpack item [USB         ,        UBOOT_ENC] to (A95X_F3_AIR_20191024senk/UBOOT_ENC.USB) size:1330176 bytes
[Msg]Unpack item [PARTITION   ,         _aml_dtb] to (A95X_F3_AIR_20191024senk/_aml_dtb.PARTITION) size:79872 bytes
[Msg]Unpack item [UBOOT       ,     aml_sdc_burn] to (A95X_F3_AIR_20191024senk/aml_sdc_burn.UBOOT) size:1330544 bytes
[Msg]Unpack item [UBOOT.ENC   ,     aml_sdc_burn] to (A95X_F3_AIR_20191024senk/aml_sdc_burn.UBOOT.ENC) size:1330688 bytes
[Msg]Unpack item [ini         ,     aml_sdc_burn] to (A95X_F3_AIR_20191024senk/aml_sdc_burn.ini) size:602 bytes
[Msg]Unpack item [PARTITION   ,             boot] to (A95X_F3_AIR_20191024senk/boot.PARTITION) size:9620480 bytes
[Msg]Unpack item [PARTITION   ,       bootloader] to (A95X_F3_AIR_20191024senk/bootloader.PARTITION) size:1330176 bytes
[Msg]Unpack item [PARTITION   ,             dtbo] to (A95X_F3_AIR_20191024senk/dtbo.PARTITION) size:438 bytes
[Msg]Unpack item [PARTITION   ,             logo] to (A95X_F3_AIR_20191024senk/logo.PARTITION) size:1020176 bytes
[Msg]Unpack item [dtb         ,           meson1] to (A95X_F3_AIR_20191024senk/meson1.dtb) size:78383 bytes
[Msg]Backup item [dtb         ,       meson1_ENC] backItemId[4][PARTITION, _aml_dtb]
[Msg]Unpack item [PARTITION   ,              odm] to (A95X_F3_AIR_20191024senk/odm.PARTITION) size:536652 bytes
[Msg]Unpack item [conf        ,         platform] to (A95X_F3_AIR_20191024senk/platform.conf) size:155 bytes
[Msg]Unpack item [PARTITION   ,          product] to (A95X_F3_AIR_20191024senk/product.PARTITION) size:14745676 bytes
[Msg]Unpack item [PARTITION   ,         recovery] to (A95X_F3_AIR_20191024senk/recovery.PARTITION) size:16307200 bytes
[Msg]Unpack item [PARTITION   ,           system] to (A95X_F3_AIR_20191024senk/system.PARTITION) size:1377898716 bytes
[Msg]Unpack item [PARTITION   ,           vbmeta] to (A95X_F3_AIR_20191024senk/vbmeta.PARTITION) size:4096 bytes
[Msg]Unpack item [PARTITION   ,           vendor] to (A95X_F3_AIR_20191024senk/vendor.PARTITION) size:204157052 bytes
[Msg]Write config file "A95X_F3_AIR_20191024senk/image.cfg" OK!
Image unpack OK!
.pre

let's write bootloader to sdcard

.pre
root@nuc:/nuc/amlogic/utils/A95X_F3_AIR_20191024senk# ~dpavlin/dd.sh aml_sdc_burn.UBOOT.ENC /dev/mmcblk0
+ dd iflag=fullblock oflag=direct conv=fsync status=progress bs=1M if=aml_sdc_burn.UBOOT.ENC of=/dev/mmcblk0
1+1 records in
1+1 records out
1330688 bytes (1.3 MB, 1.3 MiB) copied, 0.491506 s, 2.7 MB/s
.pre

power up, 230-300 mA power draw, leds are cyan with blue vertical strip, passing from right to left, and LCD screen has boot on it.
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}
{toc}

^ pinout

{image: nRF24L01_pinout.jpg}

It seems that v2.0 devies are 32k while Internet wants us to beleve that they are 16k (v1.0 maybe?)

^ original firmware output

.pre
[11985.181504] usb 2-2.1: new full-speed USB device number 7 using xhci_hcd
[11985.285687] usb 2-2.1: New USB device found, idVendor=1915, idProduct=002b
[11985.285690] usb 2-2.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[11985.285692] usb 2-2.1: Product: Nordic Semiconductor nRFready Basic Remote Dongle
[11985.285694] usb 2-2.1: Manufacturer: Nordic Semiconductor
[11985.285695] usb 2-2.1: SerialNumber: \xffffffef\xffffffbf\xffffffbf\xffffffef\xffffffbf\xffffffbf\xffffffef\xffffffbf\xffffffbf\xffffffef\xffffffbf\xffffffbf\xffffffef\xffffffbf\xffffffbf\xffffffef\xffffffbf\xffffffbf\xffffffef\xffffffbf\xffffffbf\xffffffef\xffffffbf\xffffffbf\xffffffef\xffffffbf\xffffffbf\xffffffef\xffffffbf\xffffffbf
[11985.301719] input: Nordic Semiconductor Nordic Semiconductor nRFready Basic Remote Dongle as /devices/pci0000:00/0000:00:14.0/usb2/2-2/2-2.1/2-2.1:1.0/0003:1915:002B.0005/input/input11
[11985.361937] hid-generic 0003:1915:002B.0005: input,hiddev0,hidraw2: USB HID v1.11 Keyboard [Nordic Semiconductor Nordic Semiconductor nRFready Basic Remote Dongle] on usb-0000:00:14.0-2.1/input0
.pre

^ mouse jack tools

https://github.com/BastilleResearch/mousejack

^^ find device address

.pre
dpavlin@nuc:/nuc/nRF24L01/mousejack/nrf-research-firmware/tools$ ./nrf24-scanner.py 
[2017-01-07 13:50:59.174]  12   0  65:6F:91:A9:07  
[2017-01-07 13:51:07.012]   8  10  65:6F:91:A9:07  00:C2:00:00:F8:FF:FE:00:00:49
[2017-01-07 13:51:15.216]   8  10  65:6F:91:A9:07  00:C2:00:00:17:D0:FF:00:00:58
[2017-01-07 13:51:15.231]   8   0  65:6F:91:A9:07  
[2017-01-07 13:51:15.698]  12   0  65:6F:91:A9:07  
[2017-01-07 13:51:23.456]   8  10  65:6F:91:A9:07  00:C2:00:00:EB:BF:FF:00:00:95
[2017-01-07 13:51:23.503]   8  10  65:6F:91:A9:07  00:C2:00:00:FF:0F:FF:00:00:31
[2017-01-07 13:51:23.509]   8   0  65:6F:91:A9:07  
[2017-01-07 13:51:23.840]  12   0  65:6F:91:A9:07  
.pre

^^ sniff

.pre
dpavlin@nuc:/nuc/nRF24L01/mousejack/nrf-research-firmware/tools$ ./nrf24-sniffer.py -c 8 12 -a 65:6F:91:A9:07
[2017-01-07 13:53:34.922]   8   5  65:6F:91:A9:07  00:40:00:08:B8
[2017-01-07 13:53:34.930]   8   5  65:6F:91:A9:07  00:40:00:08:B8
[2017-01-07 13:53:34.938]   8   5  65:6F:91:A9:07  00:40:00:08:B8
[2017-01-07 13:53:34.946]   8   5  65:6F:91:A9:07  00:40:00:08:B8
[2017-01-07 13:53:34.962]   8   5  65:6F:91:A9:07  00:40:00:08:B8
[2017-01-07 13:53:34.970]   8   5  65:6F:91:A9:07  00:40:00:08:B8
[2017-01-07 13:53:34.979]   8  22  65:6F:91:A9:07  00:D3:44:0F:5C:E6:CD:54:B5:71:8C:F9:99:33:00:00:00:00:00:00:00:00
[2017-01-07 13:53:34.986]   8   5  65:6F:91:A9:07  00:40:00:08:B8
[2017-01-07 13:53:34.994]   8  10  65:6F:91:A9:07  00:4F:00:01:18:00:00:00:00:98
[2017-01-07 13:53:35.125]   8   5  65:6F:91:A9:07  00:40:01:18:A7
[2017-01-07 13:53:35.278]   8  22  65:6F:91:A9:07  00:D3:B0:F4:B3:27:E3:BE:34:72:8C:F9:99:34:00:00:00:00:00:00:00:16
[2017-01-07 13:53:35.285]   8   5  65:6F:91:A9:07  00:40:00:08:B8
[2017-01-07 13:53:35.301]   8   5  65:6F:91:A9:07  00:40:00:08:B8
.pre


^ flashing

https://github.com/BastilleResearch/mousejack/issues/6
https://wiki.bitcraze.io/projects:crazyradio:spi_programming


^^ bus pirate

https://github.com/koolatron/buspirate_nrf24lu1p

| Bus Pirate || nRF24LU1+ |
| 3V3  | -> | VDD  |
| AUX  | -> | PROG |
| SCK  | -> | SCK  |
| MOSI | -> | MOSI |
| MISO | -> | MISO |
| CS   | -> | CSN  |
| GND  | -> | GND  |

.pre
dpavlin@nuc:/nuc/nRF24L01/buspirate_nrf24lu1p$ ./flasher.pl -device /dev/ttyUSB0 -input ../mousejack/nrf-research-firmware/bin/dongle.bin 

.pre

^ bootloader

^^ 512 byte replacement

https://github.com/ahtn/nrf24lu1p-512-bootloader

^^ original bootloader

https://github.com/al177/buspirate_nrf24lu1p

^ Logitech C-U0007

Version with fixed ctrl+c exit bug: https://github.com/cl0udz/mousejack

.pre
dpavlin@x230:/x230/mousejack$ git remote -v
cl0udz  https://github.com/cl0udz/mousejack (fetch)
cl0udz  https://github.com/cl0udz/mousejack (push)

dpavlin@x230:/x230/mousejack/nrf-research-firmware$ make logitech_install

[Fri Apr 27 22:10:16 2018] usb 1-1.2: new full-speed USB device number 23 using ehci-pci
[Fri Apr 27 22:10:16 2018] usb 1-1.2: New USB device found, idVendor=1915, idProduct=0102
[Fri Apr 27 22:10:16 2018] usb 1-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[Fri Apr 27 22:10:16 2018] usb 1-1.2: Product: Research Firmware
[Fri Apr 27 22:10:16 2018] usb 1-1.2: Manufacturer: RFStorm

dpavlin@x230:/x230/mousejack/nrf-research-firmware$ ./tools/nrf24-scanner.py 
[2018-04-29 14:23:51.370]   5  22  65:6F:91:A9:07  00:D3:D5:D7:4F:76:ED:63:55:70:EC:77:61:0F:00:00:00:00:00:00:00:D4
[2018-04-29 14:23:51.786]   9   5  65:6F:91:A9:07  00:40:00:08:B8




.pre
* Open firmware for RTD 2662/2660 http://openrtd2662.ru/
`irc-logger` is irc bot which records conversations, supports tags and create web archive of your conversations to enable better recall than from vague memory.

It supports several interesting features including tagging// (just add two slashes at end of the word, and it becomes tag in web archive)

{fetchrss: http://svn.rot13.org/index.cgi/irc-logger/rss/trunk full}
^ headless setup

.pre
dpavlin@nuc:~/Downloads$ unzip 2020-08-20-raspios-buster-armhf-lite.zip

dpavlin@nuc:~/Downloads$ dd iflag=fullblock oflag=direct conv=fsync status=progress bs=1M if=2020-08-20-raspios-buster-armhf-lite.img of=/dev/sdb

dpavlin@nuc:~/Downloads$ sudo mount /dev/sdb1 /mnt/sdb1/

# enable ssh
dpavlin@nuc:~/Downloads$ sudo touch /mnt/sdb1/ssh

# configure wifi
dpavlin@nuc:~/Downloads$ sudo cp /tmp/rpi4-backup/wpa_supplicant.conf /mnt/sdb1/

dpavlin@nuc:~/Downloads$ cat /mnt/sdb1/wpa_supplicant.conf
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=HR

network={
	ssid="wifi_ssid"
	psk="wifi_password"
	key_mgmt=WPA-PSK
}

dpavlin@nuc:~/Downloads$ sudo umount /mnt/sdb1
dpavlin@nuc:~/Downloads$ sudo eject /dev/sdb



.pre
OV5647 15 pin FPC

^ python

* https://github.com/waveform80/picamera

^ motion tracking

* https://github.com/YggdrasiI/RPIMotionDetection
* https://www.raspberrypi.org/forums/viewtopic.php?p=556717#p556717
{toc: }

There are many on-line resources about RFID. However, most of them are not well suited for beginners. So, if you just got RFID reader (3M in this case) and want high-level overview of what it is and what it can do, you are out of luck.

Until now, that is. This guide should help you decide if RFID is right thing for your library and when you make choice to implement it, how to do it.

This document will describe my experience with 3M 810 reader using RFID 501: RFID Standards for Libraries {file: RFID_501.pdf}

^ RFID tag

Best way to think about RFID tags is like contact-less readable barcode.

Our particular tags come in two form: RFID stickers (to be placed on books) and plastic credit-card like cards (we use them for patrons).

Have in mind that established practice is to have different RFID systems for books and patrons (we are use same one). When we asked about using same system for books and patrons, we got reply: "we don't have experience with it".
In practice, we have problem with 3M selfcheck software in some special conditions where book reader have patron card in range it gets network connection error with SIP server.
Since normal configuration of selfcheck stations is to have two different systems for patrons and books this problem doesn't show up for other users.

Each tag has unique serial number (SID) assigned by manufacturer and used in RFID collision detection protocol. It looks like hexadecimal number starting with letter `E0` like this: `E00401003123AA26`.

It's best to think of SID as unique identifier of physical tag.
Your information system will have it's own ID (barcode?) for some item.
There are cases in which you might want to change physical tag sticker on book because it's damaged. In that case, you will change SID of that item, but not barcode (which is data programmed on tag itself).

Our initial idea was to use data programmed on chip for everything, and just ignore SIDs, but we found out that there is class of RFID devices which can read ONLY SID from chip (in our case it's photocopying system).
3M software does record SIDs to log file when programming chips, but that's all. It essential ignores it for all practical intends and purposes.

Chips have 7 blocks of user data on it, each block with 4 bytes which enables us to store 28 bytes of user specified data on each tag.

^^ blank tag

^^^ 3M Manufacturing Blank

Easiest case is blank tag, in which all data on chip is 0x55

.pre
0	55 55 55 55		blank tag
1	55 55 55 55
2	55 55 55 55
3	55 55 55 55
4	55 55 55 55
5	55 55 55 55
6	00 00 00 00 
.pre

^^^ Generic blank

Generic blank seems to erase only first three blocks with zeros:

.pre
00	00 00 00 00
01	00 00 00 00
02	00 00 00 00
.pre

while rest of tag will be unchanged *including rest of data on tag*

^^ programmed tag

Tags programmed with 3M software have following data layout on them:

.pre
0	04 is 00 tt		i [4 bit] = number of item in set	[1 .. i .. s]
					s [4 bit] = total items in set
					tt [8 bit] = item type

1	dd dd dd dd		dd [16 bytes] = barcode data
2	dd dd dd dd
3	dd dd dd dd
4	dd dd dd dd

5	bb bl ll ll		b [12 bit] = branch [unsigned]
				l [20 bit] = library [unsigned]
6	cc cc cc cc		c [32 bit] = custom signed integer
.pre

This basically means that your barcode or identifier of item or patron can have up to 16 characters (by default numeric, but you can extend that to handle alphanumeric and special character if you need that) and three integer values: branch `0 .. 4095`, library `0 .. 1048575` and custom data `-2147483648 .. 2147483647`.

You might want to use those values to uniquely identify your library and branch so that your RFID tags in books won't collide with other libraries.
If you leave decision just to providers of equipment, you might end up with 300000 tags which have plain and simple 0 in those fields. Guess which value will have tags of next library which that provider will have? My guess would be 0 also.

Writing correct numbers in that fields is not enough. If you want to use 3M software, you will also have to setup it to ignore all other tags which doesn't match your library and branch.

^^ security

There is also single byte called AFI or security which can be changed without accessing content of chip. This byte is also readable by more primitive RFID devices like doors to check if book have been checked out from library.

3M is using `0xD7` (215) value for secured items (door will beep) and `0xDA` (218) as unsecured. It seems that all other values are ignored.
(I would guess that other manufacturers are using different values)

As I mentioned before, since we don't have any special values in branch, library or custom field, we have situations in which patron cards get secured when patron walks by checkout counter and 3M software is left in checkout mode.
This triggers door to ring when patron passes which is not ideal.

^^ disable tag

3M software have option to disable tags. Initial examination showed that it's simply programming of tag with following content:

.pre
00	ff 00 00 00
01	00 00 00 00
02	00 00 00 00
03	00 00 00 00
04	00 00 00 00
05	00 00 00 00
06	00 00 00 00
.pre

and security set to `d7` (this might be value from tag before disabling it, I'll have to re-check this)

While 3M software will ignore tags programmed with this content, there is *not permanent disabling of tag* since it can be programmed using other software.

^ RFID reader device

Reader consists of several part:

* black pad - reader antenna
* reader - small box with micro controller and usb port
* software

Reader is recognized as USB serial device with it's own protocol on serial port. We are mostly interested in it's protocol and our ability to use reader and tags with our custom software.

At first, I assumed that protocol with RFID readers is some kind of standard.
After extensive search on Internet I wasn't able to find any documentation about this particular protocol (I even tried to compare it with existing open source implementations just to be sure).

So, only solution was to do clean-room reverse engineering, and using that technique I developed perl module which can talk with RFID reader which is available at http://svn.rot13.org/index.cgi/RFID

After initial reverse engineering of protocol I rewrote support for 3M and CPR reader which is available at https://github.com/dpavlin/Biblio-RFID

^ Related blog posts

{fetchrss: http://mjesec.ffzg.hr/~dpavlin/blog/mt/mt-search.cgi?tag=RFID&Template=feed&IncludeBlogs=1}

^ More information

If this was too geeky for you here is some additional materials:

* "RFID for libraries FAQ"<http://www.bibliotheca-rfid.com/faq>
* "RFID - overview of protocols, librfid implementation and passive sniffing"<http://events.ccc.de/congress/2005/fahrplan/events/769.en.html>

^ ISO standard

* ISO 15962.2004 - object identifier structure
* ISO 15693 - RFID (layer 2)
* ISO 18000 Part 3 Mode 1 - 13.56MHz
* "ISO/IEC JTC1/SC17/WG8"<http://www.incits.org/tc_home/b105htm/b105Doc2003/N03-140-WG8-Work-Project.htm>

^ ISO/IEC 14443, Proximity cards

The Standard series ISO/IEC 14443 consists of 4 parts, which are:

^^ ISO/IEC 14443-1 Physical characteristics

{file: 17n1363t.doc} {file: 17n1363b.doc}

^^ ISO/IEC 14443-2 Radio frequency power and signal interface

{file: 17n1522t.pdf} {file: 17n1522c.doc}

^^ ISO/IEC 14443-2/AMD2 Amendment 2: Bit rates of fc/64, fc/32 and fc/16

{file: 17n2343T.pdf} {file: 17n2343F.doc}

^^ ISO/IEC 14443-3 Initialization and anticollision

{file: 17n1531t.pdf} {file: 17n1531c.doc}

^^ ISO/IEC 14443-3 Amendment 1: Bit rates of fc/64, fc/32 and fc/16

{file: 17n2342T.pdf} {file: 17n2342F.doc}

^^ ISO/IEC 14443-4 Transmission protocol

{file: 17N1689T.pdf} {file: 17n1689c.doc}

^ ISO/IEC 15693, Vicinity cards

^^ ISO/IEC 15693-1 Physical characteristics

{file: 17n1355t.doc} {file: 17n1355b .doc}

^^ ISO/IEC 15693-2 Air interface and initialisation

{file: 17n1486.pdf} {file: 17n1486c.doc}

^^ ISO/IEC 15693-3 Anticollision and transmission protocol

{file: 17n1692t.pdf} {file: 17n1692c.doc}

^ ISO/IEC 10373-6, 10373-7, Test methods for the contactless integrated circuit(s) cards

^^ ISO/IEC 10373-6 Proximity cards

{file: 17n1695t.pdf} {file: 17n1695c.doc}

^^ ISO/IEC 10373-6/AMD1 Amendment 1: Additional PICC test methods

{file: 17n2258t.pdf} {file: 17n2258t.doc} {file: 17n2258C.doc}

^^ ISO/IEC 10373-6/AMD2 Amendment 2: Improved RF test methods

{file: 17n2225t.pdf} {file: 17n2225F.doc}

^^ ISO/IEC 10373-7 Vicinity cards

{file: 17n1697t.pdf} {file: 17n1697c.doc}

^ ISO/IEC 10536, Close-coupled cards

^^ ISO/IEC 10536-1 Physical characteristics

{file: 17n1480t.PDF} {file: 17n1480c.doc}
Page renamed to [rtl-sdr]
Up: [Workspace Tour - Table of Contents]
Back: [Documents that people are working on]

Here's an example of what a conversation page might look like...

| ^^^ Group-forming metrics

[Adina] - I spoke this afternoon to Anil Gupta over at CyberProteins, Inc. They are interested in the groupforming metrics reports, and are interested in additional metrics about network growth.

[Ed] - It would also be useful to configure these reports more rapidly in the field. We should also consider think about providing services helping customers to choose and implement the right metrics. I'll bring this up at the next business-plan meeting. |

Follow us to see how you can use workspace pages for [meeting agendas]...
This page will document my tries to install it on current Debian unstable with support for both SQLite and MySQL. I also have ISO-8859-2 console, so it's important for me that UTF-8 encoded characters work well.

I will also try to specify differences when installing on latest Debian stable, etch.

{toc: }

^ Links

* project page: http://code.google.com/p/semantic-engine/
* "Using Latent Semantic Analysis in Bioinformatics"<http://www.hirank.com/semantic-indexing-project/presentations/biocon/slide0001.htm>

^ Development libraries

.pre
sudo apt-get install libboost-filesystem-dev libboost-graph-dev libboost-program-options-dev libsqlite3-dev libmysqlclient15-dev
.pre

This will install (currently) version 1.34 of boost which won't work without patching source code.

^ Installation

Download {file: semantic-engine-0-compile.diff} if you are installing on unstable. If not, just skip patch below.

.pre
svn co http://semantic-engine.googlecode.com/svn/trunk Semantic-Engine
cd Semantic-Engine
patch -p0 < ~/semantic-engine-0-compile.diff
./bootstrap
make
.pre

^^ Perl bindings

Compile and install perl bindings:

.pre
cd pl
perl Makefile.PL
make
make test
sudo make install
cd ..
.pre

^^ Shared parts

.pre
cd share
sudo make install
cd ..
.pre

^^ QT interface

Compile and try out QT interface using following patch: {file: semantic-engine-1-qt.diff}

.pre
cd qt/semantic_engine/
patch -p2 < ~/semantic-engine-1-qt.diff
qmake-qt4 
make
./SemanticEngine-debug
.pre

^ EPrints search using LSI

I have a little example using various tricks to index Croatian language from "EPrints"<http://www.eprints.org/software/> archive.

{fetchrss: http://svn.rot13.org/index.cgi/Semantic-Engine/rss}
https://www.unix-ag.uni-kl.de/~auerswal/ssocr/

https://github.com/auerswal/ssocr
{file: Compal_LA-6352P_PAZ00_AC100.pdf}

{toc: }

[Tegra] 2 device

^ kernel

* https://gitlab.com/groups/ac100 (gitorious is dead)

^ cpuinfo

.pre
$ cat /proc/cpuinfo
Processor       : ARMv7 Processor rev 0 (v7l)
processor       : 0
BogoMIPS        : 1998.84

Features        : swp half thumb fastmult vfp edsp vfpv3 vfpv3d16 
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x1
CPU part        : 0xc09
CPU revision    : 0

Hardware        : NVIDIA Harmony Development System
Revision        : 0000
Serial          : 0000000000000000

$ cat /proc/meminfo
MemTotal:         383348 kB
MemFree:          106528 kB
Buffers:           30116 kB
Cached:           123316 kB
SwapCached:            0 kB
Active:           164792 kB
Inactive:          85020 kB
Active(anon):      96692 kB
Inactive(anon):        0 kB
Active(file):      68100 kB
Inactive(file):    85020 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                 0 kB
Writeback:             0 kB
AnonPages:         96412 kB
Mapped:            44536 kB
Shmem:               312 kB
Slab:               8940 kB
SReclaimable:       4848 kB
SUnreclaim:         4092 kB
KernelStack:        2528 kB
PageTables:         8324 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:      191672 kB
Committed_AS:    6569284 kB
VmallocTotal:     614400 kB
VmallocUsed:       30656 kB
VmallocChunk:     520068 kB
.pre

^ Rooting

^^ nvflash

Press CTRL + ESC + power button to get into APX mode

.pre
[Thu Oct 11 06:31:57 2018] usb 2-2.4: new high-speed USB device number 13 using xhci_hcd
[Thu Oct 11 06:31:57 2018] usb 2-2.4: New USB device found, idVendor=0955, idProduct=7820, bcdDevice= 1.02
[Thu Oct 11 06:31:57 2018] usb 2-2.4: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[Thu Oct 11 06:31:57 2018] usb 2-2.4: Product: APX
[Thu Oct 11 06:31:57 2018] usb 2-2.4: Manufacturer: NVIDIA Corp.
.pre

* http://tegradeveloper.nvidia.com/tegra-android-development-pack

In theory. In practice driver package from

* http://developer.download.nvidia.com/assets/mobile/files/tegra-linux-12.alpha.1.0.tar.gz

is everything you need. It's from http://developer.nvidia.com/content/linux-tegra-release-12-alpha-1-released

^^ fastboot.stock.bin

.pre
t61p:/home/dpavlin/Downloads/ldk/bootloader/alt# wget https://github.com/muromec/putusb/raw/master/bin/fastboot.stock.bin
--2011-09-12 20:40:17--  https://github.com/muromec/putusb/raw/master/bin/fastboot.stock.bin
Resolving github.com (github.com)... 207.97.227.239
Connecting to github.com (github.com)|207.97.227.239|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://raw.github.com/muromec/putusb/master/bin/fastboot.stock.bin [following]
--2011-09-12 20:40:19--  https://raw.github.com/muromec/putusb/master/bin/fastboot.stock.bin
Resolving raw.github.com (raw.github.com)... 207.97.227.243
Connecting to raw.github.com (raw.github.com)|207.97.227.243|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 936016 (914K) [application/octet-stream]
Saving to: `fastboot.stock.bin'

100%[=====================================================>] 936,016      645K/s   in 1.4s    

2011-09-12 20:40:22 (645 KB/s) - `fastboot.stock.bin' saved [936016/936016]

t61p:/home/dpavlin/Downloads/ldk/bootloader/alt# md5sum fastboot.stock.bin 
9197365fb42c5801b4124e75ea00512c  fastboot.stock.bin
.pre

^^ backup

Following instructions at http://gitorious.org/ac100/pages/Installation

.pre
t61p:/home/dpavlin/Downloads/ldk/bootloader# ./nvflash --bl fastboot.stock.bin --go
Nvflash started
rcm version 0X20001
System Information:
   chip name: t20
   chip id: 0x20 major: 1 minor: 2
   chip sku: 0x8
   chip uid: 0x1700618943a00317
   macrovision: disabled
   hdcp: enabled
   sbk burned: false
   dk burned: false
   boot device: emmc
   operating mode: 3
   device config strap: 0
   device config fuse: 0
   sdram config strap: 0

downloading bootloader -- load address: 0x108000 entry point: 0x108000
sending file: fastboot.stock.bin
| 936016/936016 bytes sent
fastboot.stock.bin sent successfully
waiting for bootloader to initialize
bootloader downloaded successfully


t61p:/home/dpavlin/Downloads/ldk/bootloader# ./nvflash -r --getpartitiontable partitiontable.txt
Nvflash started
[resume mode]
Succesfully updated partition table information to partitiontable.txt


t61p:/home/dpavlin/Downloads/ldk/bootloader# ./nvflash -r --read 2 part-2.img
Nvflash started
[resume mode]
receiving file: part-2.img, expected size: 3145728 bytes
/ 3145728/3145728 bytes received
file received successfully
t61p:/home/dpavlin/Downloads/ldk/bootloader# ./nvflash -r --read 3 part-3.img
Nvflash started
[resume mode]
receiving file: part-3.img, expected size: 524288 bytes
/ 524288/524288 bytes received
file received successfully
t61p:/home/dpavlin/Downloads/ldk/bootloader# /nvflash -r --read 4 part-4.img
bash: /nvflash: No such file or directory
t61p:/home/dpavlin/Downloads/ldk/bootloader# ./nvflash -r --read 4 part-4.img
Nvflash started
[resume mode]
receiving file: part-4.img, expected size: 2097152 bytes
/ 2097152/2097152 bytes received
file received successfully
t61p:/home/dpavlin/Downloads/ldk/bootloader# ./nvflash -r --read 5 part-5.img
Nvflash started
[resume mode]
receiving file: part-5.img, expected size: 5242880 bytes
/ 5242880/5242880 bytes received
file received successfully
t61p:/home/dpavlin/Downloads/ldk/bootloader# ./nvflash -r --read 6 part-6.img
Nvflash started
[resume mode]
receiving file: part-6.img, expected size: 8388608 bytes
/ 8388608/8388608 bytes received
file received successfully
t61p:/home/dpavlin/Downloads/ldk/bootloader# ./nvflash -r --read 7 part-7.img
Nvflash started
[resume mode]
receiving file: part-7.img, expected size: 1048576 bytes
/ 1048576/1048576 bytes received
file received successfully
t61p:/home/dpavlin/Downloads/ldk/bootloader# ./nvflash -r --read 8 part-8.img
Nvflash started
[resume mode]
receiving file: part-8.img, expected size: 314572800 bytes
/ 314572800/314572800 bytes received
file received successfully
t61p:/home/dpavlin/Downloads/ldk/bootloader# ./nvflash -r --read 9 part-9.img
Nvflash started
[resume mode]
receiving file: part-9.img, expected size: 419430400 bytes
/ 419430400/419430400 bytes received
file received successfully
t61p:/home/dpavlin/Downloads/ldk/bootloader# ./nvflash -r --read 10 part-10.img
Nvflash started
[resume mode]
receiving file: part-10.img, expected size: 2097152 bytes
/ 2097152/2097152 bytes received
file received successfully
t61p:/home/dpavlin/Downloads/ldk/bootloader# ./nvflash -r --read 11 part-11.img
Nvflash started
[resume mode]
receiving file: part-11.img, expected size: 524288 bytes
/ 524288/524288 bytes received
file received successfully
t61p:/home/dpavlin/Downloads/ldk/bootloader# ./nvflash -r --read 12 part-12.img
Nvflash started
[resume mode]
receiving file: part-12.img, expected size: 1294991360 bytes
/ 1294991360/1294991360 bytes received
file received successfully
t61p:/home/dpavlin/Downloads/ldk/bootloader# ./nvflash -r --read 13 part-13.img
Nvflash started
[resume mode]
receiving file: part-13.img, expected size: 524288 bytes
/ 524288/524288 bytes received
file received successfully
t61p:/home/dpavlin/Downloads/ldk/bootloader# ./nvflash -r --read 14 part-14.img
Nvflash started
[resume mode]
receiving file: part-14.img, expected size: 5891424256 bytes
/ 5891424256/5891424256 bytes received
file received successfully


.pre

^ Linux

^^ links

{fetchrss: http://feeds.delicious.com/v2/rss/dpavlin/ac100?count=15 full}

^^ phh 2.6.32 kernel with working suspend and audio

* http://salaliitto.com/~gildean/ac100/wiki/phh/

.pre
t61p:/home/dpavlin/ac100/linux4tegra_10.9.3# LD_LIBRARY_PATH=./nvflash/ ./nvflash/nvflash --bl ./prebuilt/fastboot.stock.bin --read 6 tegra_partition_6.bin --go
Nvflash started
rcm version 0X20001
System Information:
   chip name: t20
   chip id: 0x20 major: 1 minor: 2
   chip sku: 0x8
   chip uid: 0x1700618943a00317
   macrovision: disabled
   hdcp: enabled
   sbk burned: false
   dk burned: false
   boot device: emmc
   operating mode: 3
   device config strap: 0
   device config fuse: 0
   sdram config strap: 0

downloading bootloader -- load address: 0x108000 entry point: 0x108000
sending file: ./prebuilt/fastboot.stock.bin
| 936016/936016 bytes sent
./prebuilt/fastboot.stock.bin sent successfully
waiting for bootloader to initialize
bootloader downloaded successfully
receiving file: tegra_partition_6.bin, expected size: 8388608 bytes
/ 8388608/8388608 bytes received
file received successfully



t61p:/home/dpavlin/ac100/linux4tegra_10.9.3# LD_LIBRARY_PATH=./nvflash/ ./nvflash/nvflash --wait --bl ./prebuilt/fastboot.stock.bin --download 6 ../32.boot.menu.v1.img --go
Nvflash started
rcm version 0X20001
System Information:
   chip name: t20
   chip id: 0x20 major: 1 minor: 2
   chip sku: 0x8
   chip uid: 0x1700618943a00317
   macrovision: disabled
   hdcp: enabled
   sbk burned: false
   dk burned: false
   boot device: emmc
   operating mode: 3
   device config strap: 0
   device config fuse: 0
   sdram config strap: 0

downloading bootloader -- load address: 0x108000 entry point: 0x108000
sending file: ./prebuilt/fastboot.stock.bin
| 936016/936016 bytes sent
./prebuilt/fastboot.stock.bin sent successfully
waiting for bootloader to initialize
bootloader downloaded successfully
sending file: ../32.boot.menu.v1.img
/ 8388608/8388608 bytes sent
../32.boot.menu.v1.img sent successfully

.pre

^ mainline kernel

* Newest howto for arch: https://gist.github.com/Nokius/81cd46405b537931a472e0a55abb7ccd

* https://archlinuxarm.org/forum/viewtopic.php?f=49&t=10116

^ u-boot from APX

This should allow you to send u-boot, kernel and initramfs to any tegra2 board which can be in APX mode without
modifying internal storage.

^^ build u-boot

.pre
dpavlin@klin:/klin/u-boot$ cat env.sh 
export CROSS_COMPILE="arm-none-eabi-" ARCH=arm
dpavlin@klin:/klin/u-boot$ . env.sh 

dpavlin@klin:/klin/u-boot$ make paz00_defconfig

make


.pre

^^ build kernel

.pre
dpavlin@klin:/klin/Tegra/linux$ git remote -v
origin  https://github.com/grate-driver/linux (fetch)
origin  https://github.com/grate-driver/linux (push)
samsung-tab-10.1        https://github.com/Decatf/linux (fetch)
samsung-tab-10.1        https://github.com/Decatf/linux (push)

dpavlin@klin:/klin/Tegra/linux$ git branch -vv
* master 63a6317580f8 [origin/master] ARM: tegra: Clear EMC interrupts on resume from LP1 on Tegra30+

dpavlin@klin:/klin/Tegra/linux$ cat /klin/u-boot/env.sh 
export CROSS_COMPILE="arm-none-eabi-" ARCH=arm
dpavlin@klin:/klin/Tegra/linux$ . /klin/u-boot/env.sh

dpavlin@klin:/klin/Tegra/linux$ make tegra_defconfig

make


.pre

^^^ create initrd with new modules

.pre
dpavlin@klin:/klin/Tegra/linux$ cat tegra-ramdisk.sh 
#!/bin/sh -xe

test -d initrd && rm -Rf initrd

mkdir initrd
cd initrd

gzip -cd  /tmp/initrd.img | fakeroot -- cpio -i -d -H newc --no-absolute-filenames

rm -R lib/modules/*

cd ..
make modules_install INSTALL_MOD_PATH=initrd/ INSTALL_MOD_STRIP=1

cd initrd

find . | cpio -o -R 0:0 -H newc > ../initrd.new.cpio

cd ..

gzip -f -6 initrd.new.cpio

/klin/u-boot/tools/mkimage -A arm -O linux -T ramdisk -C gzip -n uInitrd -d initrd.new.cpio.gz uInitrd.new
.pre

run it to create initrd:

.pre
dpavlin@klin:/klin/Tegra/linux$ ./tegra-ramdisk.sh 

Image Name:   uInitrd
Created:      Fri Oct 12 11:20:42 2018
Image Type:   ARM Linux RAMDisk Image (gzip compressed)
Data Size:    4082917 Bytes = 3987.22 KiB = 3.89 MiB
Load Address: 00000000
Entry Point:  00000000

.pre

^^ create bootloader file

latest version seems to be: https://gitlab.com/uboot-ac100/create_bootimage.git

.pre
dpavlin@nuc:/nuc/Tegra/ac100/create_bootimage/example$ ../create_image.pl /mnt/klin/klin/u-boot/u-boot-dtb-tegra.bin /m
nt/klin/klin/Tegra/linux/arch/arm/boot/zImage /tmp/postmarketOS-export/initrd.img /mnt/klin/klin/Tegra/linux/arch/arm/b
oot/dts/tegra20-paz00.dtb uboot.scr boot.img
Creating boot image for tegrarcm ...

./tmp_uboot.scr
image layout:
section  loadaddr       size
=================================
uboot   : 0x108000      505627
kernel  : 0x190000      6485800
initrd  : 0x7c0000      4082981
fdt     : 0xbb0000      29659
script  : 0xbc0000      226

image written to boot.img
.pre

Now press CTRL + ESC + power on to enter APX mode

.pre
dpavlin@nuc:/nuc/Tegra/ac100/create_bootimage/example$ sudo apt-get install libcrypto++6

dpavlin@nuc:/nuc/Tegra/ac100/create_bootimage/example$ /mnt/klin/klin/Tegra/tegrarcm/src/tegrarcm --bct paz00-micron-toshiba-8g.bct --bootloader boot.img --loadaddr 0x108000 
bct file: paz00-micron-toshiba-8g.bct
bootloader file: boot.img
load addr 0x108000
entry addr 0x108000
device id: 0x7820
uid:  0x1700618943a00317
RCM version: 2.1
downloading miniloader to target at address 0x40008000 (132976 bytes)...
miniloader downloaded successfully
Chip UID:                0x00000000000000001700618943a00317
Chip ID:                 0x20
Chip ID Major Version:   0x1
Chip ID Minor Version:   0x2
Chip SKU:                0x8 (t20)
Boot ROM Version:        0x1
Boot Device:             0x2 (EMMC)
Operating Mode:          0x3 (developer mode)
Device Config Strap:     0x0
Device Config Fuse:      0x0
SDRAM Config Strap:      0x0
sending file: paz00-micron-toshiba-8g.bct
- 4080/4080 bytes sent
paz00-micron-toshiba-8g.bct sent successfully
sending file: boot.img
- 11239650/11239650 bytes sent
boot.img sent successfully

.pre

u-boot loads detects initrd (it's small enough thanks to MODULES_STRIP to be detected without CRC errors) but no output from kernel.

https://archlinuxarm.org/forum/viewtopic.php?f=23&t=10044&p=51142&hilit=ac100#p51142

suggests CONFIG_TEGRA_DEBUG_UARTA instead of CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA but it doesn't work for me.

.pre
dpavlin@klin:/klin/Tegra/linux$ grep 'TEGRA.*UART' .config
# CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA is not set
CONFIG_TEGRA_DEBUG_UARTA=y
# CONFIG_TEGRA_DEBUG_UARTB is not set
# CONFIG_TEGRA_DEBUG_UARTC is not set
# CONFIG_TEGRA_DEBUG_UARTD is not set
# CONFIG_TEGRA_DEBUG_UARTE is not set
CONFIG_DEBUG_TEGRA_UART=y


.pre

^ serial port

https://ac100.grandou.net/serial_port_modification

{image: IMG_20181014_181159-800px.jpg}

The serial port is the JP1 connector, near the left speaker connector. Pinout, from right to left:

* 1 - in - RX UART1
* 2 - out - TX UART1
* 3 - out - T20_WAKE#
* 4 - out - +3V
* 5 - out - +1.8V
* 6
* 7
* 8 - in - SYSTEM_RESET#
* 9 - in - EC_TX80_PDATA
* 10 - in - GND

I decided to solder GND to outer pin of connector to the right of pin 1 as opposed to other side of connector.

After that, a peace of capton tape was put over solder connectors to somewhat re-enforce them and provide insulation
to keyboard cover.

Serial is 3.3V, 115200 8n1.

Output is:

.pre
dpavlin@nuc:/nuc/Tegra$ microcom -p /dev/ttyUSB2
connected to /dev/ttyUSB2
Escape character: Ctrl-\
Type the escape character to get to the prompt.

U-Boot SPL 2018.11-rc1-00130-g0a60a81ba3 (Oct 12 2018 - 11:18:01 +0200)
Trying to boot from RAM


U-Boot 2018.11-rc1-00130-g0a60a81ba3 (Oct 12 2018 - 11:18:01 +0200)

TEGRA20
Model: Toshiba AC100 / Dynabook AZ
Board: Compal Paz00
DRAM:  512 MiB
MMC:   sdhci@c8000000: 1, sdhci@c8000600: 0
Loading Environment from MMC... *** Warning - bad CRC, using default environment

In:    serial
Out:   vidconsole
Err:   vidconsole
Net:   No ethernet found.
Hit any key to stop autoboot:  0
## Executing script at 00b30000
## Loading init Ramdisk from Legacy Image at 00700000 ...
   Image Name:   uInitrd
   Image Type:   ARM Linux RAMDisk Image (gzip compressed)
   Data Size:    4269789 Bytes = 4.1 MiB
   Load Address: 00000000
   Entry Point:  00000000
   Verifying Checksum ... OK
## Flattened Device Tree blob at 00b20000
   Booting using the fdt blob at 0xb20000
   Using Device Tree in place at 00b20000, end 00b2a3da

Starting kernel ...


Error: invalid dtb and unrecognized/unsupported machine ID
  r1=0x00000c38, r2=0x00000000
Available machine support:

ID (hex)        NAME
ffffffff        Generic DT based system
ffffffff        NVIDIA Tegra SoC (Flattened Device Tree)

Please check your kernel config and/or bootloader.

.pre

According to http://billauer.co.il/blog/2014/02/uboot-linux-dtb-fdt-device-tree/ this means that kernel didn't found valid device tree and tries to detect board usin machine ID registrars.

Solution for this seems to use u-boot variables for loading kernel, ramfs and dtb as opposed to values which script creates,
so this works (loading from usb keychain):

.pre
fatload usb 0:1 ${kernel_addr_r} /boot/zImage
fatload usb 0:1 ${fdt_addr_r} /boot/tegra20-paz00.dtb
fatload usb 0:1 ${ramdisk_addr_r} /boot/uInitrd.new
bootz ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r}
.pre

Here are also known working addresses which u-boot uses:

.pre
Tegra20 (Paz00) MOD # echo ${kernel_addr_r}
0x01000000
Tegra20 (Paz00) MOD # echo ${fdt_addr_r}
0x02000000
Tegra20 (Paz00) MOD # echo ${ramdisk_addr_r} 
0x02100000
.pre

so much higher in memory map than create_image script. However, u-boot seems to want to load at 0x108000 so it's inpractical
to generate huge image to load kernel, dtb and initramfs at correct addresses.

^ bootstrap debian

based on https://wiki.debian.org/InstallingDebianOn/Toshiba/AC100

.pre
dpavlin@nuc:/mnt$ sudo debootstrap --foreign --arch=armhf stretch sdd1 http://ftp.hr.debian.org/debian

dpavlin@nuc:/mnt$ df sdd1/
Filesystem     1K-blocks   Used Available Use% Mounted on
/dev/sdd1        1021948 169056    784596  18% /mnt/sdd1

dpavlin@nuc:/mnt$ sudo cp /usr/bin/qemu-arm-static sdd1/usr/bin

dpavlin@nuc:/mnt$ sudo chroot sdd1 /debootstrap/debootstrap --second-stage

dpavlin@nuc:/mnt$ cd sdd1/
dpavlin@nuc:/mnt/sdd1$ sudo mount --bind /sys sys
dpavlin@nuc:/mnt/sdd1$ sudo mount --bind /dev dev
dpavlin@nuc:/mnt/sdd1$ sudo mount --bind /proc proc
dpavlin@nuc:/mnt/sdd1$ sudo chroot .

root@nuc:/# apt-get install u-boot-tools

root@ac100:/boot# cat boot.cmd 
ext2load usb 0:1 ${kernel_addr_r} /boot/zImage
ext2load usb 0:1 ${fdt_addr_r} /boot/tegra20-paz00.dtb
ext2load usb 0:1 ${ramdisk_addr_r} /boot/uInitrd
setenv bootargs root=/dev/sda1 rootwait CMA=64M tegrapart=recovery:300:a00:800,boot:d00:1000:800,mbr:1d00:200:800
bootz ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r}

# mkimage -C none -A arm -T script -d /boot/boot.cmd /boot/boot.scr





.pre

^ u-boot over pax, usb filesystem

.pre
dpavlin@nuc:/nuc/Tegra/ac100/create_bootimage/example$ /mnt/klin/klin/Tegra/tegrarcm/src/tegrarcm --bct paz00-micron-toshiba-8g.bct --bootloader /mnt/klin/klin/Tegra/u-boot-tegra/u-boot-dtb-tegra.bin --loadaddr 0x108000
bct file: paz00-micron-toshiba-8g.bct

.pre

Serial output:

.pre
U-Boot SPL 2018.09-rc2-38340-g3d186cf3f3 (Oct 20 2018 - 10:46:53 +0200)
Trying to boot from RAM


U-Boot 2018.09-rc2-38340-g3d186cf3f3 (Oct 20 2018 - 10:46:53 +0200)

TEGRA20
Model: Toshiba AC100 / Dynabook AZ
Board: Compal Paz00
DRAM:  512 MiB
MMC:   sdhci@c8000000: 1, sdhci@c8000600: 0
Loading Environment from MMC... OK
In:    serial
Out:   vidconsole
Err:   vidconsole
Net:   No ethernet found.
starting USB...
USB0:   USB EHCI 1.00
USB1:   No code to set up ULPI controller, please enableCONFIG_USB_ULPI and CONFIG_USB_ULPI_VIEWPORTprobe failed, error -38
USB2:   USB EHCI 1.00
scanning bus 0 for devices... 1 USB Device(s) found
scanning bus 2 for devices... 4 USB Device(s) found
       scanning usb for storage devices... 1 Storage Device(s) found
Hit any key to stop autoboot:  0
Tegra20 (Paz00) MOD # run usb_boot

.pre

^ wifi

.pre
root@ac100:/etc/network/interfaces.d# apt-get install firmware-ralink wpasupplicant

root@ac100:/etc/network/interfaces.d# cat wlx6c626d1788b3 
allow-hotplug wlx6c626d1788b3
iface wlx6c626d1788b3 inet dhcp
        wpa-ssid dreamhouse
        wpa-psk xxxxxxxx

.pre

^ disk speed

.pre
root@ac100:~# hdparm -tT /dev/sda /dev/mmcblk1

/dev/sda:
 Timing cached reads:   560 MB in  2.01 seconds = 279.14 MB/sec
 Timing buffered disk reads:  32 MB in  3.07 seconds =  10.43 MB/sec

/dev/mmcblk1:
 Timing cached reads:   598 MB in  2.00 seconds = 298.86 MB/sec
 Timing buffered disk reads: 108 MB in  3.01 seconds =  35.83 MB/sec
.pre

^^ tuhing block size

.pre
root@ac100:/home/dpavlin/flashbench# ./flashbench -a /dev/mmcblk1 --blocksize=1024
align 2147483648        pre 727µs      on 1.07ms       post 784µs     diff 316µs
align 1073741824        pre 833µs      on 1.13ms       post 789µs     diff 320µs
align 536870912 pre 798µs      on 1.13ms       post 825µs     diff 317µs
align 268435456 pre 816µs      on 1.15ms       post 795µs     diff 342µs
align 134217728 pre 742µs      on 1.12ms       post 843µs     diff 327µs
align 67108864  pre 669µs      on 987µs       post 701µs     diff 303µs
align 33554432  pre 662µs      on 1.04ms       post 643µs     diff 385µs
align 16777216  pre 837µs      on 1.09ms       post 864µs     diff 242µs
align 8388608   pre 800µs      on 1.1ms        post 881µs     diff 262µs
align 4194304   pre 812µs      on 1.07ms       post 838µs     diff 246µs
align 2097152   pre 807µs      on 1.07ms       post 808µs     diff 258µs
align 1048576   pre 832µs      on 960µs       post 838µs     diff 125µs
align 524288    pre 833µs      on 959µs       post 838µs     diff 124µs
align 262144    pre 833µs      on 959µs       post 838µs     diff 124µs
align 131072    pre 833µs      on 962µs       post 840µs     diff 126µs
align 65536     pre 825µs      on 951µs       post 838µs     diff 120µs
align 32768     pre 826µs      on 956µs       post 825µs     diff 130µs
align 16384     pre 812µs      on 924µs       post 824µs     diff 106µs
align 8192      pre 809µs      on 841µs       post 808µs     diff 32.4µs
align 4096      pre 808µs      on 836µs       post 808µs     diff 27.7µs
align 2048      pre 808µs      on 836µs       post 809µs     diff 27.6µs
.pre

8192 seems good, re-test

.pre
root@ac100:/home/dpavlin/flashbench# ./flashbench -a /dev/mmcblk1 --blocksize=4096
align 2147483648        pre 696µs      on 1.04ms       post 725µs     diff 331µs
align 1073741824        pre 917µs      on 1.18ms       post 870µs     diff 289µs
align 536870912 pre 880µs      on 1.18ms       post 907µs     diff 291µs
align 268435456 pre 899µs      on 1.2ms        post 877µs     diff 311µs
align 134217728 pre 825µs      on 1.18ms       post 927µs     diff 300µs
align 67108864  pre 864µs      on 1.11ms       post 842µs     diff 253µs
align 33554432  pre 914µs      on 1.12ms       post 897µs     diff 212µs
align 16777216  pre 921µs      on 1.14ms       post 948µs     diff 210µs
align 8388608   pre 884µs      on 1.15ms       post 965µs     diff 229µs
align 4194304   pre 895µs      on 1.12ms       post 922µs     diff 215µs
align 2097152   pre 890µs      on 1.12ms       post 890µs     diff 227µs
align 1048576   pre 916µs      on 1.01ms       post 922µs     diff 89.7µs
align 524288    pre 916µs      on 1.01ms       post 922µs     diff 90µs
align 262144    pre 916µs      on 1.01ms       post 923µs     diff 89.1µs
align 131072    pre 916µs      on 1.01ms       post 924µs     diff 91.1µs
align 65536     pre 908µs      on 1ms  post 921µs     diff 85.9µs
align 32768     pre 911µs      on 1.01ms       post 908µs     diff 96.2µs
align 16384     pre 895µs      on 973µs       post 908µs     diff 71.4µs
align 8192      pre 892µs      on 896µs       post 892µs     diff 4.57µs
.pre

create filesystem

.pre
root@ac100:/home/dpavlin/flashbench# mkfs -t ext4 -v -b 4096 -E stride=2,stripe-width=2 /dev/mmcblk1p6 

cp -ax ....

root@ac100:~# mount /dev/mmcblk1p1 /tmp/1/
root@ac100:~# cat /tmp/1/boot/boot.cmd 
ext2load mmc 0:6 ${kernel_addr_r} /boot/zImage
ext2load mmc 0:6 ${fdt_addr_r} /boot/tegra20-paz00.dtb
ext2load mmc 0:6 ${ramdisk_addr_r} /boot/uInitrd
setenv bootargs root=/dev/mmcblk1p6 rootwait CMA=64M tegrapart=recovery:300:a00:800,boot:d00:1000:800,mbr:1d00:200:800
bootz ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r}

# mkimage -C none -A arm -T script -d boot.cmd boot.scr


.pre

^ flash u-boot to mmc

based on https://paz00.ru/index.php?title=Flashing_Uboot_to_MMC&setlang=en

^^ tegrarcm to get bct

.pre
dpavlin@nuc:/nuc/Tegra$ git clone https://github.com/NVIDIA/tegrarcm

dpavlin@nuc:/nuc/Tegra$ cd tegrarcm/

dpavlin@nuc:/nuc/Tegra/tegrarcm$ sudo apt-get install libcrypto++-dev

dpavlin@nuc:/nuc/Tegra/tegrarcm$ ./autogen.sh

dpavlin@nuc:/nuc/Tegra/tegrarcm$ make

dpavlin@nuc:/nuc/Tegra/tegrarcm$ ./src/tegrarcm --version
tegrarcm 1.8
.pre

^^ create boot image

.pre
dpavlin@nuc:/nuc/Tegra/cbootimage$ git remote -v
origin  https://github.com/NVIDIA/cbootimage (fetch)
origin  https://github.com/NVIDIA/cbootimage (push)

dpavlin@nuc:/nuc/Tegra/cbootimage$ ./autogen.sh
dpavlin@nuc:/nuc/Tegra/cbootimage$ make


dpavlin@nuc:/nuc/Tegra/cbootimage$ cat > u-boot.cfg
Version       = 0x00020001;
Bctcopy       = 1;
Bctfile       = ac100.bct;
BootLoader    = u-boot.bin,0x00108000,0x00108000,Complete;


dpavlin@nuc:/nuc/Tegra/cbootimage$ cp ../ac100/create_bootimage/example/ac100-dpavlin.bct ac100.bct

dpavlin@nuc:/nuc/Tegra/cbootimage$ cp /mnt/klin/klin/Tegra/u-boot-tegra/u-boot-tegra.bin u-boot.bin

dpavlin@nuc:/nuc/Tegra/cbootimage$ ./src/cbootimage -d u-boot.cfg ac100.bct.new
bct size: 4080
**update_bl()
begin_update(): bct data: b=14 p=9
writing bootloader
  redundancy = 1
  BL[0]: 131073 0001 0000 518563 0x00108000 0x00108000
8e52c9639cb433e9e1e369cf718595c5
  BL[1]: 131073 0002 0000 302746 0x00108000 0x00108000
a9014f31e7ccafab319512de6bc48f81
**BL[2]: 0 0000 0000 0000 0x00000000 0x00000000
00000000000000000000000000000000
**BL[3]: 0 0000 0000 0000 0x00000000 0x00000000
00000000000000000000000000000000
Image file ac100.bct.new has been successfully generated!

dpavlin@nuc:/nuc/Tegra/cbootimage$ scp ac100.bct.new ac100:

dpavlin@nuc:/nuc/Tegra/cbootimage$ ssh root@ac100

# flash new boot image on ac100

root@ac100:~# echo 0 > /sys/block/mmcblk1boot0/force_ro
root@ac100:~# dd if=/home/dpavlin/ac100.bct.new of=/dev/mmcblk1boot0 
1045+0 records in
1045+0 records out
535040 bytes (535 kB, 522 KiB) copied, 0.135589 s, 3.9 MB/s
root@ac100:~# echo 1 > /sys/block/mmcblk1boot0/force_ro 



.pre

create bct backup

.pre
dpavlin@ac100:~$ sudo dd if=/dev/mmcblk1boot0 of=ac100-dpavlin-0.bct bs=4080 count=1
[sudo] password for dpavlin: 
1+0 records in
1+0 records out
4080 bytes (4.1 kB, 4.0 KiB) copied, 0.0018642 s, 2.2 MB/s
dpavlin@ac100:~$ sudo dd if=/dev/mmcblk1boot1 of=ac100-dpavlin-1.bct bs=4080 count=1
1+0 records in
1+0 records out
4080 bytes (4.1 kB, 4.0 KiB) copied, 0.0019622 s, 2.1 MB/s
.pre

in my case, first bct doesn't have OdmData, while 2nd does:

.pre
dpavlin@nuc:/nuc/Tegra$ grep Odm 0 1
0:OdmData       = 0x00000000;
1:OdmData       = 0x800c0075;


.pre

^ i2c

.pre
root@ac100:~# i2cdetect -y -r 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- UU -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 4f 
50: 50 51 52 53 54 55 56 57 -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                         
root@ac100:~# i2cdetect -y -r 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                         
root@ac100:~# i2cdetect -y -r 2
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- UU -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- UU -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                         
.pre
{image: hi3515v100-functional-block-disagram.png}

{file: hi3515v100.pdf}

Hi3515Hi3515 H.264 Encoding and Decoding Processor

{toc: }

^ Key Features

^^ CPU Core

zARM926EJ
I-cache 16 KB, D-cache 16 KB 
I-TCM 2 KB
Built-in MMU, supporting multiple open operating systems such as VxWorks, Linux, WinCE, and PalmOS
Up to 400 MHz operating frequency

^^ Video Encoding/Decodingz

H.264 main profile encoding/decoding
H.264 baseline profile encoding/decoding
JPEG/MJPEG baseline encoding/decoding

^ serial

EN-6704V 4 channel H.264 digital video recorder for @RadionaOrg has 3.3V uart with pinout GND, TX, RX, 5V

mozilla-ktdvr-plugin

en-6704v

.pre
j87

+--- ---+
|1 2 3 4|
+-------+

1 - gnd
2 - 2.29
3 - 3.3
4 - 5v
.pre

{image: IMG_20190316_185951.jpg}

hi3515v100

^ links

http://www.i-1.nl/blog/wp-content/uploads/CCF-paper-Forensic-reliabilty-DVR.pdf

https://openhisiipcam.org/hardware/briefs/hi3515v100.pdf

https://github.com/zetalabs/ezbox/blob/master/pool/bootstrap/target/linux/hi35xx/patches-2.6.32/010-mach-hi3515v100.patch

http://users.atw.hu/balubati/blog/index.php?m=08&y=12&d=18&entry=entry120818-102937&PHPSESSID=4c6c320a5aa587c554c6b8f145288148

^ SDK

https://github.com/bluhbluh/Hi3515-SDK

.pre
dpavlin@nuc:/nuc/hi3515v100$ git clone https://github.com/bluhbluh/Hi3515-SDK
Cloning into 'Hi3515-SDK'...
remote: Enumerating objects: 362, done.
remote: Counting objects: 100% (362/362), done.
remote: Compressing objects: 100% (312/312), done.
remote: Total 362 (delta 45), reused 362 (delta 45), pack-reused 0
Receiving objects: 100% (362/362), 277.99 MiB | 5.77 MiB/s, done.
Resolving deltas: 100% (45/45), done.
Checking out files: 100% (336/336), done.

.pre

^^ mtd

.pre
/stm/disk/0/p1/mtd-backup $ ls -al /dev/mtdblock*
brw-rw----    1 root     root      31,   0 Jan  1  1970 /dev/mtdblock0
brw-rw----    1 root     root      31,   1 Jan  1  1970 /dev/mtdblock1
brw-rw----    1 root     root      31,   2 Jan  1  1970 /dev/mtdblock2
brw-rw----    1 root     root      31,   3 Mar 23 00:31 /dev/mtdblock3
/stm/disk/0/p1/mtd-backup $ dd if=/dev/mtdblock0 of=0 bs=128k
32+0 records in
32+0 records out
/stm/disk/0/p1/mtd-backup $ ls -al
drwxr-xr-x    2 root     root         4096 Mar 23 02:06 .
drwxr-xr-x   25 root     root         4096 Mar 23 02:06 ..
-rw-r--r--    1 root     root      4194304 Mar 23 02:06 0
/stm/disk/0/p1/mtd-backup $ dd if=/dev/mtdblock1 of=1 bs=128k
96+0 records in
96+0 records out
/stm/disk/0/p1/mtd-backup $ dd if=/dev/mtdblock2 of=2 bs=128k
112+0 records in
112+0 records out
/stm/disk/0/p1/mtd-backup $ dd if=/dev/mtdblock3 of=3 bs=128k
16+0 records in
16+0 records out
.pre

^^ setup tftp writable server

.pre
dpavlin@x200:/mnt/nuc/hi3515v100$ cat /etc/default/tftpd-hpa 
# /etc/default/tftpd-hpa

TFTP_USERNAME="tft"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS="192.168.1.1:69"
TFTP_OPTIONS="--secure --create"
.pre

^^ backup

.pre
/stm/disk/0/p1/mtd-backup $ tftp -p -l 0 -r /0 192.168.1.1
/stm/disk/0/p1/mtd-backup $ tftp -p -l 1 -r /1 192.168.1.1
/stm/disk/0/p1/mtd-backup $ tftp -p -l 2 -r /2 192.168.1.1
/stm/disk/0/p1/mtd-backup $ tftp -p -l 3 -r /3 192.168.1.1
.pre

^ tar+nc backup

^^ on device

.pre
/mnt $ tar -cv -f - . | nc 192.168.1.1 8888
.pre

^^ on receiving side

.pre
dpavlin@x200:/mnt/nuc/hi3515v100/mnt-backup$ nc -l -p 8888 | tee mnt.tar | tar tvf -
.pre

Nice verbose output during backup on both sides and nc is much faster than tftp.
Upgrade from WebGUI 6.2.11 to 7.3.33

{toc: }

^ Install dependencies

.pre
apt-get install apache2-mpm-prefork
apt-get install libapache2-mod-perl2
apt-get install perlmagick imagemagick
.pre

Don't bother with installation of perl modules from packages. Debian has modules which are sometimes a bit too old for cutting-edge WebGUI, so just let CPAN install it for you.

^ Basic configuration

All operations on both hosts (mjesec, zemlja) are done as `root` user. This is not strictly necessery (especially for WebGUI tasks), but it's easier in combination with MySQL setup. We want to get running quickly, YMMV.

^^ Mysql binary log

Comment out following in `/etc/mysql/my.cnf`

.pre
log_bin
expire_logs_days
max_binlog_size
.pre

To preserve disk space if you are not using replication!

And restart server:

.pre
/etc/init.d/mysql restart
rm /var/log/mysql/mysql-bin.*
.pre

^ Cleanup target machine

If this is not first installation attempt, you might want to cleanup target machine first.

.pre
# root@mjesec
cd /data/WebGUI
grep dsn etc/*.conf | cut -d: -f4- \
  | xargs -i echo 'drop database {};' \
  | ssh zemlja 'cat > /data/drop_all_dbs.sql'
.pre

Now switch to target machine and finish cleanup:

.pre
# root@zemlja
cd /data
xargs -i mysql -e '{}' < /data/drop_all_dbs.sql
rm -Rf WebGUI
.pre

^ Copy existing installation

In this step, we will copy existing WebGUI 6.2.11 installation to new (virtual) host (zemlja) to test upgrade.

^^ Copy MySQL databases

.pre
# root@mjesec
cd /data/WebGUI 
grep dsn etc/*.conf | cut -d: -f4- \
  | xargs mysqldump --databases \
  | ssh zemlja mysql mysql
.pre

^^ Copy existing WebGUI installation

.pre
# root@mjesec
cd /data
tar cfp - WebGUI/ | ssh zemlja 'cd /data && tar xvfp -'
.pre

This is much faster than scp in my expirience...

^^ Finish database setup

Now, on zemlja, let's grant webgui user access to those databases:

.pre
# root@zemlja
cd /data/WebGUI
mysql -e 'create user webgui'
grep dsn etc/*.conf | cut -d: -f4- \
  | xargs -i mysql -e "grant all privileges on {}.* to webgui@localhost identified by 'password';" 
mysql -e "flush privileges"
.pre

^ Upgrade steps

First, test current enviroment for any mis-configuration:

.pre
# root@zemlja
cd /data/WebGUI/sbin
perl testEnvironment.pl
.pre

If there are missing perl libraries, install them. Some will have to be forced, but all-in-all it goes well.

And run upgrade...

.pre
# root@zemlja
cd /data/WebGUI/sbin
perl upgrade.pl --doit
.pre

Now, extract new version of webgui on which you want to upgrade (I'm assume that you downloaded required versions in /data):

.pre
cd /data/
ls
tar xvfz webgui-6.6.4-beta.tar.gz 
cd /data/WebGUI/sbin/
perl testEnvironment.pl 
perl upgrade.pl --doit
.pre

This will take a while.

After that you might want to remove backup of databases:

.pre
rm /tmp/backups/*
.pre

^^ Upgrade scripts

Here are list of upgrade scripts:

* {file: z-1-backpan.sh}
* {file: z-3-mysql-perms.sh}
* {file: z-4-webgui-6.6.5.sh}
* {file: z-5-webgui-6.8.10.sh}
* {file: z-6-webgui-7.0.9.sh}
** {file: upgrade_6.8.9-6.8.10.pl}
** {file: webgui-7.0.diff}
* {file: z-7-webgui-7.2.3.sh}
* {file: z-8-webgui-7.3.22.sh}
* {file: z-9-webgui-7.4.38.sh}

^^ Helper scripts

Backup/restore whole WebGUI instance (data+database) so that you can re-try upgrade

> This was probably one of most useful ideas enabling me to re-try upgrade until it finish without errors!

* {file: webgui-snap.sh}
* {file: webgui-restore.sh}
* {file: webgui-recover-db.sh}

^ Tweaks

Here are some commands to help you with various changes which break WebGUI:

.pre
# root@zemlja
cd /data/WebGUI
rm lib/HTML/Template.pm

cd /data/WebGUI/etc/
mv log.conf.original log.conf
mv spectre.conf.original spectre.conf
.pre

^^ MySQL encoding

My data has `iso-8859-2` while MySQL thinks it's in `latin-1`.

.pre
mysqldump --all-databases --add-drop-database --default-character-set=latin1 > all.sql
cat all.sql | sed \
 -e 's/DEFAULT CHARSET=latin1/DEFAULT CHARSET=utf8/g' \
 -e 's/character set latin1 collate latin1_bin/character set utf8 collate utf8_bin/' \
 -e 's/DEFAULT CHARACTER SET latin1/DEFAULT CHARACTER SET utf8/' \
 -e 's/SET NAMES latin1/SET NAMES utf8/' \
 | iconv -f iso-8859-2 -t utf-8 \
 | mysql --default-character-set=utf8 mysql
.pre

> *This should work, but it doesn't*

So, we are using much simplier solution which keep encoding in database in wrong latin1 encoding, but it displays correctly in WebGUI:

.pre
cat all.sql | iconv -f iso-8859-2 -t utf-8 | mysql mysql
.pre

^^ Fix configuration

Upgrade procedure isn't still perfect. Here is a list of tweaks to fix configuraion:

.pre
cd /data/WebGUI/etc/
perl -p -i -n -e 's/WebGUI::Asset::Wobject::WebGUI::Asset::Wobject::Survey/WebGUI::Asset::Wobject::Survey/g' *.conf
.pre

^^ Code cleanup

You might want to replace `WebGUI/lib/WebGUI` which is result of upgrade with clean version from distribution. I have accumulated some cruft there, and it was spitting errors in `/var/log/apache2/error.log` and `/var/log/webgui.log`

^^ Fix permissions

.pre
cd /data/WebGUI
sudo chown -R www-data */uploads
.pre

^^ Spectre

I didn't have `spectre.conf` after upgrade. Test connectivity with:

.pre
cd /data/WebGUI/sbin/
perl spectre.pl --test
.pre

Add following to `/etc/rc.local`

.pre
cd /data/WebGUI/sbin/
perl spectre.pl --daemon
.pre

^^^ Cleanup versions

Since I created few workflows which always returned commerr (because of mis-configuration) I needed to find way to manually erase them.

.pre
select tagId from assetVersionTag
join WorkflowInstance on WorkflowInstance.instanceId = assetVersionTag.workflowInstanceId ;
.pre

^^^ Delete workflow instances

.pre
delete from WorkflowInstance ;
.pre

This will erase *all* pending workflow instances. So, be sure to check if they are all stuck before running this command!

^^^ /etc/resolv.conf

Make sure your `nameserver` entries point to existing servers. If you have one of DNS servers which doesn't respord (I had 127.0.0.1 for DNS and there wasn't any DNS server on machine running WebGUI) you will get Errors 500 from spectre without any indication where the problem is.

^ Critical verision you have to upgrade to

*This part is obsoleted by scripts above which provide correct and workable upgrade path*

^^ 6.6.4

last 6.6.x version required for upgrade to 6.7.0

^^ 6.8.10

Upgrade to this version will die at one point with:

.pre
Cannot open config file '../../etc/log.conf' at /usr/share/perl5/Log/Log4perl/Config.pm line 612.
.pre

.pre
# root@zemlja
cd /data/WebGUI/etc/
cp log.conf.original log.conf
cp spectre.conf.original spectre.conf
.pre

And then, re-run upgrade procedure:

.pre
cd /data/WebGUI/sbin/
perl upgrade --doit
.pre

Unit it succeeds.

^^ 6.99.5

this verison will convert config files to JSON format

First, install *old* JSON or you will be in pain: http://backpan.perl.org/authors/id/M/MA/MAKAMAKA/JSON-0.991.tar.gz

You might have problems upgrading to version 6.99.0 or later because scripts expect configuration in JSON format, and upgrade won't convert files for you (because it created config files from tar). So, change your `upgrade.pl` beginning to something like this:

.pre
## Find site configs.

print "\nTesting site config versions...\n" unless ($quiet);
opendir(DIR,"../etc");
my @files = readdir(DIR);
closedir(DIR);
foreach my $file (@files) {
        next unless ($file =~ m/\.conf$/);
#       next if ($file eq "spectre.conf" || $file eq "log.conf");
        my $configFile = "../etc/".$file;
        open(FILE,"<".$configFile);
        my $line = <FILE>;
        close(FILE);
        unless ($line =~ m/JSON 1/) {
                print "\tConverting ".$file." from PlainConfig to JSON\n" unless ($quiet);
                convertPlainconfigToJson($configFile);
        }
}

exit;
.pre

Note commented out line and added exit.

Now you can run `upgrade.pl` once to convert configuration files to JSON, then run `testEnvironment.pl` and finally run `upgrade.pl` once more to do actual update.

^^ 7.3.22

requirement for upgrade to 7.4.0

To prevent `perl upgrade.pl --doit` die with:

.pre
Cannot open config file '../etc/log.conf' at /usr/share/perl5/Log/Log4perl/Config.pm line 612.
.pre

fix it:

.pre
cd /data/WebGUI/etc/
mv log.conf.original log.conf
.pre

and *then* run upgrade!

^ Version related notes

This are just notes. You can ignore them for normal upgrade described above.

^^ 7.3.4

Re-run upgrade procedure if it breaks

^^ 7.4.17

Attack of JSON again:

.pre
Can't locate object method "relaxed" via package "JSON"
.pre

Install http://backpan.perl.org/authors/id/R/RI/RIZEN/Config-JSON-1.1.0.tar.gz

^^ 7.4.33

It will install newer JSON and Config::JSON packages from CPAN

^ Hint

For testing, I created `*.zemlja.example.com` DNS entry, so that all sites become `old.site.name.zemlja.example.com`.
RCWL-0516 is a doppler radar microwave motion sensor module which can act as an alternative to a PIR motion sensor.

https://github.com/jdesbonnet/RCWL-0516

https://community.home-assistant.io/t/custom-sensor-using-nodemcu-and-rcwl-0516-solved/313635/13
{file: PrintrBot_Plus_LC.diff}

Old 3D printer which never worked well.

DXF files: https://www.youmagine.com/designs/printrbot-lc-1302

https://web.archive.org/web/20130115210644/http://printrbot.com/shop/plus/

{toc: }

^ PrintrBot Plus LC

The Printrbot PLUS is the larger printrbot kit–containing an 8x8x8 build volume, laser cut birch construction, an assembled Ubis hot end, and 12mm Z-axis rods in an all-in-one kit. This kit also includes 1 lb of ABS filament.

This kit includes everything you need to build the printrbot PLUS:

* printrboard: all-in-one assembled electronics with integrated SD card slot (no soldering required)
* 5 NEMA 17 stepper motors complete with cable ends attached
* laser cut birch construction
* a few printed plastic parts (gears, etc)
* WOOD Extruder Kit
* hardware (8mm smooth rods, threaded rods, and bearings
** Z axis is 12mm smooth rods and 12 mm linear bearings )
* assembled Ubis hot end
* nuts, bolts, washers, zip ties
* laser cut print bed
* 8×8 heated bed
* misc assembled cables (no soldering required)
* 3 mechanical end stops (no soldering required)
* micro USB cable

^^ nozzle

The Getting Started Guide says that all Printrbots currently ship with 0.4mm nozzles.
The convention for identifying nozzles is based on notches (or "rings") cut into the sides (vertices) of the hexagonal brass "nut".
No notch = 0.5mm
1 notch = 0.4mm
2 notches = 0.35mm

^ info

Most of information about it vanished from internet so here is some overview:

* http://reprap.org/wiki/Printrbot
* http://reprap.org/wiki/Printrboard

* https://github.com/Printrbot/printrboard

Rev.B https://github.com/Printrbot/printrboard/releases/tag/revB

^ PrintrBoard pinout

Annotated headers from http://blog.think3dprint3d.com/2012/07/panelolu-with-printrboard.html

{image: Printrboard Headers.JPG}

^ serial

.pre
[Sun Mar 18 08:23:50 2018] usb 2-4.4: new full-speed USB device number 61 using xhci_hcd
[Sun Mar 18 08:23:50 2018] usb 2-4.4: New USB device found, idVendor=16c0, idProduct=0483
[Sun Mar 18 08:23:50 2018] usb 2-4.4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[Sun Mar 18 08:23:50 2018] usb 2-4.4: Product: USB Serial
[Sun Mar 18 08:23:50 2018] usb 2-4.4: Manufacturer: Teensyduino
[Sun Mar 18 08:23:50 2018] usb 2-4.4: SerialNumber: 12345
[Sun Mar 18 08:23:50 2018] cdc_acm 2-4.4:1.0: ttyACM0: USB ACM device

dpavlin@nuc:~$ microcom p /dev/ttyACM0 
connected to /dev/ttyACM0
Escape character: Ctrl\
Type the escape character to get to the prompt.


start
echo:PowerUp
 Brown out Reset
Marlin: 1.0.0 RC2
echo: Last Updated: 2012-02-25 | Author: erik
echo: Free Memory: 4907  Pla




echo:SD init fail
workDir open failed
echo:Unknown command:"echo"
ok
echo:Unknown command:"SD init fail"
ok
echo:Unknown command:"workDir open failed"
ok
.pre

^ settings

https://github.com/Printrbot/Marlin

.pre
M501
echo:Stored settings retreived:
echo:Steps per unit:
echo:  M92 X62.11 Y64.67 Z2272.72 E536.00
echo:Maximum feedrates (mm/s):
echo:  M203 X60.00 Y60.00 Z2.00 E14.00
echo:Maximum Acceleration (mm/s2):
echo:  M201 X2000 Y2000 Z30 E10000
echo:Acceleration: S=acceleration, T=retract acceleration
echo:  M204 S3000.00 T3000.00
echo:Advanced variables: S=Min feedrate (mm/s), T=Min travel feedrate (mm/s), B=minimum segment time (ms), X=maximum xY jerk (mm/s),  Z=maximum Z jerk (mm/s)
echo:  M205 S0.00 T0.00 B20000 X20.00 Z0.40 E5.00
echo:PID settings:
echo:   M301 P22.20 I1.08 D114.00

M115
FIRMWARE_NAME:Marlin V1; Sprinter/grbl mashup for gen6 FIRMWARE_URL:http://www.mendel-parts.com PROTOCOL_VERSION:1.0 MACHINE_TYPE:Mendel EXTRUDER_COUNT:1

.pre

If this doesn't work, you can try `M503` which should display all settings without loading them from flash.

^ software bed leveler

* https://github.com/emard/zleveler

^ schematics

{file: Printrboard_RevB_Schematic150.png}

{file: Printrboard-schematics.pdf}

^ Marlin

* https://github.com/MarlinFirmware/Marlin
* http://marlinfw.org/meta/gcode/

.pre
dpavlin@nuc:/nuc/PrintrBot$ git clone https://github.com/dpavlin/Marlin

dpavlin@nuc:/nuc/PrintrBot$ cd Marlin/
.pre

^^ compile Marlin 1.1.8

https://github.com/dpavlin/Marlin/tree/PrintrBot_Plus_LC-1.1.8

.pre
dpavlin@nuc:/nuc/PrintrBot/Marlin$ git checkout PrintrBot_Plus_LC-1.1.8 

dpavlin@nuc:/nuc/PrintrBot/Marlin$ platformio run -e printrboard
Warning! Ignore unknown `envs_dir` option in `[platformio]` section

Processing printrboard (platform: teensy; board: teensy20pp; framework: arduino)
-----------------------------------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
PLATFORM: Teensy > Teensy++ 2.0
SYSTEM: AT90USB1286 16MHz 8KB RAM (127KB Flash)
.pre

^^ compile Marlin 1.1.9

different enviroment compared to 1.1.8?

.pre
dpavlin@nuc:/nuc/PrintrBot/Marlin$ git checkout PrintrBot_Plus_LC-1.1.9 

dpavlin@nuc:/nuc/PrintrBot/Marlin$ platformio run -e teensy20
.pre

^^ flashing

open boot jumper, press button

.pre
[Sun Apr 15 12:20:34 2018] usb 1-1.1: new full-speed USB device number 30 using xhci_hcd
[Sun Apr 15 12:20:34 2018] usb 1-1.1: unable to get BOS descriptor
[Sun Apr 15 12:20:34 2018] usb 1-1.1: New USB device found, idVendor=03eb, idProduct=2ffb
[Sun Apr 15 12:20:34 2018] usb 1-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[Sun Apr 15 12:20:34 2018] usb 1-1.1: Product: AT90USB128 DFU
[Sun Apr 15 12:20:34 2018] usb 1-1.1: Manufacturer: ATMEL
[Sun Apr 15 12:20:34 2018] usb 1-1.1: SerialNumber: 1.0.0


root@nuc:/nuc/PrintrBot/Marlin# apt-get install dfu-programmer


root@nuc:/nuc/PrintrBot/Marlin# dfu-programmer --targets 2>&1 | grep at90usb128
    at89c5132          at90usb1287        at90usb1286        at90usb1287-4k
    at90usb1286-4k     at90usb647         at90usb646         at90usb162

root@nuc:/nuc/PrintrBot/Marlin# dfu-programmer at90usb1286 dump --debug 99
     target: at90usb1286
    chip_id: 0x2ffb
  vendor_id: 0x03eb
    command: dump
      quiet: false
      debug: 99
device_type: AVR
------ command specific below ------

commands.c:625: dump 122880 bytes
atmel.c:579: atmel_read_flash( 0x7ffe83facaf0, 0x00000000, 0x0001e000, 0x564ef5df7000, 122880, false )
atmel.c:847: atmel_select_page( 0x7ffe83facaf0, 0 )
atmel.c:510: __atmel_read_page( 0x7ffe83facaf0, 0, 65536, 0x564ef5df7000, false )
atmel.c:537: result: -9
Unknown error.  Try enabling debug.
Failed to read 122880 bytes from device.



.pre

other useful debug levels are 100, 200, 300 - https://www.avrfreaks.net/forum/how-use-dfu-programmer

hmmm... can't backup firmware?

^^ flash firmware

.pre
dpavlin@nuc:/nuc/PrintrBot/Marlin$ dfu-programmer at90usb1286 erase
dpavlin@nuc:/nuc/PrintrBot/Marlin$ dfu-programmer at90usb1286 flash .pioenvs/printrboard/firmware.hex
Validating...
Flash did not validate. Did you erase first?

dpavlin@nuc:/nuc/PrintrBot/Marlin$ dfu-programmer at90usb1286 erase --debug 100
     target: at90usb1286
    chip_id: 0x2ffb
  vendor_id: 0x03eb
    command: erase
      quiet: false
      debug: 100
device_type: AVR
------ command specific below ------
   validate: true

commands.c:69: erase 122879 bytes
atmel.c:281: atmel_erase_flash( 0x7ffc5df9bff0, 4 )
atmel.c:671: atmel_blank_check( 0x7ffc5df9bff0, 0x00000000, 0x0001dfff )
atmel.c:847: atmel_select_page( 0x7ffc5df9bff0, 0 )
atmel.c:647: __atmel_blank_check_internal( 0x7ffc5df9bff0, 0x00000000, 0x0000ffff )
atmel.c:847: atmel_select_page( 0x7ffc5df9bff0, 1 )
atmel.c:647: __atmel_blank_check_internal( 0x7ffc5df9bff0, 0x00000000, 0x0000dfff )

.pre

^^ teensy setup pjrc

udev rule: https://www.pjrc.com/teensy/49-teensy.rules
loader: https://github.com/PaulStoffregen/teensy_loader_cli

^^ unlock chip using flip

It seems that chip is protected. However, trying to erase and program it did destry data in it (expect bootloader) for some reason, and it seem that dfu-programmer doesn't know how to work with protection features.

So, next step is to try atmel's flip under linux but this also doesn't work well.

* patch path to /dev/bus/usb/ - https://www.avrfreaks.net/forum/instructions-get-batchisp-working-ubuntu-lucid-1004?name=PNphpBB2&file=viewtopic&t=97673

.pre
root@nuc:/nuc/PrintrBot/flip.3.2.1# cat debian-install.sh 
sudo apt-get install openjdk-9-jre:i386 libusb-0.1-4:i386

root@nuc:/nuc/PrintrBot/flip.3.2.1# cat env.sh 
export JAVA_HOME=/usr/lib/jvm/java-9-openjdk-i386/
export FLIP_HOME=/nuc/PrintrBot/flip.3.2.1/bin/


root@nuc:/nuc/PrintrBot/flip.3.2.1# cd bin/
root@nuc:/nuc/PrintrBot/flip.3.2.1/bin# cp -apv libatlibusbdfu.so libatlibusbdfu.so.orig
root@nuc:/nuc/PrintrBot/flip.3.2.1/bin# sed 's/\/sys\/bus\/usb/\/dev\/bus\/usb/g' libatlibusbdfu.so.orig > libatlibusbdfu.so


# run from bin directory or it won't work (?!)

root@nuc:/nuc/PrintrBot/flip.3.2.1/bin# ./flip.sh

.pre

^ avrdude

made cable to convert 10 pin ICSP on usbasp to 6 pin ICSP on printrboard

http://reprap.org/wiki/Printrboard#Bootloaders

Pin 1 (not red wire on my harness because of re-wiring) is closest to the SD card slot.

.pre
root@nuc:/nuc/PrintrBot# avrdude -p usb1286 -c usbasp 

avrdude: warning: cannot set sck period. please check for usbasp firmware update.
avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9782 (probably usb1287)

avrdude: safemode: Fuses OK (E:F3, H:99, L:5E)

avrdude done.  Thank you.
.pre

ok, factory bootloader

^^ fuses

.pre
# disable jtag
avrdude -c usbtiny -p at90usb1286 -U lfuse:w:0xde:m -U hfuse:w:0xdb:m -U efuse:w:0xf0:m

# enabled jtag
avrdude -c usbtiny -p at90usb1286 -U lfuse:w:0xDE:m -U hfuse:w:0x9B:m -U efuse:w:0xF0:m

root@nuc:/nuc/PrintrBot# avrdude -c usbtiny -p at90usb1286 -U lfuse:w:0xde:m -U hfuse:w:0xdb:m -U efuse:w:0xf0:m
avrdude: Error: Could not find USBtiny device (0x1781/0xc9f)

avrdude done.  Thank you.

root@nuc:/nuc/PrintrBot# avrdude -c usbasp -p at90usb1286 -U lfuse:w:0xde:m -U hfuse:w:0xdb:m -U efuse:w:0xf0:m

avrdude: warning: cannot set sck period. please check for usbasp firmware update.
avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9782 (probably usb1287)
avrdude: reading input file "0xde"
avrdude: writing lfuse (1 bytes):

Writing |                                                    | 0% 0.00s ***failed;
Writing | ################################################## | 100% 0.06s

avrdude: 1 bytes of lfuse written
avrdude: verifying lfuse memory against 0xde:
avrdude: load data lfuse data from input file 0xde:
avrdude: input file 0xde contains 1 bytes
avrdude: reading on-chip lfuse data:

Reading | ################################################## | 100% 0.00s

avrdude: verifying ...
avrdude: verification error, first mismatch at byte 0x0000
         0x5e != 0xde
avrdude: verification error; content mismatch

avrdude: safemode: lfuse changed! Was de, and is now 5e
[Tue Apr 17 07:12:19 2018] usb 1-1.4: USB disconnect, device number 20
[Tue Apr 17 07:12:19 2018] usb 1-1.4: USB disconnect, device number 20
Would you like this fuse to be changed back? [y/n]
Would you like this fuse to be changed back? [y/n] n
avrdude: safemode: Fuses OK (E:F3, H:99, L:DE)

avrdude done.  Thank you.


root@nuc:/nuc/PrintrBot# avrdude -p usb1286 -c usbasp 

avrdude: warning: cannot set sck period. please check for usbasp firmware update.
avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9782 (probably usb1287)

avrdude: safemode: Fuses OK (E:F3, H:99, L:5E)

avrdude done.  Thank you.

.pre

^^ flash bootloader

huh, hum, program bootloader anyway from http://blog.lincomatic.com/?p=548

.pre
root@nuc:/nuc/PrintrBot# avrdude -p usb1286 -c usbasp -U flash:w:BootloaderDFU.hex
.pre

power cycle, return jumper re-try programming fuses

.pre
root@nuc:/nuc/PrintrBot# avrdude -c usbasp -p at90usb1286 -U lfuse:w:0xDE:m -U hfuse:w:0x9B:m -U efuse:w:0xF0:m
.pre

^^ dfu programming works

re-try dfu programming

.pre
root@nuc:/nuc/PrintrBot# dfu-programmer at90usb1286 erase
root@nuc:/nuc/PrintrBot# dfu-programmer at90usb1286 flash Marlin/.pioenvs/printrboard/firmware.hex
Validating...
61322 bytes used (49.90%)


.pre

^^ avrdude programming

.pre
dpavlin@nuc:/nuc/PrintrBot/Marlin$ avrdude -c usbasp -p usb1286 -U flash:w:.pioenvs/printrboard/firmware.hex

avrdude: warning: cannot set sck period. please check for usbasp firmware update.
avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9782 (probably usb1287)
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: warning: cannot set sck period. please check for usbasp firmware update.
avrdude: reading input file ".pioenvs/printrboard/firmware.hex"
avrdude: input file .pioenvs/printrboard/firmware.hex auto detected as Intel Hex
avrdude: writing flash (87280 bytes):

Writing | ################################################## | 100% 58.04s

avrdude: 87280 bytes of flash written
avrdude: verifying flash memory against .pioenvs/printrboard/firmware.hex:
avrdude: load data flash data from input file .pioenvs/printrboard/firmware.hex:
avrdude: input file .pioenvs/printrboard/firmware.hex auto detected as Intel Hex
avrdude: input file .pioenvs/printrboard/firmware.hex contains 87280 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 38.49s

avrdude: verifying ...
avrdude: 87280 bytes of flash verified

avrdude: safemode: Fuses OK (E:F0, H:9B, L:DE)

avrdude done.  Thank you.
.pre

^ RepRapDiscount Full Graphic Smart Controller

* http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller

^^ pinouts

{file: printrboard-lcd-pinout.png}

{image: printrboard-lcd-pinout-800px.png}

^^ Marlin pinout

.pre
diff --git a/Marlin/pins_PRINTRBOARD.h b/Marlin/pins_PRINTRBOARD.h
index 42632d174..8146505a3 100644
--- a/Marlin/pins_PRINTRBOARD.h
+++ b/Marlin/pins_PRINTRBOARD.h
@@ -166,3 +166,19 @@
   #endif
 
 #endif // ULTRA_LCD && NEWPANEL
+
+// XXX dpavlin -- my pinout
+#define LCD_PINS_RS       9   // E1       JP11-11
+#define LCD_PINS_ENABLE   8   // E0       JP11-10
+#define LCD_PINS_D4       7   // D7       JP11-8
+#define LCD_PINS_D5       6   // D6       JP11-7
+#define LCD_PINS_D6       5   // D5       JP11-6
+#define LCD_PINS_D7       4   // D4       JP11-5
+
+#define BTN_EN1        10   // C0       JP11-12
+#define BTN_EN2        11   // C1       JP11-13
+#define BTN_ENC        12   // C2       JP11-14
+
+// display delays are added to
+// Marlin/ultralcd_st7920_u8glib_rrd.h
+
diff --git a/Marlin/ultralcd_st7920_u8glib_rrd.h b/Marlin/ultralcd_st7920_u8glib_rrd.h
index db6224e47..8474bef24 100644
--- a/Marlin/ultralcd_st7920_u8glib_rrd.h
+++ b/Marlin/ultralcd_st7920_u8glib_rrd.h
@@ -49,7 +49,7 @@
   #define CPU_ST7920_DELAY_1 DELAY_NS(0)
   #define CPU_ST7920_DELAY_2 DELAY_NS(0)
   #define CPU_ST7920_DELAY_3 DELAY_NS(50)
-#elif MB(3DRAG) || MB(K8200) || MB(K8400) || MB(SILVER_GATE)
+#elif MB(3DRAG) || MB(K8200) || MB(K8400) || MB(SILVER_GATE) || MB(PRINTRBOARD)
   #define CPU_ST7920_DELAY_1 DELAY_NS(0)
   #define CPU_ST7920_DELAY_2 DELAY_NS(188)
   #define CPU_ST7920_DELAY_3 DELAY_NS(0)
.pre

^ Hardware upgrade

^^ RAMPS1.4 LCD 12864

* RAMPS1.4 LCD 12864 Control Panel 3D Printer Smart Controller LCD Display $10
** https://www.aliexpress.com/item/1-pcs-RAMPS1-4-LCD-12864-Control-Panel-3D-Printer-Smart-Controller-LCD-Display-Free-Shipping/32312042967.html
** $10 - works well, needs custom cable, well worth it from usability perspective

^^ LM8UU

* 10pcs/lot LM8UU Ball Bearings 8mm Bushing For CNC 3D Printers Parts Rail Linear Long Rod Shaft Part 8mm*15mm*24mm Aluminum Bush
** https://www.aliexpress.com/item/10pcs-lot-LM8UU-Ball-Bearings-8mm-Bushing-For-CNC-3D-Printers-Parts-Rail-Linear-Long-Rod/32834729285.html
** $4.24 - NOT recomended, worse that original VXB.com -- seller specified brand as FYSETC, parts don't have any markings

^^ Y axis coupler

* 3D Printer Parts Accessory Stepper Motor Aluminum Alloy Z Axis Flexible Coupling Coupler Shaft Couplings 5mm*8mm*25mm
** https://www.aliexpress.com/item/10pcs-lot-LM8UU-Ball-Bearings-8mm-Bushing-For-CNC-3D-Printers-Parts-Rail-Linear-Long-Rod/32834729285.html
** $0.75 - NOT for Y axis, since they are flexible
* 3D Printer Blue Aluminum Alloy Coupler for 5 x 5mm/5 x 8mm Shaft for Stepper Motor Shaft
** https://www.aliexpress.com/item/3D-Printer-Blue-Aluminum-Alloy-Coupler-for-5-x-5mm-5-x-8mm-Shaft-for-Stepper/32854452012.html
** $0.71 - great, much better than 3d printed part

^^ belts and pulleys

* 2pcs GT2 20teeth 20 Teeth Bore 5mm/8mm Timing Alumium Pulley + 2Meters Rubber GT2-6mm Open Timing Belt Width 6mm for 3D Printer
** https://www.aliexpress.com/item/2Pcs-GT2-20teeth-20-Teeth-Bore-5mm-8mm-Timing-Alumium-Pulley-2Meters-Rubber-GT2-6mm-Open/32711078503.html
** $1.90 - great, pully nut doesn't interfere with clip which is holding glass since nut is flush as opposed to 3d printed part

^^ Y axes rod

* T8 Lead Screw OD 8mm Pitch 2mm Lead 2mm 150mm 200mm 250mm 300mm 350mm 400mm 500mm with Brass Nut for Reprap 3D Printer Z Axis
** 250mm with Nut
** https://www.aliexpress.com/item/T8-Lead-Screw-Rod-OD-8mm-Pitch-2mm-Lead-2mm-Length-150mm-500mm-Threaded-Rods-with/32760102869.html
** $5.14 x 2 - great, our rods where bent from out of box

Needs 3d printed adapter for nut to fit: https://www.thingiverse.com/thing:2963508

Nut is friction fit which I consider somewhat as safety feature, if I found problems with it, I will probably add a bit of ABS goo in holes to fix it in place

^^ bed leveling

self-made sensor from RFID card, paper clip and case intrusion switch, connected in parallel with z-axis switch (it has to be normally closed, so that trigger interrupts signal)

^ BL touch

* 1 Set Newest BL Touch Auto Bed Leveling Sensor 3D Touch Auto Leveling Sensor For Anet A8 3D Printer Improve Printing Precision
** https://www.aliexpress.com/store/product/1-Set-Newest-BL-Touch-Auto-Bed-Leveling-Sensor-3D-Touch-for-3D-Printer-Improve-Printing/3108017_32837521614.html

http://www.geeetech.com/wiki/index.php/3DTouch_Auto_Leveling_Sensor

pinout, right to left

| pin | wire color | board label |
| 5 | green | G |
| 4 | red | 5V |
| 3 | yellow | S |
| 2 | black | G |
| 1 | white | Z- |

Needs additional pin for servo control (S - servo)

^^ Marlin configuration

.pre
commit 18396a8cd25585d5d562d4345ed851b91fb58821 (HEAD -> PrintrBot_Plus_LC-1.1.9)
Author: Dobrica Pavlinusic <dpavlin@rot13.org>
Date:   Sat Sep 8 11:05:54 2018 +0200

    probe offset from extruder

diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index 438494220..aeed322a7 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -770,8 +770,8 @@
  *      O-- FRONT --+
  *    (0,0)
  */
-#define X_PROBE_OFFSET_FROM_EXTRUDER 10  // X offset: -left  +right  [of the nozzle]
-#define Y_PROBE_OFFSET_FROM_EXTRUDER 10  // Y offset: -front +behind [the nozzle]
+#define X_PROBE_OFFSET_FROM_EXTRUDER 35  // X offset: -left  +right  [of the nozzle]
+#define Y_PROBE_OFFSET_FROM_EXTRUDER 5   // Y offset: -front +behind [the nozzle]
 #define Z_PROBE_OFFSET_FROM_EXTRUDER 0   // Z offset: -below +above  [the nozzle]
 
 // Certain types of probes need to stay away from edges

commit 2329e561e0f2997e78495c249706e9ce62608293
Author: Dobrica Pavlinusic <dpavlin@rot13.org>
Date:   Sat Sep 8 10:51:07 2018 +0200

    enable bed leveling
    
    AUTO_BED_LEVELING_UBL doesn't seem to compile for me ATM

diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index 38e0c343b..438494220 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -969,7 +969,7 @@
  */
 //#define AUTO_BED_LEVELING_3POINT
 //#define AUTO_BED_LEVELING_LINEAR
-//#define AUTO_BED_LEVELING_BILINEAR
+#define AUTO_BED_LEVELING_BILINEAR
 //#define AUTO_BED_LEVELING_UBL
 //#define MESH_BED_LEVELING
 
@@ -1023,6 +1023,8 @@
   //#define FRONT_PROBE_BED_POSITION MIN_PROBE_EDGE
   //#define BACK_PROBE_BED_POSITION (Y_BED_SIZE - MIN_PROBE_EDGE)
 
+  #define RIGHT_PROBE_BED_POSITION 190 // dpavlin -- probe overhangs on the right
+
   // Probe along the Y axis, advancing X after each column
   //#define PROBE_Y_FIRST
 

commit b867a948cd3b64d69e900b99a1306631d62753df
Author: Dobrica Pavlinusic <dpavlin@rot13.org>
Date:   Sun Sep 2 08:40:52 2018 +0200

    added bltouch config and pin on e-stop

diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index fd8463456..38e0c343b 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -721,7 +721,7 @@
 /**
  * The BLTouch probe uses a Hall effect sensor and emulates a servo.
  */
-//#define BLTOUCH
+#define BLTOUCH
 #if ENABLED(BLTOUCH)
   //#define BLTOUCH_DELAY 375   // (ms) Enable and increase if needed
 #endif
@@ -1909,7 +1909,7 @@
  * Set this manually if there are extra servos needing manual control.
  * Leave undefined or set to 0 to entirely disable the servo subsystem.
  */
-//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command
+#define NUM_SERVOS 1 // Servo index starts with 0 for M280 command
 
 // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle.
 // 300ms is a good value but you can try less delay.
diff --git a/Marlin/pins_PRINTRBOARD.h b/Marlin/pins_PRINTRBOARD.h
index 8146505a3..a68802725 100644
--- a/Marlin/pins_PRINTRBOARD.h
+++ b/Marlin/pins_PRINTRBOARD.h
@@ -182,3 +182,9 @@
 // display delays are added to
 // Marlin/ultralcd_st7920_u8glib_rrd.h
 
+// bltouch - use e-stop for servo
+// dpavlin@nuc:/nuc/PrintrBot/Marlin$ grep E5 m43-pins.txt 
+// PIN:  37   Port: E5        <unused/unknown>            Input  = 1
+//
+#define SERVO0_PIN	37	// E5 E-STOP
+
.pre

^^ gcode for bl-touch

M280 P0 S10 ; pushes the pin down

M280 P0 S90 ; pulls the pin up

M280 P0 S120 ; Self test – keeps going until you do pin up/down or release alarm

M280 P0 S160 ; Release alarm

M420 V ; display bed leveling

.pre
Bilinear Leveling Grid:
      0      1      2
 0 +0.445 +0.402 +0.284
 1 -0.083 +0.013 +0.023
 2 -0.678 -0.432 -0.264

echo:Bed Leveling On 
echo:Fade Height Off
.pre

----

^ Notes for Ender 3 V1.1.3

* install sanguino board support in ardunino ide https://github.com/Lauszus/Sanguino
* turn on power supply when flashing if you didn't disconnect steppers or it won't get enough power
* burn boot loader using usbasp programmer from arduino ide to make arudino ide work for upload
{file: ch9326-test.py}

{file: CH9326DS1.PDF}

UART to USB 1.1 HID

I first learned about this chip from video https://youtu.be/jJoD2ioJPP0

^ chip on sop16 breakout

Connecting only VCC, GND USB- and USB+ to target and UART RX, TG and GND to USB serial works without any additional components.

{image: IMG_20191019_175736-800px.jpg}

.pre
[2022258.670458] usb 1-5.2.3: new full-speed USB device number 41 using ehci-pci
[2022258.780644] usb 1-5.2.3: New USB device found, idVendor=1a86, idProduct=e010, bcdDevice=34.00
[2022258.780657] usb 1-5.2.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[2022258.780663] usb 1-5.2.3: Product: HID To Serial
[2022258.780669] usb 1-5.2.3: Manufacturer: WCH.CN 4
[2022258.780674] usb 1-5.2.3: SerialNumber: 12345678
[2022258.791635] hid-generic 0003:1A86:E010.000D: hiddev3,hidraw3: USB HID v1.00 Device [WCH.CN 4 HID To Serial] on usb-0000:00:1a.7-5.2.3/input0
.pre

I does not create normal /dev/input device under Linux, but sending chars over serial at 9600 8n1 does produce output at /dev/hidraw3 device

.pre
dpavlin@x200:~$ microcom -s 9600 -p /dev/ttyUSB0
.pre

^ lsusb

.pre
dpavlin@x200:~$ sudo lsusb -d 1A86:E010 -v

Bus 001 Device 041: ID 1a86:e010 QinHeng Electronics
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.00
  bDeviceClass            0
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0         8
  idVendor           0x1a86 QinHeng Electronics
  idProduct          0xe010
  bcdDevice           34.00
  iManufacturer           1 WCH.CN 4
  iProduct                2 HID To Serial
  iSerial                 3 12345678
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x0029
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          4 (error)
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              100mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0
      bInterfaceProtocol      0
      iInterface              0
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.00
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      37
         Report Descriptors:
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0020  1x 32 bytes
        bInterval               1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0020  1x 32 bytes
        bInterval               1
can't get debug descriptor: Resource temporarily unavailable
Device Status:     0x0000
  (Bus Powered)
.pre
{toc: }

^ Upgrade to current build

I opted to save everything to since USB keychain and use boot loader to update laptops. You will need:

^^ Prepare keychain

vfat file format, save following files on keychain:

* OS image: http://download.laptop.org/xo-1/os/candidate/703/jffs2/os703.img
* CRC file: http://download.laptop.org/xo-1/os/candidate/703/jffs2/os703.crc
* http://download.laptop.org/xo-1/os/official/703/jffs2/fs.zip
* latest firmware: http://dev.laptop.org/pub/firmware/q2d14a/q2d14a.rom

You can flash OS install by holding gamepad keys (on right) and powering on.

unzip Activity pack to root of keychain:

* G1G1 Activity pack: http://wiki.laptop.org/go/Image:G1G1_Activity_Pack_1.zip

After firmware upgrade and filesystem upgrade, boot with keychain and hold X key to install Activities.

^^ B4 laptops

* Latest firmware: http://wiki.laptop.org/go/Firmware
* Keys for firmware: http://wiki.laptop.org/go/Cheat_codes
* Change language: http://wiki.laptop.org/go/Upgrade_VIP

.pre
# cat /home/olpc/.i18n
LANG="en_US.UTF-8"
.pre

^^ C2 laptop

Requested developer key

^ Mash networking

* http://wiki.laptop.org/go/Mesh_Network_Details
* http://lists.infradead.org/pipermail/libertas-dev/

{fetchrss: http://feeds.delicious.com/rss/dpavlin/olpc+mash full}

^ Debian lenny

First, I used `olpc-update debian-big` (twice!) to make working OLPC with debian on it.

Here are few useful configuration files:

* {file: .Xmodmap}
* {file: .xinitrc}

.pre
apt-get remove nano
apt-get install tshark ssh screen
.pre

^ Rollout Expirience from Makedonia

.pre
23:15 < dpavlin> jel se netko od vas igrao sa 802.11s (mash)? OLPC ima podršku koja izgleda koristi WDS frame-ove (što znači da *bi* 
                 trebala raditi i na starijim karticama), a 802.11s je upravo ušao u 2.6.26
23:15 < dpavlin> usput, pročitali ste blog post i nemate komentara?
23:29 < m|sa> dpavlin: mislim da se neko iz skopske ekipe uspeo zakaciti na olpc mash kad smo ih testirali u skopju
23:33 < dpavlin> imaš možda neki mail/blog post, nešto? ;-)
23:34 < dpavlin> jeste vi malo negativani prema OLPC-u iz tog iskustva? (ne optužujem nego me zanima zašto)
23:34 -!- sasa1 [n=sasa@83-131-22-34.adsl.net.t-com.hr] has joined #razmjenavjestina
23:35 < m|sa> ne... nazalost... al imam jednu sliku s olpc mrezom ;-) vise info o rezultatima valjda ti damjan moze ponuditi 
              http://flickr.com/photos/kotle/2114609237/
23:36 < m|sa> dpavlin: ne. negativan stav je prema sadasnjim zbivanjima u samom olpc projektu. u skopju smo "servisirali" 50ak xo 
              laptopa...
23:37 < m|sa> ... i nije bilo nekih vecih problema koji nisu vezani za fakt da su to bili test verzije hardvera i softvera.
23:37 < dpavlin> kako ste uspjeli dobiti 50 kom?
23:38 < dpavlin> zapravo, razmišljam da napišem mail krstiću, ali nekako ne bih ga htio daviti nakon svega...
23:38 < dpavlin> ali nekako mi se čini da mi ne bi zamjerio, ipak je OLPC njegovo dijete :-)
23:38 < m|sa> pa nismo ih mi dobili. undp je implementirao pilot projekat u dve osnovne shkole u skopju... pa 
23:38 < dpavlin> undp?
23:38 < dpavlin> dve škole?
23:39 < m|sa> dva klasa u dve shkole
23:39 < m|sa> 2x25
23:39 < dpavlin> koji razredi?
23:39 < m|sa> mislim drugi razred
23:39 < dpavlin> i?
23:39 < m|sa> 8 godina
23:39 < m|sa> pa ceka se evaluacija projekta ;-)
23:39 < m|sa> mi smo flashali firware i buildove
23:39 < dpavlin> što je undp i od kada traje projekt i do kada?
23:39 < m|sa> i jos se brinemo za funkcionalnost
23:39 < dpavlin> m|sa: i šutiš?!
23:40 < m|sa> ne sutim!
23:40 < dpavlin> :-)
23:40 < m|sa> ali nekako nikako da uleti ta tema ;-)
23:40 < m|sa> stvar je u tome da su se deca snashla
23:40 < dpavlin> oh, oh!!! :-)
23:41 < dpavlin> ma znam da će se djeca snaći -- stvar je u tome da ga ne možeš ocijeniti na temelju 15 minuta :-)
23:41 < m|sa> i mislim da su im nastavnici veci problem u implementaciji projekta
23:41 < dpavlin> nije im težak?
23:41 < m|sa> pa ne...
23:41 < m|sa> sugar smo preveli na makedonski
23:41 < m|sa> tako da ... lakse im je
23:42 < m|sa> problem je albanskoj deci... posto nismo nasli nekog ko bi to mogao prevesti na albanski
23:42 < dpavlin> znam da su nastavnici problem, ali mi imamo cijeli grad, tako da ćemo imati dobrih nastavnika kako god okrenemo...
23:42 < m|sa> ali i tamo se nekako snalaze...
23:42 < dpavlin> hm... koliko je posla prijevod?
23:42 < dpavlin> jel' instalirate svoj action sa usb sticka? ili?
23:42 < m|sa> pa sam interfejs nije velik... to i sam znas
23:43 < dpavlin> mislim koliko ljudi/vremena vam je trebalo?
23:43 < dpavlin> ja sam samo jednom bio na openoffice.org maratonu i zapravo nemam iskustva sa prevođenjem.
23:43 < dpavlin> titlao sam filove, ali to je sasvim drugačije :-)
23:44 < m|sa> pa nisam neki lokalizator... al ljudi koji lokaliziraju floss na makedonski su pricali da je to mali poduhvat
23:44 < m|sa> mislim na sugar
23:44 < dpavlin> ok, ajdmo sad: KAKO ste došli do laptopa?!
23:45 < m|sa> znaci... undp nas je potrazio da im sredimo xo-laptope koje su oni nabavili radi njihovog pilot projekta
23:45 < dpavlin> sto je undp?
23:46 < m|sa> United Nations Development Programme
23:46 < m|sa> znas... mi smo zemja trijeceg svijeta
23:46 < m|sa> ;-)
23:46 < dpavlin> I mi smo, nemoj nikom reći.
23:46 < dpavlin> EU sad to zove zemljama 4-to svijeta, ali nema trećeg, pa se svi pitaju...
23:46 < dpavlin> to su valjda ostavili mjesto za "tranziciju"
23:47 < m|sa> posto je build + firmware koji su oni dobili s laptopa bio prilicno star... laptopi nisu bili bash funkcionalni
23:47 < m|sa> tako smo mi update-ovali sve to
23:47 < m|sa> pre toga smo preveli Sugar
23:48 < dpavlin> znam, meni radi dobro tek 704 koji je još cadidate :-)
23:48 < m|sa> zapravo... mi nemamo te laptope
23:48 < dpavlin> naravno, oni i *jesu* za djecu :-)
23:48 < m|sa> laptope imaju deca
23:48 < dpavlin> kada je počelo, koliko traje jel' se kvare?
23:48 < m|sa> *djeca
23:48 < m|sa> postoji samo jedan hardverski kvar
23:49 < m|sa> jedan monitor je postradao ... neznamo sta se desilo
23:49 < m|sa> projekt je poceo negde oktobar/novembar mislim
23:49 < m|sa> *listopad/studeni 
23:50 < dpavlin> i traje godinu dana? što ćete poslije sa laptopima? Ostaju djeci?
23:50 < m|sa> zavrsio je pre mesec dana... al je nastava sa laptopima produzila (usput... ti ce laptopi ostati kod djece)
23:51 < dpavlin> cool!
23:51 < dpavlin> (sorry, nestrpljiv sam :-)
23:51 < m|sa> ha... mislim da smo trebali ranije ispricati ovu pricu... onda mi mozda vise ljudi iz hr dosli na nsnd-u ovde ;-)
23:51 < dpavlin> sorry, ja sam mrtav. mislim da ne bih preživio put nikuda prije nego što se odmorim preko prvog maja :-)
23:52 < m|sa> da se vratim na kvarovima... tu i tamo se neshto razlabavi... al pretpostavljamo da su neki kvarovi dosli i s tvornice
23:52 < m|sa> nema veze.. zezam se :-)
23:52 < dpavlin> da, moj ima 2 dead pixela
23:53 < m|sa> meni je xo super... fali mi vga-out i mislim da mi nista vise ne treba od laptopa... cak sam se i navikao na tu malenu   tastaturu
23:53 < dpavlin> zapravo, ne *moj* (sigh!) nego od OLPC Hrvatska :-) To sam zaboravio napomenuti, dobio sam ga na posudbu...
23:53 < dpavlin> ja sam tek danas shvatio da ima sd slot.
23:53 < m|sa> a jel se kod vas nesto implementira
23:53 < dpavlin> možda sam trebao detaljnije pročitati wiki, zapravo je prepun korisnog sadržaja.
23:54 < dpavlin> dakle, *nisi* vidio blog post: http://blog.rot13.org/2008/04/first_day_with_olpc.html
23:54 < dpavlin> oh, pa zašto sam radio rss announce na kanalu? ;-)
23:56 < m|sa> dpavlin: chitam
23:56 < dpavlin> :-)
23:57 < dpavlin> pa onda znaš da mi je trenutna briga kako uopće doći do 2000 laptopa (i doduše to što se ministarstvo mora složiti o uključenju u nastavni program, ali to vjerojatno nije neizvodivo)
23:58 < m|sa> dpavlin: ne znam dali sam te dobro shvatio... al i activities se mogu apdejtati preku build upgrade
23:58 < dpavlin> sa druge strane, znamo da ne možemo nikako očekivati da ga prihvate SVI profesori, ali ideja je dati ih djeci od 1-4 razreda.
23:59 < dpavlin> to je ~2000 djece u svim školama u Varaždinu (jer to radi grad Varaždin)
23:59 < m|sa> dpavlin: mozda nije losa ideja da se poceka kako ce sve proci na balkanu. ako mk obrazovanje prihvati olpc... mozda se moze to skupa naruciti
23:59 < dpavlin> ma, čak i da samo djeci daju laptope, mislim da ima koristi.
Day changed to 25 Apr 2008
00:00 < dpavlin> nisu svi koji su koristili pero postali pjesnici :-)
00:00 < m|sa> posto verujem da ako undp kaze da je projekat bio uspesan, i nasa vlada pozeli da uvede olpc u 1-4 razred... suocit ce se s istim problemom - broj narudzbe
00:02 < dpavlin> koliko vi imate djece? siguran sam da bi bio evrope (to još jesmo svi, jel'?) mogao od zlih amera kupiti odgovarajuću količinu :-)
00:03 < m|sa> dpavlin: neznam broj. ali cilj pilot projekta je bio dati generalnu preporuku ministarstvu obrazovanja... znaci nationwide
00:05 < dpavlin> mi smo se zapravo dvoumili između dvije škole kao pilota i cijelog grada, ali zapravo imamo sreću da je Varaždin grad koji ozbiljno razmišlja o tome -- oni recimo imaju svoju otiku u zelji nakon što je počeo problem sa nacionalnim operaterom koji je prodan T-Mobile-u
00:06 < dpavlin> u jednom trenutku je ušao Čehok i rekao: "može samo za cijeli grad" i tako razriješio našu dilemu. Nakon što se poigrao na laptopu, naravno :-)
00:08 < dpavlin> svi oni su zapravo već bili toliko za to, da su spremno rekli "ajdemo pogledati kako su to napravili u Beču"
00:08 < dpavlin> znaš, Varaždin je ipak mali Beč (kao i Zagreb zapravo)
00:09 < dpavlin> sa druge strane, more nas pitanja održavanja (što ćemo valjda rješiti sa previše laptopa, jel?) jer nema smisla da to
00:09 < dpavlin> napravimo samo jednu godinu: slijedeće godine će djeca biti ljubomorna :-)
00:09 < dpavlin> mislim da se pojavila ideja rotiranja laptopa prvašićima, ali bojim se da je razvoj tehnologije protiv nas :-)
00:11 < m|sa> pa i nije tako trivijalna stvar to odrzavanje
00:11 < m|sa> ovde su namjanje para predvideli za to
00:12 < m|sa> sto je bilo klucno imajuci u obzir fakt da su buildovi i hardver bili prilicno stari i test verzije
00:13 < m|sa> prosetali su se do mit-a gde su navodno obucili nastavnice za rad
00:13 < m|sa> ;-)
00:13 < m|sa> a zaboravili su da laptopima treba odrzavanje
00:15 < m|sa> neznam kako bi to izgledalo s 2000 laptopa
00:16 -!- pae [n=leif@131-197.dsl.iskon.hr] has quit ["Leaving"]
00:16 < m|sa> mislim... pare investirane u support ne smatram da su loshe investirane pare... ali dali to gradski vjecnici isto tako 
 misle... to se pitam
00:23 < m|sa> aj poz
00:24 -!- m|sa [n=misa@79.126.133.7] has quit ["Konversation terminated!"]
00:28 < dpavlin> grr, otišo si :-) zapravo su oni pitali :-)
.pre
Very lousy plastic, space bar generated clunk, clunk sound, but otherwise nice wireless keyboard if you don't care much about quality of plastic.

^ Protocol documentation

* {file: logitech_hidpp_2.0_specification_draft_2012-06-04.pdf} from http://6xq.net/git/lars/lshidpp.git/plain/doc/logitech_hidpp_2.0_specification_draft_2012-06-04.pdf

^ Linux software

* https://github.com/pwr/Solaar

.pre
dpavlin@blue:/rest/cvs/Solaar$ sudo ./bin/solaar show
Unifying Receiver
  Device path  : /dev/hidraw3
  USB id       : 046d:c52b
  Serial       : 656F91A9
    Firmware   : 12.01.B0019
    Bootloader : 02.14
  Has 1 paired device(s) out of a maximum of 6.
  Notifications: (none)
  Device activity counters: 1=2

  1: Wireless Touch Keyboard K400
     Codename     : K400
     Kind         : keyboard
     Wireless PID : 4024
     Protocol     : HID++ 2.0
     Polling rate : 8 ms (125Hz)
     Serial number: AC5F5069
          Firmware: RQK 50.01.B0013
     The power switch is located on the edge of top right corner.
     Supports 22 HID++ 2.0 features:
         0: ROOT                   {0000}   
         1: FEATURE SET            {0001}   
         2: FEATURE INFO           {0002}   
         3: DEVICE FW VERSION      {0003}   
         4: DEVICE NAME            {0005}   
         5: BATTERY STATUS         {1000}   
         6: REPROG CONTROLS        {1B00}   
         7: REPROG CONTROLS V3     {1B03}   
         8: WIRELESS DEVICE STATUS {1D4B}   
         9: unknown:1DF0           {1DF0}   hidden
        10: unknown:1DF3           {1DF3}   internal, hidden
        11: unknown:1E00           {1E00}   hidden
        12: VERTICAL SCROLLING     {2100}   
        13: HI RES SCROLLING       {2120}   
        14: MOUSE POINTER          {2200}   
        15: FN INVERSION           {40A0}   
        16: NEW FN INVERSION       {40A2}   
        17: ENCRYPTION             {4100}   
        18: KEYBOARD LAYOUT        {4520}   
        19: TOUCHPAD FW ITEMS      {6010}   
        20: TOUCHPAD SW ITEMS      {6011}   
        21: TOUCHPAD WIN8 FW ITEMS {6012}   
     Has 18 reprogrammable keys:
         0: SHOW DESKTOP               => ShowDesktop                   is FN, reprogrammable
         1: METRO APPSWITCH            => MetroAppSwitch                is FN, reprogrammable
         2: METRO SEARCH               => MetroSearch                   is FN, reprogrammable
         3: METRO SHARE                => MetroShare                    is FN, reprogrammable
         4: METRO DEVICES              => MetroDevices                  is FN, reprogrammable
         5: METRO SETTINGS             => MetroSettings                 is FN, reprogrammable
         6: Previous                   => Previous                      is FN
         7: Play/Pause                 => Play/Pause                    is FN
         8: Next                       => Next                          is FN
         9: Mute                       => Mute                          is FN
        10: Volume Down                => Volume Down                   is FN
        11: Volume Up                  => Volume Up                     is FN
        12: MEDIA PLAYER               => Music                         nonstandard, reprogrammable
        13: Lock PC                    => WindowsLock                   nonstandard, reprogrammable
        14: SLEEP                      => Sleep                         nonstandard, reprogrammable
        15: LEFT CLICK                 => LeftClick                     mse
        16: LEFT CLICK                 => LeftClick                     mse
        17: RIGHT CLICK                => RightClick                    mse
     Battery: 90%, discharging.
.pre

^ Firmware update under Linux

* https://github.com/hughsie/fwupd
* https://blogs.gnome.org/hughsie/2017/05/22/updating-logitech-hardware-on-linux/