Welcome to TiddlyWiki created by Jeremy Ruston, Copyright © 2007 UnaMesa Association
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.
<!--{{{-->
<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
<div class='headerShadow'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
<div class='headerForeground'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>
<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 class="socialtextLogo"><img src="http://www.eu.socialtext.net/static/2.3.0.0/images/st/logo/socialtext-logo-152x26.gif" width=152 height=26></div>
</div>
<!--}}}-->
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
https://saturn.ffzg.hr/rot13/
[[SocialtextScreenStyle]]
[[SocialtextStyleOverrides]]
[[Styles HorizontalMainMenu]]
@@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&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 = '™';
}
},
{
name: 'socialtextWafl',
match: '\\{(?:[a-z]{2,16}): ?.*?\\}',
lookaheadRegExp: /\{([a-z]{2,16}): ?(.*?)\}/mg,
handler: SocialtextFormatter.wafl
},
{
name: 'socialtextPresence',
match: '(?:aim|yahoo|ymsgr|skype|callto|asap):\\w+',
lookaheadRegExp: /(aim|yahoo|ymsgr|skype|callto|asap):(\w+)/mg,
handler: SocialtextFormatter.presence
},
{
name: 'socialtextMailTo',
match: '[\\w\.]+@[\\w]+\.[\\w\.]+',
lookaheadRegExp: /([\w\.]+@[\w]+\.[\w\.]+)/mg,
handler: function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var text = lookaheadMatch[1];
createTiddlyText(createExternalLink(w.output,'mailto:'+text),text);
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
},
{
name: 'socialtextHtmlEntitiesEncoding',
match: '&#?[a-zA-Z0-9]{2,8};',
handler: function(w)
{
createTiddlyElement(w.output,'span').innerHTML = w.matchText;
}
}
];
config.parsers.socialtextFormatter = new Formatter(config.socialtext.formatters);
config.parsers.socialtextFormatter.format = 'socialtext';
config.parsers.socialtextFormatter.formatTag = 'SocialtextFormat';
} // end of 'install only once'
//}}}
/***
|''Name:''|SocialtextAdaptorPlugin|
|''Description:''|Adaptor for moving and converting data to and from Socialtext Wikis|
|''Author:''|Martin Budden (mjbudden (at) gmail (dot) com) and JeremyRuston (jeremy (at) osmosoft (dot) com)|
|''Source:''|http://www.martinswiki.com/#SocialtextAdaptorPlugin|
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/adaptors/SocialtextAdaptorPlugin.js|
|''Version:''|0.5.1|
|''Date:''|Feb 25, 2007|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev|
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|''~CoreVersion:''|2.2.0|
Socialtext REST documentation is at:
http://www.eu.socialtext.net/st-rest-docs/index.cgi?socialtext_rest_documentation
***/
//{{{
if(!version.extensions.SocialtextAdaptorPlugin) {
version.extensions.SocialtextAdaptorPlugin = {installed:true};
function SocialtextAdaptor()
{
this.host = null;
this.workspace = null;
return this;
}
SocialtextAdaptor.mimeType = 'text/x.socialtext-wiki';
SocialtextAdaptor.serverType = 'socialtext';
SocialtextAdaptor.serverParsingErrorMessage = "Error parsing result from server";
SocialtextAdaptor.errorInFunctionMessage = "Error in function SocialtextAdaptor.%0";
SocialtextAdaptor.prototype.setContext = function(context,userParams,callback)
{
if(!context) context = {};
context.userParams = userParams;
if(callback) context.callback = callback;
context.adaptor = this;
if(!context.host)
context.host = this.host;
if(!context.workspace && this.workspace)
context.workspace = this.workspace;
return context;
};
SocialtextAdaptor.doHttpGET = function(uri,callback,params,headers,data,contentType,username,password)
{
return doHttp('GET',uri,data,contentType,username,password,callback,params,headers);
};
SocialtextAdaptor.doHttpPOST = function(uri,callback,params,headers,data,contentType,username,password)
{
return doHttp('POST',uri,data,contentType,username,password,callback,params,headers);
};
SocialtextAdaptor.fullHostName = function(host)
{
if(!host)
return '';
if(!host.match(/:\/\//))
host = 'http://' + host;
if(host.substr(host.length-1) != '/')
host = host + '/';
return host;
};
SocialtextAdaptor.minHostName = function(host)
{
return host ? host.replace(/^http:\/\//,'').replace(/\/$/,'') : '';
};
// Convert a page title to the normalized form used in uris
SocialtextAdaptor.normalizedTitle = function(title)
{
var n = title.toLowerCase();
n = n.replace(/\s/g,'_').replace(/\//g,'_').replace(/\./g,'_').replace(/:/g,'').replace(/\?/g,'');
if(n.charAt(0)=='_')
n = n.substr(1);
return String(n);
};
// Convert a Socialtext date in YYYY-MM-DD hh:mm format into a JavaScript Date object
SocialtextAdaptor.dateFromEditTime = function(editTime)
{
var dt = editTime;
return new Date(Date.UTC(dt.substr(0,4),dt.substr(5,2)-1,dt.substr(8,2),dt.substr(11,2),dt.substr(14,2)));
};
SocialtextAdaptor.prototype.openHost = function(host,context,userParams,callback)
{
this.host = SocialtextAdaptor.fullHostName(host);
context = this.setContext(context,userParams,callback);
if(context.callback) {
context.status = true;
window.setTimeout(function() {callback(context,userParams);},0);
}
return true;
};
SocialtextAdaptor.prototype.openWorkspace = function(workspace,context,userParams,callback)
{
this.workspace = workspace;
context = this.setContext(context,userParams,callback);
if(context.callback) {
context.status = true;
window.setTimeout(function() {callback(context,userParams);},0);
}
return true;
};
SocialtextAdaptor.prototype.getWorkspaceList = function(context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
var uriTemplate = '%0data/workspaces';
var uri = uriTemplate.format([context.host]);
var req = SocialtextAdaptor.doHttpGET(uri,SocialtextAdaptor.getWorkspaceListCallback,context,{'accept':'application/json'});
return typeof req == 'string' ? req : true;
};
SocialtextAdaptor.getWorkspaceListCallback = function(status,context,responseText,uri,xhr)
{
context.status = false;
context.statusText = SocialtextAdaptor.errorInFunctionMessage.format(['getWorkspaceListCallback']);
if(status) {
try {
eval('var info=' + responseText);
} catch (ex) {
context.statusText = exceptionText(ex,SocialtextAdaptor.serverParsingErrorMessage);
if(context.callback)
context.callback(context,context.userParams);
return;
}
var list = [];
for(var i=0; i<info.length; i++) {
var item = {
title:info[i].title,
name:info[i].name,
modified:SocialtextAdaptor.dateFromEditTime(info[i].modified_time)
};
list.push(item);
}
context.workspaces = list;
context.status = true;
} else {
context.statusText = xhr.statusText;
}
if(context.callback)
context.callback(context,context.userParams);
};
SocialtextAdaptor.prototype.getTiddlerList = function(context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
var uriTemplate = '%0data/workspaces/%1/pages?order=newest';//!! ? or ;
var uri = uriTemplate.format([context.host,context.workspace]);
var req = SocialtextAdaptor.doHttpGET(uri,SocialtextAdaptor.getTiddlerListCallback,context,{'accept':'application/json'});
return typeof req == 'string' ? req : true;
};
SocialtextAdaptor.getTiddlerListCallback = function(status,context,responseText,uri,xhr)
{
context.status = false;
context.statusText = SocialtextAdaptor.errorInFunctionMessage.format(['getTiddlerListCallback']);
if(status) {
try {
eval('var info=' + responseText);
} catch (ex) {
context.statusText = exceptionText(ex,SocialtextAdaptor.serverParsingErrorMessage);
if(context.callback)
context.callback(context,context.userParams);
return;
}
var list = [];
for(var i=0; i<info.length; i++) {
var tiddler = new Tiddler(info[i].name);
tiddler.modified = SocialtextAdaptor.dateFromEditTime(info[i].last_edit_time);
tiddler.modifier = info[i].last_editor;
tiddler.tags = info[i].tags;
tiddler.fields['server.page.id'] = info[i].page_id;
tiddler.fields['server.page.name'] = info[i].name;
tiddler.fields['server.page.revision'] = String(info[i].revision_id);
list.push(tiddler);
}
context.tiddlers = list;
context.status = true;
} else {
context.statusText = xhr.statusText;
}
if(context.callback)
context.callback(context,context.userParams);
};
SocialtextAdaptor.prototype.generateTiddlerInfo = function(tiddler)
{
var info = {};
var host = this && this.host ? this.host : SocialtextAdaptor.fullHostName(tiddler.fields['server.host']);
var workspace = this && this.workspace ? this.workspace : tiddler.fields['server.workspace'];
uriTemplate = '%0%1/index.cgi?%2';
info.uri = uriTemplate.format([host,workspace,SocialtextAdaptor.normalizedTitle(tiddler.title)]);
return info;
};
SocialtextAdaptor.prototype.getTiddler = function(title,context,userParams,callback)
{
return this.getTiddlerRevision(title,null,context,userParams,callback);
};
SocialtextAdaptor.prototype.getTiddlerRevision = function(title,revision,context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
// request the page in json format to get the page attributes
if(revision) {
var uriTemplate = '%0data/workspaces/%1/pages/%2/revisions/%3';
context.revision = revision;
} else {
uriTemplate = '%0data/workspaces/%1/pages/%2';
context.revision = null;
}
uri = uriTemplate.format([context.host,context.workspace,SocialtextAdaptor.normalizedTitle(title),revision]);
context.tiddler = new Tiddler(title);
context.tiddler.fields.wikiformat = 'socialtext';
context.tiddler.fields['server.host'] = SocialtextAdaptor.minHostName(context.host);
context.tiddler.fields['server.workspace'] = context.workspace;
var req = SocialtextAdaptor.doHttpGET(uri,SocialtextAdaptor.getTiddlerCallback,context,{'accept':'application/json'});
return typeof req == 'string' ? req : true;
};
SocialtextAdaptor.getTiddlerCallback = function(status,context,responseText,uri,xhr)
{
context.status = false;
context.statusText = SocialtextAdaptor.errorInFunctionMessage.format(['getTiddlerCallback']);
if(status) {
try {
eval('var info=' + responseText);
context.tiddler.tags = info.tags;
context.tiddler.fields['server.page.id'] = info.page_id;
context.tiddler.fields['server.page.name'] = info.name;
context.tiddler.fields['server.page.revision'] = String(info.revision_id);
context.tiddler.modifier = info.last_editor;
context.tiddler.modified = SocialtextAdaptor.dateFromEditTime(info.last_edit_time);
} catch (ex) {
context.statusText = exceptionText(ex,SocialtextAdaptor.serverParsingErrorMessage);
if(context.callback)
context.callback(context,context.userParams);
return;
}
context.status = true;
} else {
context.statusText = xhr.statusText;
if(context.callback)
context.callback(context,context.userParams);
return;
}
var uriTemplate = context.revision ? '%0data/workspaces/%1/pages/%2/revisions/%3' : '%0data/workspaces/%1/pages/%2';
var host = SocialtextAdaptor.fullHostName(context.tiddler.fields['server.host']);
var workspace = context.workspace ? context.workspace : context.tiddler.fields['server.workspace'];
uri = uriTemplate.format([host,workspace,SocialtextAdaptor.normalizedTitle(context.tiddler.title),context.revision]);
var req = SocialtextAdaptor.doHttpGET(uri,SocialtextAdaptor.getTiddlerCallback2,context,{'accept':SocialtextAdaptor.mimeType});
};
SocialtextAdaptor.getTiddlerCallback2 = function(status,context,responseText,uri,xhr)
{
context.tiddler.text = responseText;
if(status) {
context.status = true;
} else {
context.status = false;
context.statusText = xhr.statusText;
}
if(context.callback)
context.callback(context,context.userParams);
};
SocialtextAdaptor.prototype.getTiddlerRevisionList = function(title,limit,context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
var uriTemplate = '%0data/workspaces/%1/pages/%2/revisions?accept=application/json';
if(!limit)
limit = 5;
var uri = uriTemplate.format([context.host,context.workspace,SocialtextAdaptor.normalizedTitle(title),limit]);
var req = SocialtextAdaptor.doHttpGET(uri,SocialtextAdaptor.getTiddlerRevisionListCallback,context);
return typeof req == 'string' ? req : true;
};
SocialtextAdaptor.getTiddlerRevisionListCallback = function(status,context,responseText,uri,xhr)
{
context.status = false;
if(status) {
var content = null;
try {
eval('var info=' + responseText);
} catch (ex) {
context.statusText = exceptionText(ex,SocialtextAdaptor.serverParsingErrorMessage);
if(context.callback)
context.callback(context,context.userParams);
return;
}
list = [];
for(var i=0; i<info.length; i++) {
var tiddler = new Tiddler(info[i].name);
tiddler.modified = SocialtextAdaptor.dateFromEditTime(info[i].last_edit_time);
tiddler.modifier = info[i].last_editor;
tiddler.tags = info[i].tags;
tiddler.fields['server.page.id'] = info[i].page_id;
tiddler.fields['server.page.name'] = info[i].name;
tiddler.fields['server.page.revision'] = info[i].revision_id;
list.push(tiddler);
}
var sortField = 'server.page.revision';
list.sort(function(a,b) {return a.fields[sortField] < b.fields[sortField] ? +1 : (a.fields[sortField] == b.fields[sortField] ? 0 : -1);});
context.revisions = list;
context.status = true;
} else {
context.statusText = xhr.statusText;
}
if(context.callback)
context.callback(context,context.userParams);
};
SocialtextAdaptor.prototype.putTiddler = function(tiddler,context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
context.tiddler = tiddler;
context.title = tiddler.title;
var uriTemplate = '%0data/workspaces/%1/pages/%2';
var host = context.host ? context.host : SocialtextAdaptor.fullHostName(tiddler.fields['server.host']);
var workspace = context.workspace ? context.workspace : tiddler.fields['server.workspace'];
var uri = uriTemplate.format([host,workspace,tiddler.title,tiddler.text]);
//var req = doHttp('POST',uri,tiddler.text,SocialtextAdaptor.mimeType,null,null,SocialtextAdaptor.putTiddlerCallback,context,{"X-Http-Method": "PUT"});
var req = SocialtextAdaptor.doHttpPOST(uri,SocialtextAdaptor.putTiddlerCallback,context,{"X-Http-Method": "PUT"},tiddler.text,SocialtextAdaptor.mimeType);
return typeof req == 'string' ? req : true;
};
SocialtextAdaptor.putTiddlerCallback = function(status,context,responseText,uri,xhr)
{
if(status) {
context.status = true;
} else {
context.status = false;
context.statusText = xhr.statusText;
}
if(context.callback)
context.callback(context,context.userParams);
};
SocialtextAdaptor.prototype.close = function()
{
return true;
};
config.adaptors[SocialtextAdaptor.serverType] = SocialtextAdaptor;
} //# end of 'install only once'
//}}}
/***
SocialtextStyleOverrides
***/
/*{{{*/
.headerShadow {padding: 2em 0em .5em 1em;}
.headerForeground {padding: 2em 0em .5em 1em;}
#st-page-wiki-title {
font-size: 80%;
}
.subtitle {
font-style: italic;
font-size 80%;
}
/* from #st-tags */
.tagged {
border-color: #bbeebb;
background-color: #f4fff4;
}
.tagged .listTitle {
color: #595;
font-weight: bold;
}
.tagged .button {
color: #000;
}
.selected .tagged {
background-color: ColorPalette::TertiaryLight;
border: 1px solid ColorPalette::TertiaryMid;
}
/* from #st-incoming-links */
.tagging {
border-color: #ebb;
background-color: #fff4f4;
}
.tagging .listTitle {
color: #b78;
font-weight: bold;
}
.tagging .button {
color: #999;
}
.selected .tagging {
background-color: ColorPalette::TertiaryLight;
border: 1px solid ColorPalette::TertiaryMid;
}
.tiddler {/* Tiddler body */
border:1px solid #ccc;
margin:0.5em;
background:#fff;
padding:0.5em;
}
.viewer blockquote {border-left: 0px solid}
.tiddlyLinkNonExisting {
font-style: italic;
border-bottom: 1px dashed;
}
.editor input, .editor textarea {
background: #ffd;
border-style: solid;
border-color: #888 #ccc #ccc #888;
border-width: 2px;
}
.tabContents {white-space: nowrap;}
#displayArea {margin: 1em 20em 0em 14em;}
#sidebar {
position: absolute;
right: 3px;
width: 21em;
font-size: .9em;
}
#sidebarOptions .button {
border-color: #eee;
}
#sidebarTabs .tabContents {
width: 20em;
overflow: hidden;
}
.viewer tt {
font-size: 1.2em;
line-height: 1.4em;
}
ul {list-style-type: square;}
ul ul {list-style-type: circle;}
ol {list-style-type: decimal;}
ol ol {list-style-type: decimal;}
ol ol ol {list-style-type: decimal;}
ol ol ol ol {list-style-type: decimal;}
ol ol ol ol ol {list-style-type: decimal;}
ol ol ol ol ol ol {list-style-type: decimal;}
/*}}}*/
/***
SocialtextScreenStyle
http://www.eu.socialtext.net/static/2.0.0.1/css/st/screen.css
***/
/*{{{*/
body {
font-family: Arial, sans-serif;
color: #000;
background: #eee;
margin: 0;
}
/* Wiki Navigation */
.st-wiki-nav {
clear: both;
margin-left: 10px;
margin-right: 10px;
}
.st-wiki-nav-content {
background: url('../../images/st/wiki-nav/solid.gif') repeat-x left bottom;
margin-left: 24px;
margin-right: 24px;
padding-top: 3px;
min-height: 24px;
}
* html .st-wiki-nav-content {
padding-bottom: 3px;
height: 24px;
}
.st-wiki-nav-right {
background: url('../../images/st/wiki-nav/right-round.gif') no-repeat bottom right;
}
.st-wiki-nav-left {
background: url('../../images/st/wiki-nav/left-round.gif') no-repeat bottom left;
}
#st-home {
float: left;
margin-right: 60px;
padding-top: 2px;
}
#st-home-link {
color: white;
text-decoration: none;
font-weight: bold;
font-family: Helvetica, sans-serif;
font-size: 90%;
}
#st-editing-prefix-container {
border-collapse: collapse;
width: 100%;
padding: 0px;
margin: 0px;
margin-bottom: -20px;
}
#st-editing-prefix-container tr td {
margin: 0px;
padding: 0px;
}
#st-editing-title {
color: black;
background-color: white;
text-decoration: none;
font-weight: bold;
font-family: Helvetica, sans-serif;
font-size: 90%;
margin-bottom: 0.4em;
}
#st-wiki-title-invite {
font-size: 50%;
font-family: Helvetica, sans-serif;
}
#st-wiki-title-central-page-link {
font-size: 50%;
font-family: Helvetica, sans-serif;
}
#st-wiki-title-invite a {
color: #00f;
}
#st-wiki-logo {
text-align: center;
clear: both;
}
#st-wiki-logo-image {
}
.st-wiki-nav-actions {
float: right;
color: black;
font-size: 75%;
padding-top: 3px;
}
.st-wiki-nav-actions a {
padding: 2px;
color: white;
text-decoration: none;
font-family: Helvetica, sans-serif;
}
/* Wiki Subnav */
#st-wiki-subnav {
margin-top: 2px;
font-size: 70%;
font-weight: bold;
font-family: Helvetica, sans-serif;
color: #888;
}
#st-wiki-subnav a {
padding: 2px;
color: #008;
text-decoration: none;
}
#st-wiki-subnav-right {
float: right;
margin-right: 6em;
}
#st-wiki-subnav-left {
float: left;
margin-left: 6em;
}
* html #st-wiki-subnav-left {
margin-left: 3em;
}
/* Wiki Navigation Search Bar */
#st-search-form {
margin: 0;
padding: 0;
padding-top: 1px;
}
#st-search-form .button-table {
float: left;
font-size: 79%;
font-weight: bold;
margin-left: 5px;
margin-top: 1px;
}
#st-search-form #st-search-term {
float: left;
font-size: 60%;
}
/* Content Outline */
#st-content-border, #st-edit-border {
position: relative;
clear: both;
margin-left: 3px;
margin-right: 2px;
margin-bottom: 0px;
margin-top: 0px;
border-bottom: 1px solid #eee;
}
#st-content-border-left, #st-edit-border-left {
background: url('../../images/st/page-shadow/left.gif') left top repeat-y;
position: relative;
}
#st-content-border-right, #st-edit-border-right {
background: url('../../images/st/page-shadow/right.gif') right top repeat-y;
position: relative;
}
#st-content-border-top, #st-edit-border-top {
position: relative;
background: url('../../images/st/page-shadow/top.gif') left top repeat-x;
}
#st-content-border-bottom, #st-edit-border-bottom {
background: url('../../images/st/page-shadow/bottom.gif') left bottom repeat-x;
position: relative;
}
#st-content-border-left-top, #st-edit-border-left-top {
background: url('../../images/st/page-shadow/left-top.gif') left top no-repeat;
position: relative;
}
#st-content-border-right-top, #st-edit-border-right-top {
background: url('../../images/st/page-shadow/right-top.gif') right top no-repeat;
position: relative;
}
#st-content-border-left-bottom, #st-edit-border-left-bottom {
background: url('../../images/st/page-shadow/left-bottom.gif') left bottom no-repeat;
position: relative;
}
#st-content-border-right-bottom, #st-edit-border-right-bottom {
background: url('../../images/st/page-shadow/right-bottom.gif') right bottom no-repeat;
padding-top: 5px;
padding-bottom: 9px;
position: relative;
}
* html #st-content-border-right-bottom, * html #st-edit-border-right-bottom {
padding-top: 4px;
padding-left: 7px;
padding-right: 8px;
position: relative;
}
.st-content-width-controller {
width: 100%;
position: relative;
border-collapse: collapse;
}
.st-content-width-controller td {
vertical-align: top;
}
.st-content {
position: relative;
background-color: white;
margin-top: 0px;
margin-left: 7px;
margin-right: 8px;
margin-bottom: -1px;
border-left: 1px dotted #80a9f3;
border-right: 1px dotted #80a9f3;
border: 1px solid #80a9f3;
padding: 6px 12px 12px 12px;
}
* html .st-content {
margin-top: 0px;
margin-left: 0px;
margin-right: 0px;
}
/* This textarea is only for Safari. However, if we use display:none; here Safari ignores the .value operation in JS */
#st-raw-wikitext-textarea {
width:1px;
height:1px;
margin:0;
padding:0;
}
/* Action Buttons */
.button-table, .button-table tr td {
border-collapse: collapse;
margin: 0;
padding: 0;
}
.button-rounded {
background: url('../../images/st/grey-button/left-top-rounded.png') top left no-repeat;
margin: 0;
}
.button-rounded-right-top {
background: url('../../images/st/grey-button/right-top-rounded.png') top right no-repeat;
margin: 0;
}
.button-rounded-left-bottom {
background: url('../../images/st/grey-button/left-bottom-rounded.png') bottom left no-repeat;
margin: 0;
}
.button-rounded-right-bottom {
background: url('../../images/st/grey-button/right-bottom-rounded.png') bottom right no-repeat;
margin: 0;
}
.button-straight {
background: url('../../images/st/grey-button/left-top-straight.png') top left no-repeat;
margin: 0;
}
.button-straight-right-top {
background: url('../../images/st/grey-button/right-top-straight.png') top right no-repeat;
margin: 0;
}
.button-straight-left-bottom {
background: url('../../images/st/grey-button/left-bottom-straight.png') bottom left no-repeat;
margin: 0;
}
.button-straight-right-bottom {
background: url('../../images/st/grey-button/right-bottom-straight.png') bottom right no-repeat;
margin: 0;
}
.button-content {
font-size: 90%;
}
.button-content a {
display: block;
padding: 2px;
padding-left: 10px;
padding-right: 10px;
font-family: Helvetica, Verdana, sans-serif;
font-weight: bold;
text-decoration: none;
color: black;
}
.button-content input.submit {
border: 0px;
padding: 2px;
padding-left: 10px;
padding-right: 10px;
font-family: Helvetica, Verdana, sans-serif;
font-weight: bold;
text-decoration: none;
color: black;
background-color: transparent;
}
/* Personal Homepage */
#st-homepage {
background: white url('../../images/st/homepage/blue-fade.gif') top left no-repeat;
}
#st-homepage-layout {
margin-top: 15px;
clear: both;
width: 100%;
border-collapse: collapse;
}
#st-homepage-layout tr td.st-homepage-layout-cell {
padding: 5px;
vertical-align: top;
}
#st-homepage-layout-dashboard {
width: 50%
}
#st-homepage-layout-notes {
width: 50%;
}
#st-homepage-notes, #st-homepage-dashboard {
text-align: left;
width: 95%;
}
#st-user-greeting, #st-wiki-title {
font-family: Helvetica, Verdana, sans-serif;
font-size: 150%;
}
#st-wiki-title {
margin-left: 5px;
}
#st-user-greeting {
position: relative;
text-align: right;
float: right;
}
#st-group-notes-content, #st-personal-notes-content {
}
.st-homepage-section {
margin-bottom: 15px;
}
#st-homepage-notes .st-homepage-section {
background-color: white;
border: 1px solid #aaa;
padding: 15px;
}
.st-homepage-section-title {
font-size: 110%;
font-family: Helvetica, Verdana, sans-serif;
}
#st-homepage-notes .st-homepage-section-title {
color: #aaa;
text-decoration: underline;
}
.st-homepage-notes-edit-link {
background: url('../../images/st/homepage/edit-icon.gif') no-repeat left top;
display: block;
text-indent: -2000px;
height: 13px;
width: 36px;
text-decoration: none;
padding:0;
}
* html .st-homepage-notes-edit-link {
border:1px solid white;
}
.st-homepage-notes-edit {
font-family: Verdana, sans-serif;
font-size: 65%;
float: right;
}
.st-homepage-notes-content {
font-size: 85%;
margin-top: 10px;
padding-top: 0px;
padding-bottom: 0px;
font-family: Verdana, Helvetica, sans-serif;
}
#st-dyk {
border-color: #cca !important;
background-color: #ffe !important;
}
#st-dyk-title {
color: #e4a020 !important;
text-decoration: none !important;
}
/* Homepage Simple List */
#st-whats-new-title-link {
background: url('../../images/st/homepage/icon-28-pages.gif') no-repeat left top;
}
#st-watchlist-title-link {
background: url('../../images/st/homepage/icon-28-star.gif') no-repeat left top;
}
#st-wikis-title-link {
background: url('../../images/st/homepage/icon-28-group.gif') no-repeat left top;
}
.st-homepage-simplelist-title-link {
display: block;
padding-left: 32px;
min-height: 32px;
}
* html .st-homepage-simplelist-title-link {
height: 32px;
}
.st-homepage-simplelist-title {
}
.st-homepage-simplelist-table {
margin-left: 25px;
border: 1px dashed #ddd;
border-collapse: collapse;
font-family: Verdana, Helvetica, sans-serif;
font-size: 80%;
width: 95%;
}
.st-homepage-simplelist-table td {
padding: 2px;
}
.st-homepage-simplelist-table tr.st-homepage-simplelist-row-odd {
background-color: #f3f7f7;
}
.st-homepage-simplelist-table tr.st-homepage-simplelist-row-even {
background-color: white;
}
.st-homepage-simplelist-table a {
color: #4f55dd;
text-decoration: none;
}
.st-homepage-simplelist-table a:visited {
color: #551a8b;
}
.st-homepage-simplelist-subleft {
font-size: 80%;
margin-left: 1em;
color: #666;
}
.st-homepage-simplelist-right {
width: 20%;
}
.st-homepage-simplelist-subright {
font-size: 80%;
color: #666;
}
.st-homepage-simplelist {
}
.st-homepage-simplelist-header {
min-height: 35px;
}
.st-homepage-simplelist-header .button-table {
float: right;
margin-right: 15px;
font-size: 95%;
}
.st-homepage-simplelist-header .button-table .button-content {
padding: 1px;
}
.st-homepage-whatsnew-author, .st-homepage-whatsnew-date {
color: #555;
}
.st-homepage-whatsnew-attribution {
padding-left: 1em;
font-size: 80%;
color: #aaa;
}
/* Homepage Wikis List */
#st-wikis-title {
}
/* Data and Templates */
.st-jst-template, .st-json {
display: none;
}
/* Page Sidebox Common Styles */
#st-page-boxes-toggle {
position: relative;
float: right;
text-align: right;
font-family: Verdana, Arial, sans-serif;
font-weight: bold;
font-size: 80%;
margin-bottom: 0.7em;
}
#st-page-boxes-toggle-link {
text-decoration: none;
}
#st-page-boxes-underlay {
float: right;
margin-top: -10px;
margin-right: 10px;
background: white;
z-index: 198;
clear: both;
margin-left: 15px;
}
* html #st-page-boxes-underlay {
margin-right: 4px;
}
#st-page-boxes {
background: inherit;
position: absolute;
right: 23px;
z-index: 199;
margin-top: 15px;
margin-left: 20px;
}
#st-page-boxes, #st-page-boxes-underlay {
width: 225px;
/* padding-left: 15px; */ /* Gives the white border effect, cwest dislikes it. */
}
.st-page-box {
border: 1px solid black;
padding: 5px;
font-family: Verdana, Helvetica, sans-serif;
font-size: 80%;
margin-top: 15px;
}
.st-page-box-title {
font-family: Helvetica, Verdana, sans-serif;
font-weight: bold;
margin-bottom: 10px;
}
.st-page-box-listing {
margin: 0;
padding: 0;
}
.st-page-box-listing-entry {
display: block;
}
.st-page-boxes-nobacklinks {
font-family: Verdana, Helvetica, sans-serif;
font-size: 90%;
color: #888;
}
.st-page-box-first {
margin-top: 0px;
}
/* Page Display */
#st-page-content {
clear: left;
margin-top: 6px;
margin-bottom: 0;
padding-bottom: 0;
}
#st-page-content, #st-page-content td {
font-family: Verdana, Helvetica, sans-serif;
font-size: 90%;
}
#st-page-wiki-title {
font-family: Helvetica, Verdana, sans-serif;
font-size: 65%;
font-weight: bold;
color: #aaa;
margin-bottom: 0.2em;
margin-top: 0.1em;
padding-top: 0;
}
#wiki {
margin: 0;
padding: 0;
}
#st-page-title {
}
#st-page-titletext, .st-page-title {
font-family: Helvetica, Verdana, sans-serif;
font-size: 150%;
font-weight: bold;
color: #888;
border-bottom: 1px solid #888;
}
#st-newpage-pagename-edit {
font-family: inherit;
font-size: inherit;
font-weight: inherit;
color: #000;
border: 1px solid black;
padding-left: 0.3em;
background-color: #ffd;
}
#st-page-details {
font-style: italic;
font-size: 75%;
font-family: Georgia, serif;
margin: 6px 10px 0 10px;
}
#st-page-details-feed-icon {
vertical-align: middle;
border: none;
}
#st-page-stats {
float: right;
vertical-align: middle;
}
#st-attribution {
float: left;
margin-bottom: 10px;
}
#st-page-editing-wysiwyg {
background: #ffd;
border-style: solid;
border-color: #888 #ccc #ccc #888;
border-width: 2px;
width: 100%;
}
#st-page-editing-toolbar {
margin-left: -6px;
overflow: hidden;
float: left;
height: 25px;
}
#wikiwyg_wikitext_textarea {
margin-top: 4px;
background: #ffd;
border-style: solid;
border-color: #888 #ccc #ccc #888;
border-width: 2px;
width: 100%;
font-family: monospace;
}
#st-page-maincontent {
}
#st-page-editing, #wikiwyg_wikitext_textarea {
}
#st-page-editing-pagebody-decoy, #st-page-editing-wysiwyg {
display: none;
}
#st-editing-tools-edit {
display: none;
}
#st-mode-wysiwyg-button
{
font-size: 70%;
margin-left: 4em;
}
#st-mode-wikitext-button
{
font-size: 70%;
}
#st-edit-tips
{
font-size: 70%;
}
.wikiwyg_button {
background: #FFFFFF;
border: 1px solid #FFFFFF;
cursor: pointer;
width: 20px;
height: 20px;
vertical-align: bottom;
}
.wikiwyg_button:hover {
border: 1px outset;
}
.wikiwyg_button:active {
border: 1px inset;
}
#wikiwyg_toolbar {
display: none;
}
/* Sidebox Pagetools: Revisions, Watchlist */
#st-side-box-pagetools {
border-collapse: collapse;
}
#st-rewind-norevisions {
font-family: Helvetica, Arial, sans-serif;
font-size: 11px;
color: #777;
text-decoration: none;
}
#st-side-box-pagetools a {
font-family: Helvetica, Arial, sans-serif;
font-size: 11px;
color: #555;
text-decoration: none;
}
/* Page View Tags/Incoming Links Sidebox */
#st-tags {
background: #f4fff4;
border-color: #bbeebb;
color: #999;
}
#st-tags-title {
color: #595;
}
#st-tags-addlink, #st-tags-addbutton {
font-weight: bold;
}
#st-tags-listing {
margin-bottom: 5px;
}
#st-tags-addinput, #st-tags-message, #st-tags-suggestion {
display: none;
}
#st-tags-deletemessage {
font-size: 90%;
color: #555;
display: none;
margin-top: 0.5em;
margin-bottom: 0.5em;
}
#st-tags-suggestion {
margin-top: 2px;
}
.st-tags-level1 {
font-size: 90%;
}
.st-tags-level2 {
font-size: 100%;
}
.st-tags-level3 {
font-size: 110%;
}
.st-tags-level4 {
font-size: 120%;
}
.st-tags-level5 {
font-size: 130%;
}
.st-tags-tagline .st-tags-tagdelete {
text-decoration: none;
color: #ccc;
}
.st-tags-tagline a {
text-decoration: none;
color: #444;
}
#st-tags-field {
width: 95%;
}
#st-incoming-links {
border-color: #ebb;
background-color: #fff4f4;
}
#st-incoming-links-title {
color: #b78;
}
#st-attachments {
border-color: #bbe;
background-color: #f4f4ff;
}
#st-attachments-uploadbutton, #st-attachments-managebutton {
}
#st-attachments-buttons-uploadbutton {
margin: 0px;
padding: 0px;
padding-left: 2px;
}
#st-attachments-buttons-managebutton {
margin: 0px;
padding: 0px;
padding-right: 2px;
}
#st-attachments-buttons td {
padding-right: 3px;
font-size: 99%;
}
#st-attachments-buttons {
border-collapse: collapse;
margin: 0px;
padding: 0px;
margin-top: 5px;
}
#st-attachments-title {
color: #77b;
}
.st-attachments-line {
width:100%;
overflow:hidden;
}
/* Actions Bar */
#st-actions-bar-spacer {
clear:both;
height:0.5em;
overflow:hidden;
}
#st-actions-bar-spacer-clear {
clear:both;
height:1px;
overflow:hidden;
}
#st-actions-bar, #st-editing-tools-bar {
margin-left: 30px !important;
margin-right: 30px !important;
}
/* Footer */
#st-footer {
margin-top: -8px;
margin-bottom: 5px;
clear: both;
}
/* Socialtext Attribution */
#st-socialtext-attribution {
clear: both;
text-align: center;
font-size: 80%;
font-family: Helvetica, sans-serif;
}
#st-socialtext-attribution-link {
text-decoration: none;
}
#st-socialtext-attribution-image {
border: 0;
}
/* Page Actions */
#st-edit-button-border-left-middle, #st-login-to-edit-button-border-left-middle {
background: url('../../images/st/button-blue/left-middle.gif') left top repeat-y;
}
#st-edit-button-border-right-middle, #st-login-to-edit-button-border-right-middle {
background: url('../../images/st/button-blue/right-middle.gif') right top repeat-y;
}
#st-edit-button-border-left-top, #st-login-to-edit-button-border-left-top {
background: url('../../images/st/button-blue/left-top.gif') left top no-repeat;
}
#st-edit-button-border-right-top, #st-login-to-edit-button-border-right-top {
background: url('../../images/st/button-blue/right-top.gif') right top no-repeat;
}
#st-edit-button-border-left-bottom, #st-login-to-edit-button-border-left-bottom {
background: url('../../images/st/button-blue/left-bottom.gif') left bottom no-repeat;
}
#st-edit-button-border-right-bottom, #st-login-to-edit-button-border-right-bottom {
background: url('../../images/st/button-blue/right-bottom.gif') right bottom no-repeat;
}
#st-edit-button-link, #st-login-to-edit-button-link {
}
#st-comment-button-border-left-middle {
background: url('../../images/st/button-purple/left-middle.gif') left top repeat-y;
}
#st-comment-button-border-right-middle {
background: url('../../images/st/button-purple/right-middle.gif') right top repeat-y;
}
#st-comment-button-border-left-top {
background: url('../../images/st/button-purple/left-top.gif') left top no-repeat;
}
#st-comment-button-border-right-top {
background: url('../../images/st/button-purple/right-top.gif') right top no-repeat;
}
#st-comment-button-border-left-bottom {
background: url('../../images/st/button-purple/left-bottom.gif') left bottom no-repeat;
}
#st-comment-button-border-right-bottom {
background: url('../../images/st/button-purple/right-bottom.gif') right bottom no-repeat;
}
#st-comment-button-link {
}
#st-save-button-border-left-middle {
background: url('../../images/st/button-green/left-middle.gif') left top repeat-y;
}
#st-save-button-border-right-middle {
background: url('../../images/st/button-green/right-middle.gif') right top repeat-y;
}
#st-save-button-border-left-top {
background: url('../../images/st/button-green/left-top.gif') left top no-repeat;
}
#st-save-button-border-right-top {
background: url('../../images/st/button-green/right-top.gif') right top no-repeat;
}
#st-save-button-border-left-bottom {
background: url('../../images/st/button-green/left-bottom.gif') left bottom no-repeat;
}
#st-save-button-border-right-bottom {
background: url('../../images/st/button-green/right-bottom.gif') right bottom no-repeat;
}
#st-save-button-link {
}
#st-preview-button-border-left-middle {
background: url('../../images/st/button-gold/left-middle.gif') left top repeat-y;
}
#st-preview-button-border-right-middle {
background: url('../../images/st/button-gold/right-middle.gif') right top repeat-y;
}
#st-preview-button-border-left-top {
background: url('../../images/st/button-gold/left-top.gif') left top no-repeat;
}
#st-preview-button-border-right-top {
background: url('../../images/st/button-gold/right-top.gif') right top no-repeat;
}
#st-preview-button-border-left-bottom {
background: url('../../images/st/button-gold/left-bottom.gif') left bottom no-repeat;
}
#st-preview-button-border-right-bottom {
background: url('../../images/st/button-gold/right-bottom.gif') right bottom no-repeat;
}
#st-preview-button-link {
}
#st-cancel-button-border-left-middle {
background: url('../../images/st/button-crimson/left-middle.gif') left top repeat-y;
}
#st-cancel-button-border-right-middle {
background: url('../../images/st/button-crimson/right-middle.gif') right top repeat-y;
}
#st-cancel-button-border-left-top {
background: url('../../images/st/button-crimson/left-top.gif') left top no-repeat;
}
#st-cancel-button-border-right-top {
background: url('../../images/st/button-crimson/right-top.gif') right top no-repeat;
}
#st-cancel-button-border-left-bottom {
background: url('../../images/st/button-crimson/left-bottom.gif') left bottom no-repeat;
}
#st-cancel-button-border-right-bottom {
background: url('../../images/st/button-crimson/right-bottom.gif') right bottom no-repeat;
}
#st-cancel-button-link {
}
#st-edit-more-button-border-left-middle {
background: url('../../images/st/button-blue/left-middle.gif') left top repeat-y;
}
#st-edit-more-button-border-right-middle {
background: url('../../images/st/button-blue/right-middle.gif') right top repeat-y;
}
#st-edit-more-button-border-left-top {
background: url('../../images/st/button-blue/left-top.gif') left top no-repeat;
}
#st-edit-more-button-border-right-top {
background: url('../../images/st/button-blue/right-top.gif') right top no-repeat;
}
#st-edit-more-button-border-left-bottom {
background: url('../../images/st/button-blue/left-bottom.gif') left bottom no-repeat;
}
#st-edit-more-button-border-right-bottom {
background: url('../../images/st/button-blue/right-bottom.gif') right bottom no-repeat;
}
#st-edit-more-button-link {
}
.st-page-action-button-link {
min-height: 24px;
min-width: 100px;
text-align: center;
font-family: Helvetica, Verdana, sans-serif;
font-size: 90%;
text-decoration: none;
color: #fff;
font-weight: bold;
display: block;
padding-top: 8px;
padding-bottom: 0px;
margin-bottom: -3px;
width: 100%;
margin-left: -2px;
}
* html .st-page-action-button-link {
padding-top: 5px;
padding-bottom: 0px;
height: 24px;
}
.st-page-action-button {
float: left;
margin: 0;
padding: 0;
margin-right: 10px;
min-height: 20px;
border-collapse: collapse;
width: 100px;
}
/* Attach File Interface */
#st-attachments-attachinterface {
font-family: Helvetica, sans-serif;
font-size: 90%;
display: none;
position: fixed;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
z-index: 2000;
background-image: url('../../images/st/popup/bg.png');
}
#st-attachments-manageinterface {
font-family: Helvetica, sans-serif;
font-size: 90%;
display: none;
position: absolute;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
z-index: 2000;
background-image: url('../../images/st/popup/bg.png');
}
* html #st-attachments-attachinterface {
background-image: none;
}
* html #st-attachments-manageinterface {
background-image: none;
}
* html .popup-overlay {
background-image: url('../../images/st/popup/bg.png');
background-color: #000;
opacity: .70;
position: absolute;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
z-index: 2001;
}
#st-attachments-attach-interface {
z-index: 2002;
background-color: #fff;
color: #000;
border: 4px solid #ccc;
padding: 1em;
width: 520px;
margin-left: auto;
margin-right: auto;
margin-top: 10%;
position: absolute;
top: 0px;
}
* html #st-attachments-attach-interface {
}
#st-attachments-attach-formtarget {
width: 0px;
height: 0px;
border: 0;
padding: 0;
margin: 0;
}
#st-attachments-attach-message {
font-size: 90%;
font-family: Verdana, Arial, Helvetica, Sans-Serif;
}
#st-attachments-attach-title {
font-weight: bold;
font-size: 120%;
}
#st-attachments-attach-close {
float: right;
margin-top: 6px;
}
#st-attachments-attach-uploadbutton {
float: right;
margin-right: 6px;
margin-top: 6px;
padding-bottom: 0;
}
#st-attachments-attach-fileprompt {
margin: 0.2em 0 0.4em 0;
padding-bottom: 0px;
}
#st-attachments-attach-submit {
font-size: 90%;
font-weight: bold;
}
#st-attachments-attach-filename {
font-size: 90%;
}
#st-attachments-attach-uploadmessage {
font-weight: bold;
margin-bottom: 1em;
display: none;
}
#st-attachments-attach-error {
font-weight: bold;
color: #f00;
margin-bottom: 1em;
display: none;
}
#st-attachments-attach-list {
display: none;
color: #666;
font-size: 90%;
margin-top: 1em;
margin-bottom: 1em;
border-top: 1px solid #4949BA;
border-bottom: 1px solid #4949BA;
background-color: #F5F5F5;
padding: 3px;
}
.st-attachments-attach-listlabel {
font-size: 90%;
color: #4949BA;
}
/* Queue File Dialog */
#st-attachmentsqueue-interface {
font-family: Helvetica, sans-serif;
font-size: 90%;
display: none;
position: fixed;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
background-image: url('../../images/st/popup/bg.png'); /* Don't forget IE hack for ship! */
z-index: 2000;
}
* html #st-attachmentsqueue-interface {
background-image: none;
}
#st-attachmentsqueue-dialog {
z-index: 2002;
background-color: #fff;
color: #000;
border: 4px solid #ccc;
padding: 1em;
width: 530px;
margin-left: auto;
margin-right: auto;
margin-top: 10%;
position: absolute;
top: 0px;
}
* html #st-attachmentsqueue-dialog {
}
#st-attachmentsqueue-fileprompt {
margin-bottom: 0.4em;
margin-top: 0;
padding-bottom: 0;
}
#st-attachmentsqueue-title {
font-weight: bold;
font-size: 120%;
}
#st-attachmentsqueue-close {
float: right;
margin-top: 6px;
}
#st-attachmentsqueue-uploadbutton {
float: right;
margin-right: 6px;
margin-top: 6px;
padding-bottom: 0;
}
#st-attachmentsqueue-submit {
font-size: 90%;
}
#st-attachmentsqueue-filename {
font-size: 90%;
}
#st-attachmentsqueue-message {
font-size: 90%;
font-family: Verdana, Arial, Helvetica, Sans-Serif;
}
#st-attachmentsqueue-uploadmessage {
font-weight: bold;
margin-bottom: 1em;
display: none;
}
#st-attachmentsqueue-error {
font-weight: bold;
color: #f00;
margin-bottom: 1em;
display: none;
}
#st-attachmentsqueue-list {
display: none;
color: #666;
font-size: 90%;
margin-top: 1em;
margin-bottom: 1em;
border-top: 1px solid #4949BA;
border-bottom: 1px solid #4949BA;
background-color: #F5F5F5;
padding: 3px;
}
.st-attachmentsqueue-listlabel {
font-size: 90%;
color: #4949BA;
}
/* Lists */
tr.st-trbg-even, tr.st-trbg-even td{
background-color: #f3f7f7;
}
tr.w-st-even-row, tr.w-st-even-row td {
background-color: #f3f7f7;
}
.query-results-header-title, .query-results-header-last-edit-by {
text-align: left;
}
.query-results-row-revisions {
text-align: right;
}
.query-results-content {
font-size: 85%;
border-collapse: collapse;
border: 1px dashed #ddd;
border-left: 1px solid #ddd;
border-right: 1px solid #ddd;
}
.query-results-row {
border-collapse: collapse;
border: 1px dashed #ddd;
border-left: 1px solid #ddd;
border-right: 1px solid #ddd;
}
.query-results-row a {
text-decoration: underline;
color: #00f;
}
.query-results-row td {
font-family: Verdana;
padding: 0.3em;
border-left: 1px dashed #ddd;
border-right: 1px dashed #ddd;
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
}
.query-results-header-row {
border-collapse: collapse;
border: 1px dashed #ddd;
border-left: 1px solid #ddd;
border-right: 1px solid #ddd;
}
.query-results-header-row a {
text-decoration: underline;
color: #00f;
}
.query-results-header-row th {
font-family: Helvetica;
padding: 0.3em;
border-left: 1px dashed #ddd;
border-right: 1px dashed #ddd;
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
}
div.st-actionbutton {
float: left;
}
div#deleteme-st-actions-bar {
clear: both;
margin: 0.8em 20px 0.2em auto;
padding: 0;
}
/* Manage File Interface */
#st-attachments-manage-interface {
z-index: 2002;
background-color: #fff;
color: #000;
border: 4px solid #ccc;
padding: 1em;
width: 520px;
margin-left: auto;
margin-right: auto;
margin-top: 10%;
position: absolute;
top: 0px;
}
#st-attachments-manage-filetable {
height: 150px;
margin: 0;
padding: 0;
width: 100%;
overflow: auto;
border: 1px solid #ccc;
}
#st-attachments-manage-filelisting tbody td {
font-size: 90%;
}
#st-attachments-manage-filelisting {
width: 100%;
border-collapse: collapse;
border: 0;
margin: 0;
padding: 0;
}
#st-attachments-manage-fileheader {
background: #ccc;
font-weight: bold;
border-bottom: 1px black solid;
}
#st-attachments-manage-close {
float: right;
margin-top: 3px;
margin-right: -2px;
font-weight: bold;
}
#st-attachments-manage-delete {
margin-top: 3px;
float: left;
font-weight: bold;
}
.st-attachments-manage-filerow {
border-bottom: 1px solid #ccc;
}
.row-odd {
background-color: #eee;
}
.row-even {
background-color: #fff;
}
.row-on {
background-color: #009 !important;
color: white !important;
}
.row-on a {
color: #fff !important;
}
#st-attachments-manage-deletemessage {
color: red;
}
/* Page tools icons */
#st-pagetools-print {
background: url('../../images/st/pagetools/print.gif')
left center no-repeat;
}
#st-pagetools-email {
background: url('../../images/st/pagetools/email.gif')
left center no-repeat;
}
#st-pagetools-tools {
background: url('../../images/st/pagetools/tools.gif')
left center no-repeat;
}
/*
#st-pagetools-watch {
background: url('../../images/st/pagetools/watch-blue.gif')
left center no-repeat;
}
*/
/* *********** Settings *********** */
#st-settings-pane {
}
* html #settings-pane { font-size: 85%;}
.settings-start-table {
}
* html .settings-start-table { font-size: 90%;}
#st-settings-select {
padding: 0px 10px 10px 10px;
vertical-align: top;
width: 1px;
background-color: #eff1ec;
border: none;
}
#st-settings-section {
padding: 0px 10px 10px 10px;
vertical-align: top;
}
.settings-top-header {
margin-top: 1em;
font-weight: bold;
width: 15em;
}
.settings-header {
margin-top: 1em;
font-weight: bold;
}
.settings-selections {
padding: 0px 0px 0px 20px;
line-height: 1.5em;
}
.settings-selections a:visited, .settings-selections a:active {
color: #0000ff;
}
.settings-link {
clear: both;
display: block;
}
.settings-section-left {
text-align: right;
}
.settings-label {
font-weight: bold;
}
.settings-help {
color: #888;
}
.settings-comment {
}
.users-invite-message {
padding: 0.5em 0.5em 0.5em 2em;
background-color: #eee;
/* This seems necessary to fix an IE bug that sometimes
causes the text in this div to be invisible */
z-index: 1000;
}
.workspace-entry-header {
margin-top: .5em;
font-weight: bold;
}
.workspace-entry {
margin-left: 3em;
}
.workspace-entry-p {
margin-top: .5em;
margin-bottom: .75em;
}
.workspace-subentry {
font-style: italic;
font-weight: bold;
margin-left: 1.5em;
}
.preferences-td {
padding:.5em 0 1.5em 0;
}
.preferences-query {
text-align: left;
}
.preference-radio {
background-color: #cec;
}
.user-settings-listall-headings td {
background-color: #eff3ef;
}
#st-settings-save {
padding-bottom: 0.5em;
}
.standard-button-cancel {
font-weight: bold;
background-color: #71004b;
border-left: 1px solid #aaa;
border-top: 1px solid #aaa;
border-bottom: 2px solid #333;
border-right: 2px solid #333;
color: #f4f3b9;
width: 8em;
}
.standard-button-submit {
font-weight: bold;
background-color: #656084;
border-left: 1px solid #aaa;
border-top: 1px solid #aaa;
border-bottom: 2px solid #333;
border-right: 2px solid #333;
color: #f4f3b9;
width: 8em;
}
#st-settings {
font-family: Verdana, Arial, Helvetica, Sans-Serif;
font-size: 90%;
}
/* Listview Tabs */
#st-listview a:visited {
color: #551a8b;
}
#st-listview-tabs ul {
display: block;
list-style: none outside;
margin: 0 0 0 4em;
padding: 0;
font-family: Helvetica, Arial, Sans-serif;
font-size: 80%;
}
#st-listview-tabs li {
display: block;
float: left;
margin: 0 0.8em 0 0;
padding: 3px 0.6em 0 0.6em;
border: 1px solid #d8d8d8;
border-bottom: 1px solid rgb(128, 169, 243);
background-color: #f4f4f4;
position: relative;
bottom: -2px;
}
#st-listview-tabs li.spacer {
margin: 0 0.8em 0 2em;
}
#st-listview-tabs a {
color: #bbb;
text-decoration: none;
}
#st-listview-tabs li.selected {
background-color: #fff !important;
border: 1px solid rgb(128, 169, 243) !important;
border-bottom: 1px solid #fff !important;
font-weight: bold !important;
}
#st-listview-tabs li.selected a {
color: #000 !important;
}
/* Category List Display */
#st-category-display-links {
margin-bottom: 1em;
font-size: 90%;
}
#st-tag-listbody {
font-family: Helvetica, Verdana, sans-serif;
}
/* Attachments List Display */
#st-attachments-list-body table.button-table {
margin-top: 0.1em;
font-size: 80%;
}
/* ********** PageTools Menu ************** */
div#st-editing-tools {
float: left;
}
div#st-pagetools {
z-index: 300;
font-family: Helvetica, Verdana, sans-serif;
font-size: 10px;
float: right;
margin: 18px 0 0 0em;
color: #000;
vertical-align: bottom;
position: relative;
}
#st-pagetools a {
text-decoration: none;
color: black;
padding-left: 17px;
}
#st-pagetools span {
color: inherit;
padding-left: 17px;
vertical-align: top;
}
#st-pagetools span.st-watchlist-link {
color: inherit;
vertical-align: top;
}
.st-watchlist-link {
cursor: pointer;
}
div#st-pagetools ul.level2 {
z-index: 300;
margin: 0;
padding: 0;
background: white;
border: 1px solid #CCC;
border-width: 0 1px;
}
div#st-pagetools li {
position: relative;
list-style: none;
margin: 0;
float: left;
width: 7em;
line-height: 11px;
}
div#st-pagetools ul ul li:hover {
background: #BFE2FF;
}
div#st-pagetools li a {
display: block;
text-decoration: none;
}
div#st-pagetools>ul a {
width: auto;
}
div#st-pagetools ul ul {
position: absolute;
width: auto;
display: none;
}
div#st-pagetools ul ul li {
line-height: 1.5em;
/* width: 100%; */
width: 14em;
}
.first {
border-top: 1px solid #CCC;
}
.separator {
border-bottom: 1px solid #CCC;
}
div#st-pagetools ul ul li a {
border-bottom: 1px solid #CCC;
padding-left: 15px;
padding-right: 3px;
margin-right: 3px;
border: 0px;
}
div#st-pagetools li.submenu li.submenu:hover {
z-index: 300;
background-color: #BFE2FF;
}
div#st-pagetools ul.level1 li.submenu:hover ul.level2 {
display:block;
}
div#st-pagetools ul.level2 {
top: 1.0em;
left: -9.5em;
}
/*
=head2 Revision List Display
Change these styles to update the page revision list.
*/
#st-revision-list-table {
border-collapse: collapse;
font-size: 85%;
color: #000;
}
.st-page-title-decorator {
color: #C80000;
}
.st-revision-header-emphasis {
color: #C80000;
}
.st-revision-list-compare-button-row {
}
.st-revision-list-compare-button-cell {
padding-top: 0.3em;
text-align: center;
}
.st-revision-list-compare-button {
}
#st-revision-list-header-row {
}
#st-revision-list-header-select {
padding: 6px 2px 2px 2px;
text-align: center;
}
#st-revision-list-header-revision {
padding: 6px 2px 2px 2px;
text-align: left;
}
#st-revision-list-header-edited-by {
padding: 6px 2px 2px 2px;
text-align: center;
}
#st-revision-list-header-date {
padding: 6px 2px 2px 2px;
text-align: center;
}
.st-revision-list-row {
border-collapse: collapse;
border: 1px dashed #ddd;
border-left: 1px solid #ddd;
border-right: 1px solid #ddd;
}
.st-revision-list-row td {
font-family: Verdana;
padding: 0.3em;
border-left: 1px dashed #ddd;
border-right: 1px dashed #ddd;
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
}
.st-revision-list-row-select {
padding: 3px 0 2px 0;
text-align: center;
}
.st-revision-list-row-select-old {
}
.st-revision-list-row-select-new {
}
.st-revision-list-row-revision {
}
.st-revision-list-row-revision-link {
}
.st-revision-list-row-edited-by {
}
.st-revision-list-row-date {
}
/* Revision Menu */
#st-pagetools.st-revision-view-bar {
float: left;
}
ul.st-revision-menu {
list-style: none;
margin: 0;
padding: 0.2em;
font-size: 80%;
}
ul.st-revision-menu li {
float: left;
padding: 0 0.4em 0 0.4em;
border-right: thin solid #000000;
}
ul.st-revision-menu li.st-last {
border-right: none;
}
#st-restore-revision-button {
font-size: 80%;
}
/*
=head2 Revision Compare Display
When comparing two revisions of a page, these styles apply.
*/
#st-revision-compare-table {
background-color: #f0f0f0;
}
#st-revision-compare-table td {
background-color: white;
}
.st-revision-compare-old {
background-color: #fdd;
text-decoration: line-through;
}
.st-revision-compare-new {
background-color: #dfd;
font-weight: bold;
}
/* Weblog View */
#st-weblog {
padding: 0;
}
#st-content-weblog-display-width-controller {
}
#st-content-weblog-display-width-controller-nav {
width: 230px;
margin-left: 15px;
border-left: 5px solid #ddd;
margin-top: -1px;
}
#st-weblog-content {
font-family: Verdana, Helvetica, sans-serif;
margin-top: -1px;
margin-bottom: -1px;
border-top: 1px solid #80a9f3;
border-bottom: 1px solid #80a9f3;
}
#st-weblog-title {
font-family: 'Trebuchet MS', Verdana, Helvetica, sans-serif;
font-family: 'Times New Roman', serif;
background-color: #80a9f3;
color: #fff;
font-size: 150%;
font-weight: bold;
padding: 0.2em;
padding-left: 1em;
}
#st-weblog-wikititle {
font-family: Helvetica, Verdana, sans-serif;
font-style: italic;
font-size: 40%;
color: #fff;
margin-bottom: 0.2em;
margin-top: 0.1em;
padding-top: 0;
}
#st-weblog-titletext {
font-family: Helvetica, Verdana, sans-serif;
font-weight: bold;
color: #fff;
}
div.st-weblog-entry {
margin-top: 0.2em;
margin-bottom: 4.8em;
padding: 0 1.5em 0 1.5em;
}
.st-page-title {
clear: both;
}
div.st-weblog-entrytitle span.text {
font-family: Helvetica, Verdana, sans-serif;
font-size: 150%;
font-weight: bold;
color: #000;
}
.st-weblog-entrycontent {
font-family: Verdana, Helvetica, sans-serif;
font-size: 90%;
border-bottom: 1px solid #888;
}
.st-weblog-byline {
float: left;
text-align: left;
font-style: italic;
font-size: 70%;
font-family: Verdana, Helvetica, sans-serif;
}
.st-weblog-post-links {
float: right;
text-align: right;
font-size: 70%;
font-family: Verdana, Helvetica, sans-serif;
}
#st-weblog-archives, #st-weblog-navigation {
position: relative;
float: right;
width: 230px;
}
#st-weblog-archives {
margin-top: 15px;
clear: right;
}
#st-weblog-archives-title, #st-weblog-navigation-title {
margin-left: 15px;
font-family: Helvetica, sans-serif;
font-size: 95%;
font-weight: bold;
color: #999;
border-bottom: 2px solid #f99;
padding-bottom: 5px;
padding-top: 5px;
margin-bottom: 5px;
}
#st-weblog-navigation-content {
margin-left: 15px;
font-size: 80%;
}
#st-weblog-archives ul {
margin: 0;
padding: 0;
}
#st-weblog-archives ul li {
/* list-type: none; */
display: block;
font-size: 80%;
font-family: Helvetica, sans-serif;
padding-left: 15px;
}
#st-weblog-newpost {
padding: 0.5em 0.7em 0.3em 0.3em;
}
#st-weblog-newpost-button {
}
#st-weblog-actionbar-chooseweblog {
float: right;
}
#st-weblog-postbyemail {
font-size: 70%;
font-family: Verdana, Helvetica, sans-serif;
color: #def;
padding-top: 0.4em;
}
#st-weblog-postbyemail-link {
color: #00c;
}
.st-weblog-chooseprompt {
font-size: 90%;
font-family: Verdana, Helvetica, sans-serif;
padding-right: 0.2em;
color: #000;
}
.st-spacer {
padding-right: 0.1em;
padding-left: 0.1em;
}
.st-weblog-preventries {
padding-bottom: 20px;
clear: both;
}
.st-weblog-nextentries {
clear: both;
}
div.st-weblog-entrynav {
margin-top: 0.2em;
margin-bottom: 1.8em;
padding: 0;
}
span.st-weblog-previousentries, span.st-weblog-nextentries {
font-size: 90%;
font-family: Verdana, Helvetica, sans-serif;
padding-left: 1em;
}
/* ******* Page Stats ******** */
#st-usagereport-navbar {
font-size: 80%;
padding: 0;
margin: 0;
}
#st-usagereport-date {
font-weight: bold;
margin-top: 1em;
}
#st-page-usagereport h1 {
font-size: 1.3em;
font-weight: bold;
margin-top: 1.2em;
margin-bottom: 0.3em;
}
#st-page-usagereport h2 {
font-size: 1.1em;
font-weight: bold;
margin-top: 0.8em;
margin-bottom: 0.3em;
}
/* New Page */
#st-newpage-save, #st-newpage-duplicate {
display: none;
position: fixed;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
background: url('../../images/st/popup/bg.png'); /* Don't forget IE hack for ship! */
z-index: 2000;
}
#st-newpage-save-interface {
background-color: #fff;
color: #000;
border: 4px solid #ccc;
padding: 0.5em;
width: 450px;
margin-left: auto;
margin-right: auto;
margin-top: 10%;
position:absolute;
top:0px;
z-index:2003;
}
#st-newpage-duplicate-interface {
background-color: #fff;
color: #000;
border: 4px solid #ccc;
padding: 0.5em;
width: 530px;
margin-left: auto;
margin-right: auto;
margin-top: 10%;
position:absolute;
top:0px;
z-index:2003;
}
#st-newpage-save-title, #st-newpage-duplicate-title {
margin: 0;
padding: 0;
font-weight: bold;
font-family: Helvetica, sans-serif;
font-size: 100%;
}
#st-newpage-save-prompt, #st-newpage-duplicate-prompt {
font-family: Helvetica, sans-serif;
font-size: 90%;
margin-bottom: 0.4em;
}
#st-newpage-save-buttons, #st-newpage-duplicate-buttons {
margin-top: 0.8em;
text-align: right;
}
.st-newpage-duplicate-option {
font-family: Helvetica, sans-serif;
font-size: 90%;
margin: 0;
padding: 0;
}
#st-newpage-duplicate-pagename {
font-size: 90%;
}
.st-newpage-duplicate-emphasis {
background-color: #FFFF00;
font-weight: bold;
}
#st-newpage-save-field-pagename {
margin-bottom: 0;
margin-top: 0.2em;
padding-bottom: 0;
font-size: 90%;
}
#st-newpage-save-tip {
margin-bottom: 0;
margin-top: 1.2em;
padding-bottom: 0;
font-size: 75%;
color: #888;
}
/* Wikitext Styling */
.wiki {
}
.wiki hr {
margin-top: .4em;
margin-bottom: .4em;
}
.wiki .short-rule {
width: 25%;
}
.wiki .medium-rule {
width: 50%
}
.wiki ul,
.wiki ol,
.wiki blockquote {
margin-left: 2em;
padding-left: 0em;
}
.wiki table {
border-collapse: collapse;
}
.wiki td {
border: 1px;
border-style: solid;
padding: .2em;
vertical-align: top;
}
.wiki h1,
.wiki h2,
.wiki h3,
.wiki h4,
.wiki h5,
.wiki h6 {
font-weight: bold;
font-style: normal;
margin-top: 0.1em;
margin-bottom: 8px;
}
.wiki h1 {font-size: 200%;}
.wiki h2 {font-size: 170%;}
.wiki h3 {font-size: 145%;}
.wiki h4 {font-size: 125%;}
.wiki h5 {font-size: 110%;}
.wiki h6 {font-size: 100%;}
.wiki pre {
background-color: #eee; /* XXX */
margin-left: 1em;
margin-right: 1em;
padding: .2em;
}
.wiki .incipient {
text-decoration: none;
border-bottom: 1px dashed;
}
.wiki-include-title {
background-color: #ccccff;
}
.wiki .wiki {
position: relative;
background-color: #ddddff;
border: 1px solid #ccccff;
padding: 3px;
}
.wafl_existence_error {
color: rgb(200,0,0);
border-bottom: 0.2em dashed rgb(200,0,0);
}
#st-edit-mode-container {
}
#st-edit-mode-view {
}
#st-page-editing-uploadbutton {
z-index: 1500;
float: left;
}
/* Comment UI */
body#st-commentui {
background: #ffffff;
}
#st-commentui-container {
}
#st-commentui-container a:visited,
#st-commentui-container a:active {
color: #00f;
}
#st-commentui-notetop {
}
#st-commentui-controls {
}
#st-commentui-savelink {
background-color: #fffebd;
}
#st-commentui-cancellink {
}
#st-commentui-customfield {
}
#st-commentui-customfield .customfield-label {
}
#st-commentui-customfield .customfield-input {
}
#st-commentui-textarea {
padding: 0;
border-style: inset;
border-width: thin;
background-color: #ffd;
color: black;
width: 99%;
height: 150px;
}
/*
=head2 Send Page by Email
Styles for the 'Send Page by Email' popup, accessed from the 'Email' dropdown
menu on the page bar.
*/
#email-page {
background: #ffffff;
font-size: 80%;
}
.email-page-row {
clear: both;
}
.email-page-row-label {
font-weight: bold;
float: left;
width: 5em;
margin-left: 1.2em;
margin-right: 1.2em;
text-align: right;
}
.email-page-row-content {
float: left;
padding-bottom: 1.2em;
}
.email-page-user-select-column {
float: left;
padding-right: 1.2em;
width: 14em;
}
#email-page-user-select-column-center {
width: 10em;
}
.email-page-user-select-label {
text-align: center;
}
#email-page-user-select-add-label {
padding-top: 1em;
}
.email-page-user-select-button-group {
padding-bottom: 2em;
}
.email-page-input {
width: 120px;
clear: both;
display: block;
}
.email-page-select {
width: 175px;
font-size: x-small;
}
#email-page-error-message {
text-align: center;
}
#email-page-buttons-container {
clear: both;
}
#email-page-buttons {
text-align: center;
}
.email-page-input-new {
width: 175px;
}
/* System Status, Red with icon */
#st-system-status-alert {
clear: both;
width: 50%;
margin-left: 25%;
margin-top: 10px;
padding: 5px;
color: #c00;
font-weight: bold;
font-size: 80%;
background: transparent url('../../images/st/system-message/important-note.gif') no-repeat 5px center;
padding-left: 60px;
min-height: 38px;
}
* html #st-system-status-alert {
height: 38px;
}
/* System Status, Green */
#st-system-status {
clear: both;
text-align:center;
width: 80%;
margin-left: 10%;
padding: 8px 0 3px 0;
color: #0a0;
font-family: Arial, Helvetica, sans-serif;
font-size: 80%;
}
.socialtextLogo {
text-align: center;
}
/*}}}*/
/***
|''Name:''|SparklinePlugin|
|''Description:''|Sparklines macro|
***/
//{{{
if(!version.extensions.SparklinePlugin) {
version.extensions.SparklinePlugin = {installed:true};
//--
//-- Sparklines
//--
config.macros.sparkline = {};
config.macros.sparkline.handler = function(place,macroName,params)
{
var data = [];
var min = 0;
var max = 0;
var v;
for(var t=0; t<params.length; t++) {
v = parseInt(params[t]);
if(v < min)
min = v;
if(v > max)
max = v;
data.push(v);
}
if(data.length < 1)
return;
var box = createTiddlyElement(place,"span",null,"sparkline",String.fromCharCode(160));
box.title = data.join(",");
var w = box.offsetWidth;
var h = box.offsetHeight;
box.style.paddingRight = (data.length * 2 - w) + "px";
box.style.position = "relative";
for(var d=0; d<data.length; d++) {
var tick = document.createElement("img");
tick.border = 0;
tick.className = "sparktick";
tick.style.position = "absolute";
tick.src = "data:image/gif,GIF89a%01%00%01%00%91%FF%00%FF%FF%FF%00%00%00%C0%C0%C0%00%00%00!%F9%04%01%00%00%02%00%2C%00%00%00%00%01%00%01%00%40%02%02T%01%00%3B";
tick.style.left = d*2 + "px";
tick.style.width = "2px";
v = Math.floor(((data[d] - min)/(max-min)) * h);
tick.style.top = (h-v) + "px";
tick.style.height = v + "px";
box.appendChild(tick);
}
};
}
//}}}
/***
|''Name:''|CryptoFunctionsPlugin|
|''Description:''|Support for cryptographic functions|
***/
//{{{
if(!version.extensions.CryptoFunctionsPlugin) {
version.extensions.CryptoFunctionsPlugin = {installed:true};
//--
//-- Crypto functions and associated conversion routines
//--
// Crypto "namespace"
function Crypto() {}
// Convert a string to an array of big-endian 32-bit words
Crypto.strToBe32s = function(str)
{
var be = Array();
var len = Math.floor(str.length/4);
var i, j;
for(i=0, j=0; i<len; i++, j+=4) {
be[i] = ((str.charCodeAt(j)&0xff) << 24)|((str.charCodeAt(j+1)&0xff) << 16)|((str.charCodeAt(j+2)&0xff) << 8)|(str.charCodeAt(j+3)&0xff);
}
while (j<str.length) {
be[j>>2] |= (str.charCodeAt(j)&0xff)<<(24-(j*8)%32);
j++;
}
return be;
};
// Convert an array of big-endian 32-bit words to a string
Crypto.be32sToStr = function(be)
{
var str = "";
for(var i=0;i<be.length*32;i+=8)
str += String.fromCharCode((be[i>>5]>>>(24-i%32)) & 0xff);
return str;
};
// Convert an array of big-endian 32-bit words to a hex string
Crypto.be32sToHex = function(be)
{
var hex = "0123456789ABCDEF";
var str = "";
for(var i=0;i<be.length*4;i++)
str += hex.charAt((be[i>>2]>>((3-i%4)*8+4))&0xF) + hex.charAt((be[i>>2]>>((3-i%4)*8))&0xF);
return str;
};
// Return, in hex, the SHA-1 hash of a string
Crypto.hexSha1Str = function(str)
{
return Crypto.be32sToHex(Crypto.sha1Str(str));
};
// Return the SHA-1 hash of a string
Crypto.sha1Str = function(str)
{
return Crypto.sha1(Crypto.strToBe32s(str),str.length);
};
// Calculate the SHA-1 hash of an array of blen bytes of big-endian 32-bit words
Crypto.sha1 = function(x,blen)
{
// Add 32-bit integers, wrapping at 32 bits
add32 = function(a,b)
{
var lsw = (a&0xFFFF)+(b&0xFFFF);
var msw = (a>>16)+(b>>16)+(lsw>>16);
return (msw<<16)|(lsw&0xFFFF);
};
// Add five 32-bit integers, wrapping at 32 bits
add32x5 = function(a,b,c,d,e)
{
var lsw = (a&0xFFFF)+(b&0xFFFF)+(c&0xFFFF)+(d&0xFFFF)+(e&0xFFFF);
var msw = (a>>16)+(b>>16)+(c>>16)+(d>>16)+(e>>16)+(lsw>>16);
return (msw<<16)|(lsw&0xFFFF);
};
// Bitwise rotate left a 32-bit integer by 1 bit
rol32 = function(n)
{
return (n>>>31)|(n<<1);
};
var len = blen*8;
// Append padding so length in bits is 448 mod 512
x[len>>5] |= 0x80 << (24-len%32);
// Append length
x[((len+64>>9)<<4)+15] = len;
var w = Array(80);
var k1 = 0x5A827999;
var k2 = 0x6ED9EBA1;
var k3 = 0x8F1BBCDC;
var k4 = 0xCA62C1D6;
var h0 = 0x67452301;
var h1 = 0xEFCDAB89;
var h2 = 0x98BADCFE;
var h3 = 0x10325476;
var h4 = 0xC3D2E1F0;
for(var i=0;i<x.length;i+=16) {
var j,t;
var a = h0;
var b = h1;
var c = h2;
var d = h3;
var e = h4;
for(j = 0;j<16;j++) {
w[j] = x[i+j];
t = add32x5(e,(a>>>27)|(a<<5),d^(b&(c^d)),w[j],k1);
e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
}
for(j=16;j<20;j++) {
w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
t = add32x5(e,(a>>>27)|(a<<5),d^(b&(c^d)),w[j],k1);
e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
}
for(j=20;j<40;j++) {
w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
t = add32x5(e,(a>>>27)|(a<<5),b^c^d,w[j],k2);
e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
}
for(j=40;j<60;j++) {
w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
t = add32x5(e,(a>>>27)|(a<<5),(b&c)|(d&(b|c)),w[j],k3);
e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
}
for(j=60;j<80;j++) {
w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
t = add32x5(e,(a>>>27)|(a<<5),b^c^d,w[j],k4);
e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
}
h0 = add32(h0,a);
h1 = add32(h1,b);
h2 = add32(h2,c);
h3 = add32(h3,d);
h4 = add32(h4,e);
}
return Array(h0,h1,h2,h3,h4);
};
}
//}}}
/***
|''Name:''|DeprecatedFunctionsPlugin|
|''Description:''|Support for deprecated functions removed from core|
***/
//{{{
if(!version.extensions.DeprecatedFunctionsPlugin) {
version.extensions.DeprecatedFunctionsPlugin = {installed:true};
//--
//-- Deprecated code
//--
// @Deprecated: Use createElementAndWikify and this.termRegExp instead
config.formatterHelpers.charFormatHelper = function(w)
{
w.subWikify(createTiddlyElement(w.output,this.element),this.terminator);
};
// @Deprecated: Use enclosedTextHelper and this.lookaheadRegExp instead
config.formatterHelpers.monospacedByLineHelper = function(w)
{
var lookaheadRegExp = new RegExp(this.lookahead,"mg");
lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var text = lookaheadMatch[1];
if(config.browser.isIE)
text = text.replace(/\n/g,"\r");
createTiddlyElement(w.output,"pre",null,null,text);
w.nextMatch = lookaheadRegExp.lastIndex;
}
};
// @Deprecated: Use <br> or <br /> instead of <<br>>
config.macros.br = {};
config.macros.br.handler = function(place)
{
createTiddlyElement(place,"br");
};
// Find an entry in an array. Returns the array index or null
// @Deprecated: Use indexOf instead
Array.prototype.find = function(item)
{
var i = this.indexOf(item);
return i == -1 ? null : i;
};
// Load a tiddler from an HTML DIV. The caller should make sure to later call Tiddler.changed()
// @Deprecated: Use store.getLoader().internalizeTiddler instead
Tiddler.prototype.loadFromDiv = function(divRef,title)
{
return store.getLoader().internalizeTiddler(store,this,title,divRef);
};
// Format the text for storage in an HTML DIV
// @Deprecated Use store.getSaver().externalizeTiddler instead.
Tiddler.prototype.saveToDiv = function()
{
return store.getSaver().externalizeTiddler(store,this);
};
// @Deprecated: Use store.allTiddlersAsHtml() instead
function allTiddlersAsHtml()
{
return store.allTiddlersAsHtml();
}
// @Deprecated: Use refreshPageTemplate instead
function applyPageTemplate(title)
{
refreshPageTemplate(title);
}
// @Deprecated: Use story.displayTiddlers instead
function displayTiddlers(srcElement,titles,template,unused1,unused2,animate,unused3)
{
story.displayTiddlers(srcElement,titles,template,animate);
}
// @Deprecated: Use story.displayTiddler instead
function displayTiddler(srcElement,title,template,unused1,unused2,animate,unused3)
{
story.displayTiddler(srcElement,title,template,animate);
}
// @Deprecated: Use functions on right hand side directly instead
var createTiddlerPopup = Popup.create;
var scrollToTiddlerPopup = Popup.show;
var hideTiddlerPopup = Popup.remove;
// @Deprecated: Use right hand side directly instead
var regexpBackSlashEn = new RegExp("\\\\n","mg");
var regexpBackSlash = new RegExp("\\\\","mg");
var regexpBackSlashEss = new RegExp("\\\\s","mg");
var regexpNewLine = new RegExp("\n","mg");
var regexpCarriageReturn = new RegExp("\r","mg");
}
//}}}
This is the home page for Dobrica Pavlinušić's random unstructured stuff.
Welcome to my new unsorted stuff site. If you are here to "learn about rot13"<http://en.wikipedia.org/wiki/ROT13> this might not be the right place.
If you are, however looking latest and/or unsorted snippets which didn't made to "my homepage"<http://www.rot13.org/~dpavlin/> or "blog"<http://blog.rot13.org/> you might be on right place.
| {search: category: projects} | {search: category: howto} | {recent_changes: rot13} |
{fetchrss: http://blog.rot13.org/index.xml}
http://git.rot13.org/?p=air-quality;a=blob;f=pms3003.pl;hb=HEAD
{file: PMS3003 series data manual_English_V2.5.pdf}
http://www.plantower.com/en/content/?107.html
http://aqicn.org/sensor/pms3003/
https://github.com/avaldebe/AQmon/blob/master/Documents/PMS3003_LOGOELE.pdf (different manufacturer)
http://download.kamami.pl/p563980-PMS3003%20series%20data%20manual_English_V2.5.pdf
{toc: }
^ spec
Parameters :Index (Unit )
Measuring range: 0.3-1.0um ; 1.0-2.5um ; 2.5-10um
Measurement units: ug/m3
3 Measurement accuracy: ug/m3
4 Response time: <10s
5 Work current: 5V200ma@ Work State 5V2ma@ Standby Fitness
Counting efficiency :50%@0.3um 98% @> = 0.5 um
Response time :≤ 10 sec
DC supply voltage :5 V
Operating current :120 mA
Standby Current :≤ 200 µA
Data interface level :L <0.8 @ 3.3 H> 2.7@3.3 V
Operating temperature range :-20 ~ + 50 °C
Operating humidity range :0 to 99%
MTBF :≥ 3 Year
Size :65 × 42 × 23 mm
^ pinout
PIN1 :VCC :Power Supply (5V).
PIN2 :GND :Ground.
PIN3 :SET :Standby mode (when 0), operating mode (when 1) TTL 3V3
PIN4 :RXD :Serial receive / TTL level @ 3.3V.
PIN5 :TXD :Serial transmit / TTL level @ 3.3V.
PIN6 :RESET :Module reset / TTL level @ 3.3V.
PIN7,8 :NC :Not connected.
^ serial
9600
starts with 0x42 0x4d
Byte buffer index Description
1 – Constant value (0x42)
2 0 Constant value (0x4d)
3 1 Frame length
4 2
5 3 PM1.0 concentration unit (μg/m3)
6 4
7 5 PM2.5 concentration unit (μg/m3)
8 6
9 7 PM10 concentration unit (μg/m3)
10 8
11 9 PM1.0 concentration unit under atmospheric environment (μg/m3)
12 10
13 11 PM2.5 concentration unit under atmospheric environment (μg/m3)
14 12
15 13 PM10 concentration unit under atmospheric environment (μg/m3)
16 14
17 15 reserved
18 16
19 17 reserved
20 18
21 19 reserved
22 20
23 21 Control sum
24 22
^ code
^^ Arduino
doesn't check checksum: https://github.com/suda/PMS3003/blob/master/src/PMS3003.cpp
much better library: https://github.com/fu-hsi/pms
^^ Node MCU
https://github.com/avaldebe/AQmon/blob/master/lua_modules/pms3003.lua
{toc}
^ [RaspberryPi] 3
^^ GATT
* doesn't really compile for me -- https://github.com/comarius/bunget
** https://www.raspberrypi.org/forums/viewtopic.php?uid=25856&f=41&t=148449&start=0
* https://github.com/msaunby/ble-sensor-pi
* https://github.com/ecc1/ble
^ nRF24L01+
* http://dmitry.gr/index.php?r=05.Projects&proj=11.%20Bluetooth%20LE%20fakery
* https://github.com/sandeepmistry/arduino-nRF24L01-BLE
* http://simonebaracchi.eu/posts/temperature-beacon/
^ Quintic BLE
Quintic Private Profile Guide http://www.nxp.com/documents/application_note/AN11846.pdf
Q 9021 http://cache.nxp.com/documents/data_sheet/QN902X.pdf?pspll=1
* serial port tools: https://github.com/Informatic/qn902x-tools
* BLE pyhton lib https://github.com/IanHarvey/bluepy
* https://github.com/dpavlin/quintic-ble
^^ [RaspberryPi] 3
unbind device in phone app
.pre
root@rpi3:/home/pi# hcitool lescan
LE Scan ...
08:7C:BE:92:85:23 Quintic BLE
08:7C:BE:92:85:23 (unknown)
.pre
^^ Android
using BLE Scanner
.pre
nRF Master Control Panel, 2016-05-21
Quintic BLE (08:7C:BE:92:85:23)
V 07:17:01.689 Connecting to 08:7C:BE:92:85:23...
D 07:17:01.701 gatt = device.connectGatt(autoConnect = false)
D 07:17:01.907 [Callback] Connection state changed with status: 0 and new state: CONNECTED (2)
D 07:17:01.939 [Broadcast] Action received: android.bluetooth.device.action.ACL_CONNECTED
I 07:17:01.962 Connected to 08:7C:BE:92:85:23
D 07:17:01.987 wait(600ms)
V 07:17:02.614 Discovering services...
D 07:17:02.628 gatt.discoverServices()
D 07:17:03.328 [Callback] Services discovered with status: 0
I 07:17:03.352 Services discovered
V 07:17:03.422 Generic Access (0x1800)
- Device Name [R W] (0x2A00)
- Appearance [R] (0x2A01)
- Peripheral Privacy Flag [R W] (0x2A02)
- Peripheral Preferred Connection Parameters [R] (0x2A04)
- Reconnection Address [R W WNR] (0x2A03)
Generic Attribute (0x1801)
- Service Changed [I R] (0x2A05)
Client Characteristic Configuration (0x2902)
Unknown Service (0000fee8-0000-1000-8000-00805f9b34fb)
- Unknown Characteristic [N] (003784cf-f7e3-55b4-6c4c-9fd140100a16)
Client Characteristic Configuration (0x2902)
Characteristic User Description (0x2901)
- Unknown Characteristic [WNR] (013784cf-f7e3-55b4-6c4c-9fd140100a16)
Unknown Service (0000fee9-0000-1000-8000-00805f9b34fb)
- Unknown Characteristic [W WNR] (d44bc439-abfd-45a2-b575-925416129600)
Characteristic User Description (0x2901)
- Unknown Characteristic [N] (d44bc439-abfd-45a2-b575-925416129601)
Client Characteristic Configuration (0x2902)
V 07:17:29.219 Reading all characteristics...
V 07:17:29.236 Reading characteristic 00002a00-0000-1000-8000-00805f9b34fb
D 07:17:29.250 gatt.readCharacteristic(00002a00-0000-1000-8000-00805f9b34fb)
I 07:17:29.465 Read Response received from 00002a00-0000-1000-8000-00805f9b34fb, value: (0x) 51-75-69-6E-74-69-63-20-42-4C-45, "Quintic BLE"
A 07:17:29.484 "Quintic BLE" received
V 07:17:29.497 Reading characteristic 00002a01-0000-1000-8000-00805f9b34fb
D 07:17:29.512 gatt.readCharacteristic(00002a01-0000-1000-8000-00805f9b34fb)
I 07:17:29.660 Read Response received from 00002a01-0000-1000-8000-00805f9b34fb, value: (0x) 00-00
A 07:17:29.670 "[0] Unknown" received
V 07:17:29.681 Reading characteristic 00002a02-0000-1000-8000-00805f9b34fb
D 07:17:29.692 gatt.readCharacteristic(00002a02-0000-1000-8000-00805f9b34fb)
I 07:17:29.853 Read Response received from 00002a02-0000-1000-8000-00805f9b34fb, value: (0x) 00
A 07:17:29.873 "(0x) 00" received
V 07:17:29.886 Reading characteristic 00002a04-0000-1000-8000-00805f9b34fb
D 07:17:29.897 gatt.readCharacteristic(00002a04-0000-1000-8000-00805f9b34fb)
I 07:17:30.050 Read Response received from 00002a04-0000-1000-8000-00805f9b34fb, value: (0x) 64-00-C8-00-00-00-D0-07
A 07:17:30.061 "Connection Interval: 125.00ms - 250.00ms,
Slave Latency: 0,
Supervision Timeout Multiplier: 2000" received
V 07:17:30.074 Reading characteristic 00002a03-0000-1000-8000-00805f9b34fb
D 07:17:30.085 gatt.readCharacteristic(00002a03-0000-1000-8000-00805f9b34fb)
I 07:17:30.243 Read Response received from 00002a03-0000-1000-8000-00805f9b34fb, value: 0 bytes
V 07:17:30.254 Reading characteristic 00002a05-0000-1000-8000-00805f9b34fb
D 07:17:30.265 gatt.readCharacteristic(00002a05-0000-1000-8000-00805f9b34fb)
I 07:17:30.439 Read Response received from 00002a05-0000-1000-8000-00805f9b34fb, value: (0x) 01-00-FF-FF
A 07:17:30.451 "Affected Attribute Handle Range: 0x0001 - 0xFFFF" received
V 07:17:35.488 Enabling services...
V 07:17:35.507 Enabling indications for 00002a05-0000-1000-8000-00805f9b34fb
D 07:17:35.527 gatt.writeDescriptor(00002902-0000-1000-8000-00805f9b34fb, value=0x0200)
I 07:17:35.704 Data written to descr. 00002902-0000-1000-8000-00805f9b34fb, value: (0x) 02-00
A 07:17:35.713 "Indications enabled" sent
D 07:17:35.736 gatt.setCharacteristicNotification(00002a05-0000-1000-8000-00805f9b34fb, true)
V 07:17:35.754 Indications enabled for 00002a05-0000-1000-8000-00805f9b34fb
V 07:17:35.764 Enabling notifications for 003784cf-f7e3-55b4-6c4c-9fd140100a16
D 07:17:35.775 gatt.writeDescriptor(00002902-0000-1000-8000-00805f9b34fb, value=0x0100)
I 07:17:35.995 Data written to descr. 00002902-0000-1000-8000-00805f9b34fb, value: (0x) 01-00
A 07:17:36.007 "Notifications enabled" sent
D 07:17:36.030 gatt.setCharacteristicNotification(003784cf-f7e3-55b4-6c4c-9fd140100a16, true)
V 07:17:36.042 Notifications enabled for 003784cf-f7e3-55b4-6c4c-9fd140100a16
V 07:17:36.055 Enabling notifications for d44bc439-abfd-45a2-b575-925416129601
D 07:17:36.066 gatt.writeDescriptor(00002902-0000-1000-8000-00805f9b34fb, value=0x0100)
I 07:17:36.191 Data written to descr. 00002902-0000-1000-8000-00805f9b34fb, value: (0x) 01-00
A 07:17:36.203 "Notifications enabled" sent
D 07:17:36.227 gatt.setCharacteristicNotification(d44bc439-abfd-45a2-b575-925416129601, true)
V 07:17:36.240 Notifications enabled for d44bc439-abfd-45a2-b575-925416129601
V 07:17:36.251 All services enabled
V 07:17:38.528 Reading remote RSSI...
D 07:17:38.542 gatt.readRemoteRssi()
I 07:17:38.564 Remote RSSI received: -64 dBm
.pre
^ nRF51822
Brand: Makibes
Model: ID107
Bluetooth version: V4.0 BLE
Waterproof rating: Life-level waterproof
Main chip: Nordic nRF51822
Pulse sensor: Silicon labs Si1142
G-sensor: kx022-1020
{toc: }
This page documents my attempt to install Seaside as loadbalanced configuration with multiple squeak images under OpenVZ
^ Create VE
.pre
# download template
root@mljac:~# cd /var/lib/vz/template/cache
root@mljac:~# wget http://download.openvz.org/template/precreated/contrib/debian-5.0-i386-minimal.tar.gz
root@mljac:~# vzctl create 1001 --ostemplate debian-5.0-i386-minimal --ipadd 10.0.0.1 --hostname gw.rot13.org
# configure
root@mljac:~# vzctl set 1011 --nameserver 192.168.1.2 --save
.pre
Use something like {file: vz-nat.sh} to configure NAT on your OpenVZ machine.
^ Seaside
.pre
# dependencies
root@seaside:/srv# apt-get install unzip
root@seaside:/srv# wget -nd -nH http://www.seaside.st/distributions/Seaside-2.8.3.app.zip
root@seaside:/srv# unzip Seaside-2.8.3.app.zip
Archive: Seaside-2.8.3.app.zip
root@seaside:/srv# ln -s Seaside-2.8-578.app seaside
Adding new group `squeak' (1000) ...
Adding new user `squeak' (1000) with group `squeak' ...
Not creating home directory `/home/squeak'.
root@seaside:/srv# chown -R squeak:squeak Seaside-2.8-578.app/
.pre
^^ Startup
{file: Seaside.sh} - use something like this script to start headless squeak.
Actual `-headless` option didn't seem to work for me
^ Front-end HTTP proxy
{include: [nginx]}
^ Monitoring
We will be using "monit"<http://mmonit.com/monit/>, light-weight process monitor written in C to monitor servers on our virtual machine. It will do startup of our services, monitor load and report alerts.
For it to work, we need to have a script which will start/stop squeak.
Use following configuration: {file: monitrc}
Also install following two shells scripts in `/srv' so that monit can call them to start or stop services
* {file: seaside.sh}
* {file: nginx.sh}
.pre
# check syntax
root@seaside:~# /etc/init.d/monit syntax
Control file syntax OK
.pre
And you are rady to go.
* "monit@squeak1"<http://seaside.rot13.org:2812/> to view current server status
^^ Test
open "http://hostname:8080/seaside/"<http://seaside.rot13.org:8080/seaside/> to test seaside
^ More info
* http://onsmalltalk.com/scaling-seaside-more-advanced-load-balancing-and-publishing
* http://blog.blobworks.com/2008/12/16/squeak-in-jail/
* https://bytesmith.seework.com
.pre
{weblog_list: }
.pre
Helpful notes from chat about [ULX3S]
{toc: }
^ i2c
https://gitter.im/ulx3s/Lobby?at=5dfcf29acf771f7708ff69e9
It should not be that hard. I have i2c in SaxonSoc in other projects such as https://github.com/SpinalHDL/SaxonSoc/blob/dev/hardware/scala/saxon/board/blackice/BlackiceSocArduino.scala#L25
The generated board support packages include a generated dts, but it is not used yet and the simple i2c generator that I wrote does not generate the dts.
There is a problem building SaxonSoc Linux, that some build randomly do not work. It seems to be something to do with SDRAM access.
@Dolu1990 is about to redo the SDRAM access for the Ulx3s, which should make it more reliable and faster, as he plans to support double frequency access.
There is a lot of information on the development of the u-boot version here , which might be useful to you - SpinalHDL/SaxonSoc#7
https://github.com/SpinalHDL/SaxonSoc/pull/7
I2c Linux support will also need a spinal.lib driver here - https://github.com/SpinalHDL/linux/tree/linux-5.0.y/drivers/i2c
The terasic De1Soc version of SaxonSoc Linux has a dts entry for an led for disk access - https://github.com/SpinalHDL/buildroot/blob/saxon/board/spinal/saxon_default/spinal_saxon_default_de1_soc.dts#L194
We really need a better GPIO mapping for the Ulx3s. That might involve including adding a second gpio peripheral to the hardware (gpioB) and doing a better lpf file mapping to pins. It might mean increasing the niumbers of pins that support interrupts. It would be good to include access to the buttons and switches and to make it easy to add Pmods that need interrupt support like the enc28j60 one.
^ ecp5pll
> Mario Hoffmann @hoffma_gitlab Aug 05 16:11
Hello, I wanted to have a 90 degree shifted clock. I was trying out the ecp5pll from @emard. I get it running and the clock adjustment seems to work, but somehow it does not get shifted for me. Is this currently not working with yosys and so forth, is there anything I have to take care of, or might it just be a bug on my side? Tried to search this chat a bit and just searched a bit on the internet but the things I found about it were quite old and not necessarily about my problem. Any ideas? I am using the vhdl version btw
> emard @emard Aug 05 16:59
There's some order of signals and small delays between them for dynamic shifting to work. https://github.com/emard/ulx3s-misc/blob/master/examples/sdram/memtest_mister/hdl/top/top_memtest.v#L73 here is module to control phase shifts by pressing of BTN for testing of SDRAM with variable phase shift of the clock to chip
> Mario Hoffmann @hoffma_gitlab Aug 05 17:01
alright, ill look at that. thanks
> Mario Hoffmann @hoffma_gitlab Aug 05 17:53
Oh nice it works. My thinking was just a bit wrong and there was a little bug too. Thanks
> emard @emard Aug 05 18:07
ecp5pll has possibility for fine-precision phase adjustment but this simple BTN module doesn't generate proper phaseloadreg signal https://github.com/emard/ulx3s-misc/blob/master/examples/sdram/memtest_mister/hdl/btn_ecp5pll_phase.v#L51
^ display
https://gitter.im/ulx3s/Lobby?at=5f3b7df7ee58011680b36cb0
> emard @emard Aug 18 09:06
SSD1331 96x64 is full featured OLED beautiful contrast, but currently best buy is ST7789 1.3" 240x240 LCD less contrast but more pix and less $. Do not solder directly the display. Solder female 7-pin header and plug the display. Mechanical stabilization can be 3D printed https://github.com/emard/ulx3s/tree/master/box it will "work" properly only if whole box is printed. There is no problem with heat normally to FPGA but SSD1331 with wrong software commands can become hot to fry fingers and smoke, it happened to me once, colors faded and I just replaced display. Onboard USB-SERIAL can provide 2nd JTAG channel for openocd debugger of RISCV processor it will work but it will be VERY slow (for debug single step ok, but for transferring Mbps no).
^ rtc
https://gitter.im/ulx3s/Lobby?at=5f3b86a1a8c178017657caf6
> emard @emard Aug 18 09:43
Yes for RTC I first saw it "works" but after few reboots I found out that it resets to compile time or something. Core could consult onboard RTC using i2c and then set unix time integer counter which will continue ticking afterwards. For setting RTC we have esp32 and other options. Btw import ntptime; ntptime.settime() will set ESP32 localtime() from a pool of network NTP servers and then esp32 can initialize onboard RTC here I have played with this https://github.com/emard/ulx3s-misc/tree/master/examples/rtc/micropython-mcp7940n/esp32
https://gitter.im/ulx3s/Lobby?at=5f3dbb34750a2741302ea427
> emard @emard Aug 20 01:52
@pnru_gitlab here is 8-bit master interface. I haven't tested it very simple by reading seconds and seems ok https://github.com/emard/ulx3s-misc/blob/master/examples/rtc/i2c_master/proj/hdl/i2c_master_8bit.v
https://gitter.im/ulx3s/Lobby?at=5f3e2d1c07c30d132a9c4f58
> emard @emard Aug 20 09:58
when we are at verilog, I have found on the net several i2c bidirectional bridges. Only one code worked at our board but it works only if compiled by diamond. trellis compiles but doesn't work. Can someone take a look what I have missed: bridge: https://github.com/emard/ulx3s-misc/blob/master/examples/rtc/micropython-mcp7940n/proj/hdl/i2c_bridge.v toplevel usage: https://github.com/emard/ulx3s-misc/blob/master/examples/rtc/micropython-mcp7940n/proj/top/top_i2c_bridge.v
> emard @emard Aug 20 22:04
for me it works for any gpdi_scl/sda PULLMODE=UP, DOWN, or NONE so it's not pull setting. I can prepare a bitstream and micropython to ulx3s-bin example that initializes the clock setting time from NTP
> emard @emard Aug 20 22:18
https://github.com/emard/ulx3s-bin/tree/master/esp32/micropython/rtc can you try this RTC esp32 example for NTP setting? >>> rtcdemo.mcp.time should advance seconds
> emard @emard Aug 21 00:04
RTC traffic also appears at GPDI connector (if there's i2c chip 3.3V->5V adapter soldered on board PCA9306D). Some monitors may hold i2c lines. Also gpdi connector can be used to monitor traffic if e.g. you have hdmi breakout board
If you don't have battery, RTC will keep setting until board is powered off
If you have 2 ULX3S boards and mini-display OLED/LCD, you can connect 2 ULX3S together and on one run scopeio, which will monitor the other i2c traffic
I can prepare scope stuff for such setup because scopeio is vhdl, advanced so much that ghdl won't have chance in near future to compile it
> emard @emard Aug 21 00:09
UPS but we have problem there will be 2 RTC chips colliding address :)
about i2c master 8bit. First write highest bytes 3,2,1 (order not important) and last write byte 0, this should initiate i2c transaction. byte 3=0x80 is READ, byte 3=0x00 is write
If you write 0x00 to register 0x00 (seconds) it will stop RTC. To start, it needs 0x80 written to 0x00 (MSB bit must be set) then the RTC should start "ticking"
> emard @emard Aug 21 18:14
I fixed i2c_bridge.v to work with both trellis and diamond.
> Paul Ruiz @pnru_gitlab Aug 21 23:35
Which way does the battery go? I think with the + side (cap) up and the - side (ribbed) to the PCB?
@emard: thanks for all the links, but your code already appears to work. The long one is interesting, it uses the same two level state machine idea that my non-working i2c controller uses.
> emard @emard Aug 21 23:59
Battery goes + up (larger part of battery should be in contact with metallic holder soldered) - down (smaller part of battery in contact to big circular pad on the PCB
Glad to hear good news that my code works - it hasn't been tested on real CPU but I made some BTNs toplevel and a read and write to register 0 worked
^ scopeio
https://gitter.im/ulx3s/Lobby?at=5f3c27ffa05e464346d2f6ea
> emard @emard Aug 18 21:11
@gkankanh MAX11125 is 1Msa/s total so e.g. if you use 4ch then each channel will be 0.25MSa/s per channel. For oscilloscope it, we have ready solution at hdl4fpga/ULX3S/scopeio you will see traces on monitor. For analysis, onboard USB-serial can do 3Mbps so it could be nearly useable. For faster ADC, yes 100 Mbit ethernet ETH8720 from ebay, module for 2.2$ and for example ebay's AN108 AD/DA module 32MSa/s input, 125MSa/s output https://www.ebay.com/itm/ADDA-Module-Data-Signal-Acquisition-High-speed-Directly-pluggable-connector-/253556250998 also scopeio supports it
^ how to solder headers
https://gitter.im/ulx3s/Lobby?at=5f3cd88378f4a801801336cb
> emard @emard Aug 19 09:45
To have GP/GN not be swapped from "default" design, Either solder 90° FEMALE headers on top side of board (nice for PMODs directly) or straight 0° MALE pins down on bottom side of board. PMODs can also plug to other end of flat cable and pinout will be identical as if 90° was soldered onboard.
^ nmingen
https://gitter.im/ulx3s/Lobby?at=5f3cfbce8b8d4f633effcea7
> Lawrie Griffiths @lawrie Aug 19 12:15
I am using Ubuntu 20.04, so I need to use pip3 not pip. (You can't get python2 pip on 20.04 easily).
The installation instructions for nmgen-boards says "Todo", so I installed it like the m_labs version said.
I changed the blinky example to use ULX3S_85F_Platform and ran that. It complained that tool {} was missing.
It seemed that it needed OpenFpgaLoader for upload, so I installed that, and then the blinky worked.
.pre
from nmigen import *
from nmigen_boards.ulx3s import *
class Blinky(Elaboratable):
def elaborate(self, platform):
led = platform.request("led", 0)
timer = Signal(26)
m = Module()
m.d.sync += timer.eq(timer + 1)
m.d.comb += led.o.eq(timer[-1])
return m
if __name__ == "__main__":
platform = ULX3S_85F_Platform()
platform.build(Blinky(), do_program=True)
.pre
https://github.com/GuzTech/ulx3s-nmigen-examples
https://github.com/greatscottgadgets/luna
^ SDRAM memtest
https://gitter.im/ulx3s/Lobby?at=5f4ea96249a1df0a12c0d83e
> Lawrie Griffiths @lawrie Sep 01 22:04
@pnru_gitlab @Dolu1990 asked these questions about using the SDRAM, which I thought you might know something about from all your recent work on SDRAM drivers:
I'm thinking about the SDRAM
currently, the soc is at 50 mhz, and the sdram run at 100 Mhz using DDR io
but maybe we should quad pump the SDRAM, and doing some bootloader calibration to ajust read delays
i'm just currently not sure what is the critical path of the SDRAM chip themself
in other words "why they are specified to X frequancy and not more"
> Dolu1990 @Dolu1990 Sep 01 22:05
Moaaaar powaaaaaaaa
> emard @emard Sep 01 22:36
oooh yeea :)) if you want to push SDRAM near the edge and give it some heat, on selected designs it can push 133MHz chips to 180-200 MHz, fmax depends on each board. 12F performs better than 85F. Here's memtest https://github.com/emard/ulx3s-misc/tree/master/examples/sdram/memtest_mister shows results on DVI monitor and with BTNs can adjust phase shift dynamically and watch for errors.
> Dolu1990 @Dolu1990 Sep 01 23:01
<3
Nice thanks :)
So this test controle the shift of the clock sent to the DRAM ?
(it doesn't use the programable input delay ?)
> emard @emard Sep 01 23:08
Yes this has a classic sdram driver that normally needs 90° phase offset to chip hardware, but as fmax is getting higher the actual phase shift which makes it really work moves. PLL is used to provide phase shift. Paul has made a better sdram driver with cool vendor-independent delay solution with a number of NOT gates.Only ns delay per NOT gate remains vendor dependent
> Dolu1990 @Dolu1990 Sep 01 23:09
ok :D
> Paul Ruiz @pnru_gitlab 00:02
@lawrie @Dolu1990 I am not sure I understand the SDRAM questions. In any case, my latest version is here: https://gitlab.com/pnru/cortex/-/blob/master/sdram.v
In particular note new lines 45-47 - I am not sure why, but this mod generally pushes Fmax up to about 200MHz (it depends a bit on the NextPNR seed).
I am not sure what you mean by "using DDR io" - does the SDRAM chip on the ULX3S support DDR? Maybe you mean by DDR that it runs at twice the speed of the CPU or that it uses burst size 2?
I don't know what the critical path in the SDRAM chip is, but I do have a hypothesis. When working with a CAS delay of 3 clocks, the data really arrives after 2 clocks plus 6-7ns (spending on the speed grade). If you clock a grade 6 chip (PC166) faster, a clock cycle will take less than 6ns and the data will only arrive after the third rising clock edge. My guess is that the 6-7ns is related to the speed of the sense amplifiers or something like that.
^ resource utilization
https://gitter.im/ulx3s/Lobby?at=5f4f8c30d4f0f55ebbf93007
> Dolu1990 @Dolu1990 Sep 02 14:12
Is somebody aware of a way to get hearchical ressource utilisation report out from yosys/next-pnr for ECP5 ?
Basicaly, trying to nail down the ressource usage
> David Shah @daveshah1 Sep 02 14:18
You can get a hierarchical report with Yosys by passing -noflatten to synth_ecp5
^ ps2 keyboard
https://gitter.im/ulx3s/Lobby?at=5f57e59c59ac794e02f71d14
> Kid CUDA @KidCUDA_gitlab Sep 08 22:12
anyone used a PS2 keyboard with ULX3S?
like a proper PS2 keyboard with the pins adapted to USB?
is a level shifter needed or is the USB port 5V-data-tolerant?
from the schematic it doesn't look 5V tolerant but I'm not sure how else it would work with just a pure PS2 adapter as suggested in the docs
> emard @emard Sep 08 22:52
@KidCUDA_gitlab US2 pins are 5V tolerant, limited by R and Zener diodes. Still some PS/2 keyboards don't accept 3.3V levels. Best is to obtain combo PS/2+USB they usually work in both modes for ULX3S
PS/2 is normally used over OTG connector for most of our retro-computing cores, apple1-2, ti99, zx, vic20, QL just to name a few
^ cortex
source: https://gitlab.com/pnru/cortex
https://gitter.im/ulx3s/Lobby?at=5f500a7eec534f584fdbeb15
> Paul Ruiz @pnru_gitlab Sep 02 23:11
8s is super-comfortable! Btw I wonder how did cortex start, before it ever booted they need some filesystem to hold files. Is cortex filesystem mountable by modern linux? How did they made it in early times?
The Cortex was a traditional home computer with Basic in its day. Running Unix on it was my project some 6-7 years ago. It was a long journey: porting a C compiler and tool chain, building simple kernels with a linked in user program (downloaded to the H/W via something similar to S-records), etc. When the time for disk access came, I used a tool to create & manage disk images.
For the original Unix, the file system was almost the first thing that was built, after the assembler (that is how a.out got its name: assembler output). An empty disk image was written by a custom format program. Files were then loaded from paper tape. Some 1969/1970 Unix code can be found here:
https://www.tuhs.org/cgi-bin/utree.pl
In its first incarnations it was all assembler, but many of the core ideas were already there. Some more background is here:
https://www.bell-labs.com/usr/dmr/www/hist.html
> emard @emard Sep 02 23:14
Ahaaaa so unix was not all the time available on cortex hardware. Still I'd wanted to know how did you initially start with populated filesystem. Normally e.g. if we have linux on riscv, we can mount the same partition on x86 PC, copy files and and it will work on riscv, but how was this done on cortex?
So If I understood, you have a tool that from a directory creates disk image, but there's currently no support to actually mount cortex fs on linux for example. linux has some possibility to write a user-space fs driver like "fuse" but I ghess thats difficult and fragile
> Paul Ruiz @pnru_gitlab Sep 02 23:29
You can follow my journey here, in 315 commits:
https://www.jslite.net/cgi-bin/9995/timeline?n=400&y=all&v=0
I use a program ("ufs") which creates a disk image from scratch and then adds files to it. The source code is here:
https://www.jslite.net/cgi-bin/9995/dir?ci=84b2a75947eb76db&name=fsutil
Even on the mini Cortex hardware, the CF Card uses FAT formatting and has an image file on it. I make sure the image is contiguous and the boot loader lets the Unix disk driver know in which sector the image starts. This way I can simply copy disk images to the CF card without needing to use special tools.
Actually, the card also has disk images for other OS's as well - MDEX and NOS, which are somewhat similar to CP/M and MS-DOS 3 respectively.
> emard @emard Sep 02 23:44
There has been a lot of concentrated effort! The idea to use contiguous file in FAT is very good, so the CF itself can be easily written from laptop.
> Paul Ruiz @pnru_gitlab Sep 02 23:53
Thank you. The ulx3s Cortex has it even easier: because of the ESP32, now I don't even have to worry about things being contiguous and I can ftp disk images without having to handle the SD card.
> emard @emard Sep 03 00:34
yeees it was a piece of luck that for esp32 appeared good micropython support with almost all important things working and that spi-jtag adventure turned out successful. I have ulx3s with SD in a box and once inserted SD I never move out, just ftp files. Things will be even better when WROVER-E prototype starts working, 4MB RAM, 16MB FLASH no more out of memory. Bitstreams could be unzipped on-the-fly, even larger FLASH chips supported with 64K and 256K erase blocks (esp32 must buffer data size of erase block and now we are struggling with 4K buffers)
^ saxonsoc audio
https://gitter.im/ulx3s/Lobby?at=5f6482c3603d0b37f43d3ec0
> Lawrie Griffiths @lawrie Sep 18 11:49
I have a 4-cpu 85F SaxonSoc version with music, working now.
It is now inSmp/bitstreams/ulx3s_85f_blue_4core_saxonsoc.bit
I renamed images as oldimages and the new one are in Smp/images.
You need dtb, uImage and you need to untar the new rootfs.tar.
You will also need:
.pre
root@buildroot:~# cat .asoundrc
pcm.!default {
type plug
slave.pcm "softvol" #make use of softvol
}
pcm.softvol {
type softvol
slave {
pcm "hw:0,0" #redirect the output to dmix (instead of "hw:0,0")
}
control {
name "PCM" #override the PCM slider to set the softvol volume level globally
card 0
}
}
.pre
To play music do: mpg123 -T -f 4096 -m file.mp3.
Or to play in the background nohup mpg123 -T -f 4096 -m file.mp3 &
It is set up for a 64MB blue 85f.
https://gitter.im/ulx3s/Lobby?at=5f648d8cf51808513b4f7db5
> olu1990 @Dolu1990 Sep 18 12:35
.asoundrc isn't necessary, it just add volume controles in alsamixer app
I would suggest to not add the .asoundrc for single core versions, as it add quite a bit of overhead
the -m of mpg123 is for mono, if the mp3 bit rate isn't to high, it might be fine in stereo
(for single core)
^ saxonsoc rtc
https://gitter.im/ulx3s/Lobby?at=5f69eb5d6a6e094525ac61f5
https://gitter.im/ulx3s/Lobby?at=5f69f087e1dd7c19548aad12
> Dolu1990 @Dolu1990 Sep 22 14:39
got the rtc to start counting seconds and read it via :
.pre
i2cset -y 0 0x6F 0x00 0x80
sleep 4
i2cget -y 0 0x6F 0x00
.pre
https://gitter.im/ulx3s/Lobby?at=5f6a4562e1dd7c19548b96f0
> Lawrie Griffiths @lawrie Sep 22 20:41
.pre
oot@buildroot:~# cat date.sh
R6=`i2cget -y 0 0x6f 0x06`
R5=`i2cget -y 0 0x6f 0x05`
R4=`i2cget -y 0 0x6f 0x04`
R2=`i2cget -y 0 0x6f 0x02`
R1=`i2cget -y 0 0x6f 0x01`
YY="${R6:2:2}"
MON="$((${R5:2:2}-20))"
DD="${R4:2:2}"
HH="${R2:2:2}"
MM="${R1:2:2}"
echo "20$YY-$MON-$DD $HH:$MM"
root@buildroot:~# ./date.sh
2020-9-22 19:40
date -s "`./date.sh`"
.pre
https://gitter.im/ulx3s/Lobby?at=5f6a69588fe6f11963554984
> emard @emard Sep 22 23:15
.pre
#include <stdio.h>
#include <stdlib.h>
#define I2C_SLAVE 0x703
#define O_RDWR 2
int i2c_rtc;
void rtc_open(int addr)
{
i2c_rtc = open("/dev/i2c-0", O_RDWR);
ioctl(i2c_rtc, I2C_SLAVE, addr);
}
void rtc_read(unsigned char *buf, int reg, int n)
{
buf[0] = reg;
write(i2c_rtc, buf, 1);
read(i2c_rtc, buf, n);
}
void i2cdemo(void)
{
int i;
unsigned char buf[7];
// mask for BCD SEC MIN HOUR WKDAY DAY MONTH YEAR
unsigned char mask[7] = {0x7F, 0x7F, 0x3F, 0x07, 0x3F, 0x1F, 0xFF};
rtc_read(buf, 0, sizeof(buf));
for(i = sizeof(buf)-1; i >= 0; i--)
printf(" %02x", buf[i] & mask[i]);
printf("\n");
}
int main(int argc, char *argv[])
{
int i;
rtc_open(0x6F);
for(i = 0; i < 60; i++)
{
i2cdemo();
sleep(1);
}
return 0;
}
root@buildroot:/home/root/rtc# ./a.out
20 09 22 02 21 14 27
20 09 22 02 21 14 28
20 09 22 02 21 14 29
20 09 22 02 21 14 30
20 09 22 02 21 14 31
.pre
^ saxonsoc jtag
https://gitter.im/ulx3s/Lobby?at=5f78c209dfe47e4d57464c10
> Lawrie Griffiths @lawrie Oct 03 20:25
The pins to connect to are these - https://github.com/SpinalHDL/SaxonSoc/blob/dev-0.1/hardware/synthesis/radiona/ulx3s/smp/ulx3s_v20_linux_uboot.lpf#L342-L348
> emard @emard Oct 03 20:26
I tried to upload SVF file and it works, (fast). Yes, this pins connection is important. Is there a simple JTAG openocd scan command I can test it to make sure I connected all
Some command similar to
.pre
jtag newtap lfe5 tap -expected-id 0x21111043 -irlen 8 -irmask 0xFF -ircapture 0x5
.pre
> Dolu1990 @Dolu1990 Oct 03 20:29
hoo when openocd run it scan everything
> emard @emard Oct 03 20:29
yes yes I see it on above linked script
> Dolu1990 @Dolu1990 Oct 03 20:30
i'm not sur there a command to rescan, just rerun it ^^
> emard @emard Oct 03 20:31
OK I need to make a bit on the solder and pins to board, then I will test it and when I get vexrisc scanned by openocd jtag I will put it online for remote access
> Dolu1990 @Dolu1990 Oct 03 20:31
you should get a scan like 0x10001FFF
> Lawrie Griffiths @lawrie Oct 03 20:33
@Dolu1990 Doesn't @emard need to build your version of openocd - https://github.com/SpinalHDL/openocd_riscv
> Dolu1990 @Dolu1990 Oct 03 20:34
Yes
so :
You can source the source.sh, and then do a saxon_clone; saxon_openocd
this will build it
Then modify https://github.com/SpinalHDL/SaxonSoc/blob/dev-0.1/bsp/radiona/ulx3s/smp/openocd/usb_connect.cfg#L2 to match the jtag you have installed, and then saxon_openocd_connect
> Dolu1990 @Dolu1990 Oct 03 21:02
sudo apt-get install libtool automake libusb-1.0.0-dev texinfo libusb-dev libyaml-dev pkg-config for the full depedency on debian
> emard @emard 00:00
.pre
Escape character is '^]'.
Open On-Chip Debugger
> init
> scan_chain
TapName Enabled IdCode Expected IrLen IrCap IrMask
-- ------------------- -------- ---------- ---------- ----- ----- ------
0 fpga_spinal.bridge Y 0x10001fff 0x10001fff 4 0x01 0x0f
.pre
Got openocd to connect
https://gitter.im/ulx3s/Lobby?at=5f7c33646e0eb844696af0a2
> Lawrie Griffiths @lawrie 11:05
You then need a usb JTAG device, preferably an FT2232 one, and you connect the pins to gn0 - gn3. I have not used openocd with SaxonSoc for a while, but @Dolu1990 uses it all the time.
^ micropython socks
https://gitter.im/ulx3s/Lobby/archives/2020/10/10?at=5f820bfb07361f0cc6430489
> kost @kost Oct 10 19:31 UTC
since you guys around SaxonSoc made such a great progress. I had to do my part of the promise.
Just released socks server for micropython at https://github.com/kost/micropython-socks
that means you can tunnel any SOCKS5 connection over ESP32
since micropython does not come with NAT support, that means you can go to the internet over ESP32 using SOCKS server.
Installation is simple if you have connected ESP32 already to the internet:
You have to run this on ulx3s repl shell:
.pre
import upip
upip.install('micropython-socks')
.pre
and then you can just simply say:
.pre
import socks
socks.start()
.pre
it will start listening on 0.0.0.0:1080 for SOCKS5 connections.
Then you can simply from SaxonSoc test it with the following (or any other host):
.pre
curl --socks5 192.168.4.1:1080 http://ifconfig.co
.pre
^ nmigen - OV7670 with st7789
https://gitter.im/ulx3s/Lobby?at=5f949a4e6c8d484be2a6df34
> Lawrie Griffiths @lawrie Oct 24 23:19
@goran-mahovlic I now have a version of the OV7670 camera application working in nmigen with the st7789 display - https://github.com/lawrie/ulx3s-nmigen-examples/tree/master/ov7670
^ oberon
https://gitter.im/ulx3s/Lobby?at=5f949d40270d004bcfea9716
> Charles Perkins @charlesap Oct 24 23:31
@pnru_gitlab @emard I have created a new disk image based on the www.projectoberon.com sources, only adding some more LED output in the inner core boot process.
Here's a zip file of a disk image that you should be able to directly write to an SD card: https://github.com/io-core/io/blob/main/images/ledboot.img.zip ... this image has the Oberon partition at the correct offset but I did not bother to format the first part with a FAT partition. It boots on my ulx3s with the earlier Oberon .bit file.
.pre
Here's the meaning of the LEDs on booting:
LEDs: 7------- In BootLoad Firmware
LEDs: 7-----1- In BootLoad Firmware
LEDs: 7----2-- In BootLoad Firmware
LEDs: -------0 Control transferred to Modules
LEDs: ------1- Control transferred to Files
LEDs: -----2-- Control transferred to Kernel
LEDs: ----3--- In Kernel - Temporary Trap installed
LEDs: ---4---- In Kernel - Stack and heap origins and limits configured
LEDs: --5----- Kernel SecMap initialized, control transferred to FileDir
LEDs: -6------ Directory traversal complete
LEDs: 7------- Sectors marked, control transferred to Modules which has loaded Oberon.
LEDs: -------- Icons are defined, display subsystem initialized, ready to load System.
LEDs: --5----0 GC in the Oberon Loop
LEDs: --5---10 GC in the Oberon Loop
LEDs: --5--210 GC in the Oberon Loop
LEDs: --5-----
.pre
If there is an early trap before the system introduces a nicer printing trap the leds will fast-blink now with the trap value (0-7).
If the system gets an error trying to load modules after the boot loader successfully loads the kernel (which Oberon needs to actually display graphics and text to the screen) then this code fast-blinks bit zero.
The Oberon source code modified with the LED output is here:
https://github.com/io-orig/projectoberon/blob/main/Kernel.Mod.NL
https://github.com/io-orig/projectoberon/blob/main/FileDir.Mod.NL
https://github.com/io-orig/projectoberon/blob/main/Files.Mod.NL
https://github.com/io-orig/projectoberon/blob/main/Modules.Mod.NL
https://github.com/io-orig/projectoberon/blob/main/Oberon.Mod.NL
^ oled pins
https://gitter.im/ulx3s/Lobby?at=5fa2bcb374152347c213d4ae
> emard @emard Nov 04 11:59
@sthornington yes bitstream projects do rearrange pins. At least GND and 3.3V must match, FPGA is flexible about pins, practical is to plug display directly without wires. Original markings are for SSD1331. ST7789 7-pin is similar but I think pin has BL (backlight) function instead of CS. wifi_gpio17 refers to the same thing and also ESP32 is flexible about SPI pinout so you can match practicaly any combination.
esp32 Channels 1 or 2 itself are the same but if you mount SD card from ESP32 it will always use channel 1 so channel 2 remains free. Without SD channel 1 or 2 are for display the same.
@sthornington of course GND and VCC can't be swapped by FPGA, because OLED draws current and must connect to hard power supply, can't be powered from FPGA 16mA pins (so low power devices actually could swap even GND/VCC). new board will have 8-pin LCD header instead of 7-pin but there's really crowded with routing so additional 2 pins are nearly impossible. But if display has GND and VCC swapped, then it will fit to external connector GN/GN 0-27 so there's still a possibility to plug such display directly on board on the side
^ rtc - i2c master example
https://gitter.im/ulx3s/Lobby?at=5fa7ba79c6fe0131d4e19d31
> emard @emard Nov 08 10:29
There is example https://github.com/emard/ulx3s-misc/tree/master/examples/rtc/i2c_master/proj which makes i2c master in verilog, talks to RTC and displays time as HEX on DVI and LCD. There can't be interference with ESP32 because ESP32 is not directly connected to RTC, FPGA is between them.
^ rt2232 second channel openocd
https://gitter.im/ulx3s/Lobby?at=5fc57a82150b213e980592d8
> emard @emard 00:04
@sthornington if you have external ft2232 it is fastest and normally used as openocd jtag debugger for softcore cpus like litex or saxonsoc linux. Secondary US1 channel is possible and fully supported by openocd, but it will be unacceptably slow to transfer big files like kernel or root fs images. https://github.com/emard/ulx3s-jtagthru/blob/master/scripts/ft231x2.ocd here is some project that has openocd script to export secondard jtag channel to external pins but normally you can use it internally to soft-core too. See also the schematics for your board (v3.0.8) how FTDI is connected to FPGA
> Simon Thornington @sthornington 01:04
@emard thanks, mostly what I want to get going is an on-board scope to dump traces, is there any particular recommended F2232 interface? Does that plug into the jtag header of the below the oled one?
> emard @emard 02:56
any FT2232 breakout board or programmer is ok. It should connect to external pins GP/GN something, depends on where litex/saxonsoc expects them, usually pins 0-5 I guess. I does not plug to JTAG header, it doesn't need to program ECP5 but the CPU RISC5 done by FPGA. If you need onboard scope to display traces in realtime check hdl4fpga project, it has great scope for our boards.
^ esp32 passthrough
https://gitter.im/ulx3s/Lobby?at=601c699dd0d32d7d4fc94dfc
> liebman @liebman Feb 04 22:39
@emard this one is improved. It tristates gpio0 instead if setting it high so that it can be used elsewhere if needed. Also added an enable that can be used as a reset for the esp32.
.pre
module ulx3s_passthru (
input wire txd,
output wire rxd,
input wire dtr,
input wire rts,
input wire esp_txd,
output wire esp_rxd,
output wire esp_en,
output wire esp_io0,
input wire en,
);
// TX/RX passthru
assign rxd = esp_txd;
assign esp_rxd = txd;
// Programming logic
// SERIAL -> ESP32
// DTR RTS -> EN IO0
// 1 1 1 Z
// 0 0 1 Z
// 1 0 0 Z
// 0 1 1 0
assign esp_en = (~dtr | rts) & en;
assign esp_io0 = ( dtr | ~rts) ? 1'bz : 1'b0; // we only want to drive this pin low
endmodule
.pre
can be called like
.pre
module top(
input wire clk_25mhz,
output wire ftdi_rxd,
input wire ftdi_txd,
inout wire ftdi_ndtr,
inout wire ftdi_nrts,
output wire wifi_rxd,
input wire wifi_txd,
inout wire wifi_en,
inout wire wifi_gpio0,
output [7:0] led,
input [6:0] btn,
output wire shutdown,
);
ulx3s_passthru passthru(.txd(ftdi_txd),
.rxd(ftdi_rxd),
.dtr(ftdi_ndtr),
.rts(ftdi_nrts),
.esp_txd(wifi_txd),
.esp_rxd(wifi_rxd),
.esp_en(wifi_en),
.esp_io0(wifi_gpio0),
.en(btn[0]), // btn[0] will work as a reset for esp
);
// blinky for something to do so we know its operational
assign led[0] = btn[1];
assign led[6:1] = 0;
assign led[7] = wifi_gpio0;
endmodule
.pre
> liebman @liebman Feb 04 23:18
thats good to know, which are the (non esp) pins that are clock capable?
(that explains why some of my tests failed)
> emard @emard Feb 04 23:19
They are mentioned on pdf schematics_v3.0.8 let me see
https://github.com/emard/ulx3s/blob/master/doc/schematics_v308.pdf page 2 GP,GN 12 are clock capable and shared with ESP32 but small design fail is those pins are on ESP32 input only. In new board v3.1.5 I tried to fix this by routing one esp32 output capable pin to FPGA clock input capable...
PCLK .. means primary clock capable pins. they are best. GR_PCLK are second best, general routed to primary clock capable
A small fix could be possible with a jumper GN11-GN12 this will connect ESP32 pin 25 GN11 which is output capable to FPGA clock input capable at GN12
^ lpf documentation
https://gitter.im/ulx3s/Lobby?at=601fa45432e01b4f717e0ebb
> Dave Anderson @danderson 09:27
Couldn't find any decent docs other than nextpnr source code and poorly explained technical notes from lattice, so I wrote https://github.com/danderson/ulxs/blob/main/lpf.md
Also comes with pointers to the Lattice tech notes that go into more detail about e.g. ECP5 configuration and I/O pin config.
^ hdmi
https://gitter.im/ulx3s/Lobby?at=6029a8349337c51bc688733e
> splinedrive @splinedrive Feb 14 23:46
Hi, I have done a hdmi reimplementation for ulx3s and blackicemx (ice40) they have the same code base. I hope you like it. I learned from other projects to take the semantic (ulx3s-examples-dvi, fpga4fun, ...) . ulx3s has DDR and SRD support and blackicemx can only DDR. I used the pmod from Luke Wren. It works only with passive resistors and works with long hdmi cables without any problems. https://github.com/splinedrive/my_hdmi_device
^ osd
https://gitter.im/ulx3s/Lobby?at=603a1016457d6b4a948f3208
> Lawrie Griffiths @lawrie 10:25
@sylefeb I am not sure that between us, @emard and I, have documented the OSD and rom loader very well. There are lots of versions of the code in different projects. This is the spi slave from my Z80 template project - https://github.com/lawrie/ulx3s_z80_template/blob/main/src/osd/spirw_slave_v.v
The rest of the code is in that osd directory.
This is a version of the micropython code that reads and writes memory and controls the cpu remotely from the esp32 - https://github.com/lawrie/ulx3s_z80_template/blob/main/esp32/spiram.py
The rest of the esp32 code including osd.py is in that directory.
Here is a youtube video that shows the osd and loader being used - https://www.youtube.com/watch?v=YE7pSuZiN9Y&t=8s
The latest version of the osd look a bit nicer.
This is my TRS 80 Model 1 implementation that has a short description on using the OSD - https://github.com/lawrie/ulx3s_z80_trs80
Perhaps @emard knows of a better description of all this.
The OSD and loader is used by many Ulx3s projects including the Apple II, C64, ZX Spectrum, Mac Plus, QL, TI-99/4A, Amiga (OSD only), Vic 20, NES, SNES, Sega Master System, Orao, etc.
This is a good video by @Speccery that shows the OSD used on the TI-99/4A - https://www.youtube.com/watch?v=zdST3wz00KU
I don't think there is a Risc-V implementation on the Ulx3s that uses the OSD yet.
> emard @emard 12:16
@sylefeb @lawrie OSD loader behaves similar as SPI RAM using 32-bit byte address. FPGA behaves as SPI slave, ESP32 as SPI master. If slave needs to initiate transfer, there is additional IRQ line. Resources at SPI address space are memory mapped, RAM to upload for CPU, reset/halt control, buttons, OSD video chars, floppy disks etc. All is very simple and protocol is not too much standardized so it can be adapted to completely unusual usage. Generally for apple2 c64 vic20 mac trs80 etc we just copy-paste the same thing
^ saxonsoc memory map
https://gitter.im/ulx3s/Lobby?at=606dcc72bc8e6f2e0d2e5be9
> Dolu1990 @Dolu1990 Apr 07 17:14
@irvise:matrix.org
0x340000
That's the flash address. the CPU copy that part of the flash to the SDRAM at 0x80F80000 (global address). See :
Memory copy : https://github.com/SpinalHDL/SaxonSoc/blob/dev-0.3/bsp/radiona/ulx3s/smp/app/bootloaderConfig.h#L99
source address : OPENSBI_FLASH
destination address : OPENSBI_MEMORY
Then it does similar things with uboot but with that set of addresses : https://github.com/SpinalHDL/SaxonSoc/blob/dev-0.3/bsp/radiona/ulx3s/smp/app/bootloaderConfig.h#L22
if I generate a program that load to the address 0x380000 it should "just work"
Yes, as long you programe is complied to sit at 0x80F00000 in the global memory space
And where can I find more info on what memory addresses are being used for MMIO
This autogenerated header file contains all the peripheral addresses :
https://github.com/SpinalHDL/SaxonSoc/blob/dev-0.3/bsp/radiona/ulx3s/smp/include/soc.h#L64
blink
See https://github.com/SpinalHDL/SaxonSoc/blob/dev-0.3/software/standalone/blinkAndEcho/src/main.c
used with https://github.com/SpinalHDL/SaxonSoc/blob/dev-0.3/bsp/radiona/ulx3s/smp/include/bsp.h#L15
you can compile it using the command "saxon_standalone_compile blinkAndEcho" It will sit where uboot sit (see <https://github.com/SpinalHDL/SaxonSoc/blob/dev-0.3/bsp/radiona/ulx3s/smp/linker/default.ld#L1>)
^ nmigen
https://gitter.im/ulx3s/Lobby?at=608e7b59d5e2793379e961a8
> Lawrie Griffiths @lawrie May 02 12:13
I am currently working on my nmigen OV7670 camera application - https://github.com/lawrie/ulx3s-nmigen-examples/blob/master/image/camtest.py
That now displays the image on the HDMI monitor and I am starting to add image signal processing functions like brightness and color control, and simple edge detection.
The latest code that I have pushed calculates the mouse pointer (p_x, p_y) - https://github.com/lawrie/ulx3s-nmigen-examples/blob/master/image/image_stream.py
If you set the ImageStream filter switch then pixels with a red channel value less than some threshold are filtered out and the remaining pixels are displayed on the HDMI monitor as pure red. You can adjust the threshold with the up and down arrows, and a value of about 30 seems best. As the threshold is increased the picture turns black except where the laser pointer points, and the spot gets smaller as the threshold is increased. I then calculate the min and max x and y values for those red pixels, and calculate the mid points as p_x and p_y. It seems to be working.
^ saxon esp32ecp5 start
https://gitter.im/ulx3s/Lobby?at=60b93a55a10461235db71cff
> emard @emard Jun 03 22:23
I have just checked saxonsoc linux and it still works, lAN8720 ethernet (ssh) works out of the box. Tetris still compiles and works. A small hint here is the esp32 script for new esp32ecp5 to start linux
.pre
import os
from machine import SDCard, Pin
import ecp5
os.mount(SDCard(slot=3),"/sd")
# copy to root of SD card: dtb, rootfs.cpio.uboot, uImage
# flash with "False" without starting the bitstream
ecp5.flash("/sd/linux/smp/fw_jump.bin@0x340000",0x340000,False)
ecp5.flash("/sd/linux/smp/u-boot.bin@0x380000",0x380000,False)
ecp5.prog("/sd/linux/smp/ulx3s_12f_1core_saxonsoc.bit")
os.umount("/sd")
p12=Pin(12,Pin.IN)
p13=Pin(13,Pin.IN)
p14=Pin(14,Pin.IN)
p15=Pin(15,Pin.IN)
.pre
With esp32ecp5 I'd recommend micropython builds with idf3 because idf4 builds reboot ad SD card deinit (ftp> site umount)
^ dfu and openfpgaloader
https://gitter.im/ulx3s/Lobby?at=6213c5d29a09ab24f36e464d
I suggest new passthru with DFU integrated. Get or compile latest openFPGALoader. connect to US1 and flash this first: You don't need to unzip, openfpgaloader will detect .gz and unzip on-the-fly
.pre
download https://github.com/emard/ulx3s-bin/blob/master/fpga/dfu/85f-v317/multiboot.img.gz
openFPGALoader -b ulx3s -f --unprotect-flash --file-type raw multiboot.img.gz
.pre
If you hold BTN1 or set DIP SW1 ON and plug board to US2 (optionally press BTN0 if it doesn't power up at plug) then USB DFU compatible device should be detected and you can use much faster flashing like this
.pre
openFPGALoader -b ulx3s_dfu bitstream.bit
.pre
This is for user-bitstream, if you need to reflash bootloader DFU itself from US2, hold BTN1 and BTN2 together and use DFU alternate 5 option back to ESP32: plug to US1 again and try to erase and flash ESP32
^ bootloader switches
https://gitter.im/ulx3s/Lobby?at=62370af9f43b6d783f0de7d8
> emard @emard 12:07
@NostosArch bootloader checks DIP SW1 state on power up. Switching it afterwards doesn't matter. 3 LEDs ON means it is DFU bootloader and passthru, and US2 should enumerate DFU with 3 LEDS it should be possible to flash esp32 with 3 LEDs on. 7 LEDs on means it is in passthru only (not DFU) mode. esp32 should be able to be flashed from passthru-only mode like from DFU+passthru mode. Apart from that I can either say esp32 is flashed with something difficult to get rid of or another PC and OS should be tried.
I didn't follow, but are you using linux microsoft or apple? Does ESP32 respond with ">>>" usbserial 115200 micropyhton prompt on US1?
If you upload blink, then passthru-only mode is overwritten. Still DFU+passthru mode (3 LEDs) is kept (write protected from fujprog, only openfpgaloader can overwrite bootloader). So DFU+passthru 3 LEDS should allow flashing esp32 but of course PCs and OSs compatibility and contents of esp32 already flashed may cause difficulty
{toc: }
Product Name: GP2Y1010AU0F dust sensor module
https://www.instructables.com/id/How-to-Interface-With-Optical-Dust-Sensor/
Too cheap to be useful? https://techblog.calvinboey.com/review-of-the-sharp-dust-sensor-gp2y1010au0f/
https://d.lij.uno/misc-dust-detector-with-arduino-serial-comm.html
^ Technical parameters
Power supply voltage: DC5 � 2V
Operating Current: 20mA (peak)
Sensitivity: 0.5V / (0.1mg / m3)
The minimum detection level of particles: 0.8 m
Clean air voltage: 0.9V typ.
Working temperature: -10 ~ 65
Storage temperature: -20 ~ 80
Size: 46mm � 30mm � 17.6mm
Size Weight: 15g
^ arduino
https://github.com/mickey9801/GP2Y1010AU0F
calcVoltage = voMeasured * (this->_VCC / 1024.0);
// linear equation taken from http://www.howmuchsnow.com/arduino/airquality/
dustDensity = (0.17 * calcVoltage - 0.1) * 1000.0;
Source code here works much better if you do 10 readings and average them before sending result
^ tasmota
https://github.com/arendst/Tasmota/pull/7118
{image: CY7C68013A.jpg}
{toc}
^ Cypress CY7C68013A EZ-USB FX2LP
{file: U2CY7C68013-56.pdf}
1. With CY7C68013A-56 chip: low-power version of the enhanced 51-core, 16KBprogram data areas, frequency of 48Mhz, 480Mbps high-speed transmission protocol standards, compatible with USB2.0
2. Firmware, EEPROM: Complete in-system programming solution with a USB cabledirectly to download firmware, on-board to provide 16K (24LC128) a large program memory (EEPROM), used as storage VID / PID and the USB firmware, the program space to meet the CY7C68013A Needs.
3. All the GPIO pin through the 2.54mm standard leads to very convenient for learners toexpand DIYdesign.
4. With the board firmware can be achieved through the core function of the logic analyzer
5. PDF format, provide the schematic and code
.pre
dpavlin@blue:/bluez/CY7C68013A$ lsusb -d 04b4:8613
Bus 003 Device 023: ID 04b4:8613 Cypress Semiconductor Corp. CY7C68013 EZ-USB FX2 USB 2.0 Development Kit
.pre
Be sure to disable any udev rules which try to load firmware for other devices with FX2
^ [Altera] USBBlaster clone
* http://fpga4u.epfl.ch/wiki/FX2
^^ pull-up TMS, TDI, pull-down TCK
Altera recommends that you use pull-up resistor values between 1k and 10k ohms on the TMS and TDI pins and a pull-down resistor valueof 1k ohmson the TCK pin.
.pre
dpavlin@blue:/bluez/CY7C68013A/USB-Blaster/fx2fw-sdcc$ make
asx8051 -plosgff vectors.a51
make: asx8051: Command not found
Makefile:42: recipe for target 'vectors.rel' failed
make: *** [vectors.rel] Error 127
dpavlin@blue:/bluez/CY7C68013A/USB-Blaster/fx2fw-sdcc$ dpkg -l sdcc
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Architecture Description
+++-=======================-================-================-====================================================
ii sdcc 3.4.0+dfsg-2 amd64 Small Device C Compiler
.pre
^^ Loading firmware
.pre
Aug 17 17:38:26 blue kernel: [13787.802348] usb 3-1.6.4.4: new high-speed USB device number 26 using ehci-pci
Aug 17 17:38:26 blue kernel: [13787.894557] usb 3-1.6.4.4: New USB device found, idVendor=04b4, idProduct=8613
Aug 17 17:38:26 blue kernel: [13787.894563] usb 3-1.6.4.4: New USB device strings: Mfr=0, Product=0, SerialNumber=0
Aug 17 17:38:26 blue kernel: [13787.894945] usbtest 3-1.6.4.4:1.0: FX2 device
Aug 17 17:38:26 blue kernel: [13787.894950] usbtest 3-1.6.4.4:1.0: high-speed {control bulk-in bulk-out} tests (+alt)
root@blue:/bluez/CY7C68013A/USB-Blaster/fx2fw-sdcc# DEVICE=/dev/bus/usb/003/026 /sbin/fxload -t fx2lp -I usbjtag.hex -v
microcontroller type: fx2lp
single stage: load on-chip memory
open RAM hexfile image usbjtag.hex
stop CPU
write on-chip, addr 0x0000 len 6 (0x0006)
write on-chip, addr 0x000b len 3 (0x0003)
write on-chip, addr 0x0013 len 3 (0x0003)
write on-chip, addr 0x001b len 3 (0x0003)
write on-chip, addr 0x0023 len 3 (0x0003)
write on-chip, addr 0x002b len 3 (0x0003)
write on-chip, addr 0x0033 len 3 (0x0003)
write on-chip, addr 0x003b len 3 (0x0003)
write on-chip, addr 0x0043 len 3 (0x0003)
write on-chip, addr 0x004b len 3 (0x0003)
write on-chip, addr 0x0053 len 3 (0x0003)
write on-chip, addr 0x005b len 3 (0x0003)
write on-chip, addr 0x0063 len 3 (0x0003)
write on-chip, addr 0x006b len 1 (0x0001)
write on-chip, addr 0x0080 len 56 (0x0038)
write on-chip, addr 0x0100 len 128 (0x0080)
write on-chip, addr 0x0fa0 len 3 (0x0003)
write on-chip, addr 0x0fb9 len 3 (0x0003)
write on-chip, addr 0x0fa3 len 3 (0x0003)
write on-chip, addr 0x0180 len 1008 (0x03f0)
write on-chip, addr 0x0570 len 77 (0x004d)
write on-chip, addr 0x0fbc len 6 (0x0006)
write on-chip, addr 0xe100 len 83 (0x0053)
write on-chip, addr 0xe154 len 150 (0x0096)
write on-chip, addr 0x05bd len 452 (0x01c4)
write on-chip, addr 0x0f98 len 2 (0x0002)
write on-chip, addr 0x0781 len 440 (0x01b8)
write on-chip, addr 0x0fb3 len 6 (0x0006)
write on-chip, addr 0x0f9a len 6 (0x0006)
write on-chip, addr 0x0939 len 1008 (0x03f0)
write on-chip, addr 0x0d29 len 595 (0x0253)
write on-chip, addr 0x0fa6 len 13 (0x000d)
write on-chip, addr 0x0f7c len 28 (0x001c)
... WROTE: 4110 bytes, 33 segments, avg 124
reset CPU
root@blue:/bluez/CY7C68013A/USB-Blaster/fx2fw-sdcc#
Aug 17 17:41:23 blue kernel: [13964.652392] usb 3-1.6.4.4: USB disconnect, device number 26
Aug 17 17:41:24 blue kernel: [13965.107683] usb 3-1.6.4.4: new high-speed USB device number 27 using ehci-pci
Aug 17 17:41:24 blue kernel: [13965.199976] usb 3-1.6.4.4: config 1 interface 0 altsetting 0 bulk endpoint 0x81 has invalid maxpacket 64
Aug 17 17:41:24 blue kernel: [13965.199981] usb 3-1.6.4.4: config 1 interface 0 altsetting 0 bulk endpoint 0x2 has invalid maxpacket 64
Aug 17 17:41:24 blue kernel: [13965.201001] usb 3-1.6.4.4: New USB device found, idVendor=09fb, idProduct=6001
Aug 17 17:41:24 blue kernel: [13965.201005] usb 3-1.6.4.4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
Aug 17 17:41:24 blue kernel: [13965.201008] usb 3-1.6.4.4: Product: USB-Blaster
Aug 17 17:41:24 blue kernel: [13965.201009] usb 3-1.6.4.4: Manufacturer: EPFL
Aug 17 17:41:24 blue kernel: [13965.201011] usb 3-1.6.4.4: SerialNumber: 00000000
.pre
^ FX2 lib
* https://github.com/djmuhlestein/fx2lib
^ libfx2loader
* https://github.com/makestuff/libfx2loader
.pre
dpavlin@blue:/bluez/CY7C68013A$ wget http://www.swaton.ukfsn.org/bin/makestuff-lindar-20130719.tar.gz
dpavlin@blue:/bluez/CY7C68013A$ tar xvf makestuff-lindar-20130719.tar.gz
dpavlin@blue:/bluez/CY7C68013A$ cd makestuff/libs/
dpavlin@blue:/bluez/CY7C68013A/makestuff/libs$ ../scripts/msgit.sh makestuff/libfx2loader
Cloning into 'libfx2loader'...
remote: Counting objects: 174, done.
remote: Total 174 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (174/174), 58.68 KiB | 0 bytes/s, done.
Resolving deltas: 100% (112/112), done.
Checking connectivity... done.
dpavlin@blue:/bluez/CY7C68013A/makestuff/3rd$ ln -s ../../fx2lib/
dpavlin@blue:/bluez/CY7C68013A/makestuff/libs$ cd libfx2loader/
.pre
^ smbus
* http://www.karosium.com/p/smbusb.html
* https://github.com/karosium/smbusb
{toc: }
^ Links
* http://jimmyg.org/2007/12/07/nginx-proxying-to-pylons-with-ssl-on-debian-etch/
* https://calomel.org/nginx.html
^ Compilation and packaging
.pre
dpavlin@llin:/rest/unix/www$ wget http://sysoev.ru/nginx/nginx-0.7.31.tar.gz
dpavlin@llin:/rest/unix/www$ tar tvfz nginx-0.7.31.tar.gz
dpavlin@llin:/rest/unix/www/nginx-0.7.31$ ./configure --with-http_ssl_module --prefix=/srv/nginx
make
sudo checkinstall
.pre
^ Installation
.pre
root@seaside:~# dpkg -i nginx_0.7.31-1_i386.deb
Selecting previously deselected package nginx.
(Reading database ... 8333 files and directories currently installed.)
Unpacking nginx (from nginx_0.7.31-1_i386.deb) ...
Setting up nginx (0.7.31-1) ...
root@seaside:~# cd /srv/nginx/
.pre
^ Changes
{fetchrss: http://git.rot13.org/?p=nginx.git;a=rss fulltext}
Links that I collected while trying it out...
{toc: }
If you know Croatian, start here: http://radiona.org/wiki/inventory/fabrikator_2_mini
to configure wifi and get web interface working
.pre
M550 SSID
M551 PaSsWoRd
# verify IP from ap
M552
.pre
^ tools
* https://github.com/emard/fab2mini
^ g-code
https://marlinfw.org/docs/gcode/M018.html
Disable all steppers immediately
M18
^ schematics
* board schematics https://github.com/goran-mahovlic/stm32Board/
** http://www.lemilica.com/reversing-mini-fabrikator-v2-malyan-m100-3d-printer/
^ software
.pre
dpavlin@nuc:/nuc/Fabrikator_ii_mini$ sudo apt install repetier-host
.pre
mjesec installation of dspam
.pre
sudo apt-get install dspam libdspam7-drv-pgsql
.pre
Automatic installation using PostgreSQL doesn't really work, so we will do it manually:
.pre
createuser dspam
createdb --owner dspam --encoding utf-8 dspam
cd /usr/share/doc/libdspam7-drv-pgsql
psql dspam dspam < pgsql_objects.sql
psql dspam dspam < virtual_users.sql
.pre
And then, more or less follow http://www.kirya.net/articles/setting-up-dspam-as-a-filter-for-postfix-on-debian-sarge/
https://tasmota.github.io/docs/devices/Sonoff-T1/
Configuration > Configure Module > Sonoff T1 3CH
immediately after flashing Tasmota (so it won't reset when powered from adapter):
> SetOption13 1
mapping: https://github.com/arendst/Tasmota/blob/a466c5abf33386c3dda34696e11ae975c7ac6649/tasmota/tasmota_template.h#L2468
.pre
{ // SONOFF_T13 - Sonoff T1 3CH (ESP8285)
GPI8_KEY1, // GPIO00 Button 1
GPI8_USER, // GPIO01 Serial RXD and Optional sensor
GPI8_USER, // GPIO02 Optional Sensor (J3 Pin 5)
GPI8_USER, // GPIO03 Serial TXD and Optional sensor
GPI8_REL3, // GPIO04 Blue Led and Relay 3 (0 = Off, 1 = On)
GPI8_REL2, // GPIO05 Blue Led and Relay 2 (0 = Off, 1 = On)
// GPIO06 (SD_CLK Flash)
// GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
// GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
GPI8_KEY2, // GPIO09 Button 2
GPI8_KEY3, // GPIO10 Button 3
// GPIO11 (SD_CMD Flash)
GPI8_REL1, // GPIO12 Blue Led and Relay 1 (0 = Off, 1 = On)
GPI8_LED1_INV, // GPIO13 Blue Led (0 = On, 1 = Off) - Link and Power status
0, 0, 0, 0
},
.pre
^ Problem
After first install with official Android app it broke account so hard, that web login to xiaomi just reloaded page in loop, and fan dissipated from Android app.
^ wifi reset
power + m button for 7 seconds.
^ token
I created local xiaomi account, which is useful, since you need password for this tool to work.
https://github.com/PiotrMachowski/Xiaomi-cloud-tokens-extractor
.pre
dpavlin@nuc:/nuc/Xiaomi-cloud-tokens-extractor$ git remote -v
origin https://github.com/PiotrMachowski/Xiaomi-cloud-tokens-extractor (fetch)
origin https://github.com/PiotrMachowski/Xiaomi-cloud-tokens-extractor (push)
dpavlin@nuc:/nuc/Xiaomi-cloud-tokens-extractor$ . venv/bin/activate
(venv) dpavlin@nuc:/nuc/Xiaomi-cloud-tokens-extractor$ python token_extractor.py
---------
NAME: Xiaomi Smart Tower Fan 2
ID: 897218688
MAC: AC:8C:46:C9:2C:B4
IP: 192.168.3.120
TOKEN: REDACTED
MODEL: xiaomi.fan.p45
---------
.pre
^ code
https://github.com/rytilahti/python-miio/issues/1544 - doesn't seem to login into xiaomi cloud for me
^^ home assistant
https://github.com/syssi/xiaomi_fan/issues/282 - doesn't support my model
.pre
2025-07-29 09:23:06.378 ERROR (MainThread) [custom_components.xiaomi_miio_fan.fan] Unsupported device found! Please create an issue at https://github.com/syssi/xiaomi_fan/issues and provide the following data: xiaomi.fan.p45
.pre
https://github.com/XiaoMi/ha_xiaomi_home - doesn't work for me
Finally, Xiaomi Miot Auto works.
https://github.com/syssi/xiaomi_fan/issues/214
https://github.com/al-one/hass-xiaomi-miot
no need to patch local home assistant installation.
^ teardown video
https://www.youtube.com/watch?v=8GoeoD_eyvk
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.
Recent changes are best way to get a hang of what's going on.
| {search: category: projects} | {search: category: howto} |
{fetchrss: http://blog.rot13.org/index.xml}
Oxymoron, right? Well for somebody who loves perl so much, it is. Anyway here it is...
{toc: }
^ One-liners
^^ show phpinfo from shell
.pre
echo '<? phpinfo() ?>' | php5
.pre
^ Security scanning
^^ Spike PHP Security Audit Tool
http://developer.spikesource.com/projects/phpsecaudit/
.pre
sudo apt-get install php5-xslt
.pre
Small list of checked expressions, quite difficult to browse.
^^ Pixky
http://pixybox.seclab.tuwien.ac.at/pixy/
Enables taint analysis of code. Doesn't handle ISO-8859-2 chars well, and breaks with terrifing error, but it's a very promising tool (in Java, sigh)
^^ phc
http://www.phpcompiler.org/
Great tool to get php's AST tree. Used by "Plumhead"<http://www.perlfoundation.org/parrot/index.cgi?plumhead>
^ Links
{fetchrss: http://del.icio.us/rss/dpavlin/php+security full}
Here are some quick notes about installation on clean Debian etch machine
This page is aimed towards system administrators, if you want information how to customize design of page take a look at [SocialText CSS design] (which is included on bottom of this page).
{toc: }
^ Helper packages
.pre
sudo apt-get install wv xpdf-utils unrtf unzip links
sudo cpan MP3::Tag
.pre
^ Install source
.pre
svn co https://repo.socialtext.net:8999/svn/socialtext/trunk socialtext
cd socialtext/nlw
# checkout lastest Socialtext::Resting client
svn export --force https://repo.socialtext.net:8999/svn/socialtext-clients/trunk/rest/perl/Socialtext-Resting/lib/Socialtext/ lib/Socialtext/
./configure --socialtext-open 1 --apache-proxy 0 --force-ssl-login 1
make
sudo bash
make install
update-rc.d -f apache-perl remove
update-rc.d st-apache defaults
update-rc.d ceqlotron defaults
/etc/init.d/st-apache start
/etc/init.d/ceqlotron start
.pre
^ Update existing checkout
.pre
cd socaialtext
svn update
cd nlw
./configure --socialtext-open 1 --apache-proxy 0 --force-ssl-login 1
make
make test
sudo make install
sudo /etc/init.d/st-apache stop
sudo /etc/init.d/ceqlotron restart
sudo /etc/init.d/st-apache start
.pre
^ Add new admin user
.pre
sudo -u www-data st-admin create-user --email dpavlin@rot13.org --password wikidream \
--first-name Dobrica --last-name Pavlinusic
sudo -u www-data st-admin add-workspace-admin --email dpavlin@rot13.org
.pre
^ Configuring mailer
^^ postfix
Install and configure postfix for mail delivery
.pre
apt-get install postfix
vi /etc/postfix/main
.pre
Important lines are following:
.pre
alias_maps = hash:/etc/aliases, hash:/etc/aliases.deliver
alias_database = hash:/etc/aliases, hash:/etc/aliases.deliver
.pre
They add `/etc/aliases.deliver` (which SocialText generates with names of wiki workspaces) to configuration.
Next, we need to create `/etc/aliases.deliver.db` which is binary version of database needed for postfix. It's extremly important that `aliases.deliver` file is owned by `www-data` because postfix picks user which will do e-mail delivery based on owner of aliases file. If your owner of `/var/www/socialtext` is some other user than `www-data` you will have to modify following command appropriately:
.pre
# make www-data owner of file
chown www-data:root /etc/aliases.deliver
# allow root group to write in /etc/
chmod g+w /etc/
# create /etc/aliases.deliver.db
sudo postalias /etc/aliases.deliver
.pre
Now restart postfix as `root` user
.pre
/etc/init.d/postfix restart
.pre
^^ crontab
Add following to `/etc/crontab` to refresh aliases database for postfix regularly:
.pre
*/10 * * * * root postalias /etc/aliases.deliver
.pre
^ Handling e-mail errors
.pre
sudo tail /var/log/mail.log | grep st-admin
.pre
> dsn=5.3.0, status=bounced (Command died with status 13: "/usr/local/bin/st-admin deliver-email --workspace bio". Command output: open nlw-stats.log: Permission denied at /usr/local/share/perl/5.8.8/Socialtext/Statistics.pm line 103. END failed--call queue aborted. )
This problem is reported on socialtext-devel list, but no response so far.
.pre
# sudo vi +24 /usr/local/share/perl/5.8.8/Socialtext/Statistics.pm
Readonly my $LOG_NAME => 'nlw-stats.log';
Readonly my $LOG_PATH => $ENV{APACHE_LOG_DIR}
? "$ENV{APACHE_LOG_DIR}/$LOG_NAME"
: "/tmp/$LOG_NAME";
.pre
^ Customize template
Remove "Did you know?" box from dashboard
.pre
sudo vi /usr/share/nlw/template/view/homepage
.pre
Or from your `socialtext/nlw` checkout (so that `make install` will install correct one):
.pre
vi share/template/view/homepage
.pre
^ Fix RSS feed errors
If you are using `{fetchrss http://blog.rot13.org/index.xml}` and having problems with RSS feeds, try to re-installing two perl modules:
.pre
sudo cpan XML::RSS XML::Atom
.pre
^ Change e-mail address of workspace
This configuration change will feed responses to e-mails generated by wiki back into wiki. You might not want to do that! :-)
.pre
st-admin set-workspace-config --workspace rot13 \
email_notification_from_address '"random unstructured stuff" <rot13@wiki.rot13.org>'
.pre
^ Access simple version of page
Every SocialText wiki has a lite version available at http://wiki.example.com/lite/page/:workspace/
For this wiki it's http://saturn.ffzg.hr/lite/page/rot13
^ Configure sane resource usage
Since SocialText wiki is designed to run on dedicated box, it's resource requiements are not for faint-hearted users. However, if you are installing it on machine with constraint hardware (or virtual machine) you might want to decrease number of `apache-perl` server which are created on startup and kept running. Each apache child takes about 80Mb of RAM, so lowering number of children will have beneficial effect on your memory usage.
If you open `/etc/apache-perl/st-httpd.conf` you will see comment that describes command used for generating this configuration. So, let's edit command limits, re-create config and restart apache:
.pre
vi +485 dev-bin/gen-config
dev-bin/gen-config --sitewide --apache-proxy=0 --hostname=saturn.ffzg.hr
/etc/init.d/st-apache reload
.pre
^ Convert RSS feed URLs to absolute
If you need to fetch RSS feeds from remote URLs and those providers create only relative URLs in feeds (like svnweb does) that this patch might help you: {file: FetchRSSPlugin.pm.diff}
It does dirty magic to prepend hostname before URL in feeds making them work from Socialtext wiki which is on different host.
^ Problems with 8-bit UTF-8 encoded characters in URLs
It seems that trunk of socialtext
.pre
Repository Root: https://repo.socialtext.net:8999/svn/socialtext
Repository UUID: 593ce9bc-2028-0410-bb98-c566b643a948
Revision: 6127
Node Kind: directory
Schedule: normal
Last Changed Author: jjp
Last Changed Rev: 6028
Last Changed Date: 2007-12-10 19:38:21 +0100 (Mon, 10 Dec 2007)
.pre
has problems with `CGI.pm` 3.31. As a temporary work-around use {file: backpan.sh} to download `CGI.pm` 3.29 which is known to work.
^ Enable html wafl in workspace
This enables `.html` markup which enables embedded html into wiki page
.pre
st-admin set-workspace-config --workspace razmjenavjestina allows_html_wafl 1
.pre
^ Upgrade to 2.2
There are various problems with this upgrade.
^^ Socialtext::Resting
For a start, you will have to install Socialtext::Resting clinet *in the middle* of `make install` because import of help workspace will fail.
You can get it from https://repo.socialtext.net:8999/svn/socialtext-clients/trunk/rest/perl/Socialtext-Resting
^^ Missing directory
.pre
mkdir /etc/apache-perl/socialtext-conf.d
.pre
^^ Missing skins
http://code.google.com/p/socialtext-skins/wiki/SkinningIssues
.pre
.pre
Problem not yet solved.
----
{include: [SocialText CSS design]}
^ 2030
* http://hackaday.com/2014/02/15/chinese-3020-cnc-machine-gets-some-upgrades/
* http://lab.whitequark.org/notes/2014-02-12/cnc3020t-emc2-configuration-and-hidden-features/
{toc: }
^ MongoDB
^^ Checkout source
.pre
dpavlin@t61p:/rest/cvs$ git clone git://github.com/mongodb/mongo.git
Initialized empty Git repository in /rest/cvs/mongo/.git/
remote: Counting objects: 32011, done.
remote: Compressing objects: 100% (9340/9340), done.
remote: Total 32011 (delta 22724), reused 31556 (delta 22412)
Receiving objects: 100% (32011/32011), 20.57 MiB | 1.12 MiB/s, done.
Resolving deltas: 100% (22724/22724), done.
.pre
^^ Install build dependencies
.pre
dpavlin@t61p:/rest/cvs/mongo$ sudo apt-get install \
libboost-dev libboost-thread-dev libboost-filesystem-dev libboost-program-options-dev libboost-date-time-dev \
libpcre3-dev xulrunner-dev libreadline-dev
.pre
^^ Build Debian package
`debian/control` file needs modification for unstable: http://svn.rot13.org/index.cgi/pxelator/view/mongodb/mongo-debian-control-xulrunner.diff
.pre
dpavlin@t61p:/rest/cvs$ cd mongo/
# patch source
dpavlin@klin:/rest/cvs/mongo$ patch -p1 < /srv/pxelator/mongodb/mongo-debian-control-xulrunner.diff
patching file debian/control
# clean before new build
dpavlin@t61p:/rest/cvs/mongo$ sudo rm -Rf debian/mongodb
dpavlin@t61p:/rest/cvs/mongo$ time dpkg-buildpackage -rfakeroot -b
...
real 6m16.744s
user 5m41.701s
sys 0m19.393s
.pre
^ Perl driver
.pre
dpavlin@t61p:/rest/cvs$ git clone git://github.com/mongodb/mongo-perl-driver.git
Initialized empty Git repository in /rest/cvs/mongo-perl-driver/.git/
remote: Counting objects: 1782, done.
remote: Compressing objects: 100% (1673/1673), done.
remote: Total 1782 (delta 1122), reused 0 (delta 0)
Receiving objects: 100% (1782/1782), 1.45 MiB | 747 KiB/s, done.
Resolving deltas: 100% (1122/1122), done.
sudo apt-get install libany-moose-perl libdata-types-perl
dpavlin@t61p:/rest/cvs$ cd mongo-perl-driver/
perl Makefile.PL
make test
sudo dh-make-perl
.pre
^ Binaries
* http://debian.rot13.org/
^ Queries
^^ PXElator audit examples
.pre
> use pexlator
> db.audit.group({ key:{ 'package.name':true }, initial:{ count: 0 }, reduce:function(o,p) { p.count++ } });
> show profile
11052ms Sun Jan 31 2010 13:24:47
query pxelator.$cmd ntoreturn:1 reslen:690 nscanned:0
query: { group: { key: { package.name: true }, initial: { count: 0.0 }, ns: "audit", $reduce: function (o, p) {
p.count++;
} } } nreturned:1 bytes:674 11052ms
> db.audit.ensureIndex({ 'package.name':true })
> db.audit.group({ key:{ 'package.name':true }, initial:{ count: 0 }, reduce:function(o,p) { p.count++ } });
.pre
no visible speed impact.
We are really interested only in daemons which aren't null:
.pre
> db.audit.ensureIndex( { daemon: true } )
> db.audit.group({
key: { daemon:true }
,cond: { daemon: { $exists: true } }
,initial: { count: 0 }
,reduce: function(o,p) { p.count++ }
});
.pre
dhcp count usage by ip
.pre
> db.audit.ensureIndex( { "package.name": true } )
> db.audit.group({ key:{ ip:true }, cond: { "package.name": "dhcpd" }, initial: { count: 0 }, reduce: function(o,p) { p.count++ } });
.pre
package usage
.pre
> db.setProfilingLevel(2,1000);
> db.audit.group({ key:{ "package.name":true }, initial:{ count:0 }, reduce:function(o,p){ p.count++ } })
> db.system.profile.find().sort({$natural:-1}).limit(10)
{ "ts" : "Sun Jan 24 2010 15:07:53 GMT+0100 (CET)", "info" : "query pxelator.$cmd ntoreturn:1 reslen:642 nscanned:0
query: { group: { key: { package.name: true }, initial: { count: 0.0 }, ns: \"audit\", $reduce: function (o, p) {
p.count++;
} } } nreturned:1 bytes:626 13887ms", "millis" : 13887 }
> db.audit.ensureIndex({ "package.name":true })
> db.audit.group({ key:{ "package.name":true }, initial:{ count:0 }, reduce:function(o,p){ p.count++ } })
.pre
doesn't help much, because we don't have `cond` in query.
^^ Profile
.pre
> db.setProfilingLevel(2,1000);
{ "was" : 2, "ok" : 1 }
> db.system.profile.find()
.pre
^ Indexes
.pre
> db.system.indexes.find()
{ "name" : "_id_", "ns" : "pxelator.audit", "key" : { "_id" : ObjectId("000000000000000000000000") } }
{ "ns" : "pxelator.audit", "key" : { "daemon" : true }, "name" : "daemon_" }
{ "ns" : "pxelator.audit", "key" : { "key" : "package.time" }, "name" : "key_" }
{ "ns" : "pxelator.audit", "key" : { "package.name" : true }, "name" : "package.name_" }
.pre
^ Comparison with CouchDB
Migrate from CouchDB to MongoDB using http://svn.rot13.org/index.cgi/pxelator/view/bin/couchdb2mongodb.pl
^^ Disk usage
.pre
root@opr:~# du -hc /var/lib/couchdb/0.9.0/.pxelator* /var/lib/couchdb/0.9.0/pxelator.couch
655M /var/lib/couchdb/0.9.0/.pxelator_design
23M /var/lib/couchdb/0.9.0/.pxelator_temp
7.8G /var/lib/couchdb/0.9.0/pxelator.couch
8.4G total
root@opr:~# du -hc /var/lib/mongodb/pxelator.*
65M /var/lib/mongodb/pxelator.0
129M /var/lib/mongodb/pxelator.1
257M /var/lib/mongodb/pxelator.2
513M /var/lib/mongodb/pxelator.3
513M /var/lib/mongodb/pxelator.4
513M /var/lib/mongodb/pxelator.5
17M /var/lib/mongodb/pxelator.ns
2.0G total
.pre
^^ Map/Reduce differences
CouchDB
.pre
# map
function(doc) {
if ( doc.package.name == 'dnsd' )
emit(doc.peerhost,1);
}
# reduce
function (k,v) {
return sum(v);
}
.pre
MongoDB
.pre
> m = function() { emit(this.peerhost,1) }
> r = function(k,vals) { var sum = 0; for (var i in vals) sum += vals[i]; return sum; }
> res = db.audit.mapReduce(m, r, { query:{"package.name":"dnsd"} } )
{
"result" : "tmp.mr.mapreduce_1264448081_3",
"timeMillis" : 6040,
"counts" : {
"input" : {
"top" : 0,
"bottom" : 204293
},
"emit" : {
"top" : 0,
"bottom" : 204293
},
"output" : {
"top" : 0,
"bottom" : 22
}
},
"ok" : 1,
}
> db[res.result].find().limit(10)
.pre
Comparison with ad-hoc query
.pre
> db.setProfilingLevel(2,1000);
> db.audit.group({ key:{ "peerhost":true }, cond:{ "package.name":"dnsd" },
initial:{ count:0 }, reduce:function(o,p){ p.count++ } })
> db.system.profile.find().sort({$natural:-1}).limit(10)
{ "ts" : "Mon Jan 25 2010 21:21:11 GMT+0100 (CET)", "info" : "query pxelator.$cmd ntoreturn:1 reslen:1148 nscanned:0
query: { group: { key: { peerhost: true }, cond: { package.name: \"dnsd\" }, initial: { count: 0.0 }, ns: \"audit\", $reduce: function (o, p) {
p.count++;
} } } nreturned:1 bytes:1132 2161ms", "millis" : 2161 }
.pre
So, going through server-side JavaScript is *3x performance penalty*
^ Blog posts
{fetchrss: http://blog.rot13.org/mt/mt-search.cgi?tag=MongoDB&Template=feed&IncludeBlogs=1}
^ Debian amd64 version
^^ build
.pre
root@klin:~/rest/virtual# debootstrap --arch amd64 squeeze ./mongodb-amd64 http://10.60.0.91:3142/debian
root@klin:~/rest/virtual# chroot mongodb-amd64/
root@klin:/# apt-get install \
git-core locales dpkg-dev debhelper scons \
libboost-dev libboost-thread-dev libboost-filesystem-dev libboost-program-options-dev libboost-date-time-dev \
libpcre3-dev xulrunner-dev libreadline-dev
root@klin:/# cd /srv/
root@klin:/srv# git clone git://github.com/mongodb/mongo.git
root@klin:/srv# cd mongo/
root@klin:/srv/mongo# time dpkg-buildpackage -rfakeroot -b
.pre
^^ run
.pre
dpavlin@klin:~$ sudo chroot /virtual/mongodb-amd64/ su -c '/usr/bin/mongod --dbpath /var/lib/mongodb --logpath /var/log/mongodb/MongoDB.log run' mongodb
.pre
{file: hack-B008-k3w.txt}
{toc: }
^ Kindle 3 serial pinout
{image: kindle3-serial.jpg}
from http://www.electricstuff.co.uk/kindlehack.html
^^ Bus Pirate connection
| TX | RxD | black |
| RX | TxD | gray |
| GND | GND | brown |
| 1.7V | VPU | green |
.pre
HiZ>v
Pinstates:
1.(BR) 2.(RD) 3.(OR) 4.(YW) 5.(GN) 6.(BL) 7.(PU) 8.(GR) 9.(WT) 0.(Blk)
GND 3.3V 5.0V ADC VPU AUX CLK MOSI CS MISO
P P P I I I I I I I
GND 0.00V 0.00V 0.00V 0.50V L L H L H
HiZ>m
1. HiZ
2. 1-WIRE
3. UART
4. I2C
5. SPI
6. 2WIRE
7. 3WIRE
8. LCD
x. exit(without change)
(1)>3
Set serial port speed: (bps)
1. 300
2. 1200
3. 2400
4. 4800
5. 9600
6. 19200
7. 38400
8. 57600
9. 115200
10. BRG raw value
(1)>9
Data bits and parity:
1. 8, NONE *default
2. 8, EVEN
3. 8, ODD
4. 9, NONE
(1)>1
Stop bits:
1. 1 *default
2. 2
(1)>1
Receive polarity:
1. Idle 1 *default
2. Idle 0
(1)>1
Select output type:
1. Open drain (H=Hi-Z, L=GND)
2. Normal (H=3.3V, L=GND)
(1)>1
Ready
UART>P
Pull-up resistors ON
UART>v
Pinstates:
1.(BR) 2.(RD) 3.(OR) 4.(YW) 5.(GN) 6.(BL) 7.(PU) 8.(GR) 9.(WT) 0.(Blk)
GND 3.3V 5.0V ADC VPU AUX - TxD - RxD
P P P I I I I I I I
GND 0.00V 0.00V 0.00V 1.31V L L H L H
UART>(1)
UART bridge
Reset to exit
Are you sure? y
.pre
^ Links
* http://www.mobileread.com/forums/showthread.php?t=88004 - download jailbreak and usbnetwork
* http://www.cowlark.com/kindle/getting-started.html
* http://trac.ak-team.com/browser/Configs/trunk/Kindle/Hacks
{fetchrss: http://feeds.delicious.com/v2/rss/dpavlin/kindle?count=15 full}
^ Kindle 2.5.8 update to 3.1
* http://yifan.lu/tag/kindle/
* http://www.mobileread.com/forums/showthread.php?t=127969
.pre
# mount DXG
cp update_dxg-2.5.8-prepare_kindle.bin /mnt/usb/
# Update Your Kindle
dpavlin@t61p:~$ ls -al /mnt/usb/output/
total 694948
drwxr-xr-x 2 dpavlin dpavlin 4096 May 11 17:51 .
drwxr-xr-x 9 dpavlin dpavlin 4096 Jan 1 1970 ..
-rwxr-xr-x 1 dpavlin dpavlin 474 May 11 17:44 make-backup.log
-rwxr-xr-x 1 dpavlin dpavlin 297 May 11 16:56 make-image.log
-rwxr-xr-x 1 dpavlin dpavlin 419454976 May 11 17:51 rootfs.img
-rwxr-xr-x 1 dpavlin dpavlin 292155092 May 11 17:44 update_restore-os.bin
mkdir -p /mnt/backuppc/kindle-dxg
cp -rv /mnt/usb/output /mnt/backuppc/kindle-dxg/
# mount K3G
dpavlin@t61p:~/Downloads/kindle/kindle-updater-beta-3$ cp update_k3g-3.1-create_updater.bin /mnt/usb/
dpavlin@t61p:~$ cp /backup/kindle-dxg-output/rootfs.img /mnt/usb/
dpavlin@t61p:~$ touch /mnt/usb/NO_TTS
dpavlin@t61p:~$ sudo eject /dev/sdb
# Update Your Kindle
dpavlin@t61p:~$ mount /mnt/usb
dpavlin@t61p:~$ cp /mnt/usb/output/* /backup/kindle-k3g-output/
dpavlin@t61p:~$ sudo eject /dev/sdb
# mount DXG
dpavlin@t61p:~$ mount /mnt/usb
dpavlin@t61p:~$ cp /backup/kindle-k3g-output/update_dxg-update-os.bin /mnt/usb/
dpavlin@t61p:~$ cp /backup/kindle-k3g-output/tts-files.tar /mnt/usb/
dpavlin@t61p:~$ sudo eject /dev/sdb
# Update Your Kindle
.pre
^^ client: Kindle DXG D00801 - 2.5.8 555370010
.pre
[root@kindle root]# cat /proc/cpuinfo
Processor : ARMv6-compatible processor rev 4 (v6l)
BogoMIPS : 1593.88
Features : swp half thumb fastmult vfp edsp java
CPU implementer : 0x41
CPU architecture: 6TEJ
CPU variant : 0x0
CPU part : 0xb36
CPU revision : 4
Cache type : write-back
Cache clean : cp15 c7 ops
Cache lockdown : format C
Cache format : Harvard
I size : 16384
I assoc : 4
I line length : 32
I sets : 128
D size : 16384
D assoc : 4
D line length : 32
D sets : 128
Hardware : Mario Platform
Revision : 31020
Serial : "B009A1A010860A1B"
[root@kindle root]# cat /proc/partitions
major minor #blocks name
7 0 3510232 loop0
31 0 128 mtdblock0
31 1 3584 mtdblock1
31 2 32 mtdblock2
31 3 128 mtdblock3
31 4 3584 mtdblock4
31 5 64 mtdblock5
31 6 128 mtdblock6
31 7 24 mtdblock7
31 8 64 mtdblock8
179 0 3952640 mmcblk0
179 1 409624 mmcblk0p1
179 2 24576 mmcblk0p2
179 3 8192 mmcblk0p3
179 4 3510240 mmcblk0p4
[root@kindle root]# cat /proc/meminfo | head -1
MemTotal: 127128 kB
[root@kindle root]# cat /proc/cmdline
console=ttymxc0,115200 mem=128M ro ip=none root=/dev/mmcblk0p1 lpj=2654208 panic=10 quiet
.pre
^^ Host: Kindle 3G+Wifi D00901 - 3.1 558700031
.pre
[root@kindle root]# cat /proc/cpuinfo
Processor : ARMv6-compatible processor rev 3 (v6l)
BogoMIPS : 511.18
Features : swp half thumb fastmult vfp edsp java
CPU implementer : 0x41
CPU architecture: 6TEJ
CPU variant : 0x1
CPU part : 0xb36
CPU revision : 3
Cache type : write-back
Cache clean : cp15 c7 ops
Cache lockdown : format C
Cache format : Harvard
I size : 16384
I assoc : 4
I line length : 32
I sets : 128
D size : 16384
D assoc : 4
D line length : 32
D sets : 128
Hardware : Amazon MX35 Luigi Board
Revision : 35020
Serial : "B006A0A0117503RS"
BoardId : "SP1B000000000000"
[root@kindle root]# cat /proc/meminfo | head -1
MemTotal: 256536 kB
[root@kindle root]# cat /proc/partitions
major minor #blocks name
7 0 3205336 loop0
179 0 3907584 mmcblk0
179 1 665628 mmcblk0p1
179 2 24576 mmcblk0p2
179 3 8192 mmcblk0p3
179 4 3205344 mmcblk0p4
[root@kindle root]# cat /proc/cmdline
console=ttymxc0,115200 mem=256M panic=10 root=/dev/mmcblk0p1 ro ip=none quiet lpj=2555904
.pre
^ API
* http://kdk-javadocs.s3.amazonaws.com/index.html?overview-summary.html
* http://download.oracle.com/javame/config/cdc/ref-impl/pbp1.1.2/jsr217/index.html
{fetchrss: http://adq.livejournal.com/data/rss?tag=kindle}
* http://code.google.com/p/adqmisc/
^ Source
^^ Amazon
* http://www.amazon.com/gp/help/customer/display.html?ie=UTF8&nodeId=200203720
^^ Open Source
* https://github.com/apetresc/Kindle-Widget-Toolkit
* https://github.com/proDOOMman/KindleNote
* http://code.google.com/p/kdk-emulator/
* http://www.mobileread.com/forums/showthread.php?t=103867
* http://code.google.com/p/kindleflow/
* http://www.reddit.com/r/kindle/comments/dsrjm/readabilitymod_article_mode_update_for_kindle_3/
^^ standalone kindle terminal
* http://info.iet.unipi.it/~luigi/kindle/
* http://www.mobileread.com/forums/showthread.php?t=125860
^ Download Java2ME
Last version available for Linux: http://www.oracle.com/technetwork/java/download-135801.html
^ Web server mobi mime type
.pre
AddType application/x-mobipocket-ebook .mobi
.pre
^ wpa_supplicant
* http://www.mobileread.com/forums/showthread.php?t=99681
.pre
id="$(wpa_cli add_network | sed -n '2p')"
wpa_cli \
set_network $id ssid "UIC-Wireless" \
set_network $id key_mgmt IEEE8021X \
set_network $id eap TTLS \
set_network $id identity "netid-here" \
set_network $id anonymous_identity "anonymous" \
set_network $id password "password-here" \
set_network $id ca_cert "/mnt/us/certs/Thawte_Premium_Server_CA.pem" \
set_network $id phase2 "auth=PAP" \
enable_network $id \
quit
.pre
^ X patch
* http://code.google.com/p/savory/source/browse/trunk/x11-on-kindle/xorg-1.6.patch
^ Kindle diagnostic mode
* http://www.mobileread.com/forums/showthread.php?t=122362
touch /mnt/us/ENABLE_DIAGS
^ Duokan
* http://www.mobileread.com/forums/showthread.php?t=105316
^ QEmu
* http://people.debian.org/~aurel32/qemu/armel/
.pre
wget http://people.debian.org/~aurel32/qemu/armel/debian_lenny_armel_standard.qcow2 \
http://people.debian.org/~aurel32/qemu/armel/initrd.img-2.6.26-2-versatile \
http://people.debian.org/~aurel32/qemu/armel/vmlinuz-2.6.26-2-versatile \
qemu-system-arm -M versatilepb -kernel vmlinuz-2.6.26-2-vert=/dev/sda1" -m 256
.pre
Convert image to ext3 image and it will also work on Kindle using loopback mount
^^ rootfs images
.pre
qemu-img convert -f raw -O qcow2 /backup/kindle-dxg-output/rootfs.img dxg.qcow2
sudo mount /backup/kindle-dxg-output/rootfs.img rootfs/ -o loop,ro
.pre
^ HTML to mobi
* https://dev.mobileread.com/trac/mobiperl/wiki
.pre
#!/bin/sh
dir=/home/dpavlin/Downloads/pdf/aosabook.org/www.aosabook.org/en/
list=/tmp/list
echo index.html > $list
grep '<td><a href="' $dir/index.html | cut -d\" -f2 | grep -v \# >> $list
ls $dir/*.html | sed "s!$dir/!!" > /tmp/list.all
sort /tmp/list /tmp/list.s
sort /tmp/list.all /tmp/list.all.s
diff /tmp/list.s /tmp/list.all.s | grep '^> ' | cut -d" " -f2 >> $list
tool_dir=`pwd`
cd $dir
$tool_dir/html2mobi \
--mobifile /tmp/aosa.mobi \
--title "The Architecture of Open Source Applications" \
--author "Amy Brown and Greg Wilson (eds.)" \
--coverimage $dir/../images/cover.jpg \
--removejavascript \
--imagerescale 0 \
--gentoc \
`cat $list`
.pre
^ manual network setup using wifi
.pre
# add wireless network
[root@kindle root]# vi /var/local/system/wpa_supplicant.conf
[root@kindle root]# /etc/init.d/wpa_supplicant restart
[root@kindle root]# udhcpc -i wlan0
# ip route add default via ip.of.gw
[root@kindle root]# cat /etc/resolv.conf
nameserver 8.8.8.8
[root@kindle root]# iptables -A INPUT -i wlan0 -j ACCEPT
[root@kindle root]# iptables -A OUTPUT -o wlan0 -j ACCEPT
.pre
{toc: }
^ board markings
Different to board on this page, mine has following markings:
HYS-01-008_V3.4
2018-07-20
^ boot loader mode
Short GPIO0 and GND during boot to enter flash mode before connecting to the serial programmer. The power indicator LED will be strong red to confirm the device has entered this mode. As soon as the short is removed, the red color will be dimmed. The device will then be ready for flashing.
^ Sonoff-Tasmota
https://github.com/arendst/Sonoff-Tasmota/wiki/BlitzWolf-SHP2
^^ configuration
.pre
dpavlin@nuc:/nuc/esp8266/Sonoff-Tasmota/sonoff$ cp user_config_override_sample.h user_config_override.h
# edit user_config_override.h to define wifi and mqtt i also added:
#undef MODULE
#define MODULE BLITZWOLF_BWSHP
#undef USE_DOMOTICZ
#undef USE_HOME_ASSISTANT
.pre
^^ build
.pre
dpavlin@nuc:/nuc/esp8266/Sonoff-Tasmota$ export PLATFORMIO_BUILD_FLAGS='-DUSE_CONFIG_OVERRIDE'
dpavlin@nuc:/nuc/esp8266/Sonoff-Tasmota$ platformio run -e sonoff
.pre
^^ flash
.pre
root@x200:/mnt/nuc/esptool# ./esptool.py --chip esp8266 --port /dev/ttyUSB0 --before no_reset --after no_reset erase_flash
esptool.py v2.7-dev
Serial port /dev/ttyUSB0
Connecting...
Chip is ESP8266EX
Features: WiFi
MAC: 80:7d:3a:4e:32:97
Uploading stub...
Running stub...
Stub running...
Erasing flash (this may take a while)...
Chip erase completed successfully in 1.3s
Staying in bootloader.
root@x200:/mnt/nuc/esptool# ./esptool.py --chip esp8266 --port /dev/ttyUSB0 --before no_reset --after no_reset write_flash --flash_mode dout 0x00000 /mnt/nuc/esp8266/Sonoff-Tasmota/.pioenvs/sonoff/firmware.bin
esptool.py v2.7-dev
Serial port /dev/ttyUSB0
Connecting....
Chip is ESP8266EX
Features: WiFi
MAC: 80:7d:3a:4e:32:97
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Auto-detected Flash size: 1MB
Compressed 519456 bytes to 358637...
Wrote 519456 bytes (358637 compressed) at 0x00000000 in 31.7 seconds (effective 131.1 kbit/s)...
Hash of data verified.
Leaving...
Staying in bootloader.
.pre
^ espurina - DON"T USE IT!
https://github.com/xoseperez/espurna/wiki/Hardware-BLITZWOLF-BW-SHP2
TL;DR -- it doesn't work for me at all -- it reboots when I access web page and doesn't send data over mqtt or influxdb reliably. I can't recommend it at all, but I'm leaving my attempts below....
^^ download pre-compiled binary and flash it
https://github.com/xoseperez/espurna/releases/tag/1.13.5
.pre
root@x200:/mnt/nuc/esptool# wget https://github.com/xoseperez/espurna/releases/download/1.13.5/espurna-1.13.5-blitzwolf-bwshpx.bin
root@x200:/mnt/nuc/esptool# ./esptool.py --chip esp8266 --port /dev/ttyUSB0 erase_flash
esptool.py v2.7-dev
Serial port /dev/ttyUSB0
Connecting....
Chip is ESP8266EX
Features: WiFi
MAC: 80:7d:3a:4e:32:97
Uploading stub...
Running stub...
Stub running...
Erasing flash (this may take a while)...
Chip erase completed successfully in 1.3s
Staying in bootloader.
# again power cycle device with gpio connected to ground, and disconnect it....
root@x200:/mnt/nuc/esptool# ./esptool.py --chip esp8266 --port /dev/ttyUSB0 write_flash --flash_mode dout 0x00000 ./espurna-1.13.5-blitzwolf-bwshpx.bin
esptool.py v2.7-dev
Serial port /dev/ttyUSB0
Connecting....
Chip is ESP8266EX
Features: WiFi
MAC: 80:7d:3a:4e:32:97
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Auto-detected Flash size: 1MB
Compressed 492880 bytes to 352587...
Wrote 492880 bytes (352587 compressed) at 0x00000000 in 31.2 seconds (effective 126.5 kbit/s)...
Hash of data verified.
Leaving...
Staying in bootloader.
.pre
^^ configuration
https://github.com/xoseperez/espurna/wiki/Configuration
connect to first boot AP
When asked for credentials, enter "admin" as username and "fibonacci" as password.
I configured mqtt and start pushing data using telegraf to influxdb. json doesn't work with telegraf.
^^ ota update
https://github.com/xoseperez/espurna/wiki/OTA
.pre
dpavlin@nuc:/nuc/esp8266/espurna/code$ git remote -v
origin https://github.com/xoseperez/espurna (fetch)
origin https://github.com/xoseperez/espurna (push)
dpavlin@nuc:/nuc/esp8266/espurna/code$ platformio run -e blitzwolf-bwshpx-ota
.pre
for some rason, updateing using web interface browse/upload did work for me first time, but not after that.
Is version 1.13.6-dev broken?
^^^ ota manager
https://github.com/xoseperez/espurna/wiki/Espurna-OTA-Manager
Does not work for me.
^^^ platformio ota
.pre
dpavlin@nuc:/nuc/esp8266/espurna/code$ ESPURNA_IP=192.168.3.103 platformio run -t upload -e blitzwolf-bwshpx-ota -v
.pre
{file: auth.txt}
* create ceritifcates {file: cert.sh}
* install debian tools {file: mitm-install.sh}
^ Dell's documentation
* {file: DellRemoteAccessController5Security.Pdf}
* {file: DellRemoteAccessController4Security.Pdf}
{toc: }
I will try to collect useful protocol information about Dell's (actually ""<>) RAC protocol
My main goal is to use Dell RAC from Linux, without all troubles described in "my blog post"<http://blog.rot13.org/2009/12/dells_rac_support_under_linux_drek.html>
^ Hardware
According to "Exploring the DRAC5"<http://www.dell.com/downloads/global/power/ps3q06-20060118-McGary.pdf>:
* AMD Alchemy Au1550 333 MHz processor
* Virtual media performance with up to 1.5 MB/sec transfer speeds
* Data storage through remote and local 16 MB USB keys
* Improved maximum supported screen resolution 1280*1024
^ Proprietary ports
| Port | Protocol | Type | Ver | Enc | Direction | Usage | Configurable |
| 3668 | Proprietary | TCP | 1.0 | None | In/Out | CD/diskette virtual media service | Yes |
| 3669 | Proprietary | TCP | 1.0 | 128-bit SSL | In/Out | CD/diskette virtual media service | Yes |
| 5900 | Proprietary | TCP | 1.0 | 128-bit SSL | In/Out | Video redirection | Yes |
| 5901 | Proprietary | TCP | 1.0 | 128-bit SSL | In/Out | Keyboard/Mouse redirection | Yes |
^ Supported SSL Cipher Suites
DRAC 5 supports SSL version 3 and TLS version 1.0. The following are ciphers supported on DRAC 5:
* SSL_RSA_WITH_RC4_128_MD5
* SSL_RSA_WITH_RC4_128_SHA
* SSL_RSA_WITH_3DES_EDE_CBC_SHA
* SSL_RSA_WITH_3DES_EDE_CBC_MD5
* TLS_RSA_WITH_AES_128_CBC_SHA
* TLS_RSA_WITH_AES_256_CBC_SHA
^ IPMI RMCP+ Encryption
DRAC 5 IPMI over LAN and SOL use RMCP+ for Authentication and Key exchange. For details on the RMCP+ protocol, see the IPMI 2.0 specification.
DRAC 5 IPMI supports the following encryption algorithms:
* AES-CBC-128 (128-bit AES with CBC)
* RC4-128 (128-bit RC4)
^ Console Redirection Security
^^ Authentication and Encryption
DRAC 5 can continuously redirect the managed system's video, keyboard and mouse (KVM) to the management station. It is a very powerful feature, is very easy to use, and does not require any software installation on the managed system. A user can access this feature to remotely manage the system as if they were sitting in front of the system. A security authentication and encryption protocol has been implemented in console redirection to prevent a hostile, rogue client from breaking into the console redirect path without authenticating though the web server. 128-bit SSL encryption secures the keyboard keystrokes during the remote console redirection and therefore does not allow unauthorized "snooping" of the network traffic. The following sequence of security protocol operations is performed during the establishment of a console redirection session:
# A user logs into the main web GUI then clicks the "Open Consoles" tab.
# The Web GUI sends a pre-authentication request to the DRAC 5 web server via the HTTPS channel (SSL encrypted).
# The DRAC 5 web server returns a set of secret data (including an encryption key) via the SSL channel. The console redirection authentication key (32 bytes long) is dynamically generated to prevent replay attack.
# The Console redirection client sends a login command with an authentication key to a console redirection server keyboard/mouse port for authentication via SSL channel.
# If authentication is successful, a console redirection session and two console redirection pipes (one for keyboard/mouse and one for video) are established. The keyboard/mouse pipe is always SSL encrypted. The video pipe encryption is optional. (Users can choose to encrypt or not to encrypt the video pipe before they start their console redirection session).
^ Video redirection
.pre
root@klin:~# ssldump -r /tmp/rac_t1.pcap
New TCP connection #1: klin.local(52028) <-> 10.60.0.102(5900)
1 1 0.0148 (0.0148) C>S Handshake
ClientHello
Version 3.0
cipher suites
SSL_RSA_WITH_RC4_128_MD5
SSL_RSA_WITH_3DES_EDE_CBC_SHA
SSL_RSA_WITH_DES_CBC_SHA
compression methods
NULL
1 2 0.0165 (0.0016) S>C Handshake
ServerHello
Version 3.0
session_id[0]=
cipherSuite SSL_RSA_WITH_RC4_128_MD5
compressionMethod NULL
.pre
^^ SSL man in the middle
First, we need a really old distribution to support cipher suites. http://www.debian.org/distrib/archive
openssl versions:
* potato - 0.9.4-5 - includes just sslv2, so it's too old
* woody - 0.9.6c-2.woody.7
.pre
sudo debootstrap --arch i386 woody woody http://archive.debian.org/debian-archive/debian
sudo chroot woody
.pre
.pre
# /etc/apt/sources.list
deb http://archive.debian.org/debian-archive/debian potato main non-free contrib
deb http://archive.debian.org/debian-non-US/ potato/non-US main contrib non-free
.pre
.pre
apt-get install stunnel
openssl req -new -x509 -days 365 -nodes -out cert.pem -keyout cert.pem
# https mitm
stunnel -p cert.pem -d 443 -r 5443
stunnel -c -d 5443 -r 10.60.0.100:443
# 5900 mitm
stunnel -p cert.pem -d 5900 -r 5999
stunnel -c -d 5999 -r 10.60.0.100:5900
.pre
Check ssl connection
.pre
ssldump -i eth0 'port 5900' -A -N
.pre
Following is *bad*
.pre
2 2 0.0489 (0.0000) S>CV3.0(2) Alert
level fatal
value handshake_failure
.pre
Dump unencrypted communication
.pre
sudo tshark -w /tmp/5900-plain.pcap 'port 5999'
.pre
5900 and 5901 traffic with two keystrokes:
{image: drac-traffic.png}
* http://svn.rot13.org/index.cgi/scripts/view/trunk/mitm-ssl.pl
Dump all traffic:
* 5999 - unencrypted 5900
* 5443 - unencrypted 443 (https)
* 5901 - just port redir
.pre
sudo tshark -w /tmp/590x-3.pcap -i any 'port 5999 or port 5901 or port 5443'
.pre
.pre
# create client certificate
openssl req -new -x509 -days 365 -nodes -out ssl.cert -keyout ssl.key
root@opr:~/rac-ssl# ./mitm-ssl.pl --lport 5900 --laddr 10.60.0.91 --rport 5900 --raddr 10.60.0.100 --serverkey ssl.key --servercert ssl.cert
root@opr:~/rac-ssl# ./mitm-ssl.pl --lport 443 --laddr 10.60.0.91 --rport 443 --raddr 10.60.0.100 --serverkey ssl.key --servercert ssl.cert
.pre
^ Video adjust
* PS - Pixel sampling 00 - f0
.pre
# 0 PS
S>C 42454546 82020020 0080005a 0f42001b 04200000 03200258 00000002 00000000
C>S 42454546 03090010 00080000 00000000
C>S 42454546 03000010 00000000 00000000
# 10
S>C 42454546 82020020 0080005a 0f42001b 04200050 03200258 00000002 00000000
C>S 42454546 03090010 00500000 00000000
C>S 42454546 03000010 00000000 00000000
# 30
S>C 42454546 82020020 0080005a 0f42001b 042000f0 03200258 00000002 00000000
C>S 42454546 03090010 00f00000 00000000
.pre
* HORI - Horizontal position
.pre
# 0 HORI
S>C 42454546 82020020 0080005a 0e74001b 042000f0 03200258 00000002 00000000
C>S 42454546 04000010 00000000 00000000
# ~100
S>C 42454546 82020020 0080005a 0eda001b 042000f0 03200258 00000002 00000000
C>S 42454546 04000010 00000000 00000000
# 100
S>C 42454546 82020020 0080005a 0ed8001b 042000f0 03200258 00000002 00000000
C>S 42454546 04000010 00000000 00000000
# 200
S>C 42454546 82020020 0080005a 0f3c001b 042000f0 03200258 00000002 00000000
# 400
S>C 42454546 82020020 0080005a 1004001b 042000f0 03200258 00000002 00000000
.pre
* VERT - Vertical position
.pre
# 0 VERT
42454546 82020020 0080005a 1004000a 042000f0 03200258 00000002 00000000
# 10
42454546 82020020 0080005a 1004001e 042000f0 03200258 00000002 00000000
# 40
42454546 82020020 0080005a 10040032 042000f0 03200258 00000002 00000000
.pre
* CO - Contrast
.pre
# 0 CO
42454546 82020020 00800000 10040032 042000f0 03200258 00000002 00000000
# 255
42454546 82020020 008000ff 10040032 042000f0 03200258 00000002 00000000
.pre
^ Keyboard redirection protocol 5900
^^ mouse
.pre
# top-left x y
42454546 02010010 0000 000c 0008 0000
# bottom-right
42454546 02010010 0000 0282 0383 0000
# mouse click in the middle of screen
42454546 02010010 0001 018a 0147 0000
.pre
^^ keyboard
.pre
# a b c d ... down
C>S 42454546 02000010 00010004 00000000
C>S 42454546 02000010 00000005 00000000
C>S 42454546 02000010 00010005 00000000
C>S 42454546 02000010 00000006 00000000
C>S 42454546 02000010 00010006 00000000
C>S 42454546 02000010 00000007 00000000
C>S 42454546 02000010 00010007 00000000
.pre
^ Virtual media 3668
.pre
sudo tshark -w /tmp/drac-vmedia.pcap -i any 'port 5443 or port 3668'
.pre