Welcome to TiddlyWiki created by Jeremy Ruston, Copyright © 2007 UnaMesa Association
Yay! 100 Hz with 4 floating-point channels .
Requesting all 4 channels in a single LocalBus request - sampling them each 10 ms and plotting simultaneously gives a really smooth experience.
And according to ''top'' there is 0% CPU usage. No wonder, since all processing is pushed down to the hardware by means of an asynchronous architecture. UART write, UART interrupt-on-receive, UART read. That all takes place in the kernel.
The actual processing, correcting for byte order, scaling, converting values to screen coordinates, and finally manipulating the Linux framebuffer device to turn on coloured pixels on the display, is done in quite a few milliseconds.
!!InformationSpaces
Marathon Coding!
After having refactored the Calibrator out in a separate component, the orchestration in the main PDM Service is now complete.
Remains TODO:
* Some serious timing, handling of lacks, etc.
* Handshaking,
!!Story
The Sampler is a Pipe which takes an initial Frame as input. It the does its job (request/response), and stores the sampled data in the provided frame.
It then queues the frame up for the rest of the PipeLine.
Instead of discarding the oldest frame, then, the oldest frame goes into the sampler again.
!!!Synopsis
This module lets you inspect the blueprint of the [[<netropy:space/>]] that hosts it.
!!!Content
There is no inner structure to the blueprint. Rather the service acts as a generic XML service, returning the content of the blueprint at a given location.
!!!Example
Viewing the definition of the ''Hello World'' application at {{{/hello/world}}} on this server can be accomplished by visiting {{{/blueprint/hello/world}}}.
This works, because there is a blueprint service located at {{{/blueprint}}}, a convention used for allowing introspection into a [[<netropy:space/>]]
The following {{{<iframe/>}}} shows the content of the blueprint at {{{/hello/world}}}. Depending on your browser, you may have to view the source of the frame to see the actual XML.
<html><iframe src="/blueprint/raw/hello/world" style="width:100%;"/></html>
!!!Attributes
*''type''<br/>(optional) the MIME type of the result. It defaults to {{{text/xml}}}. See the note below.
*''style''<br/>(optional) URL for an XSL stylesheet to refer to in the generated result. The default is not to style the result.
>//''NOTE!''//
>The service does //always// generate XML on success. The ''type'' attribute is only a hint for the client, and is //not// used, nor checked, by the service itself. Reasonable values are {{{text/xml}}} or {{{text/plain}}}.
!!!Other Issues
Beware that the generated XML may become quite large, and that XSL transformation of such huge documents puts a heavy load on a browser.
Also, some browsers are quite unforgiving about illformed XML, which shows up from time to time. Mostly when some "bad javascript" gets pasted into the blueprint.
In particular Firefox/Mozilla has an issue with generating {{{<base/>}}} tags in XSL style sheets, leading to an error:
{{{
Error during XSLT transformation: Waiting for …
}}}
!!!Synopsis
This service, when given a blueprint, produces a new executable instance of <<tiddler xeno>> with the hosting servers architecture.
!!!Attributes
!!!Synopsis
The visitor has information on from where he originated. So we use this to call back for further information.
!!!
!!!Discussion
Knowing that the visitor's origin is a space structured just like the origin's space can have great benefits. You can treat the other part like yourself then... same structure, same words (namespace)...
!!!Synopsis
This service lets you copy information.
!!!Attributes
*''init''<br/>(optional) An URL from where the information shall be copied at service initialisation time. If the service fails to retrieve the information, it may fall back on the content provided in the inner structure.<br/>If no information was retrieved and no inner structure is given, the service is in an invalid state, and requests will fail with a ''500 Internal Server Error''.
*''type''<br/>(optional) The MIME type which will be used as Content-Type in the reply as well as an Accept header if the content is fetched from elsewhere via HTTP.<br/>The default is {{{text/plain}}}, which may be overruled by the Content-Type of the actual content fetched.<br/>Note that XML types will be parsed, whereas scripts and CSS will be enclosed in a CDATA section. See ''Embedding scripts'' below.
!!!Example
This server has mounted [[jQuery]] in the following manner:
{{{
<jquery>
<xeno:copy init="http://code.jquery.com/jquery-1.9.1.min.js" type="application/javascript"/>
</jquery>
}}}
!!!Embedding scripts
Due to the definition of XML, symbols like ''<'' and ''>'' are not valid in text nodes.
And writing {{{<}}} and {{{>}}} would make the code next to unreadable.
The solution is to embed the script in a CDATA section, e.g.
{{{
<mytoolbar>
<xeno:copy type="text/javascript"/>
//<![CDATA[
// Application specific code
$(jQuery).fn.myToolBar()
//]]>
</xeno:copy>
</mytoolbar>
}}}
Note that the tags for the CDATA section are inside comments, as the ''copy'' service returns //everything// between the tags.
You may use another syntax, which relies on the ''copy'' service returning only the contents of the CDATA section in the case where the inner structure consists of only one such section (which mostly will be the case when you want to serve a script):
{{{
<mytoolbar>
<xeno:copy type="text/javascript"/><![CDATA[
// Application specific code
$(jQuery).fn.myToolBar = function(parameters) {
...
]]></xeno:copy>
</mytoolbar>
}}}
!!!Synopsis
This module acts as an interface to the hosting computers file system. It is a ProtocolResolver, translating an http:// URL to a file:// URL. Mozilla browsers also do that, as you can see if you click [[here|file:/]].
!!!Attributes
*''mount''<br/>(required) a path to the file system object that should be made available. Both absolute and relative paths are allowed. The syntax is OS dependent.
*''mode''<br/>(optional) can be ''static'' or ''dynamic'' (the default).
*''type''<br/>(optional) forces a specific MIME type of the result (the default is determined by the ''disk:mime'' mappings -- see below).
!!!Example
This server has mounted the directory where XSLTForms is installed as a dynamic file service:
{{{
<xeno:disk mount="./xsltforms-beta"/>
}}}
!!!Service Tags
*''disk:mime''<br/>defines a mapping from a file extension to a specific MIME type. The default set of mappings is:
{{{
<disk:mime type="text/xml">xml</disk:mime>
<disk:mime type="text/xml">xsl</disk:mime>
<disk:mime type="text/css">css</disk:mime>
<disk:mime type="text/javascript">js</disk:mime>
<disk:mime type="text/html">htm</disk:mime>
<disk:mime type="text/html">html</disk:mime>
<disk:mime type="text/plain">txt</disk:mime>
<disk:mime type="image/gif">gif</disk:mime>
<disk:mime type="image/jpeg">jpg</disk:mime>
<disk:mime type="image/jpeg">jpeg</disk:mime>
<disk:mime type="image/png">png</disk:mime>
<disk:mime type="application/octet-stream">exe</disk:mime>
<disk:mime type="application/octet-stream">*</disk:mime>
}}}
*''disk:default''<br/>(only used for ''type='dynamic' '' in connection with a mounted directory)<br/>declares a file to be served when the request otherwise would result in a ''404 Not Found'' response.<br/>This is quite useful when serving e.g. pictures of employees, based on their initials, where you can use this feature as a fallback to serve a "no image available" picture.
!!!Example:
{{{
<xeno:disk mount="images/employees" default="no-image.png"/>
}}}
!!!Synopsis
This module lets you insert loose fragments into the structure of a [[<netropy:space/>]]. No need to say, use this at your own risk and don't bet your life on it. But it is good for tinkering, and an expression of the fact, that the programmer has had a poor imagination, not foreseeing every possible use of the information present in an InformationSpace.
!!!Content
!!!Example
{{{
<xeno:space ...>
<xeno:http port="8901"/>
<xeno:duct_tape doctype="html"/>
<xeno:copy type="text/html">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
...
</xeno:copy>
</xeno:space>
}}}
This is a minimal space, serving one wellformed static ''HTML'' document on port ''8901''.
{{{
</>
}}}
An SVG description of fonts you can get from a source like http://www.fileformat.info/info/unicode/char/1e47/index.htm. Note that the URL of this encodes the ''utf-16'' code for the char. Your ''utf-8'' must be transcoded on the fly.
!!!Synopsis
This module maintains an HTTP port into a [[<xeno:space/>]].
!!!Attributes
*''addr''<br/>(default 0.0.0.0/0::0) The IP address to bind to.
*''port''<br/>(default 8901) An IP port number. Remember the first 1024 are reserved for the system. If you want the [[xeno]] to behave like a normal webserver, use port 80 and make sure the user running the process has rights to open that port.
!!!Notes
* Services which should be private can be exposed on the loopback (127.0.0.1) interface.
!!Synopsis
This service installs extension services into <<tiddler xeno>>.
!!!Synopsis
This service declares a template which may be referenced later.
!!!Attributes
Remaining attributes are taken as variable names, which may be used for substitution in the inner structure.
!!![[AttributeSyntax]]
!!!Hello World Example
{{{
...
<xeno:pattern module='hello' xmlns='this' greeting='Hello' subtext='world'>
<hello>
<xeno:copy init='@subtext'>
<netropy:copy type='text/xml'>
...
<xeno:pattern/>
...
<div>
<xeno:copy src='@greeting'/> <xeno:copy src='@subtext'/>!
</div>
...
<xeno:pattern/>
...
</xeno:copy>
</xeno:copy>
</hello>
</xeno:pattern>
...
}}}
Here we define a pattern which shall be known as ''hello''.
The pattern uses copies of the variable {{{ subtext}}} twice. First as the name of a tag, and a second time (inside the {{{<div/>}}}) as simple text.
!!!Using variables
Variables are accessed with the ''copy'' service, which actually is being executed when instantiating the pattern. That happens when compiling the blueprint of the containing space.
To illustrate, the above pattern when used like this
{{{
<this:hello/>
}}}
will result in a structure which looks like this:
{{{
...
<hello>
<world>
<xeno:copy type='text/xml'>
...
<div>Hello world!</div>
...
</xeno:copy>
</world>
</hello>
...
}}}
!!!Using patterns
To use a pattern, you simply write:
{{{
<xeno:pattern module='hello' subtext='XENOmat'/>
}}}
The resulting structure is left as an exercise for the reader.
!!!Missing attributes
In case we don't supply an attribute, and the pattern declaration has no default value for it, the ''copy'' will produce nothing. //It takes two to tango//, you might say.
So a use of ''hello'' with no {{{subtext}}} will result in
{{{
...
<hello/>
...
}}}
!!!Etymology
This service is named in honor of the BETA Programming Language, which (inevitably) has had its influence on this technology.
You may visualise an information space in many ways.
The programming philosophy of <<tiddler xeno>> is not to push any particular view about the implementation, but to focus on the structures within a ''<xeno:space/>''. We can only talk about these structures in general by using spacial terms. But since spatial concepts map quite well to most domains (as shall be given with the next few examples) this hardly imposes any problems.
!!!Embedded systems
As a hardware or embedded software developer, working with embedded systems, you might interpret a ''<xeno:space/>'' as a set of registers, which you may read and write to. This is not a completely wrong picture, since <<tiddler xeno>> is designed from the bottom up to maximise utilisation of the hardware which runs below. Also some simple I/O-service designed for a specific device might use exactly that interpretation in the structure of the space, e.g.
{{{
<xeno:space host="boiler.example.net">
...
<temperature>
<custom:AR4 register="33" offset="32" scale="1.4"/>
<temperature>
...
</xeno:space>
}}}
where navigating to {{{/temperature}}} returns some sensory input -- a temperature value in the example above -- offset and scaled, ready for consumption by any client of the device. And with minimal overhead.
The "~AR4" service can be implemented in native C or C++.
!!!Continuous Integration
The dynamic nature of a ''<xeno:space/>'' and the versatility of services allows you easily to make mockups, like from the example above:
{{{
...
<temperature>
<xeno:stash/>
<temperature>
...
}}}
where a ''stash'' is simulating the register and some tool as simple as the local [[editor|editor]] can be used to change its values.
Part of your development team may start coding the application building on the XML interface, while others finish the hardware and implement the device or platform specific services needed.
The whole team does continuous integration by gradually replacing the mockups with real implementations.
!!!!Code coverage
Due to the nature of a ''<xeno:space/>'', you have information at hand on the number of visits to a particual place. This information can be used as data for statistics, as well as for optimising the structure of your data. Often visited subspaces might benefit from having a port of their own, maybe with restricted access, localhost only.
!!!Systems integration
In another context, a ''<xeno:space/>'' may look more like a huge XML document, tying together information from a number of different sources into a logical unit, e.g.
{{{
<xeno:space host="people.example.com">
...
<staff>
<!-- database data -->
<xeno:sql style="employee-list" ... />
<images>
<!-- serving pictures for employees -->
<xeno:disk mount="/photos/employees/">
<disk:default path="/photos/employees/missing.jpg" />
</xeno:disk>
</images>
<employee-list>
<!-- stylesheet for presenting employees, also using images -->
<xeno:copy type="text/xsl">
<xsl:stylesheet .../>
</xeno:copy>
</employee-list>
</staff>
...
</xeno:space>
}}}
While developing a web application, the use of mockups also can come in handy.
!!!Synopsis
This module acts as an interface to an SQL database.
!!!Content
The inner structure of the ''sql'' service contains the SQL to execute on the database.
The SQL //must// be surrounded by an XML element (which then will wrap each row of the result) and it //must// start immediately after the opening tag. Apart from the SQL being wellformed in respect to the configured ''database'', these are the only requirements.
!!!Example 1
Here is a sample of what an instance of this service may look like.
{{{
<xeno:sql database="Northwind" style="productstyle" type="text/xml" encoding="iso-8859-1" batch="products" xmlns:sql="http://www.strxtrs.net/netropy/sql">
<product>
SELECT
<sql:attribute name="id">p.ProductID</sql:attribute>,
<name>p.ProductName</name>,
<quantity>p.QuantityPerUnit</quantity>,
<price>p.UnitPrice</price>,
<stock>p.UnitsInStock</stock>,
<supplier>s.CompanyName</supplier>
FROM
Products p, Suppliers s
WHERE
p.SupplierID = s.SupplierID
ORDER BY ProductName
</product>
</xeno:sql>
}}}
and the result will be something like
{{{
<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>
<?xml-stylesheet type="text/xsl" href="productstyle"?>
<products>
<product id="17"><name>Alice Mutton</name><quantity>20 - 1 kg tins</quantity><price>39.0000</price><stock>0</stock><supplier>Pavlova, Ltd.</supplier></product>
<product id="3"><name>Aniseed Syrup</name><quantity>12 - 550 ml bottles</quantity><price>10.0000</price><stock>13</stock><supplier>Exotic Liquids</supplier></product>
...
</products>
}}}
You can execute the example right [[here|/northwind/products]] or check the [[used SQL|/blueprint/lax/northwind/products/xeno:sql]].
!!!Attributes
*''database''<br/>(required) name of an ODBC data source.
*''style''<br/>(optional) URL to a stylesheet to refer to in the result.
*''type''<br/>(optional) the MIME type of the result (default "text/xml").
*''encoding''<br/>(optional) the encoding of the result (default "utf-8")<br/>Many ODBC data sources contain data encoded with ''iso-8859-1'', the default Windows encoding.
*''batch''<br/>(optional) name of a tag to enclose lists of the items specified in the inner structure.
!!!Service Tags
*''sql:attribute''<br/>injects the value selected from the database as an attribute of the surrounding tag.
*''sql:text''<br/>injects the value selected from the database as a child text node of the surrounding tag.
!!!Example 2
This example shows how you can use the ''sql'' service as a way to generate HTML fragments, which you may use to generate bits and pieces for an AJAX applicaton.
{{{
<category-options>
<!-- example of a service which directly returns an html fragment -->
<xeno:sql wrap="select" database="Northwind" type="text/xml; charset=iso-8859-1" xmlns:sql="http://www.strxtrs.net/netropy/sql">
<option xmlns="http://www.w3.org/1999/xhtml">
SELECT
<sql:attribute name="value">CategoryID</sql:attribute>,
<sql:text>CategoryName</sql:text>
FROM
Categories
ORDER BY CategoryName
</option>
</xeno:sql>
</category-options>
}}}
!!!Example 3
Inserting data into a database is just as easy:
{{{
<xeno:sql database="Escapa Highscore Spreadsheet" encoding="iso-8859-1">
<score>
INSERT INTO HIGHSCORE ( NAME, SCORE )
VALUES (<name>?</name>, <seconds>?</seconds>)
</score>
</xeno:sql>
}}}
!!!Synopsis
A service of spatial nature, which displays information on a window.
Works pretty much like an <iframe/> in HTML.
You can manipulate the DOM by exploiting the spatial nature like in the following example:
!!!Example
In some <xeno:space/> define
{{{
<touch-screen>
<xeno:view show="hello">
<a name="hello" href="/hello/world" title="Hello World!"/>
</xeno:view>
</touch-screen>
}}}
!!!Attributes
''show'' (for having your own "display" MarkupLanguage).
<<tiddler xeno>> is a machine designed to transport and transform structured information while using a minimum of energy on the physical level. It achieves that goal by leveraging the tension inherent in any representation of information - the difference between “something” and “nothing” - and putting that tension to work in a physical sense. To quote one of the great minds in cybernetics and system theory of the last century:
>What we mean by information — the elementary unit of information — is a difference
>which makes a difference.
>
>//[[Gregory Bateson|http://en.wikipedia.org/wiki/Gregory_Bateson]]//
>//1904-1980//
This basic principle of acting on some potential relates <<tiddler xeno>> more to the family of [[Cellular Automata|http://en.wikipedia.org/wiki/Cellular_automata]] than to the tribe of traditional information processors.
!!The physical reality
In prevailing technology the driving force for moving bits around is obtained by means of logic circuits situated separately from the information. The function and //sole purpose// of these circuits is to synthesise yet another representation (e.g. the result of a binary comparison) which in effect provides the tension for a change in state (i.e. trigger a flow of electrons in a small region of the semiconductor).
There is no need to point out that this approach to computation demands an order more of energy, which (apart from producing thermal noise and generating secondary demands for cooling) also inhibits the use of a number of renewable energy sources which simply cannot deliver sufficient power for these kind of processors.
We simply believe, that these inhibitions neither are needed nor wanted in modern information systems.
!!Proof of concept
So far we have managed to construct a working simulation of <<tiddler xeno>> in software, so to speak a virtual machine, which is called [[xeno]]. You are reading information served from it right now.
It uses ~UTF-8 encoded XML for the representation of structured information and HTTP for transport. This choice is not completely arbitrary, since transporting XML over HTTP naturally opens up for interoperability over the internet.
As a note, the demand for the extra level of circuits mentioned in the previous section is a direct consequence from using the [[Von Neumann bottleneck architecture|http://en.wikipedia.org/wiki/Von_Neumann_architecture#Von_Neumann_bottleneck]]. This problem naturally can not be overcome in software, unless you cheat and trim your information to fit into the processors cache.
!!Further development
We're currently working on two fronts:
*Porting <<tiddler xeno>> to other Linux dialects to have it embedded in even more electronic devices.
*Congestion control: An addition to the DefaultPolicy.
A previous interest,
*Researching into the feasibility of implementing <<tiddler xeno>> in VHDL onto an FPGA.
was quickly dismissed, as I experienced how hot those chips actually get. WhatAHideousWasteOfEnergy.
While developing <<tiddler xeno>> the following publications have been a great inspiration and help to me. A warm thank you to the respective developers, initiators, writers, and publishers.
www.w3.org - the mother-source of all standards.
developer.mozilla.org - good coverage of evolvements and examples of using those standards.
www.tiddlywiki.com - a wonderful tool for organising information, a spirited sibling to <<tiddler xeno>>.
!!!Personal Thanks
Torben Nielsen, Bjarne Stroustrup, Werner Ganahl, and the whole team at [[GINS|http://www.gantner-instruments.com]].
At the end of the day, every piece of software has to be specified, written, tested, and deployed. Developing with a <<tiddler xeno>> makes that easy.
!!!!!Small
The <<tiddler xeno>> provides a ''single infrastructure'' necessary to build and deploy applications. It works as an XML repository, lets you integrate your relational databases, and provides you with a high performance web server, giving you everything you need to fulfill your XML content delivery needs.
!!!!!Fast
This means that you can more ''quickly'' develop applications ready for market, and those applications run more efficiently and effectively because they are on a single platform, saving you both time and money.
At certain "sites" in your information space, there may be services who process information for visitors inside a [[<xeno:space/>|InformationSpaces]].
This wiki, which you are reading now, is defined in this servers space as
{{{
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<xeno:space xmlns:xeno="xeno:XENOmat">
...
<manual>
<!-- serve a specific file (preload it) -->
<netropy:disk mode="static" mount="manual.html" type="text/html"/>
</manual>
...
</xeno:space>
}}}
!!!!Basic Modules
<<tiddler [[Built In Services]]>>
!!Referencing attributes
@attribute means the value of the attribute from the enclosing [[<netropy:pattern/>]]. Think of XPath navigation syntax:
{{{
||| What is this? How should the Q.reader react to this event?
HTTP/1.0 POST /measured/Q.readerDAQ/
Content-Type: x-application/not-an-iana-type
<netropy:event from="/">
</netropy:event>
}}}
$attribute is used for runtime binding, and it has two cases:
* $0, or any number, means the value of the attribute is taken from the remainder of the URL, relative to the ''"/"'' denoting the entry into the runtime instance of the <netropy:pattern/>.
{{{
<!-- given the hello world example -->
...
<this:hello greeting="$1" />
...
}}}
<netropy:handler/> could be implemented as a pattern, taking a <netropy:event/> which itself is a structure, where the sender can fill in some attributes.
Working with <<tiddler xeno>> has very few prerequisites.
!!Introductory Articles
* [[InformationSpaces]]<br/>A primer on the "world view" of <<tiddler xeno>>.<br/><br/>
* [[Streams, Stacks, Stashes, and Spaces]]<br/>The fundamental components of <<tiddler xeno>>.
!!Caveat Programmer
You should have good knowledge of
*''[[XML|http://www.w3.org/TR/xml]]''
and accompanying technologies like
*''[[XSLT|http://www.w3.org/TR/xslt]]''
*''[[XPath|http://www.w3.org/TR/xpath]]''
Read those specs from the ~W3C if you haven't already! <<smiley ;-)>>
Eine hervoragende [[deutsche version|http://www.linkwerk.com/]] gibt es beim Team von [[linkwerk]].
The blueprint for this <<tiddler xeno>>:
<html><iframe src='/blueprint' style='width:100%;height:32em;'/></html>
Read more about this service [[here|<xeno:blueprint/>]].
<<tiddler xeno>> comes with a number of built in services:
*[[copy|<xeno:copy/>]] - copies the content of the service back through the port, where the request entered. Assumes copyright for content. <<smiley ;-)>>
*[[stash|<xeno:stash/>]] - a place to put and get variable information, structured or unstructured.
*[[disk|<xeno:disk/>]] - maps a file or file system to a site and serves the content of disk based files.
*''space'' - a place to extend simply by going there and setting up the structure on the way.
*[[sql|<xeno:sql/>]] - a place to interface with a database (ODBC in the Win32 version). ODBC also allows you also to use an Excel® spreadsheet as your data source as in the [[Escapa!|/escapa/]] sample application.
*[[blueprint|<xeno:blueprint/>]] - a service which allows you to introspect on the [[<xeno:space/>]] it resides in.
*[[http|<xeno:http/>]] - sets up a HTTP server to access this space from the outside.
You don't have to manipulate an XML DOM to program services for <<tiddler xeno>>.
The C++ API consists of a number of templates, which lets you define service objects, and help you map your own classes directly to the native structures of <<tiddler xeno>>.
/***
| Name:|Clock2|
| Author:|Simon Baird|
| Description:|A skinnable, sizeable analog clock|
| Source:|http://tiddlyspot.com/mptw/#Clock2|
| Requires:|Firefox 1.5.x or maybe Safari|
| Version:|1.0.3|
| Date:|4-Aug-2006|
!!Note
* Does not work in IE or Opera due to lack of canvas support.
* If you make a nice skin send it to me and I will include it here.
!!Ideas
* Can we support IE with this? http://sourceforge.net/projects/excanvas
* Skin should specify order of drawing so things can be on top of other things
* Fix it so we can have filled and/or stroked elements
* Skin should allow any number of moving and static elements
* Make download and example for non-TW use
* Make floating draggable?
!!Examples
{{{
<<clock2 fancy>><<clock2 120>>
<<clock2 chunkySwiss>> <<clock2 60 chunkySwiss noSeconds>><<clock2 '{
outerBorder: { lineWidth: 60, radius:55, color: "#dd8877", alpha: 1 },
smallIndicator: { lineWidth: 4, startAt: 80, endAt: 95, color: "white", alpha: 1 },
largeIndicator: { lineWidth: 12, startAt: 77, endAt: 89, color: "#dd8877", alpha: 1 },
hourHand: { lineWidth: 15, startAt: -15, endAt: 50, color: "white", alpha: 1 },
minuteHand: { lineWidth: 10, startAt: 24, endAt: 200, color: "#771100", alpha: 0.6 },
secondHand: { lineWidth: 3, startAt: 22, endAt: 83, color: "green", alpha: 0 },
secondDecoration: { lineWidth: 1, startAt: 52, radius: 26, fillColor: "white", color: "red", alpha: 0.2 }
}'>>
}}}
<<clock2 fancy>><<clock2 120>>
<<clock2 chunkySwiss>> <<clock2 60 chunkySwiss noSeconds>><<clock2 '{
outerBorder: { lineWidth: 60, radius:55, color: "#dd8877", alpha: 1 },
smallIndicator: { lineWidth: 4, startAt: 80, endAt: 95, color: "white", alpha: 1 },
largeIndicator: { lineWidth: 12, startAt: 77, endAt: 89, color: "#dd8877", alpha: 1 },
hourHand: { lineWidth: 15, startAt: -15, endAt: 50, color: "white", alpha: 1 },
minuteHand: { lineWidth: 10, startAt: 24, endAt: 200, color: "#771100", alpha: 0.6 },
secondHand: { lineWidth: 3, startAt: 22, endAt: 83, color: "green", alpha: 0 },
secondDecoration: { lineWidth: 1, startAt: 52, radius: 26, fillColor: "white", color: "red", alpha: 0.2 }
}'>>
See also BigClock.
!!Code
***/
//{{{
window.CoolClock = function(canvasId,displayRadius,skinId,showSecondHand) {
return this.init(canvasId,displayRadius,skinId,showSecondHand);
}
CoolClock.config = {
clockTracker: {},
tickDelay: 1000,
longTickDelay: 15000,
defaultRadius: 85,
renderRadius: 100,
defaultSkin: "swissRail",
skins: {
// try making your own...
swissRail: {
outerBorder: { lineWidth: 1, radius:95, color: "black", alpha: 1 },
smallIndicator: { lineWidth: 2, startAt: 89, endAt: 93, color: "black", alpha: 1 },
largeIndicator: { lineWidth: 4, startAt: 80, endAt: 93, color: "black", alpha: 1 },
hourHand: { lineWidth: 8, startAt: -15, endAt: 50, color: "black", alpha: 1 },
minuteHand: { lineWidth: 7, startAt: -15, endAt: 75, color: "black", alpha: 1 },
secondHand: { lineWidth: 1, startAt: -20, endAt: 85, color: "red", alpha: 1 },
secondDecoration: { lineWidth: 1, startAt: 70, radius: 4, fillColor: "red", color: "red", alpha: 1 }
},
chunkySwiss: {
outerBorder: { lineWidth: 5, radius:97, color: "black", alpha: 1 },
smallIndicator: { lineWidth: 4, startAt: 89, endAt: 93, color: "black", alpha: 1 },
largeIndicator: { lineWidth: 8, startAt: 80, endAt: 93, color: "black", alpha: 1 },
hourHand: { lineWidth: 12, startAt: -15, endAt: 60, color: "black", alpha: 1 },
minuteHand: { lineWidth: 10, startAt: -15, endAt: 85, color: "black", alpha: 1 },
secondHand: { lineWidth: 4, startAt: -20, endAt: 85, color: "red", alpha: 1 },
secondDecoration: { lineWidth: 2, startAt: 70, radius: 8, fillColor: "red", color: "red", alpha: 1 }
},
fancy: {
outerBorder: { lineWidth: 5, radius:95, color: "green", alpha: 0.7 },
smallIndicator: { lineWidth: 1, startAt: 80, endAt: 93, color: "black", alpha: 0.4 },
largeIndicator: { lineWidth: 1, startAt: 30, endAt: 93, color: "black", alpha: 0.5 },
hourHand: { lineWidth: 8, startAt: -15, endAt: 50, color: "blue", alpha: 0.7 },
minuteHand: { lineWidth: 7, startAt: -15, endAt: 92, color: "red", alpha: 0.7 },
secondHand: { lineWidth: 10, startAt: 80, endAt: 85, color: "blue", alpha: 0.3 },
secondDecoration: { lineWidth: 1, startAt: 30, radius: 50, fillColor: "blue", color: "red", alpha: 0.15 }
}
}
};
CoolClock.prototype = {
init: function(canvasId,displayRadius,skinId,showSecondHand) {
this.canvasId = canvasId;
this.displayRadius = displayRadius || CoolClock.config.defaultRadius;
this.skinId = skinId || CoolClock.config.defaultSkin;
this.showSecondHand = typeof showSecondHand == "boolean" ? showSecondHand : true;
this.tickDelay = CoolClock.config[ this.showSecondHand ? "tickDelay" : "longTickDelay"];
this.canvas = document.getElementById(canvasId);
this.canvas.setAttribute("width",this.displayRadius*2);
this.canvas.setAttribute("height",this.displayRadius*2);
this.renderRadius = CoolClock.config.renderRadius;
var scale = this.displayRadius / this.renderRadius;
this.ctx = this.canvas.getContext("2d");
this.ctx.scale(scale,scale);
CoolClock.config.clockTracker[canvasId] = this;
this.tick();
return this;
},
fullCircle: function(skin) {
this.fullCircleAt(this.renderRadius,this.renderRadius,skin);
},
fullCircleAt: function(x,y,skin) {
with (this.ctx) {
save();
globalAlpha = skin.alpha;
lineWidth = skin.lineWidth;
beginPath();
arc(x, y, skin.radius, 0, 2*Math.PI, false);
if (skin.fillColor) {
fillStyle = skin.fillColor
fill();
}
else {
// XXX why not stroke and fill
strokeStyle = skin.color;
stroke();
}
restore();
}
},
radialLineAtAngle: function(angleFraction,skin) {
with (this.ctx) {
save();
translate(this.renderRadius,this.renderRadius);
rotate(Math.PI * (2 * angleFraction - 0.5));
globalAlpha = skin.alpha;
strokeStyle = skin.color;
lineWidth = skin.lineWidth;
if (skin.radius) {
this.fullCircleAt(skin.startAt,0,skin)
}
else {
beginPath();
moveTo(skin.startAt,0)
lineTo(skin.endAt,0);
stroke();
}
restore();
}
},
render: function(hour,min,sec) {
var skin = CoolClock.config.skins[this.skinId];
this.ctx.clearRect(0,0,this.renderRadius*2,this.renderRadius*2);
this.fullCircle(skin.outerBorder);
for (var i=0;i<60;i++)
this.radialLineAtAngle(i/60,skin[ i%5 ? "smallIndicator" : "largeIndicator"]);
this.radialLineAtAngle((hour+min/60)/12,skin.hourHand);
this.radialLineAtAngle((min+sec/60)/60,skin.minuteHand);
if (this.showSecondHand) {
this.radialLineAtAngle(sec/60,skin.secondHand);
this.radialLineAtAngle(sec/60,skin.secondDecoration);
}
},
nextTick: function() {
setTimeout("CoolClock.config.clockTracker['"+this.canvasId+"'].tick()",this.tickDelay);
},
stillHere: function() {
return document.getElementById(this.canvasId) != null;
},
refreshDisplay: function() {
var now = new Date();
this.render(now.getHours(),now.getMinutes(),now.getSeconds());
},
tick: function() {
if (this.stillHere()) {
this.refreshDisplay()
this.nextTick();
}
}
}
config.macros.clock2 = {
counter: 0,
handler: function (place,macroName,params,wikifier,paramString,tiddler) {
var size,skin,seconds,skinData;
for (var i=0;i<params.length;i++)
if (/^\d+$/.exec(params[i]))
size = params[i];
else if (params[i] == "noSeconds")
seconds = false;
else if (/^\{/.exec(params[i]))
eval("skinData = " + params[i]);
else
skin = params[i];
if (skinData) {
CoolClock.config.skins.customSkin = skinData;
skin = "customSkin";
}
var canvas = createTiddlyElement(place,"canvas","clockcanvas"+this.counter);
var clock = new CoolClock("clockcanvas"+this.counter,size,skin,seconds);
this.counter++;
}
}
//}}}
!!Now try this!
Use [[station_clock.svg]] as background.<<tiddler "nojazz_swiss_clock.svg">>
Who ever invented word SourceCode should be flogged with a wet baguette.
What mostly is meant, is the text which is used as a source for some compiler or assembler for the program to produce code. The bit-patterns which machines understand. //That// is the code. Others are computer languages, which basically are used to instruct other programs to emit code. Which, when stuffed into different segments in the machines, is interpreted as instructions or data. Or both. ROM and RAM.
Probably another instance of the [[AngloSaxonDownsideUpSyndrome]].
<html><img src="http://upload.wikimedia.org/wikipedia/commons/thumb/d/d4/RNA-codons.png/220px-RNA-codons.png"></html>
Back around when a photocopier replaced the old spirit duplicators in more and more places, more and more things got "copied". To wit: Even parts of peoples bodies! That's hard to do on a spirit duplicator, and you might ask yourself: Why? Why do people copy things? Documents, for instance. Or crazy cartoons. Or funny diagrams. The usual office wall stuff. For one, those things are easy to make an almost perfect copy from. And because we can, thanks to technology. All it requires is a push on a button.
Few people would take the work to copy such a drawing by hand - and hence we live in an age, where very few people also have the skill to do it well. This is a direct consequence of the former. Any skill requires amounts of talent and practice, and like any form of learning, you start out your practice by copying. As a child you copy the behavior of those around you. Later on you copy the letters and digits, and symbols, the teachers shows you at school. And so on.
The driving force in copying might be viewed at as a urge to achieve some form of symmetry (GregoryBateson). Symmetry is one concept extremely important to communication theory, as it expresses itself as a way of ensuring that "the message got across". And in relation to our own profession as information technicians and technologists, we may use symmetry for obtaining simplicity in design (Henney, 2001).
Complementarity is the other force in the field of information theory. This is the "difference" that makes stuff interesting (as opposed to InformationDeprivation), since on a physical level such differences are conceptualised as a potential for energy transfer.
!!Case AO.dk
!!XMLRCP (Q.station)
RPCMeas.GetVariables
!!!!Timing
Waiting: 21ms
Receiving: 11ms
!!!!Request
{{{
POST / HTTP/1.1
Host: 192.168.5.61:1200
Connection: keep-alive
Content-Length: 331
Cache-Control: no-cache
Origin: http://192.168.5.61
Pragma: no-cache
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4
Content-type: text/xml
Accept: text/xml
Referer: http://192.168.5.61/local/jsxmlrcp/debugger.html
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
<?xml version="1.0"?>
<methodCall>
<methodName>RPCMeas.GetVariables</methodName>
<params><param>
<value><struct>
<member><name>MethodID</name>
<value><string>RPCMeas::GetVariables</string></value>
</member>
<member><name>VariableIndex</name>
<value><int>-1</int></value>
</member>
</struct></value>
</param>
</params>
</methodCall>
}}}
!!!!Response
{{{
HTTP/1.1 200 OK
Server: GINSXMLRPC++ 1.0
Access-Control-Allow-Origin: *
Content-Type: text/xml
Content-length: 9753
<?xml version="1.0" encoding="ISO-8859-1"?>
<methodResponse>
<params>
<param>
<value>
<struct>
<member>
<name>MethodID</name>
<value>RPCMeas::GetVariables</value>
</member>
<member>
<name>VariableList</name>
<value>
<array>
<data>
<value>
<struct>
<member>
<name>AccessIndex</name>
<value>
<i4>0</i4>
</value>
</member>
<member>
<name>DataRate</name>
<value>
<i4>0</i4>
</value>
</member>
<member>
<name>DataType</name>
<value>USINT64</value>
</member>
<member>
<name>DataTypeCode</name>
<value>
<i4>12</i4>
</value>
</member>
<member>
<name>Format</name>
<value></value>
</member>
<member>
<name>InputByteOffset</name>
<value>
<i4>0</i4>
</value>
</member>
<member>
<name>InputIndex</name>
<value>
<i4>0</i4>
</value>
</member>
<member>
<name>IsInput</name>
<value>
<i4>1</i4>
</value>
</member>
<member>
<name>IsOutput</name>
<value>
<i4>0</i4>
</value>
</member>
<member>
<name>Name</name>
<value>Timestamp</value>
</member>
<member>
<name>OutputByteOffset</name>
<value>
<i4>-1</i4>
</value>
</member>
<member>
<name>OutputIndex</name>
<value>
<i4>-1</i4>
</value>
</member>
<member>
<name>RangeMax</name>
<value>
<double>0</double>
</value>
</member>
<member>
<name>RangeMin</name>
<value>
<double>0</double>
</value>
</member>
<member>
<name>Unit</name>
<value></value>
</member>
<member>
<name>VariableType</name>
<value>ARI</value>
</member>
</struct>
</value>
<value>
<struct>
<member>
<name>AccessIndex</name>
<value>
<i4>0</i4>
</value>
</member>
<member>
<name>DataRate</name>
<value>
<i4>0</i4>
</value>
</member>
<member>
<name>DataType</name>
<value>FLOAT</value>
</member>
<member>
<name>DataTypeCode</name>
<value>
<i4>14</i4>
</value>
</member>
<member>
<name>Format</name>
<value></value>
</member>
<member>
<name>InputByteOffset</name>
<value>
<i4>8</i4>
</value>
</member>
<member>
<name>InputIndex</name>
<value>
<i4>1</i4>
</value>
</member>
<member>
<name>IsInput</name>
<value>
<i4>1</i4>
</value>
</member>
<member>
<name>IsOutput</name>
<value>
<i4>0</i4>
</value>
</member>
<member>
<name>Name</name>
<value>Variable 1_1</value>
</member>
<member>
<name>OutputByteOffset</name>
<value>
<i4>-1</i4>
</value>
</member>
<member>
<name>OutputIndex</name>
<value>
<i4>-1</i4>
</value>
</member>
<member>
<name>RangeMax</name>
<value>
<double>5</double>
</value>
</member>
<member>
<name>RangeMin</name>
<value>
<double>-5</double>
</value>
</member>
<member>
<name>Unit</name>
<value>mV/V</value>
</member>
<member>
<name>VariableType</name>
<value>AIN</value>
</member>
</struct>
</value>
<value>
<struct>
<member>
<name>AccessIndex</name>
<value>
<i4>0</i4>
</value>
</member>
<member>
<name>DataRate</name>
<value>
<i4>0</i4>
</value>
</member>
<member>
<name>DataType</name>
<value>FLOAT</value>
</member>
<member>
<name>DataTypeCode</name>
<value>
<i4>14</i4>
</value>
</member>
<member>
<name>Format</name>
<value></value>
</member>
<member>
<name>InputByteOffset</name>
<value>
<i4>12</i4>
</value>
</member>
<member>
<name>InputIndex</name>
<value>
<i4>2</i4>
</value>
</member>
<member>
<name>IsInput</name>
<value>
<i4>1</i4>
</value>
</member>
<member>
<name>IsOutput</name>
<value>
<i4>0</i4>
</value>
</member>
<member>
<name>Name</name>
<value>Variable 2_1</value>
</member>
<member>
<name>OutputByteOffset</name>
<value>
<i4>-1</i4>
</value>
</member>
<member>
<name>OutputIndex</name>
<value>
<i4>-1</i4>
</value>
</member>
<member>
<name>RangeMax</name>
<value>
<double>2.5</double>
</value>
</member>
<member>
<name>RangeMin</name>
<value>
<double>-2.5</double>
</value>
</member>
<member>
<name>Unit</name>
<value>mV/V</value>
</member>
<member>
<name>VariableType</name>
<value>AIN</value>
</member>
</struct>
</value>
<value>
<struct>
<member>
<name>AccessIndex</name>
<value>
<i4>0</i4>
</value>
</member>
<member>
<name>DataRate</name>
<value>
<i4>0</i4>
</value>
</member>
<member>
<name>DataType</name>
<value>FLOAT</value>
</member>
<member>
<name>DataTypeCode</name>
<value>
<i4>14</i4>
</value>
</member>
<member>
<name>Format</name>
<value></value>
</member>
<member>
<name>InputByteOffset</name>
<value>
<i4>16</i4>
</value>
</member>
<member>
<name>InputIndex</name>
<value>
<i4>3</i4>
</value>
</member>
<member>
<name>IsInput</name>
<value>
<i4>1</i4>
</value>
</member>
<member>
<name>IsOutput</name>
<value>
<i4>1</i4>
</value>
</member>
<member>
<name>Name</name>
<value>Variable 3_1</value>
</member>
<member>
<name>OutputByteOffset</name>
<value>
<i4>0</i4>
</value>
</member>
<member>
<name>OutputIndex</name>
<value>
<i4>0</i4>
</value>
</member>
<member>
<name>RangeMax</name>
<value>
<double>0</double>
</value>
</member>
<member>
<name>RangeMin</name>
<value>
<double>0</double>
</value>
</member>
<member>
<name>Unit</name>
<value></value>
</member>
<member>
<name>VariableType</name>
<value>SPT</value>
</member>
</struct>
</value>
<value>
<struct>
<member>
<name>AccessIndex</name>
<value>
<i4>0</i4>
</value>
</member>
<member>
<name>DataRate</name>
<value>
<i4>0</i4>
</value>
</member>
<member>
<name>DataType</name>
<value>FLOAT</value>
</member>
<member>
<name>DataTypeCode</name>
<value>
<i4>14</i4>
</value>
</member>
<member>
<name>Format</name>
<value></value>
</member>
<member>
<name>InputByteOffset</name>
<value>
<i4>20</i4>
</value>
</member>
<member>
<name>InputIndex</name>
<value>
<i4>4</i4>
</value>
</member>
<member>
<name>IsInput</name>
<value>
<i4>1</i4>
</value>
</member>
<member>
<name>IsOutput</name>
<value>
<i4>1</i4>
</value>
</member>
<member>
<name>Name</name>
<value>Variable 4_1</value>
</member>
<member>
<name>OutputByteOffset</name>
<value>
<i4>4</i4>
</value>
</member>
<member>
<name>OutputIndex</name>
<value>
<i4>1</i4>
</value>
</member>
<member>
<name>RangeMax</name>
<value>
<double>0</double>
</value>
</member>
<member>
<name>RangeMin</name>
<value>
<double>0</double>
</value>
</member>
<member>
<name>Unit</name>
<value></value>
</member>
<member>
<name>VariableType</name>
<value>SPT</value>
</member>
</struct>
</value>
<value>
<struct>
<member>
<name>AccessIndex</name>
<value>
<i4>0</i4>
</value>
</member>
<member>
<name>DataRate</name>
<value>
<i4>0</i4>
</value>
</member>
<member>
<name>DataType</name>
<value>FLOAT</value>
</member>
<member>
<name>DataTypeCode</name>
<value>
<i4>14</i4>
</value>
</member>
<member>
<name>Format</name>
<value></value>
</member>
<member>
<name>InputByteOffset</name>
<value>
<i4>24</i4>
</value>
</member>
<member>
<name>InputIndex</name>
<value>
<i4>5</i4>
</value>
</member>
<member>
<name>IsInput</name>
<value>
<i4>1</i4>
</value>
</member>
<member>
<name>IsOutput</name>
<value>
<i4>0</i4>
</value>
</member>
<member>
<name>Name</name>
<value>Potiz</value>
</member>
<member>
<name>OutputByteOffset</name>
<value>
<i4>-1</i4>
</value>
</member>
<member>
<name>OutputIndex</name>
<value>
<i4>-1</i4>
</value>
</member>
<member>
<name>RangeMax</name>
<value>
<double>100</double>
</value>
</member>
<member>
<name>RangeMin</name>
<value>
<double>0</double>
</value>
</member>
<member>
<name>Unit</name>
<value>%</value>
</member>
<member>
<name>VariableType</name>
<value>AIN</value>
</member>
</struct>
</value>
<value>
<struct>
<member>
<name>AccessIndex</name>
<value>
<i4>0</i4>
</value>
</member>
<member>
<name>DataRate</name>
<value>
<i4>0</i4>
</value>
</member>
<member>
<name>DataType</name>
<value>FLOAT</value>
</member>
<member>
<name>DataTypeCode</name>
<value>
<i4>14</i4>
</value>
</member>
<member>
<name>Format</name>
<value></value>
</member>
<member>
<name>InputByteOffset</name>
<value>
<i4>28</i4>
</value>
</member>
<member>
<name>InputIndex</name>
<value>
<i4>6</i4>
</value>
</member>
<member>
<name>IsInput</name>
<value>
<i4>1</i4>
</value>
</member>
<member>
<name>IsOutput</name>
<value>
<i4>0</i4>
</value>
</member>
<member>
<name>Name</name>
<value>I 1</value>
</member>
<member>
<name>OutputByteOffset</name>
<value>
<i4>-1</i4>
</value>
</member>
<member>
<name>OutputIndex</name>
<value>
<i4>-1</i4>
</value>
</member>
<member>
<name>RangeMax</name>
<value>
<double>20</double>
</value>
</member>
<member>
<name>RangeMin</name>
<value>
<double>4</double>
</value>
</member>
<member>
<name>Unit</name>
<value> mA</value>
</member>
<member>
<name>VariableType</name>
<value>AIN</value>
</member>
</struct>
</value>
<value>
<struct>
<member>
<name>AccessIndex</name>
<value>
<i4>0</i4>
</value>
</member>
<member>
<name>DataRate</name>
<value>
<i4>0</i4>
</value>
</member>
<member>
<name>DataType</name>
<value>FLOAT</value>
</member>
<member>
<name>DataTypeCode</name>
<value>
<i4>14</i4>
</value>
</member>
<member>
<name>Format</name>
<value></value>
</member>
<member>
<name>InputByteOffset</name>
<value>
<i4>32</i4>
</value>
</member>
<member>
<name>InputIndex</name>
<value>
<i4>7</i4>
</value>
</member>
<member>
<name>IsInput</name>
<value>
<i4>1</i4>
</value>
</member>
<member>
<name>IsOutput</name>
<value>
<i4>0</i4>
</value>
</member>
<member>
<name>Name</name>
<value>I 2</value>
</member>
<member>
<name>OutputByteOffset</name>
<value>
<i4>-1</i4>
</value>
</member>
<member>
<name>OutputIndex</name>
<value>
<i4>-1</i4>
</value>
</member>
<member>
<name>RangeMax</name>
<value>
<double>20</double>
</value>
</member>
<member>
<name>RangeMin</name>
<value>
<double>4</double>
</value>
</member>
<member>
<name>Unit</name>
<value> mA</value>
</member>
<member>
<name>VariableType</name>
<value>AIN</value>
</member>
</struct>
</value>
<value>
<struct>
<member>
<name>AccessIndex</name>
<value>
<i4>0</i4>
</value>
</member>
<member>
<name>DataRate</name>
<value>
<i4>0</i4>
</value>
</member>
<member>
<name>DataType</name>
<value>FLOAT</value>
</member>
<member>
<name>DataTypeCode</name>
<value>
<i4>14</i4>
</value>
</member>
<member>
<name>Format</name>
<value></value>
</member>
<member>
<name>InputByteOffset</name>
<value>
<i4>36</i4>
</value>
</member>
<member>
<name>InputIndex</name>
<value>
<i4>8</i4>
</value>
</member>
<member>
<name>IsInput</name>
<value>
<i4>1</i4>
</value>
</member>
<member>
<name>IsOutput</name>
<value>
<i4>0</i4>
</value>
</member>
<member>
<name>Name</name>
<value>Temp 1</value>
</member>
<member>
<name>OutputByteOffset</name>
<value>
<i4>-1</i4>
</value>
</member>
<member>
<name>OutputIndex</name>
<value>
<i4>-1</i4>
</value>
</member>
<member>
<name>RangeMax</name>
<value>
<double>850</double>
</value>
</member>
<member>
<name>RangeMin</name>
<value>
<double>-200</double>
</value>
</member>
<member>
<name>Unit</name>
<value> °C</value>
</member>
<member>
<name>VariableType</name>
<value>AIN</value>
</member>
</struct>
</value>
</data>
</array>
</value>
</member>
</struct>
</value>
</param>
</params>
</methodResponse>
}}}
* The ''origin'' (or ''root'') of a //xeno::context// is the enclosing [[<xeno:space/>]].
!!!Up Next
# [[<xeno:fbdev/>]]
# Use xeno as a client as well. E.g. {{{ xeno 8901 PUT /some/stash?disposition=download c:\My Documents\file.xml }}}, i.e. a CommandLineSyntax - simple implement it as a grammar with a special actionpack.
# [[<xeno:system/>]] look into registry, metadata, statistics, etc.
# [[<xeno:blueprint/>]] to render "text/javascript" as well as providing CSS styling to the XML.
# HTTP parser.
# Combine async request with parser (UserState might be a stackless coroutine-object implementing the handler)...
# Given server runs as a daemon, it could be bootstrapped directly from the serial port
# Let the server re-source the blueprint.xml when it is changed by an editor. Not a good idea, first investigate how {{{asio_dir_monitor}}} could me reimplemented to fit.
!!!Crazy & wild ideas
Implement a ''netropyfs''. Each directory has a virtual file ''.blueprint''
!!!Done - might improve
# [[<xeno:display/>]] using webkit as a space. One might even use some kind of attribution on the content, like {{{}}}
# [[<xeno:disk/>]] has a problem with methods ''stream'' and ''send''...
# [[<netropy:duct_tape/>]] just for {{{ doctype="html"}}}. CHECK!
# Pull through the ''http:'' namespace for the lower layer stack: replace {{{HTTPRequest}}} with {{{http:Request xmlns:http="http://www.strxtrs.net/netropy/http/1.0"}}}
# <empty></empty> tags should preserve the separation.
# {{{Content-Length}}} ''must'' be right for Google Chrome.
# Server now runs as a daemon.
Mostly named Javascript, but actually a w3c standard:
Ultimately all information systems must run on hardware, and <<tiddler xeno>> is designed from the bottom up for efficient resource utilisation.
!!!!!Space
We have gone to extreme lengths to avoid caching of data where the operating system readily does this (like serving content from a file system). This leads to a measurable much more efficient management of resources.
!!!!!Time
Apart from being an engine with an extremely small memory footprint, the <<tiddler xeno>> ''VM'' also uses a minimal amount of synchronisation, as the necessary concurrency control already is in place in most hosting operating systems. This results in response times far below those of traditional application servers.
!!ReST (Q.reader)
http://192.168.5.41:8901/qreader/measured/
!!!!Timing
Waiting: 40ms
Receiving: 1ms
!!!!Request
{{{
GET /qreader/measured/ HTTP/1.1
Host: 192.168.5.41:8901
Connection: keep-alive
Cache-Control: no-cache
Pragma: no-cache
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
}}}
!!!!Response
{{{
HTTP/1.0 200 OK
Server: netropy/1.6.5 (Linux)
Content-Length: 673
Content-Type: application/xml
<channels>
<channel name="AIN1" color="red" display="" unit="V">11.67</channel>
<channel name="AIN2" color="red" display="" unit="Ω">3187.89</channel>
<channel name="DIN1" color="red" display="" unit="">OFF</channel>
<channel name="AIN3" color="red" display="" unit="V">6.51</channel>
<channel name="AIN4" color="red" display="" unit="V">9.37</channel>
<channel name="DIN2" color="red" display="" unit="">0</channel>
<channel name="DIN3" color="red" display="" unit="">0</channel>
<channel name="DIN4" color="red" display="" unit="">0</channel>
<channel name="LUA1" color="red" display="" unit="">11.6686</channel>
</channels>
}}}
Gregory Bateson was a British anthropologist, cyberneticist, psychologist, and philosopher.
<<tiddler Bateson>>
!Why and when you should use which codes
!!!204 No Content
Saves you from sending or parsing any headers, when there explicitly is no content.
!!!404 Not Found
When part of the URL denotes a nonexisting item.
E.g., this code will be returned when there is no display "15" configured in the ''measured'' service, and you request the URL
{{{
/device/display/channels
}}}
Assuming no display "channels" is configured on this device, you can try clicking <html><a href="/device/display/channels" class="externalLink" target="_blank">/device/display/channels</a></html>.
or when the value named "SB01.Temperature" does not exist
{{{
/device/values/SB01.Temperature
}}}
{{{
}}}
{{{
}}}
{{{
}}}
{{{
}}}
<code>hello</code>
!!!503 Service Unavailable
A service may depend on hardware being initialized. From the time when the service starts until it is ready, the service should return this code. Generally, this is a temporary state.
!!!504 Gateway Timeout
A service may be forwarding requests to some device. When the service does not receive a timely response from the upstream server, this code is appropriate.
Since you have full control over the information architecture in a <<tiddler xeno>>, you may collect information from all kinds of sources and structure it to your needs.
Having full control over the data flow in your information network, enables you to address scalability issues very easy.
!!The Geographical Metaphor
Thinking of information "residing" at some geographical location is not uncommon. Cognitive research has also shown that geography has strong influence on the ability to recall memories. Most people have experienced memories suddenly coming back when revisiting a place.
It seems to have been an evolutionary advantage for our species that the human brain organizes information such that our learned knowledge is accessible in a context dependent manner. It keeps our thoughts from getting in a muddle. E.g. when we stand at the banks of a river, our knowledge about fishing will be easy to recall, whereas our knowledge about programming languages hardly is relevant in that context. And vice versa when we're in the office.
The space metaphor also makes use of "maps" which may enable the user to get an overview over otherwise immensurable amounts of information.
If we imagine all of our information located in some form of "space", we need additional information to aid us in navigating around. Think of signs placed in a landscape. The same information we the can use for making a map of that space, so we can navigate it efficiently.
!!Using Markup to Structure Space
<<tiddler UsingNameSpaces>>
Most interfaces to the hardware are implemented in C, and provide therefore an API in that same language. Worshipers of (as well as devotees to) ObjectOrientedProgramming are not happy with the abstract notion of a, e.g. [[file descriptor|FileDescriptor]], and hence encapsulate that with another abstraction of, e.g. a derivative of {{{std::istream}}}, {{{java.io.AbstractStream}}} for the WitnessesOfJava, or the class {{{System.IO.Stream}}} found in .NET runtime.
Ideally the abstractions written in C++ would disappear at runtime because a modern compiler can inline code and optimize the added level of abstraction away. This leaves the generated code with only the necessary functionality to accomplish the task, given the API to the hardware. On the other hand, given Linux or any modern OS for that matter, there //is already a whole lot of abstraction made// in the system API, and most attempts to implement services start for an ObjectIDiot with "defining a framework".
ConnectAbility - the ability to connect.
{{{
Copyright (c) 2018, Peter Hübel
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Netropy Project, the XENOmat, nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL PETER HÜBEL BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
}}}
[[Welcome]] [[Built In Services]] <html><a href='/#Demos' class='tiddlyLink tiddlyLinkExisting' title='Back to the main page of the demos'>Demos</a></html>
<!--{{{-->
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml' />
<link rel='shortcut icon' href='data:image/x-icon;base64,AAABAAEAEBAQAAAAAAAoAQAAFgAAACgAAAAQAAAAIAAAAAEABAAAAAAAgAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAA0c7LAICAgAD%2F%2F%2F8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzMwAzMwAAADEjADEjAAAAMhMAMhMAAAAzMwAzMwAAADIjADIjAAAAMiMAMiMAAAAyIwAyIwAAADIjADIjAAAAMiMAMiMgAAAyIwAyIwAAADIhMxIjAAAAMiIiIhMAAAAyIyIhMAAAADMzMzMAAAAAAAAAAAAAD%2F%2FwAA4YcAAOGHAADhhwAA4YcAAOGHAADhhwAA4YcAAOGHAADhhwAA4YcAAOAHAADgBwAA4A8AAOAfAAD%2F%2FwAA' type='image/x-icon' />
<!--}}}-->
Lets look at a HAR log from Chrome. JSON, as you can see. These are the data used for displaying the Network info in Developer Tools:
<html><div style="height: 50vh; overflow: scroll;">
<img src="images/fast.png" width="99%" style="border: 1px solid #ABC;"/>
Given only a few resources, there is quite a lot of data:
<pre>
{
"log": {
"version": "1.2",
"creator": {
"name": "WebInspector",
"version": "537.36"
},
"pages": [
{
"startedDateTime": "2016-06-03T22:13:57.609Z",
"id": "page_1",
"title": "http://netropy.huebel.freeshells.org:8901/",
"pageTimings": {
"onContentLoad": 15458.580000035,
"onLoad": 15458.465000032447
}
}
],
"entries": [
{
"startedDateTime": "2016-06-03T22:13:57.609Z",
"time": 7579.862000013236,
"request": {
"method": "GET",
"url": "http://netropy.huebel.freeshells.org:8901/",
"httpVersion": "HTTP/1.1",
"headers": [
{
"name": "Accept-Encoding",
"value": "gzip, deflate, sdch"
},
{
"name": "Host",
"value": "netropy.huebel.freeshells.org:8901"
},
{
"name": "Accept-Language",
"value": "en-US,en;q=0.8,de;q=0.6,da;q=0.4"
},
{
"name": "Upgrade-Insecure-Requests",
"value": "1"
},
{
"name": "User-Agent",
"value": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"
},
{
"name": "Accept",
"value": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
},
{
"name": "Cache-Control",
"value": "max-age=0"
},
{
"name": "Cookie",
"value": "txtMainTab=More; txtMoreTab=Orphans"
},
{
"name": "Connection",
"value": "keep-alive"
}
],
"queryString": [],
"cookies": [
{
"name": "txtMainTab",
"value": "More",
"expires": null,
"httpOnly": false,
"secure": false
},
{
"name": "txtMoreTab",
"value": "Orphans",
"expires": null,
"httpOnly": false,
"secure": false
}
],
"headersSize": 493,
"bodySize": 0
},
"response": {
"status": 200,
"statusText": "OK",
"httpVersion": "HTTP/1.1",
"headers": [
{
"name": "Access-Control-Allow-Origin",
"value": "*"
},
{
"name": "Server",
"value": "XENOmat/2.4.8 (Linux)"
},
{
"name": "Connection",
"value": "Keep-Alive"
},
{
"name": "Keep-Alive",
"value": "timeout=10"
},
{
"name": "Content-Length",
"value": "15646"
},
{
"name": "Content-Type",
"value": "text/html;charset=utf-8"
}
],
"cookies": [],
"content": {
"size": 15646,
"mimeType": "text/html",
"compression": 0
},
"redirectURL": "",
"headersSize": 192,
"bodySize": 15646,
"_transferSize": 15838
},
"cache": {},
"timings": {
"blocked": 0.479000038467348,
"dns": 1148.5279999906227,
"connect": 1831.75599999958,
"send": 0.05299999611997919,
"wait": 1714.43499997258,
"receive": 2884.611000015866,
"ssl": -1
},
"connection": "892766",
"pageref": "page_1"
},
{
"startedDateTime": "2016-06-03T22:14:02.324Z",
"time": 2863.8439999776892,
"request": {
"method": "GET",
"url": "http://netropy.huebel.freeshells.org:8901/styles",
"httpVersion": "HTTP/1.1",
"headers": [
{
"name": "Accept-Encoding",
"value": "gzip, deflate, sdch"
},
{
"name": "Host",
"value": "netropy.huebel.freeshells.org:8901"
},
{
"name": "Accept-Language",
"value": "en-US,en;q=0.8,de;q=0.6,da;q=0.4"
},
{
"name": "User-Agent",
"value": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"
},
{
"name": "Accept",
"value": "text/css,*/*;q=0.1"
},
{
"name": "Referer",
"value": "http://netropy.huebel.freeshells.org:8901/"
},
{
"name": "Cookie",
"value": "txtMainTab=More; txtMoreTab=Orphans"
},
{
"name": "Connection",
"value": "keep-alive"
},
{
"name": "Cache-Control",
"value": "max-age=0"
}
],
"queryString": [],
"cookies": [
{
"name": "txtMainTab",
"value": "More",
"expires": null,
"httpOnly": false,
"secure": false
},
{
"name": "txtMoreTab",
"value": "Orphans",
"expires": null,
"httpOnly": false,
"secure": false
}
],
"headersSize": 466,
"bodySize": 0
},
"response": {
"status": 200,
"statusText": "OK",
"httpVersion": "HTTP/1.1",
"headers": [
{
"name": "Access-Control-Allow-Origin",
"value": "*"
},
{
"name": "Server",
"value": "XENOmat/2.4.8 (Linux)"
},
{
"name": "Connection",
"value": "Keep-Alive"
},
{
"name": "Keep-Alive",
"value": "timeout=10"
},
{
"name": "Content-Length",
"value": "1149"
},
{
"name": "Content-Type",
"value": "text/css"
}
],
"cookies": [],
"content": {
"size": 1149,
"mimeType": "text/css",
"compression": 0
},
"redirectURL": "",
"headersSize": 176,
"bodySize": 1149,
"_transferSize": 1325
},
"cache": {},
"timings": {
"blocked": 0.743000011425465,
"dns": 0.591999967582525,
"connect": 1336.355999985242,
"send": 0.1139999949398316,
"wait": 322.4490000284302,
"receive": 1203.5899999900691,
"ssl": -1
},
"connection": "892780",
"pageref": "page_1"
},
{
"startedDateTime": "2016-06-03T22:14:02.324Z",
"time": 10711.25899994513,
"request": {
"method": "GET",
"url": "http://netropy.huebel.freeshells.org:8901/jquery",
"httpVersion": "HTTP/1.1",
"headers": [
{
"name": "Accept-Encoding",
"value": "gzip, deflate, sdch"
},
{
"name": "Host",
"value": "netropy.huebel.freeshells.org:8901"
},
{
"name": "Accept-Language",
"value": "en-US,en;q=0.8,de;q=0.6,da;q=0.4"
},
{
"name": "User-Agent",
"value": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"
},
{
"name": "Accept",
"value": "*/*"
},
{
"name": "Referer",
"value": "http://netropy.huebel.freeshells.org:8901/"
},
{
"name": "Cookie",
"value": "txtMainTab=More; txtMoreTab=Orphans"
},
{
"name": "Connection",
"value": "keep-alive"
},
{
"name": "Cache-Control",
"value": "max-age=0"
}
],
"queryString": [],
"cookies": [
{
"name": "txtMainTab",
"value": "More",
"expires": null,
"httpOnly": false,
"secure": false
},
{
"name": "txtMoreTab",
"value": "Orphans",
"expires": null,
"httpOnly": false,
"secure": false
}
],
"headersSize": 451,
"bodySize": 0
},
"response": {
"status": 200,
"statusText": "OK",
"httpVersion": "HTTP/1.1",
"headers": [
{
"name": "Access-Control-Allow-Origin",
"value": "*"
},
{
"name": "Server",
"value": "XENOmat/2.4.8 (Linux)"
},
{
"name": "Connection",
"value": "Keep-Alive"
},
{
"name": "Keep-Alive",
"value": "timeout=10"
},
{
"name": "Content-Length",
"value": "92647"
},
{
"name": "Content-Type",
"value": "application/javascript"
}
],
"cookies": [],
"content": {
"size": 92647,
"mimeType": "application/javascript",
"compression": 0
},
"redirectURL": "",
"headersSize": 191,
"bodySize": 92647,
"_transferSize": 92838
},
"cache": {},
"timings": {
"blocked": 0.666999956592917,
"dns": 0.48200000310316304,
"connect": 1336.4920000312839,
"send": 0.05299999611997919,
"wait": 339.26999999675013,
"receive": 9034.29499996128,
"ssl": -1
},
"connection": "892781",
"pageref": "page_1"
},
{
"startedDateTime": "2016-06-03T22:14:02.468Z",
"time": 1353.2439999980852,
"request": {
"method": "GET",
"url": "http://www.leutert.com/media/oilgas/images/artificial-lift/pdm/fg-thumbs/pdm_display.jpg",
"httpVersion": "HTTP/1.1",
"headers": [
{
"name": "Cookie",
"value": "wb_9296_session_id=93a3ntqlphqhhveq2r7u9n1gt5"
},
{
"name": "Accept-Encoding",
"value": "gzip, deflate, sdch"
},
{
"name": "Host",
"value": "www.leutert.com"
},
{
"name": "Accept-Language",
"value": "en-US,en;q=0.8,de;q=0.6,da;q=0.4"
},
{
"name": "User-Agent",
"value": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"
},
{
"name": "Accept",
"value": "image/webp,image/*,*/*;q=0.8"
},
{
"name": "Cache-Control",
"value": "max-age=0"
},
{
"name": "If-None-Match",
"value": "\"e02b27cd-1049-4f712f41f3300\""
},
{
"name": "Connection",
"value": "keep-alive"
},
{
"name": "If-Modified-Since",
"value": "Tue, 15 Apr 2014 11:18:04 GMT"
},
{
"name": "Referer",
"value": "http://netropy.huebel.freeshells.org:8901/"
}
],
"queryString": [],
"cookies": [
{
"name": "wb_9296_session_id",
"value": "93a3ntqlphqhhveq2r7u9n1gt5",
"expires": null,
"httpOnly": false,
"secure": false
}
],
"headersSize": 622,
"bodySize": 0
},
"response": {
"status": 304,
"statusText": "Not Modified",
"httpVersion": "HTTP/1.1",
"headers": [
{
"name": "Date",
"value": "Fri, 03 Jun 2016 22:14:03 GMT"
},
{
"name": "Server",
"value": "nginx/1.8.1"
},
{
"name": "Connection",
"value": "keep-alive"
},
{
"name": "ETag",
"value": "\"e02b27cd-1049-4f712f41f3300\""
}
],
"cookies": [],
"content": {
"size": 4169,
"mimeType": "image/jpeg"
},
"redirectURL": "",
"headersSize": 148,
"bodySize": 0,
"_transferSize": 148
},
"cache": {},
"timings": {
"blocked": 0.888000009581447,
"dns": 1193.3369999751485,
"connect": 80.64300002297,
"send": 0.09799998952007627,
"wait": 69.5030000060799,
"receive": 8.774999994785276,
"ssl": -1
},
"connection": "892792",
"pageref": "page_1"
},
{
"startedDateTime": "2016-06-03T22:14:03.821Z",
"time": 9137.228999985382,
"request": {
"method": "GET",
"url": "http://netropy.huebel.freeshells.org:8901/download/images/xenobot.png",
"httpVersion": "HTTP/1.1",
"headers": [
{
"name": "Accept-Encoding",
"value": "gzip, deflate, sdch"
},
{
"name": "Host",
"value": "netropy.huebel.freeshells.org:8901"
},
{
"name": "Accept-Language",
"value": "en-US,en;q=0.8,de;q=0.6,da;q=0.4"
},
{
"name": "User-Agent",
"value": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"
},
{
"name": "Accept",
"value": "image/webp,image/*,*/*;q=0.8"
},
{
"name": "Referer",
"value": "http://netropy.huebel.freeshells.org:8901/"
},
{
"name": "Cookie",
"value": "txtMainTab=More; txtMoreTab=Orphans"
},
{
"name": "Connection",
"value": "keep-alive"
},
{
"name": "Cache-Control",
"value": "max-age=0"
}
],
"queryString": [],
"cookies": [
{
"name": "txtMainTab",
"value": "More",
"expires": null,
"httpOnly": false,
"secure": false
},
{
"name": "txtMoreTab",
"value": "Orphans",
"expires": null,
"httpOnly": false,
"secure": false
}
],
"headersSize": 497,
"bodySize": 0
},
"response": {
"status": 200,
"statusText": "OK",
"httpVersion": "HTTP/1.0",
"headers": [
{
"name": "Content-Length",
"value": "50577"
},
{
"name": "Server",
"value": "XENOmat/2.4.8 (Linux)"
},
{
"name": "Content-Type",
"value": "image/png"
}
],
"cookies": [],
"content": {
"size": 50577,
"mimeType": "image/png",
"compression": 0
},
"redirectURL": "",
"headersSize": 98,
"bodySize": 50577,
"_transferSize": 50675
},
"cache": {},
"timings": {
"blocked": 0.484000018332154,
"dns": 0.43399998685345,
"connect": 1366.1790000041944,
"send": 0.1049999846100036,
"wait": 2036.9490000303,
"receive": 5733.077999961091,
"ssl": -1
},
"connection": "892801",
"pageref": "page_1"
},
{
"startedDateTime": "2016-06-03T22:14:13.067Z",
"time": 175.4320000181906,
"request": {
"method": "GET",
"url": "http://netropy.huebel.freeshells.org:8901/escapa/highscore",
"httpVersion": "HTTP/1.1",
"headers": [
{
"name": "Cookie",
"value": "txtMainTab=More; txtMoreTab=Orphans"
},
{
"name": "Accept-Encoding",
"value": "gzip, deflate, sdch"
},
{
"name": "Host",
"value": "netropy.huebel.freeshells.org:8901"
},
{
"name": "Accept-Language",
"value": "en-US,en;q=0.8,de;q=0.6,da;q=0.4"
},
{
"name": "User-Agent",
"value": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"
},
{
"name": "Accept",
"value": "*/*"
},
{
"name": "Referer",
"value": "http://netropy.huebel.freeshells.org:8901/"
},
{
"name": "X-Requested-With",
"value": "XMLHttpRequest"
},
{
"name": "Connection",
"value": "keep-alive"
},
{
"name": "Cache-Control",
"value": "max-age=0"
}
],
"queryString": [],
"cookies": [
{
"name": "txtMainTab",
"value": "More",
"expires": null,
"httpOnly": false,
"secure": false
},
{
"name": "txtMoreTab",
"value": "Orphans",
"expires": null,
"httpOnly": false,
"secure": false
}
],
"headersSize": 495,
"bodySize": 0
},
"response": {
"status": 200,
"statusText": "OK",
"httpVersion": "HTTP/1.1",
"headers": [
{
"name": "Access-Control-Allow-Origin",
"value": "*"
},
{
"name": "Server",
"value": "XENOmat/2.4.8 (Linux)"
},
{
"name": "Connection",
"value": "Keep-Alive"
},
{
"name": "Keep-Alive",
"value": "timeout=10"
},
{
"name": "Content-Length",
"value": "61"
},
{
"name": "Content-Type",
"value": "text/javascript"
}
],
"cookies": [],
"content": {
"size": 61,
"mimeType": "text/javascript",
"compression": 0
},
"redirectURL": "",
"headersSize": 181,
"bodySize": 61,
"_transferSize": 242
},
"cache": {},
"timings": {
"blocked": 0.645000021904707,
"dns": -1,
"connect": -1,
"send": 0.0429999781772491,
"wait": 167.23200003616503,
"receive": 7.511999981943603,
"ssl": -1
},
"connection": "892781",
"pageref": "page_1"
}
]
}
}
</pre></div></html>
Now the interesting part is the request of the small image shown above:
<html><div><pre>
"request": {
"method": "GET",
"url": "http://netropy.huebel.freeshells.org:8901/download/images/xenobot.png",
"httpVersion": "HTTP/1.1",
"headers": [
{
"name": "Accept-Encoding",
"value": "gzip, deflate, sdch"
},
{
"name": "Host",
"value": "netropy.huebel.freeshells.org:8901"
},
{
"name": "Accept-Language",
"value": "en-US,en;q=0.8,de;q=0.6,da;q=0.4"
},
{
"name": "User-Agent",
"value": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"
},
{
"name": "Accept",
"value": "image/webp,image/*,*/*;q=0.8"
},
{
"name": "Referer",
"value": "http://netropy.huebel.freeshells.org:8901/"
},
{
"name": "Cookie",
"value": "txtMainTab=More; txtMoreTab=Orphans"
},
{
"name": "Connection",
"value": "keep-alive"
},
{
"name": "Cache-Control",
"value": "max-age=0"
}
],
},
</pre></div></html>
<!--{{{-->
<div class='header'>
<div class='gradient' macro='gradient vert #FF8614 #DA4A0D '>
<div class='titleLine'>
<div refresh='content' tiddler='xenoma.svg'></div>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span> – <span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
<div id='topMenu' refresh='content' tiddler='MainMenu'></div>
</div>
</div>
<div id='bodywrapper'>
<div id='sidebar'>
<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
<div id='displayArea'>
<div id='messageArea'></div>
<div id='tiddlerDisplay'></div>
</div>
<div id='contentFooter'>XENOmat Handbook © 2004-2018 by Peter Hübel</div>
</div>
<!--}}}-->
{{{
...
<result channel='3' op='*'>
<push op='+'>
<push channel="0" as="float"/>
<push channel="1" as="float"/>
</push>
<push op='/'>
<push channel="2" as="float"/>
<push const="3.14" as="float"/>
</push>
</result>
...
}}}
The guy programming most of this stuff.
Inside every ''<netropy:space/>'' there may be defined a policy.
The policy of a space has direct effect on the behaviour of any visitor in it.
A policy may govern:
* How the visitor navigates in the space
**using a "greedy algorithm", which also gives us an heuristic for disambiguation of paths for free - not very unlike the algorithm used for parsing an URI Reference (see Section 4.3 and Appendix B of [[RFC2396|http://www.ietf.org/rfc/rfc2396.txt]])
**or using a "lazy" approach, polling every service on the way to handle the payload. This policy is especially useful when building "service pipelines" for visitors to step through.
* The criteria for goal completion - when has the visitor has reached his goal (or died in the attempt)
* What to do when the visitor has reached his goal
**leave at once with the payload,
**or leave (most of) the payload and receive a ticket for later retrieval. In most cases you don't really want all 120.000 records from some SQL query returned in one big XML document. Really not. What you want is pagination, and this policy helps you implement it easily.
* What a visitor may collect from the space, while he moves towards his goal.
** structural information (a blueprint module implements a space with such a policy)
** contextual information (the products of services consulted)
For interoperability, a space should make the blueprint of its policy publicly available, so that clients know what to expect from sending a visitor to that space.
!!Default policy
When not specified, the default policy of a <netropy:space/> is as follows:
* Use a "greedy algorithm" to reach as far into the space as possible, before even considering to consult a service. In other words: Walk as far as you can, until you find yourself at your goal, or have run into a dead end.
* Arriving at a place with all steps taken, the visitor has reached his goal and hands over the request to whatever services or spaces there are present at that place.
* Have not all steps been taken, apparently there is a dead end, and the only way out must lead into another space. Hence any services will be ignored, and only the spaces may take a punch at resolving the full path.
* If a full path does not exist, and the visitor tries to deliver a payload (i.e. a HTTP PUT or POST), the missing places are constructed, and the payload inserted at the newly constructed site.
* If the visitor has some payload after consulting a service or visiting some (sub-)space, the job is considered done and the visitor leaves at once.
If someone says:
"That's impossible!"
You should understand that as:
"According to my very limited experience and narrow understanding of reality, that's very unlikely."
<html><span>
<pre>
<quote attribute="George Bateson">What we mean by <term>information</term> - the elementary unit of information - is a <selection><category>difference</category> <predicate>which makes a <category>difference</category></predicate></selection>.</quote>
</pre>
</span></html>The source of which is:
{{{
<html><span>
<pre>
<quote attribute="Gregory Bateson">What we mean by <term>information</term> - the elementary unit of information - is a <selection><category>difference</category> <predicate>which makes a <category>difference</category></predicate></selection>.</quote>
</pre>
</span></html>
}}}
Code generation is always a brute force attempt to solve a problem. The key problem we always face, is finding the right abstraction, and then implementing it. Of course, due to the large increase in computing power, things like the Kinect have actually been built and are available now in any consumer electronics outlet around the globe.
short for ''Representational State Transfer'', is the basic idea behind the HTTP protocol.
* The BETA Programming Language
''Pro:'' When a service tag is encountered during parsing of the blueprint, it could be parsed until the opening tag is complete (that means all attributes are on the stack).
This (incomplete) context is being passed on to the generator. Many services will ignore this context, but it could be used to
* select among different generators based on the value of an attribute
* make a general check of required attributes (we have woetzel meta info for that already)
* add attributes onto the stack, which do not even exist in the blueprint //per se//
* add content prior to initialisation (since the final context can only be appended to)
A well behaved service would announce in advance (based on the initial context) how much space it needs on the stack.
''Contra:'' If somebody needs to change the attributes on a dynamic base, maybe this information should be conveyed in some other way, i.e. as part of the application protocol. There should be no need to implement this in a general way, as some but not all will use that. And you should only pay as you go.
A service like [[<xeno:duct_tape/>]] basically does nothing but providing the contact with some prologue, some hints about how to interpret what will be delivered.
Typically that will be a {{{<!DOCTYPE html>}}} tag, or some {{{<?xml:stylesheet ... ?>}}} processing instruction.
The concept would be to let the contact -- when having found the service to execute just browse throught the list of the service's attributes, to check if any of them are have a service associated, and if so, invoke that service prior to executing the found service.
The code layout of [[xeno]] is a perfect fit for shared memories, as everything is code - even the data.
!!Traditional models of shared c++ objects
have trouble, because the object could change class because of object slicing?
/***
This CSS by Dave Birss.
***/
/*{{{*/
.tabSelected {
background: #fff;
}
.tabUnselected {
background: #eee;
}
#sidebar {
color: #000;
background: transparent;
}
#sidebarOptions {
background: #fff;
}
#sidebarOptions input {
border: 1px solid #ccc;
}
#sidebarOptions input:hover, #sidebarOptions input:active, #sidebarOptions input:focus {
border: 1px solid #000;
}
#sidebarOptions .button {
color: #999;
}
#sidebarOptions .button:hover {
color: #000;
background: #fff;
border-color:white;
}
#sidebarOptions .button:active {
color: #000;
background: #fff;
}
#sidebarOptions .sliderPanel {
background: transparent;
}
#sidebarOptions .sliderPanel A {
color: #999;
}
#sidebarOptions .sliderPanel A:hover {
color: #000;
background: #fff;
}
#sidebarOptions .sliderPanel A:active {
color: #000;
background: #fff;
}
.sidebarSubHeading {
color: #000;
}
#sidebarTabs {`
background: #fff
}
#sidebarTabs .tabSelected {
color: #000;
background: #fff;
border-top: solid 1px #ccc;
border-left: solid 1px #ccc;
border-right: solid 1px #ccc;
border-bottom: none;
}
#sidebarTabs .tabUnselected {
color: #999;
background: #eee;
border-top: solid 1px #ccc;
border-left: solid 1px #ccc;
border-right: solid 1px #ccc;
border-bottom: none;
}
#sidebarTabs .tabContents {
background: #fff;
}
#sidebarTabs .txtMoreTab .tabSelected {
background: #fff;
}
#sidebarTabs .txtMoreTab .tabUnselected {
background: #eee;
}
#sidebarTabs .txtMoreTab .tabContents {
background: #fff;
}
#sidebarTabs .tabContents .tiddlyLink {
color: #999;
border:none;
}
#sidebarTabs .tabContents .tiddlyLink:hover {
background: #fff;
color: #000;
border:none;
}
#sidebarTabs .tabContents {
color: #000;
}
#sidebarTabs .button {
color: #666;
}
#sidebarTabs .tabContents .button:hover {
color: #000;
background: #fff;
}
#sidebar {color:#999;}
/*}}}*/
//the e''X''tensible ''E''ngine for ''N''etworked ''O''bjects//
TiddlyWiki > Osmosoft > BT.com >
http://www.btplc.com/Innovation/Innovation/Internet/index.htm
http://tidalblog.blogspot.com/2006/07/treeline-view-of-tiddlywiki.html
DevelopingStepByStep
//The following is inspired by Gregory Batesons "Metalogues", and the setting is an adult trying to answer some of the odd questions a child may asks about [[InformationSystems]]. My own son knows not much more than the fact that I spend a lot of time working on and with them.//
!!What //is// information?
>- Well... that depends who you ask. It is something that helps you make decisions.
>- But how?
>- Well, for instance: If you knew, that you'd get dessert today, if you tidy up your room...
>- O.k., I'll do it now!!!
>- No, wait - first I'll answer your question... An Englishman named Gregory Bateson, who lived in the last century, once defined information as "a difference which makes a difference". I think he came quite close to the point.<br/>Think of the way you sense sounds around you. Much of it is noise. The computer humming, cars on the street. Background noise. You don't notice it. But when suddenly there is an unexpected sound - that tells you something. It makes a difference.
In physics, you may equal information and energy. Surely on any level in the world of information systems, there is some dependency on the physical level. Computers use electric power, take up space, generate heat... All those are limiting factors, and all are consequences of a loss of information.
>When you grow older you can read...
>''Steps to an ecology of mind'' by Gregory Bateson.
!!But where does information come from?
Information in the form of ''XML'' is one-dimensional. Don't get deluded by the tree-like structures, it mostly is represented as. This apparent structure comes from meta information embedded in the text, the ''tags''.
Think of the physical reality of Web Tech. In a network information flows through cables or optical fibers until it reaches its destination. We use the concept of a ''stream'' to describe this movement of information.
Imagine the stream below entering a <<tiddler xeno>> (scroll the data):
{{{
<?xml version="1.0" encoding="utf-8" standalone="yes"?><information><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/><lots/></information>
}}}
Inside the server the information is folded in a structure we call a ''stack'':
{{{
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<information>
<lots/>
<lots/>
<lots/>
<!-- stuff omitted -->
<lots/>
<lots/>
<lots/>
<lots/>
</information>
}}}
!!Wait! That's not a stack!
You mean a stack is like this?
|→{{{top}}}|
| ... |
| ... |
| ... |
| ... |
| ... |
| ... |
| ... |
| ... |
No, sorry, the stack we mean is not so abstract. It is more like this:
[img[Part of a Conventional Information Processing System|/download/real-stack.jpg]]
Services may operate on this stack and transform it:
{{{
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<information>
<lots/>
<!-- stuff deleted -->
<lots/>
<even>
<more>new data added</more>
</even>
</information>
}}}
and the result may be flushed out on a ''stream'' again.
Quick and effective information processing due to structure.
!!Ah, those memories!
<<tiddler xeno>> has a clean desk policy internally. That means those stacks disappear whenever work is done.
To prevent your information from disappearing, it can be put into a ''stash'', a place in the information space, from where you can get it later on.
It is not possible to apply transformations to information residing in a ''stash'', because <<tiddler xeno>> treats it as unstructured information.
!!Sorting out stuff
To structure your information, you arrange it in a ''space''. You can learn more about spaces in the tiddler [[InformationSpaces]].
!!!Form and function
Before even attempting to structure information, we should take a look at the ''form'' (or //shape//) of the information.
In the context of <<tiddler xeno>> the form of information is mostly ''XML''. The rationale behind that decision is that ''XML'' goes well with any <html><abbr title="Content Management System">CMS</abbr></html> and gives you many integration points for your information.
Furthermore the choice of ''XML'' (like in "extensible") as the syntax for describing the structure of our information gives us a lot of extra benefits when addressing the Javascript/XML/HTTP world.
!!![[Using Markup Language|UsingMarkupLanguage]]
<<tiddler UsingMarkupLanguage>>
!!![[Using Namespaces|UsingNameSpaces]]
<<tiddler UsingNameSpaces>>
!!![[At Your Service|AtYourService]]
<<tiddler AtYourService>>
[[SideBarWG]]
/***
!Top Menu Styles
***/
/*{{{*/
#topMenu br {display:none; }
#topMenu { background: #000 ; color:#fff;padding: 1em 1em;}
/*}}}*/
/***
!General
***/
/*{{{*/
body {
background: #444;
margin: 0 auto;
}
pre {
-webkit-tab-size: 2;
-moz-tab-size: 2;
}
#contentWrapper{
background: #fff;
border: 0;
margin: 0 auto;
max-width: 80em;
padding:0;
}
/*}}}*/
/***
!Header rules
***/
/*{{{*/
.titleLine{
margin: 20px auto 0em ;
margin-left:1.7em;
margin-bottom: 40px;
padding: 0;
text-align: left;
color: #fff;
}
.siteTitle {
font-size: 2em;
font-weight: bold;
}
.siteSubtitle {
font-size: 1.1em;
margin: .5em auto 1em;
}
.gradient {margin: 0 auto;}
.header {
background: #fff;
margin: 0 auto;
padding:0 12px;
}
/*}}}*/
/***
!Display Area
***/
/*{{{*/
#bodywrapper {margin:0 12px; padding:0;background:#fff; height:1%}
#displayArea {
margin: 0em 16em 0em 1em;
text-align: left;
}
.tiddler {
padding: 1em 1em 0em 0em;
}
h1,h2,h3,h4,h5 { color: #000; background: transparent; padding-bottom:2px; border-bottom: 1px dotted #666; }
.title {color:black; font-size:1.8em; border-bottom:1px solid #333; padding-bottom:0.3px;}
.subtitle { font-size:90%; color:#ccc; padding-left:0.25em; margin-top:0.1em; }
.shadow .title {
color: #aaa;
}
.tagClear{
clear: none;
}
* html .viewer pre {
margin-left: 0em;
}
* html .editor textarea, * html .editor input {
width: 98%;
}
.tiddler {margin-bottom:1em; padding-bottom:0em;}
.toolbar .button {color:#bbb; border:none;}
.toolbar .button:hover, .toolbar .highlight, .toolbar .marked, .toolbar a.button:active {background:transparent; color:#111; border:none; text-decoration:underline;}
#sidebar .highlight, #sidebar .marked {background:transparent;}
.tagging, .tagged {
display: none;
border: 1px solid #eee;
background-color: #F7F7F7;
}
.selected .tagging, .selected .tagged {
background-color: #eee;
border: 1px solid #bbb;
}
.tagging .listTitle, .tagged .listTitle {
color: #bbb;
}
.selected .tagging .listTitle, .selected .tagged .listTitle {
color: #222;
}
.tagging .button:hover, .tagged .button:hover {
border: none; background:transparent; text-decoration:underline; color:#000;
}
.tagging .button, .tagged .button {
color:#aaa;
}
.selected .tagging .button, .selected .tagged .button {
color:#000;
}
.viewer blockquote {
border-left: 3px solid #000;
}
.viewer pre, .viewer code {
border: 1px dashed #ccc;
background: #eee;}
.viewer hr {
border: 0;
border-top: solid 1px #333;
margin: 0 8em;
color: #333;
}
.highlight, .marked {
background:transparent;
color:#111;
border:none;
text-decoration:underline;
}
.viewer .highlight, .viewer .marked {
text-decoration:none;
}
#sidebarTabs .highlight, #sidebarTabs .marked {color:#000; text-decoration:none;}
.tabSelected {
color: #000;
background: #fff;
border-top: solid 1px #ccc;
border-left: solid 1px #ccc;
border-right: solid 1px #ccc;
border-bottom: none;
}
.viewer .tabSelected:hover{color:#000;}
.viewer .tabSelected {font-weight:bold;}
.tabUnselected {
color: #999;
background: #eee;
border-top: solid 1px #ccc;
border-left: solid 1px #ccc;
border-right: solid 1px #ccc;
border-bottom: solid 1px #ccc;
padding-bottom:1px;
}
.tabContents {
background: #fff;
color: #000;
}
/*}}}*/
/***
!!!Tables
***/
/*{{{*/
.viewer table {
border: 1px solid #000;
}
.viewer th, thead td {
background: #000;
border: 1px solid #000;
color: #fff;
}
.viewer td, .viewer tr {
border: 1px solid #111;
}
/*}}}*/
/***
!!!Editor area
***/
/*{{{*/
.editor input, .editor textarea {
border: 1px solid #ccc;
}
.editor {padding-top:0.3em;}
.editor textarea:focus, .editor input:focus {
border: 1px solid #333;
}
/*}}}*/
/***
!Sidebar
***/
/*{{{*/
#sidebar{
position:relative;
float:right;
margin-bottom:1em;
display:inline;
width: 16em;
}
#sidebarOptions .sliderPanel {
background: #eee; border:1px solid #ccc;
}
/*}}}*/
/***
!Body Footer rules
***/
/*{{{*/
#contentFooter {
text-align: left;
clear: both;
color:#fff;
background: #000;
padding: 1em 2em;
font-weight:bold;
}
/*}}}*/
/***
!Link Styles
***/
/*{{{*/
a {
color: #000;
text-decoration: none;
}
a:hover {
color: #FF6600;
background:#fff;
}
.button {
color: #000;
border: 1px solid #fff;
}
.button:hover {
color: #fff;
background: #ff8614;
border-color: #000;
}
.button:active {
color: #fff;
background: #ff8614;
border: 1px solid #000;
}
.tiddlyLink { /* border-bottom: 1px dotted #000; */ }
.tiddlyLink:hover {border-bottom: 1px dotted #FF6600;}
.titleLine a { /*border-bottom: 1px dotted #FF9900; */ }
.titleLine a:hover { border-bottom: 1px dotted #fff;}
.siteTitle a, .siteSubtitle a {
color: #fff;
}
.viewer .button {border: 1px solid #ff8614; font-weight:bold;}
.viewer .button:hover, .viewer .marked, .viewer .highlight{background:#ff8614; color:#fff; font-weight:bold; border: 1px solid #000;}
#topMenu .button, #topMenu .tiddlyLink {
margin-left:0.5em; margin-right:0.5em;
padding-left:3px; padding-right:3px;
color:white;
}
#topMenu .button:hover, #topMenu .tiddlyLink:hover { background:#000; color:#FF8814}
#topMenu a{border:none;}
/*}}}*/
/***
!Message Area /%=================================================%/
***/
/*{{{*/
#messageArea {
border: 4px dotted #ff8614;
background: #000;
color: #fff;
font-size:90%;
}
#messageArea .button {
padding: 0.2em;
color: #000;
background: #fff;
text-decoration:none;
font-weight:bold;
border:1px solid #000;
}
#messageArea a {color:#fff;}
#messageArea a:hover {color:#ff8614; background:transparent;}
#messageArea .button:hover {background: #FF8614; color:#fff; border:1px solid #fff; }
/*}}}*/
/***
!Popup /%=================================================%/
***/
/*{{{*/
.popup {
background: #ff8814;
border: 1px solid #333;
}
.popup hr {
color: #333;
background: #333;
border-bottom: 1px;
}
.popup li.disabled {
color: #333;
}
.popup li a, .popup li a:visited {
color: #eee;
border: none;
}
.popup li a:hover {
background: #ff8614;
color: #fff;
border: none;
text-decoration:underline;
}
/*}}}*/
/*{{{*/
.blog h2, .blog h3, .blog h4{
margin:0;
padding:0;
border-bottom:none;
}
.blog {margin-left:1.5em;}
.blog .excerpt {
margin:0;
margin-top:0.3em;
padding: 0;
margin-left:1em;
padding-left:1em;
font-size:90%;
border-left:1px solid #ddd;
}
#tiddlerWhatsNew h1, #tiddlerWhatsNew h2 {border-bottom:none;}
div[tags~="RecentUpdates"], div[tags~="lewcidExtension"] {margin-bottom: 2em;}
#hoverMenu .button, #hoverMenu .tiddlyLink {border:none; font-weight:bold; background:#f37211; color:#fff; padding:0 5px; float:right; margin-bottom:4px;}
#hoverMenu .button:hover, #hoverMenu .tiddlyLink:hover {font-weight:bold; border:none; color:#f37211; background:#000; padding:0 5px; float:right; margin-bottom:4px;}
#topMenu .fontResizer {float:right;}
#topMenu .fontResizer .button{border:1px solid #000;}
#topMenu .fontResizer .button:hover {border:1px solid #f37211; color:#fff;}
#sidebarTabs .txtMainTab .tiddlyLinkExisting {
font-weight: normal;
font-style: normal;
}
#sidebarTabs .txtMoreTab .tiddlyLinkExisting {
font-weight: bold;
font-style: normal;
}
.blog h2, .blog h3, .blog h4{
margin:0;
padding:0;
border-bottom:none;
}
.blog {margin-left:1.5em;}
.blog .excerpt {
margin:0;
margin-top:0.3em;
padding: 0;
margin-left:1em;
padding-left:1em;
font-size:90%;
border-left:1px solid #ddd;
}
#tiddlerWhatsNew h1, #tiddlerWhatsNew h2 {border-bottom:none;}
div[tags~="RecentUpdates"], div[tags~="lewcidExtension"] {margin-bottom: 2em;}
#hoverMenu {background:transparent;}
#hoverMenu .button, #hoverMenu .tiddlyLink {border:none; font-weight:bold; background:#f37211; color:#fff; padding:0 5px; float:right; margin-bottom:4px;}
#hoverMenu .button:hover, #hoverMenu .tiddlyLink:hover {font-weight:bold; border:none; color:#f37211; background:#000; padding:0 5px; float:right; margin-bottom:4px;}
#topMenu .fontResizer {float:right;}
#topMenu .fontResizer .button{border:1px solid #000;}
#topMenu .fontResizer .button:hover {border:1px solid #f37211; color:#fff;}
#sidebarTabs .txtMainTab .tiddlyLinkExisting {
font-weight: normal;
font-style: normal;
}
#sidebarTabs .txtMoreTab .tiddlyLinkExisting {
font-weight: bold;
font-style: normal;
}
/*}}}*/
|Overview over tasks in application development|c
|!Task|!Description|!Process|!Language or Protocol|!Tool(s)|
|Data Acquisition|Gathering information|Hardware Interfacing|C/C++|Eclipse|
|Publishing|Making information available|Structuring|C++ → XML / JSON|~|
|~|~|Transport|IP / TCP / HTTP|Wireshark|
|Presentation |Making things visible and touchable|Structuring|HTML|Eclipse (or ''any editor'') & //Modern Browser//|
|~|~|Styling|CSS|~|
|Interaction|~|Adding behaviour|ECMAscript|~|
* IP ~SubProtocols (TCP or UDP or IMPC > FTP or HTTP or DNS) for interoperability and means of transport (but it might be any protocol of serial nature). Remember: [[HTTP is an application protocol.]]
* XML or JSON (or any block structured format) for interoperability.
* C/C++ (serializable to XML or JSON) objects for abstracting hardware. ''Note:'' Most interfaces to the hardware are implemented in C, and provide therefore an API in that same language.
* HTML(5) and CSS for representation.
* ECMAscript for adding behaviour.
!!!Footprint
Less than 400 kB with all services installed. The core processor (without the HTTP server and services) is about 2kB (!) on a 32-bit architecture.
!!!Memory Usage
About 5 MB for this server, having cashed some content in memory due to disk constraints (live data available shortly).
!!!Deployment
The <<tiddler xeno>> virtual machine consists of one single executable. Extension modules may be added by means of dynamic libraries (platform specific), and eventually the ''boost'' runtime libraries [[may have to be installed|ListOfDistributions]].
The configuration of a server instance consists of one single XML document (the [[Blueprint]]), which may be changed at runtime.
!!!Supported Platforms
*OS X / ~FreeBSD / Darwin (64 bit)
*Ubuntu / Debian Linux (32 / 64 bit)
*Raspberry Pi
*Windows (32 / 64 bit)
!!Don't modify the element, modify it's style
When dragging around an element, that is styled with an absolute or relative position, you should modify the unique manufactered style that it already has been given by the rendering engine.
I see very much <<tiddler xeno>> and [[TiddlyWiki|http://www.tiddlywiki.org]] merging together. I might make a [[<netropy:wiki/>]] service...
Look at this: http://psd.tiddlyspace.com/#[[Open%20Toilet%20Data]]
* Ihi & Ussi
* FragenAnDieKollegen
|~ViewToolbar|closeTiddler closeOthers +editTiddler > fields syncing permalink references jump|
|~EditToolbar|closeOthers +saveTiddler -cancelTiddler deleteTiddler|
Markup should be a non-intrusive as possible.
Take a look at the following quote from [[Gregory Bateson|http://en.wikipedia.org/wiki/Gregory_Bateson]]:
<<tiddler QuotationExample>>
What you see displayed is the result of your browser trying to interpret the information found in the XML (actually XHTML) delivered from this server.
The browser knows about the {{{<html>}}}-tags, so the result is boxed. But since your browser does not know how to interpret that {{{<quote>}}} stuff, it just passes along the pure contents - without the tags - for you to read on the display. This is very reasonable behaviour, as you can see.
<html><iframe src="/blueprint/raw/quote/xeno:copy/quote" style="width:100%;height:32em;"/></html>
The concept of markup, or tagging, blends well into the concept of a "space", where information
resides at different "sites" within that space.
To be able to navigate in that information space, you assign names to those sites and use markup to divide the information space into smaller spaces:
{{{
<xeno:space xmlns="http://lab.strxtrs.net/2009/05/14" xmlns:xeno="xeno:XENOmat">
<somewhere><there><is><some>Information</some></is></there></somewhere>
<elsewhere><deeply><hidden><away>Garbage</away></hidden></deeply></elsewhere>
</xeno:space>
}}}
Such an XML document we call a [[blueprint|Blueprint]]. It describes an information space to be realised by a <<tiddler xeno>>. Note that every server instance defines an XML namespace itself (the default namespace {{{xmlns}}}), which in turn defines the vocabulary for navigating its content.
Navigation is performed by using paths. In the example above, the path will start at the entry
port (the XML document root {{{/}}}) of the space (which is bound to an HTTP connection on port 80).
Then the expression
{{{
/elsewhere/deeply/hidden/away
}}}
would be such a path, showing the way to the garbage.
<<tiddler xeno>> uses the knowledge of the namespace to perform ultrafast lookups throughout the entire information structure.
It is worth noticing, that all the names you define for structuring your model, are your own, and mostly subject only to the limitations for qualified names given by XML.
That means for one, you can model in your own language, e.g.
{{{
}}}
<html>
<head>
<style>
.town-sign {
height: 120px; width: 200px;
border: 1px solid black;
position: relative; overflow: hidden;
display: inline-block;
padding: 0 auto;
}
.blue-stripe, .white-stripe { margin: 0px; padding: 0px; position: static; }
.blue-stripe { background: blue; height: 25%; }
.white-stripe { background: white; height: 50%; text-align: center; vertical-align: center; }
.red-bar {
background: red;
height: 20px; width: 150%;
z-order: 1;
position: absolute;
top: -10px; left: 0px;
transform: rotate(30deg);
transform-origin: 0 0;
}
.name { font-size: 20pt; vertical-align: center; line-height: 60px; }
</style>
</head>
<body>
<div class="town-sign">
<div class="blue-stripe"></div>
<div class="white-stripe"><span class="name">Stag Nation</span></div>
<div class="blue-stripe"></div>
<div class="red-bar"></div>
</div>
<div class="town-sign">
<div class="blue-stripe"></div>
<div class="white-stripe"><span class="name">Stag Nation</span></div>
<div class="blue-stripe"></div>
</div>
</body>
</html>
!!<<tiddler xeno>> is ...
... a ''lightweight'' virtual machine for processing ''structured data'' with support for <html><abbr title='eXtensible Markup Language'>XML</abbr></html>, <html><abbr title='JavaScript Object Notation'>JSON</abbr></html>, and just about any binary format you can imagine. It has been built for the [[Internet of Things]].
Its [[specifications|Technical Specifications]] in terms of speed, low overhead and robustness makes <<tiddler xeno>> well suited for ''embedded'' applications.
On heavily loaded systems, it may also serve as an extremely efficient [[information hub|Information Hub]] to back a <html><abbr title="Content Management System">CMS</abbr></html> or for gathering, processing, and visualising ''real time data''.
In general, a <<tiddler xeno>> is a flexible tool for making legacy data accessible via web services.
The programming model is [[XML centric|XML Centric Programming Model]], and enables developers to build applications in an ''agile way''. Just load your content into a <<tiddler xeno>> and you're ready to go. Add other kinds of content, modify existing structures and keep going. ''Develop'', ''test'', and ''deploy'' with extremely ''fast turnaround'' times.
Or develop [[extensions|<xeno:extend/>]] in ''C/C++''.
!!The <<tiddler xeno>> is //not//...
... another web server, CMS, "integration platform", or whatever it may look like to you, when you interact with it on an IP network, like you do now.
The case is, that this particular software implementation uses ~UTF-8 encoded XML or JSON for the representation of structured information and HTTP for transport. That choice is not completely arbitrary, since transporting ''XML'' or ''JSON'' over ''HTTP'' naturally opens up for interoperability over the internet.
!!The <<tiddler xeno>> is rather ...
... a ''virtual machine'', a spin-off product from an ongoing [[R&D project|http://www.strxtrs.net/strXtrs/Evolving%20Technologies.html]] on information processing and intelligent networks.
As much of the structured data in embedded systems is represented as ''C/C++'' structures, <<tiddler xeno>> also supports direct mapping of services to memory and other devices of a machine.
If you are interested in the physical levels of information processing, you might get a better understanding of the design of this software by reading [[a short introduction to the XENOmat|A short introduction to the XENOmat]].
!!What's the netropy stuff about?
''netropy'' is the name of the technology, on which <<tiddler xeno>> is built.
The name is a play on words, derived from the concept of [[entropy|http://en.wikipedia.org/wiki/Entropy]]. The concept of entropy has often been loosely associated with the amount of ''order'', ''disorder'', and/or ''chaos'' in a system.
From the Wikipedia entry about [[Information Theory|http://en.wikipedia.org/wiki/Information_theory]]:
>A key measure of information in the theory is known as [[entropy|http://en.wikipedia.org/wiki/Entropy_(information_theory)]], which is usually expressed by the average number of bits needed for storage or communication. Intuitively, entropy quantifies the uncertainty involved when encountering a [[random variable|http://en.wikipedia.org/wiki/Random_variable]]. For example, a fair coin flip (2 equally likely outcomes) will have less entropy than a roll of a die (6 equally likely outcomes).
Real life data are a lot more complex than that. As entropy increases steadily in our information society, we see and address the need for information to ''spread'' as fast and ''frictionless'' on the net as possible.
Controlling entropy - which in itself may be brought to good uses. This is the main design rationale behind <<tiddler xeno>>.
!!Benefits
!![[... for developers|Agile application development]]
<<tiddler [[Agile application development]]>>
!![[... for machines|Efficient resource management]]
<<tiddler [[Efficient resource management]]>>
!!Where do I go from here?
A good starting point would be to read about some of the [[basic concepts|Basic Concepts]] of <<tiddler xeno>>.
You can also jump right to the [[Technical Specifications]] to see if a <<tiddler xeno>> fits your needs.
//pr.// ''['Wutsl]''
Woetzel is a technique for traversing an object structure in C++, solely based on language features present since the 1980's.
Traversal is a prerequisite for serialization, which is the application of the technique used as an example throughout this introduction.
!The object "life cyclus" in C++
This section is a small recapitulation of object creation and destruction in C++, and you may skip it at your convenience.
In C++, objects are instances of classes. This is an extension of the {{{struct}}} concept from the C programming language. A class may have a number of special methods for initialization, called the ''constructor'' (or in programmer jargon //''ctor''//).
Constructors are named like the class and do not return anything. You also can not invoke them directly, as we shall see in a while. A constructor without any arguments is called the //default contructor//.
Likewise there may be a special method called the ''destructor'' (or ''//dtor//''), which is invoked when the object ends its life cyclus. It also is named like the class, but is prefixed with a negation operator.
We can see these methods in action with the following small example C++ program:
{{{
#include <iostream>
#include <string>
using namespace std;
class Sample {
public:
Sample() { cout << "ctor" << endl; }
~Sample() { cout << "dtor" << endl; }
void do() { cout << "i=" << i << ", s='" << s << "'\n"; }
private:
int i;
std::string s;
};
int main(int argc, char** argv)
{
for (int i=0; i<3; ++i) {
cout << "Enter: ";
Sample test;
cout << "Do: ";
test.do();
cout << "Exit: ";
}
return 0;
}
}}}
Compiled and executed, we see a number of things from the output:
{{{
ctor
i=0, s=''
dtor
ctor
i=0, s=''
dtor
ctor
i=0, s=''
dtor
}}}
* The members {{{i}}} and {{{s}}} are initialized by default.
> C++ guarantees that members get initialized to their default values. That means the default constructor for numeric types mostly is all null bits.
* The object {{{test}}} is constructed and destroyed in every execution of the loop.
> C++ being a block structured language, this holds for all blocks, and it is considered good practice to use this language feature to control the acquisition and release of shared resources such as memory or file handles.
!Where in memory is the object?
In the example above the {{{Sample}}} object was created on the stack. This also is the case for the {{{std::string}}} object embedded inside it.
The compiler knows how many bytes it needs for the object, so it reserves an adequate range of memory for it on the stack and passes the address of that memory to the constructor. The constructor on its side can refer to that memory through a special pointer called ''this''.
''Q:'' Do I really need to use XSLT to convert my data into HTML, so they can be displayed in a browser?
''A:'' No, actually you have several other options. XSLT has merely the benefit, that you can build a library of components for rendering your data in a consistent way.
Your other options for visualizing XML data are:
* Using CSS for styling, as described in [[this document from W3C|http://www.w3.org/Style/styling-XML.html]]. As a remark aside, note how the page uses HTTP to give you multiple choices for language. An "intelligent" service might use the information on that page to do an automatic redirect.
* Do the transformation with ''<script/>ing''. This site uses [[jQuery|http://www.jquery.com]] in some instances to traverse a XML document and generate a dynamic GUI.
* Use a ''<xeno:service/>'' as an endpoint for a ''ReST'' service and code the GUI in the framework of your choice. Most platforms have bindings for ReST (TODO! References)
!!XENOEMA
<<tiddler SiteSubtitle>>
!!XENACE
//- eXtensible Embedding of Networked Objects in Asynchronous Computing Engines
!!XENOASE
<html><img width="10%" height="10%" src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIj8+Cjxzdmcgd2lkdGg9IjM2MCIgaGVpZ2h0PSIyMjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiA8Zz4KICA8dGl0bGU+QWxpZW48L3RpdGxlPgogIDxnIGZpbHRlcj0idXJsKCNhbGllbl9ibHVyKSIgaWQ9ImFsaWVuIj4KICAgPGcgaWQ9InN2Z18yIj4KICAgIDxwYXRoIGQ9Im0yMTIuMDk2OTg1LDcxLjEwNDc2N2MyMi42NDI4MjIsLTIuMjY5ODkgMzQuMDQwMjk4LC03LjEzNDE5NyAzOS41LC0xMS40OTcyNTdjMTcuNzU0MjExLC0xNC4xODgwMyAxMS4zMjUzNDgsLTI3LjM1MzgzMiAyMiwtMjQuNDMxNzIxYzEwLjUsMi44NzQzMjEgMTAuNDc2NzQ2LDE0LjA3OTMxMSAxNy41LDE3LjI0NTkyMmM4LjUsMy44MzI0MjggLTIuMDM3MTA5LC0zMy42OTQ1MyA2LjUsLTMxLjEzODQ2YzgsMi4zOTUyNjkgOC45NzE4NjMsMjEuNDA4OTc5IDIxLDI2LjM0NzkyOWMxMC41LDQuMzExNDgxIC02LjYwOTAwOSwtNDQuNjMxMTggOCwtMzQuMDEyNzhjMTQuNSwxMC41MzkxNyAzNSw1Mi42OTU4NTUgMSw2NC4xOTMxNDdjLTM0LDExLjQ5NzI4NCAtODQuNDQ2NjcxLDE0LjgzODA1MSAtMTAxLDE0LjM3MTYwNWMtMTcsLTAuNDc5MDY1IC0zMi42NTk4ODIsLTE5LjI1NzgxMyAtMTQuNSwtMjEuMDc4MzU0bDAsLTAuMDAwMDMxeiIgaWQ9InBhdGgyMzk5IiBzdHJva2UtbWl0ZXJsaW1pdD0iNCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSI1IiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGZpbGw9IiNiYThkNzMiIHN0cm9rZT0iIzAwMDAwMCIvPgogICAgPHBhdGggZD0ibTE0OS41LDcxLjEwNDc2N2MtMjIuNjQyNzc2LC0yLjI2OTg5IC0zNC4wNDAyODMsLTcuMTM0MTk3IC0zOS40OTk5OTIsLTExLjQ5NzI1N2MtMTcuNzU0MTgxLC0xNC4xODgwMyAtMTEuMzI1MzQsLTI3LjM1MzgzMiAtMjIsLTI0LjQzMTcyMWMtMTAuNSwyLjg3NDMyMSAtMTAuNDc2NzMsMTQuMDc5MzExIC0xNy41MDAwMDgsMTcuMjQ1OTIyYy04LjUsMy44MzI0MjggMi4wMzcxMzIsLTMzLjY5NDUzIC02LjUsLTMxLjEzODQ2Yy04LDIuMzk1MjY5IC04Ljk3MTg0LDIxLjQwODk3OSAtMjEsMjYuMzQ3OTI5Yy0xMC41LDQuMzExNDgxIDYuNjA5MDMyLC00NC42MzExOCAtOCwtMzQuMDEyNzhjLTE0LjUsMTAuNTM5MTcgLTM1LDUyLjY5NTg1NSAtMSw2NC4xOTMxNDdjMzQsMTEuNDk3Mjg0IDg0LjQ0NjY2MywxNC44MzgwNTEgMTAxLjAwMDAxNSwxNC4zNzE2MDVjMTcsLTAuNDc5MDY1IDMyLjY1OTg4MiwtMTkuMjU3ODEzIDE0LjQ5OTk4NSwtMjEuMDc4MzU0bDAsLTAuMDAwMDMxeiIgaWQ9InBhdGgzMTcxIiBzdHJva2UtbWl0ZXJsaW1pdD0iNCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSI1IiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGZpbGw9IiNhZDdlNjEiIHN0cm9rZT0iIzAwMDAwMCIvPgogICA8L2c+CiAgIDxwYXRoIHN0cm9rZT0iIzAwMDAwMCIgaWQ9InBhdGg0IiBkPSJtMTgzLjU4MDEzOSw5LjQxNzI2Yy0zMy42OTc3MjMsMCAtODAuMjE1NTQ2LDIxLjU5NTkyIC04MC4yMTU1NDYsNzcuNzg1NTA2YzAsMC4xODQ2ODUgMCwwLjM5MDgyMyAwLDAuNTc1NWMwLjM4NTc2NSw1NS45MzU5MDUgNTYuNDExMzAxLDEyNS4xNDgyNzcgODAuMjE1NTQ2LDEyNS4xNDgyNzdjMjMuODkzNzY4LDAgODAuMjE0OTA1LC02OS41MzQxOCA4MC4yMTQ5MDUsLTEyNS43MjM3NzhjMCwtNTYuMTg5NTg3IC00Ni41MTgxMTIsLTc3Ljc4NTUwNiAtODAuMjE0OTA1LC03Ny43ODU1MDZsMCwwem0tNzIuMTU5OTIsODIuNzQwMTcyYzM5LjI1Njg4OSwwIDY3LjYyMTIzOSwyOC4xMTgxNDEgNjcuNjIxMjM5LDcwLjI5NDM4Yy00MS4wNzE4ODQsMCAtNjcuNjIxMjM5LC0yNi45NjUyNzEgLTY3LjYyMTIzOSwtNzAuMjk0Mzh6bTE0NS42ODA2MTEsMGMwLDQzLjMyOTEwOSAtMjcuMDkzOTY0LDcwLjI5NDM4IC02OC45ODI5NzEsNzAuMjk0MzhjMCwtNDIuMTc2MjM5IDI4LjkzMjM4OCwtNzAuMjk0MzggNjguOTgyOTcxLC03MC4yOTQzOHoiIGZpbGw9IiNhYWJiYWEiIHN0cm9rZS13aWR0aD0iNCIvPgogIDwvZz4KIDwvZz4KIDxkZWZzPgogIDxmaWx0ZXIgaGVpZ2h0PSIyMDAlIiB3aWR0aD0iMjAwJSIgeT0iLTUwJSIgeD0iLTUwJSIgaWQ9ImFsaWVuX2JsdXIiPgogICA8ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSIxIi8+CiAgPC9maWx0ZXI+CiA8L2RlZnM+Cjwvc3ZnPg=="></html>
[[XENOS?|http://en.wikipedia.org/wiki/Xenos_vesparum]]
The system model in <<tiddler xeno>> is expressed in XML.
The behaviour of an instance of <<tiddler xeno>> -- as well as the content it serves -- itself is defined in an XML document we call the ''[[blueprint|Blueprint]]''.
!!Implications of the Model on Programming
XML is (as the name implies) a Markup Language. That means for some information, e.g. a document, the text has been tagged with additional information about how the reader should interpret different parts of the document.
!!Tools you will need
Working with XENO Server requires nothing more than a good XML editor and a decent browser.
The Eclipse CDT has the possibility for installing the Eclipse Web Tools, which contain a very decent XML editor. Personally I use this for editing the blueprint while debugging in Eclipse.
XSLTForms allows common browsers to manipulate XForms. It is an open source client-side implementation of an XForms engine, not a plug-in or install, that works with all major browser (Internet Explorer, FireFox, Opera, Safari, Chrome and more).
The products home page is at http://www.agencexml.com/xsltforms, and is hosted at ~SourceForge.
<html><a href="http://sourceforge.net/projects/xsltforms/"><img src="http://sflogo.sourceforge.net/sflogo.php?group_id=242651&type=12"/></a></html>
As part of the Netropy project we want to experiment more with [[XRX|http://en.wikipedia.org/wiki/XRX_(web_application_architecture)]] and have mounted the package from the XSLTForms project on this <<tiddler xeno>> at <html><a href='/xsltforms/index.htm' class='tiddlyLink tiddlyLinkExisting' title='Opens the XSLTForms demo'>/xsltforms</a></html>.
''netropy'' is the name of the technology, on which <<tiddler xeno>> is built.
The name is a play on words, derived from the concept of [[entropy|http://en.wikipedia.org/wiki/Entropy]]. The concept of entropy has often been loosely associated with the amount of ''order'', ''disorder'', and/or ''chaos'' in a system.
From the Wikipedia entry about [[Information Theory|http://en.wikipedia.org/wiki/Information_theory]]:
>A key measure of information in the theory is known as [[entropy|http://en.wikipedia.org/wiki/Entropy_(information_theory)]], which is usually expressed by the average number of bits needed for storage or communication. Intuitively, entropy quantifies the uncertainty involved when encountering a [[random variable|http://en.wikipedia.org/wiki/Random_variable]]. For example, a fair coin flip (2 equally likely outcomes) will have less entropy than a roll of a die (6 equally likely outcomes).
Real life data are a lot more complex than that. As entropy increases steadily in our information society, we see and address the need for information to ''spread'' as fast and ''frictionless'' on the net as possible.
Controlling entropy - which in itself may be brought to good uses. This is the main design rationale behind <<tiddler xeno>>.
<html>
<style type="text/css">
svg.clock {
width: 600px;
height: 600px;
margin: 20px;
}
@keyframes turn {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
#dial {
transform: scale(.9);
transform-origin: 50% 50%
}
#center {
fill: url(#bulb);
Xfill: red;
}
#sec {
fill: red;
transform-origin: 50% 50%;
animation: turn 60s steps(60,end) infinite;
}
#min {
fill: black;
transform-origin: 50% 50%;
animation: turn 3600s steps(60,end) infinite;
}
#hrs {
fill: black;
transform-origin: 50% 50%;
animation: turn 43200s linear infinite;
}
#hrs, #min {
stroke: lightgray;
}
#min {
transition: transform 0.3s cubic-bezier(.4,2.08,.55,.44);
}
#sec {
transition: transform 0.2s cubic-bezier(.4,2.08,.55,.44);
}</style>
<!-- this second style defines the starting state of the -->
<!-- animation. a negative delay behaves like a fast forward -->
<!-- the formula is:
-->
<!-- it represents seconds until noon or midnight -->
<!-- this example sets the time to 11:59:57 (AM or PM) -->
<style>
#hrs {
animation-delay: -43197s;
}
#min {
animation-delay: -3597s;
}
#sec {
animation-delay: -57s;
}
</style>
<svg class="clock">
<use href="#station_clock.svg" id="dial"/>
<defs>
<radialGradient id="bulb" cx="50%" cy="50%" r="75%">
<stop offset="0%" style="stop-color:#fff;"></stop>
<stop offset="50%" style="stop-color:#555;"></stop>
<stop offset="100%" style="stop-color:#333;"></stop>
</radialGradient>
</defs>
<g id="hrs" class="hand">
<rect x="48%" y="25%" width="4%" height="40%"></rect>
</g>
<g id="min" class="hand">
<rect x="48.5%" y="10%" width="3%" height="50%"></rect>
</g>
<g id="sec" class="hand">
<rect x="49.5%" y="15%" width="1%" height="50%"></rect>
<circle cx="50%" cy="15%" r="4%"></circle>
</g>
<circle id="center" r="1.75%" cx="50%" cy="50%"></circle>
</svg>
</html>
<html>
<!--{{{-->
<svg width="100%" height="100%" viewBox="-100 -100 200 200" version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<circle cx="-50" cy="-50" r="30" style="fill:red" />
<image x="10" y="20" width="80" height="80" xlink:href="recursion.svg" />
</svg>
<!--}}}-->
</html>
//Copied here by [[Peter Hübel]]
/*{{{*/
version.extensions.smileyMacro = {major: 0, minor: 1, revision: 0, date: new Date(2005,7,20)};
//Author: Alan Hecht
config.macros.smiley = {}
config.macros.smiley.handler = function(place,macroName,params)
{
var palette = ["transparent","#000000","#1a1507","#352e18","#464646","#666666","#a3141e","#b06b63","#cc9900","#dd9030","#dddddd","#e89d00","#edc32a","#f3cb3c","#fdf201","#fdf526","#ff3149","#ffac00","#ffbf06","#ffc846","#ffcc66","#ffd758","#ffdd01","#ffea7b","#ffed55","#ffffff"];
var data = params;
var imageMap = null;
if(data[0] == ":-)" || data[0] == ":)")
imageMap = "aaaaabbbbbaaaaaaaabdtyyvtdbaaaaabnyxxxxxujbaaabmyyffyffuujbaadyyyeeyeetttdabppppddyddpmmlbbwoooooooowsrlbbwwpooooowwmrlbbwwboooowwwbllbbwwwboooowbrllbacwwwbbbbbrllcaablswwwwsrrlibaaablsssrrllibaaaaabcrrlllcbaaaaaaaabbbbbaaaaa";
else if(data[0] == ":-(" || data[0] == ":(")
imageMap = "aaaaabbbbbaaaaaaaabdtyyvtdbaaaaabnyxxxxxujbaaabmyyyyyyyuujbaadyyyeeyeetttdabppppddyddpmmlbbwoooooooowsrlbbwwpooooowwmrlbbwwoooooowwrllbbwwwwbbbbbsrllbacwwbwwwwsbllcaablswwwwsrrlibaaablsssrrllibaaaaabcrrlllcbaaaaaaaabbbbbaaaaa";
else if(data[0] == ";-)" || data[0] == ";)")
imageMap = "aaaaabbbbbaaaaaaaabdtyyvtdbaaaaabnyxxxxxujbaaabmyyxxxxxuujbaadyyyxxxeetttdabppphddyddpmmlbbwoooooooowsrlbbwwpooooowwmrlbbwwboooowwwbllbbwwwboooowbrllbacwwwbbbbbrllcaablswwwwsrrlibaaablsssrrllibaaaaabcrrlllcbaaaaaaaabbbbbaaaaa";
else if(data[0] == ":-|" || data[0] == ":|")
imageMap = "aaaaabbbbbaaaaaaaabdtyyvtdbaaaaabnyxxxxxujbaaabmyyffyffuujbaadyyyeeyeetttdabppppddyddpmmlbbwoooooooowsrlbbwwpooooowwmrlbbwwoooooowwrllbbwwwwbbbbbsrllbacwwwwwwwsrllcaablswwwwsrrlibaaablsssrrllibaaaaabcrrlllcbaaaaaaaabbbbbaaaaa";
else if(data[0] == ":-D" || data[0] == ":D")
imageMap = "aaaaabbbbbaaaaaaaabdtyyvtdbaaaaabnyxxxxxujbaaabmyyeeyeeuujbaadyyyeeyeetttdabppppyyyyypmmlbbwbbbbbbbbbbblbbwbkzzzzzzzkbwbbwbfzzzzzzzfbwbbwbkzzzzzzzkbwbacwbkzzzzzkblcaablsbkzzzkblibaaablsbbbbblibaaaaabcrrlllcbaaaaaaaabbbbbaaaaa";
else
createTiddlyElement(place,"span",null,"errorNoSuchMacro","unknown smiley");
if(imageMap)
{
var box = createTiddlyElement(place,"span",null,"smiley",String.fromCharCode(160));
box.style.position = "relative";
box.style.width = "15px";
box.style.height = "15px";
box.style.marginLeft = "1px";
box.style.marginRight = "1px";
box.style.paddingRight = "12px";
box.style.verticalAlign = "top";
//now divide into 15x15 grid and create each pixel
// rows
for(r=0; r<15; r++)
{
// columns
for(c=0; c<15; c++)
{
//create each pixel with the correct background
var pix = document.createElement("img");
pix.className = "smileyPixel";
pix.style.position = "absolute";
pix.border = 0;
pix.style.top = r + "px";
pix.style.left = c + "px";
pix.style.width = "1px";
pix.style.height = "1px";
pix.style.backgroundColor = palette[imageMap.charCodeAt((r*15)+c)-97];
pix.src = "data:image/gif,GIF89a%01%00%01%00%91%FF%00%FF%FF%FF%00%00%00%C0%C0%C0%00%00%00!%F9%04%01%00%00%02%00%2C%00%00%00%00%01%00%01%00%40%02%02T%01%00%3B";
box.appendChild(pix);
}
}
}
}
/*}}}*/
<html>
<!-- via the great article at https://cssanimation.rocks/clocks/ -->
<svg id="station_clock.svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 598.4 598.4"><path d="M288.1 0H312v69.7h-23.9zM139.99 45.646l20.697-11.95 34.85 60.36-20.697 11.95zM34.507 159.213l11.95-20.698 60.36 34.85-11.95 20.698zM0 286.3h69.7v23.9H0zM45.685 458.4l-11.95-20.697 60.36-34.85 11.95 20.697zM159.177 563.854l-20.698-11.95 34.85-60.36 20.697 11.95zM286.3 528.7h23.9v69.7h-23.9zM458.41 552.728l-20.696 11.95-34.85-60.36 20.697-11.95zM563.803 439.128l-11.95 20.698-60.36-34.85 11.95-20.698zM528.7 288.1h69.7V312h-69.7zM552.767 139.98l11.95 20.696-60.36 34.85-11.95-20.697zM439.093 34.558l20.697 11.95-34.85 60.36-20.697-11.95z"/><path d="M297.3 0h5.7v30.2h-5.7zM266.037 1.892l5.668-.596 3.156 30.034-5.667.596zM235.113 6.936l5.575-1.185 6.28 29.54-5.576 1.185zM204.985 15.225l5.42-1.76 9.333 28.722-5.42 1.76zM175.776 26.578l5.207-2.32 12.282 27.59-5.207 2.317zM147.96 41.074l4.936-2.85 15.1 26.153-4.937 2.85zM121.804 58.29l4.61-3.35 17.753 24.43-4.612 3.352zM97.626 78.08l4.236-3.814 20.206 22.442-4.235 3.814zM75.582 100.325l3.813-4.236 22.442 20.206-3.814 4.236zM56.07 124.826l3.35-4.612 24.433 17.752-3.35 4.61zM39.183 151.215l2.85-4.936 26.153 15.1-2.85 4.935zM25.09 179.183l2.32-5.207 27.587 12.283-2.32 5.206zM14.032 208.526l1.76-5.422 28.724 9.332-1.76 5.42zM6.105 238.835l1.185-5.575 29.54 6.28-1.186 5.574zM1.46 269.743l.597-5.67 30.033 3.157-.595 5.67zM0 295.3h30.2v5.7H0zM1.857 332.288l-.595-5.67 30.034-3.155.595 5.67zM6.96 363.223l-1.185-5.576 29.54-6.278 1.184 5.574zM15.24 393.425l-1.762-5.42L42.2 378.67l1.762 5.422zM26.597 422.562l-2.32-5.207 27.59-12.283 2.317 5.207zM40.957 450.387l-2.85-4.936 26.153-15.1 2.85 4.937zM58.186 476.545l-3.35-4.61 24.432-17.753 3.35 4.61zM78.076 500.792l-3.814-4.235 22.44-20.207 3.815 4.235zM100.33 522.772l-4.235-3.813 20.207-22.443 4.236 3.814zM124.846 542.335l-4.61-3.35 17.75-24.433 4.612 3.35zM151.202 559.21l-4.936-2.85 15.1-26.154 4.936 2.85zM179.22 573.284l-5.206-2.318 12.283-27.588 5.206 2.318zM208.43 584.296l-5.422-1.76 9.33-28.724 5.423 1.76zM238.75 592.265l-5.576-1.185 6.278-29.54 5.576 1.186zM269.755 596.93l-5.67-.596 3.157-30.034 5.67.595zM295.3 568.2h5.7v30.2h-5.7zM332.322 596.535l-5.67.595-3.155-30.034 5.67-.595zM363.2 591.42l-5.576 1.186-6.28-29.54 5.576-1.184zM393.41 583.067l-5.42 1.76-9.332-28.722 5.42-1.76zM422.634 571.74l-5.207 2.32-12.282-27.588 5.207-2.32zM450.368 557.376l-4.937 2.85-15.1-26.153 4.938-2.85zM476.51 540.16l-4.613 3.35-17.75-24.432 4.61-3.35zM500.797 520.222l-4.236 3.814-20.206-22.44 4.236-3.815zM522.833 497.957l-3.814 4.236-22.442-20.207 3.814-4.236zM542.314 473.465l-3.35 4.61-24.432-17.75 3.35-4.61zM559.222 447.122l-2.85 4.936-26.153-15.1 2.85-4.936zM573.337 419.162l-2.318 5.207-27.59-12.284 2.32-5.207zM584.298 389.93l-1.76 5.42-28.724-9.332 1.76-5.42zM592.253 359.577l-1.185 5.575-29.538-6.28 1.185-5.574zM596.918 328.572l-.596 5.668-30.033-3.155.594-5.67zM568.2 297.3h30.2v5.7h-30.2zM596.5 266.002l.596 5.67-30.034 3.155-.596-5.67zM591.444 235.137l1.185 5.575-29.54 6.278-1.184-5.575zM583.08 205l1.762 5.42-28.723 9.332-1.762-5.42zM571.67 175.744l2.317 5.207-27.588 12.284-2.32-5.207zM557.346 147.93l2.85 4.935-26.153 15.1-2.85-4.936zM540.137 121.78l3.35 4.613-24.432 17.75-3.35-4.61zM520.292 97.555l3.814 4.235-22.44 20.207-3.815-4.235zM497.963 75.52l4.236 3.814-20.208 22.442-4.236-3.814zM473.545 56.01l4.61 3.35-17.75 24.432-4.612-3.35zM447.11 39.17l4.936 2.85-15.1 26.154-4.937-2.85zM419.16 25.128l5.206 2.32-12.283 27.586-5.207-2.318zM389.927 14.06l5.42 1.762-9.33 28.723-5.422-1.76zM359.588 6.137l5.575 1.185-6.278 29.54-5.575-1.186zM328.583 1.472l5.67.596-3.157 30.034-5.67-.596z"/></svg>
</html>
<html>
<a href="http://www.strxtrs.net" style="text-decoration:none;" target="_blank"><span style="font-family:Courier;font-weight:normal;font-size:18pt;color:white;background:#abba;padding:2px 7px 5px 5px;border: thin solid #898;">strχtrs</span></a></html>
----
<html>
<span style="font:18pt Courier;color:white;background:#abba;padding:2pt 5pt 5pt;border:thin solid #898;">strχtrs</span>
</html>
<html>
The (almost) original...
<alien>
<div>
<svg width="360" height="240" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
<defs>
<filter id="xeno-alien-blur">
<feGaussianBlur stdDeviation="0.1"/>
</filter>
</defs>
<g id="xeno-alien" filter="url(#xeno-alien-blur)">
<g id="xeno-alien-antlers">
<path stroke="#66aaff" fill="#ba8d73" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="4" d="m212.09698,84.10477c22.64282,-2.26989 34.0403,-7.13419 39.5,-11.49725c17.75421,-14.18803 11.32535,-27.35383 22,-24.43172c10.5,2.87432 10.47675,14.07931 17.5,17.24592c8.5,3.83243 -2.03711,-33.69453 6.5,-31.13846c8,2.39527 8.97186,21.40898 21,26.34793c10.5,4.31148 -6.60901,-44.63118 8,-34.01278c14.5,10.53917 35,52.69585 1,64.19315c-34,11.49728 -84.44667,14.83805 -101,14.3716c-17,-0.47906 -32.65988,-19.25781 -14.5,-21.07835l0,-0.00003l0,-0.00002l0,0.00001z"/>
<path stroke="#66aaff" fill="#ad7e61" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="4" d="m149.5,84.10477c-22.64278,-2.26989 -34.04028,-7.13419 -39.49999,-11.49725c-17.75418,-14.18803 -11.32534,-27.35383 -22,-24.43172c-10.5,2.87432 -10.47673,14.07931 -17.50001,17.24592c-8.5,3.83243 2.03713,-33.69453 -6.5,-31.13846c-8,2.39527 -8.97184,21.40898 -21,26.34793c-10.5,4.31148 6.60903,-44.63118 -8,-34.01278c-14.5,10.53917 -35,52.69585 -1,64.19315c34,11.49728 84.44666,14.83805 101.00002,14.3716c17,-0.47906 32.65991,-19.25781 14.49998,-21.07835l0,-0.00003l0,-0.00002l0,0.00001z"/>
</g>
<ellipse id="xeno-alien-lid" cx="185" cy="100" rx="70" ry="50" fill="#aba" stroke-width="3" stroke="black"/>
<path id="xeno-alien-scull" stroke="#66aaff" fill="#aabbaa" d="m183.58014,22.41726c-33.69772,0 -80.21555,21.59592 -80.21555,77.78551c0,0.18468 0,0.39082 0,0.5755c0.38577,55.93592 56.4113,125.14828 80.21555,125.14828c23.89377,0 80.2149,-69.53418 80.2149,-125.72378c0,-56.18959 -46.51811,-77.78551 -80.2149,-77.78551l0,0zm-72.15992,82.74017c39.25689,0 67.62124,28.11814 67.62124,70.29438c-41.07188,0 -67.62124,-26.96527 -67.62124,-70.29438zm145.68061,0c0,43.32911 -27.09396,70.29438 -68.98299,70.29438c0,-42.17624 28.93237,-70.29438 68.98299,-70.29438z"/>
<g id="xeno-alien-cloud" transform="rotate(-175, 183.781, 59.1591)" filter="url(#xeno-alien-blur)">
<path id="path2844" d="m214.16611,33.88718c0,13.95767 -14.30699,25.27265 -31.95561,25.27265c-17.64862,0 -31.95558,-11.31499 -31.95558,-25.27265c0,-13.95769 14.30696,-25.27264 31.95558,-25.27264c17.64862,0 31.95561,11.31495 31.95561,25.27264z" fill-rule="nonzero" fill="#729fcf"/>
<path id="path2844-3" d="m212.74486,34.75774c0,13.85592 -13.72656,25.08839 -30.6591,25.08839c-16.93256,0 -30.65912,-11.23248 -30.65912,-25.08839c0,-13.85591 13.72658,-25.08838 30.65912,-25.08838c16.93254,0 30.6591,11.23247 30.6591,25.08838z" fill-rule="nonzero" fill="#eeeeec"/>
<path id="path2844-9" d="m215.4758,65.934c0,12.66261 -11.60977,22.92763 -25.9312,22.92763c-14.32143,0 -25.93118,-10.26501 -25.93118,-22.92763c0,-12.66266 11.60976,-22.92779 25.93118,-22.92779c14.32143,0 25.9312,10.26513 25.9312,22.92779z" fill-rule="nonzero" fill="#eeeeec"/>
<path id="path2844-5" d="m235.90642,48.21708c0,12.66263 -11.60979,22.92778 -25.93115,22.92778c-14.3214,0 -25.93121,-10.26516 -25.93121,-22.92778c0,-12.66266 11.60982,-22.92772 25.93121,-22.92772c14.32137,0 25.93115,10.26506 25.93115,22.92772z" fill-rule="nonzero" fill="#729fcf"/>
<path id="path2844-11" d="m178.28154,55.51225c0,12.66266 -11.60979,22.92772 -25.93118,22.92772c-14.32146,0 -25.93123,-10.26505 -25.93123,-22.92772c0,-12.66266 11.60977,-22.92777 25.93123,-22.92777c14.3214,0 25.93118,10.26511 25.93118,22.92777z" fill-rule="nonzero" fill="#729fcf"/>
<path id="path2844-11-1" d="m180.79059,56.68127c0,12.66264 -11.89996,22.92769 -26.57947,22.92769c-14.67935,0 -26.57941,-10.26505 -26.57941,-22.92769c0,-12.66264 11.90005,-22.92778 26.57941,-22.92778c14.6795,0 26.57947,10.26514 26.57947,22.92778z" fill-rule="nonzero" fill="#eeeeec"/>
<path id="path2844-1" d="m147.37369,75.57402c0,10.21645 -9.26437,18.49847 -20.6925,18.49847c-11.42827,0 -20.6926,-8.28202 -20.6926,-18.49847c0,-10.21644 9.26431,-18.49849 20.6926,-18.49849c11.42815,0 20.6925,8.28205 20.6925,18.49849z" fill-rule="nonzero" fill="#729fcf"/>
<path id="path2844-1-76" d="m147.95515,76.01443c0,9.59975 -9.09853,17.38191 -20.32208,17.38191c-11.22359,0 -20.32215,-7.78217 -20.32215,-17.38191c0,-9.59987 9.09856,-17.38203 20.32215,-17.38203c11.22356,0 20.32208,7.78217 20.32208,17.38203z" fill-rule="nonzero" fill="#eeeeec"/>
<path id="path2844-5-4" d="m236.35464,50.41742c0,13.27312 -11.81717,24.0331 -26.39427,24.0331c-14.57715,0 -26.39421,-10.75996 -26.39421,-24.0331c0,-13.27314 11.81706,-24.03315 26.39421,-24.03315c14.5771,0 26.39427,10.76001 26.39427,24.03315z" fill-rule="nonzero" fill="#eeeeec"/>
<path id="path2844-2" d="m261.57568,56.03331c0,12.66272 -11.60979,22.92778 -25.93118,22.92778c-14.32141,0 -25.93118,-10.26507 -25.93118,-22.92778c0,-12.66258 11.60977,-22.92772 25.93118,-22.92772c14.3214,0 25.93118,10.26514 25.93118,22.92772z" fill-rule="nonzero" fill="#729fcf"/>
<path id="path2844-2-2" d="m260.80273,55.94434c0,11.95045 -11.69267,21.63804 -26.11636,21.63804c-14.42369,0 -26.11642,-9.68758 -26.11642,-21.63804c0,-11.9504 11.69273,-21.63815 26.11642,-21.63815c14.42369,0 26.11636,9.68777 26.11636,21.63815z" fill-rule="nonzero" fill="#eeeeec"/>
<path id="path2844-1-7" d="m148.94524,90.42492c0,6.76295 -5.39445,12.24546 -12.04884,12.24546c-6.65434,0 -12.04882,-5.48253 -12.04882,-12.24546c0,-6.76307 5.39448,-12.24554 12.04882,-12.24554c6.65439,0 12.04884,5.48246 12.04884,12.24554z" fill-rule="nonzero" fill="#729fcf"/>
<path id="path2844-1-7-2" d="m149.31294,89.65868c0,6.66121 -5.31154,12.06121 -11.86362,12.06121c-6.55203,0 -11.86359,-5.4 -11.86359,-12.06121c0,-6.66116 5.31154,-12.06132 11.86359,-12.06132c6.55206,0 11.86362,5.40015 11.86362,12.06132z" fill-rule="nonzero" fill="#eeeeec"/>
<path id="path2844-4" d="m192.94972,86.77734c0,12.6627 -11.60977,22.92775 -25.93123,22.92775c-14.32141,0 -25.93117,-10.26505 -25.93117,-22.92775c0,-12.66265 11.60976,-22.92769 25.93117,-22.92769c14.32146,0 25.93123,10.26504 25.93123,22.92769z" fill-rule="nonzero" fill="#729fcf"/>
<path id="path2844-4-2" d="m193.09142,86.18201c0,12.39523 -11.33678,22.44341 -25.32135,22.44341c-13.98454,0 -25.32129,-10.04817 -25.32129,-22.44341c0,-12.3952 11.33675,-22.44352 25.32129,-22.44352c13.9846,0 25.32135,10.04832 25.32135,22.44352z" fill-rule="nonzero" fill="#eeeeec" stroke-width="9"/>
<path id="path2844-8" d="m250.05074,76.35563c0,12.66267 -11.6098,22.92787 -25.9312,22.92787c-14.32144,0 -25.93118,-10.2652 -25.93118,-22.92787c0,-12.66262 11.60976,-22.9277 25.93118,-22.9277c14.3214,0 25.9312,10.26507 25.9312,22.9277z" fill-rule="nonzero" fill="#729fcf"/>
<path id="path2844-8-1" d="m248.67133,76.0716c0,12.17935 -11.63055,22.05274 -25.97752,22.05274c-14.34702,0 -25.97751,-9.87339 -25.97751,-22.05274c0,-12.17928 11.63049,-22.05262 25.97751,-22.05262c14.34697,0 25.97752,9.87333 25.97752,22.05262z" fill-rule="nonzero" fill="#eeeeec"/>
<path id="path2844-1-7-6" d="m199.81541,105.18665c-8.26813,1.36013 -16.07886,-3.92541 -17.44579,-11.80544c-1.36694,-7.88001 4.22757,-15.37059 12.49565,-16.73054c8.2681,-1.36009 16.07883,3.9254 17.44579,11.80544c1.36697,7.88004 -4.22752,15.37053 -12.49565,16.73055z" fill-rule="nonzero" fill="#729fcf"/>
<path id="path2844-1-7-6-5" d="m200.13701,103.74516c-8.12935,1.36001 -15.80901,-3.92554 -17.15297,-11.80546c-1.34404,-7.88001 4.15659,-15.37065 12.28595,-16.73066c8.12936,-1.36008 15.80902,3.92541 17.15306,11.80556c1.34399,7.87991 -4.15666,15.3704 -12.28603,16.73056l-0.00003,0l0.00002,0z" fill-rule="nonzero" fill="#eeeeec"/>
</g>
</g>
</svg>
</div>
<p>Lost? Try the <a href="/leutert/overview">overview</a>!</p>
<script type="text/javascript">//<![CDATA[
(function(window){
var alien_lid = window.document.getElementById('xeno-alien-lid');
function blink(lid, pos, min, max, delta) {
pos += delta;
if (pos < min) {
pos = min; delta = -delta;
}
else if (pos > max) {
pos = max; delta = -delta;
}
lid.setAttribute('ry', pos);
window.setTimeout(blink, 100, lid, pos, min, max, delta);
};
window.setTimeout(blink, 100, alien_lid, 10, 10, 70, 5);
})(window);
///]]></script>
</alien>
</html>
<html><svg width="360" height="240" xmlns="http://www.w3.org/2000/svg">
<defs>
<filter id="xeno-alien-blur">
<feGaussianBlur stdDeviation="0.1"/>
</filter>
</defs>
<style type="text/css">
@keyframes blink {
0% { transform: scale(1,1); }
100% { transform: scale(1,.8); }
}
#xeno-alien-eyelids {
fill: #aabbaa;
animation: blink 2s infinite alternate;
}
</style>
<g>
<title>xenome</title>
<g id="alien">
<ellipse id="xeno-alien-eyelids" cx="184" cy="100" rx="78" ry="70" fill="#aabbaa" stroke="#66aaff"></ellipse>
<g filter="url(#xeno-alien-blur)" id="antlers">
<path stroke="#66aaff" fill="#ba8d73" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="4" d="m212.09698,84.10477c22.64282,-2.26989 34.0403,-7.13419 39.5,-11.49725c17.75421,-14.18803 11.32535,-27.35383 22,-24.43172c10.5,2.87432 10.47675,14.07931 17.5,17.24592c8.5,3.83243 -2.03711,-33.69453 6.5,-31.13846c8,2.39527 8.97186,21.40898 21,26.34793c10.5,4.31148 -6.60901,-44.63118 8,-34.01278c14.5,10.53917 35,52.69585 1,64.19315c-34,11.49728 -84.44667,14.83805 -101,14.3716c-17,-0.47906 -32.65988,-19.25781 -14.5,-21.07835l0,-0.00003l0,-0.00002l0,0.00001z" id="svg_1"/>
<path stroke="#66aaff" fill="#ad7e61" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="4" d="m149.5,84.10477c-22.64278,-2.26989 -34.04028,-7.13419 -39.49999,-11.49725c-17.75418,-14.18803 -11.32534,-27.35383 -22,-24.43172c-10.5,2.87432 -10.47673,14.07931 -17.50001,17.24592c-8.5,3.83243 2.03713,-33.69453 -6.5,-31.13846c-8,2.39527 -8.97184,21.40898 -21,26.34793c-10.5,4.31148 6.60903,-44.63118 -8,-34.01278c-14.5,10.53917 -35,52.69585 -1,64.19315c34,11.49728 84.44666,14.83805 101.00002,14.3716c17,-0.47906 32.65991,-19.25781 14.49998,-21.07835l0,-0.00003l0,-0.00002l0,0.00001z"/>
</g>
<path id="scull" stroke="#66aaff" fill="#aabbaa" d="m183.58014,22.41726c-33.69772,0 -80.21555,21.59592 -80.21555,77.78551c0,0.18468 0,0.39082 0,0.5755c0.38577,55.93592 56.4113,125.14828 80.21555,125.14828c23.89377,0 80.2149,-69.53418 80.2149,-125.72378c0,-56.18959 -46.51811,-77.78551 -80.2149,-77.78551l0,0zm-72.15992,82.74017c39.25689,0 67.62124,28.11814 67.62124,70.29438c-41.07188,0 -67.62124,-26.96527 -67.62124,-70.29438zm145.68061,0c0,43.32911 -27.09396,70.29438 -68.98299,70.29438c0,-42.17624 28.93237,-70.29438 68.98299,-70.29438z"/>
</g>
<g id="cloud" transform="rotate(-175, 183.781, 59.1591)" filter="url(#xeno-alien-blur)">
<path d="m214.16611,33.88718c0,13.95767 -14.30699,25.27265 -31.95561,25.27265c-17.64862,0 -31.95558,-11.31499 -31.95558,-25.27265c0,-13.95769 14.30696,-25.27264 31.95558,-25.27264c17.64862,0 31.95561,11.31495 31.95561,25.27264z" fill-rule="nonzero" fill="#729fcf"/>
<path d="m212.74486,34.75774c0,13.85592 -13.72656,25.08839 -30.6591,25.08839c-16.93256,0 -30.65912,-11.23248 -30.65912,-25.08839c0,-13.85591 13.72658,-25.08838 30.65912,-25.08838c16.93254,0 30.6591,11.23247 30.6591,25.08838z" fill-rule="nonzero" fill="#eeeeec"/>
<path d="m215.4758,65.934c0,12.66261 -11.60977,22.92763 -25.9312,22.92763c-14.32143,0 -25.93118,-10.26501 -25.93118,-22.92763c0,-12.66266 11.60976,-22.92779 25.93118,-22.92779c14.32143,0 25.9312,10.26513 25.9312,22.92779z" fill-rule="nonzero" fill="#eeeeec"/>
<path d="m235.90642,48.21708c0,12.66263 -11.60979,22.92778 -25.93115,22.92778c-14.3214,0 -25.93121,-10.26516 -25.93121,-22.92778c0,-12.66266 11.60982,-22.92772 25.93121,-22.92772c14.32137,0 25.93115,10.26506 25.93115,22.92772z" fill-rule="nonzero" fill="#729fcf"/>
<path d="m178.28154,55.51225c0,12.66266 -11.60979,22.92772 -25.93118,22.92772c-14.32146,0 -25.93123,-10.26505 -25.93123,-22.92772c0,-12.66266 11.60977,-22.92777 25.93123,-22.92777c14.3214,0 25.93118,10.26511 25.93118,22.92777z" fill-rule="nonzero" fill="#729fcf"/>
<path d="m180.79059,56.68127c0,12.66264 -11.89996,22.92769 -26.57947,22.92769c-14.67935,0 -26.57941,-10.26505 -26.57941,-22.92769c0,-12.66264 11.90005,-22.92778 26.57941,-22.92778c14.6795,0 26.57947,10.26514 26.57947,22.92778z" fill-rule="nonzero" fill="#eeeeec"/>
<path d="m147.37369,75.57402c0,10.21645 -9.26437,18.49847 -20.6925,18.49847c-11.42827,0 -20.6926,-8.28202 -20.6926,-18.49847c0,-10.21644 9.26431,-18.49849 20.6926,-18.49849c11.42815,0 20.6925,8.28205 20.6925,18.49849z" fill-rule="nonzero" fill="#729fcf"/>
<path d="m147.95515,76.01443c0,9.59975 -9.09853,17.38191 -20.32208,17.38191c-11.22359,0 -20.32215,-7.78217 -20.32215,-17.38191c0,-9.59987 9.09856,-17.38203 20.32215,-17.38203c11.22356,0 20.32208,7.78217 20.32208,17.38203z" fill-rule="nonzero" fill="#eeeeec"/>
<path d="m236.35464,50.41742c0,13.27312 -11.81717,24.0331 -26.39427,24.0331c-14.57715,0 -26.39421,-10.75996 -26.39421,-24.0331c0,-13.27314 11.81706,-24.03315 26.39421,-24.03315c14.5771,0 26.39427,10.76001 26.39427,24.03315z" fill-rule="nonzero" fill="#eeeeec"/>
<path d="m261.57568,56.03331c0,12.66272 -11.60979,22.92778 -25.93118,22.92778c-14.32141,0 -25.93118,-10.26507 -25.93118,-22.92778c0,-12.66258 11.60977,-22.92772 25.93118,-22.92772c14.3214,0 25.93118,10.26514 25.93118,22.92772z" fill-rule="nonzero" fill="#729fcf"/>
<path d="m260.80273,55.94434c0,11.95045 -11.69267,21.63804 -26.11636,21.63804c-14.42369,0 -26.11642,-9.68758 -26.11642,-21.63804c0,-11.9504 11.69273,-21.63815 26.11642,-21.63815c14.42369,0 26.11636,9.68777 26.11636,21.63815z" fill-rule="nonzero" fill="#eeeeec"/>
<path d="m148.94524,90.42492c0,6.76295 -5.39445,12.24546 -12.04884,12.24546c-6.65434,0 -12.04882,-5.48253 -12.04882,-12.24546c0,-6.76307 5.39448,-12.24554 12.04882,-12.24554c6.65439,0 12.04884,5.48246 12.04884,12.24554z" fill-rule="nonzero" fill="#729fcf"/>
<path d="m149.31294,89.65868c0,6.66121 -5.31154,12.06121 -11.86362,12.06121c-6.55203,0 -11.86359,-5.4 -11.86359,-12.06121c0,-6.66116 5.31154,-12.06132 11.86359,-12.06132c6.55206,0 11.86362,5.40015 11.86362,12.06132z" fill-rule="nonzero" fill="#eeeeec"/>
<path d="m192.94972,86.77734c0,12.6627 -11.60977,22.92775 -25.93123,22.92775c-14.32141,0 -25.93117,-10.26505 -25.93117,-22.92775c0,-12.66265 11.60976,-22.92769 25.93117,-22.92769c14.32146,0 25.93123,10.26504 25.93123,22.92769z" fill-rule="nonzero" fill="#729fcf"/>
<path d="m193.09142,86.18201c0,12.39523 -11.33678,22.44341 -25.32135,22.44341c-13.98454,0 -25.32129,-10.04817 -25.32129,-22.44341c0,-12.3952 11.33675,-22.44352 25.32129,-22.44352c13.9846,0 25.32135,10.04832 25.32135,22.44352z" fill-rule="nonzero" fill="#eeeeec" stroke-width="9"/>
<path d="m250.05074,76.35563c0,12.66267 -11.6098,22.92787 -25.9312,22.92787c-14.32144,0 -25.93118,-10.2652 -25.93118,-22.92787c0,-12.66262 11.60976,-22.9277 25.93118,-22.9277c14.3214,0 25.9312,10.26507 25.9312,22.9277z" fill-rule="nonzero" fill="#729fcf"/>
<path d="m248.67133,76.0716c0,12.17935 -11.63055,22.05274 -25.97752,22.05274c-14.34702,0 -25.97751,-9.87339 -25.97751,-22.05274c0,-12.17928 11.63049,-22.05262 25.97751,-22.05262c14.34697,0 25.97752,9.87333 25.97752,22.05262z" fill-rule="nonzero" fill="#eeeeec"/>
<path id="path2844-1-7-6" d="m199.81541,105.18665c-8.26813,1.36013 -16.07886,-3.92541 -17.44579,-11.80544c-1.36694,-7.88001 4.22757,-15.37059 12.49565,-16.73054c8.2681,-1.36009 16.07883,3.9254 17.44579,11.80544c1.36697,7.88004 -4.22752,15.37053 -12.49565,16.73055z" fill-rule="nonzero" fill="#729fcf"/>
<path id="path2844-1-7-6-5" d="m200.13701,103.74516c-8.12935,1.36001 -15.80901,-3.92554 -17.15297,-11.80546c-1.34404,-7.88001 4.15659,-15.37065 12.28595,-16.73066c8.12936,-1.36008 15.80902,3.92541 17.15306,11.80556c1.34399,7.87991 -4.15666,15.3704 -12.28603,16.73056l-0.00003,0l0.00002,0z" fill-rule="nonzero" fill="#eeeeec"/>
</g>
</g>
</svg></html>