Search Results for: feed

implementing an SVG viewer in JavaScript

Last week, I wrote about the idea of rendering SVG through JavaScript. At the time, it seemed possible, but pretty difficult. Today, I sat down and threw a few hours at it, and have a simple viewer that shows about 80% of basic shapes.

check this out (in a non-SVG browser, of course)

The actual drawing of the shapes is handled with Walter Zorn’s JSGraphics library, so I did not need to do much, in that regard.

The most difficult part was the parsing of the SVG itself. I could not find an XML parser for JavaScript that I liked, so I spent a bit of time writing one into the script. The parser reads the file in using the XMLHttpRequest object, then parses it into a walkable DOM-tree.

The next difficult part was more frustrating than tricky – apparently, there is no simple “navigator.SVGSupported” constant, so I spent a bit of time finding some tests for that. That bit still annoys me…

I have not tested this in IE yet (I don’t have Windows on any of my home machines), so will probably need to fix up some things in it tomorrow.

Walter’s script does not yet support anti-aliasing or bezier lines, which I have mailed him about.

When I started working on this, I was only doing it as a way to improve the speed of FCKEditor‘s icons. For some reason, I could not see the more obvious benefits to this, which would make it justifiable to spend some time working on this on company time.

However, it dawned on me that SVG is perfect for drawing clean graphs for various purposes, without complex PHP. That means that I may be able to get some time sanctioned for this purpose at my place of employment (which means I won’t simply lose interest and go do something else for a few months).

Anyway – enjoy, and give me some feedback!

webme 0.5

I will be releasing version 0.5 of my CMS, WebME (Website Management Engine) over the weekend. I’m seriously interested in getting feedback in it, so any of you that might be interested, please either mail me (kae blah verens blah com), or comment below.

If you are interested, please give an example of a site that you would like to use as a template. DO NOT use any commercial sites – use your own non-work-related sites, ye buggers! Remember that I am doing this in my free time, to try and promote the CMS and improve it. Don’t be unfair and ask me to convert your commercial sites, as that would be unethical, and I just will not do it – remember, I have mouths to feed as well.

I am particularly interested in finding out what people find difficult, buggy, or just plain wrong.

I’ll make another post when it’s ready, with a generic post. Those of you that supplied a sample site will be mailed individually with your versions.

The WebME will be released as GPL. The code you receive, you are free to re-use in personal or commercial sites. If you make any improvements to it, please be kind enough to post the improvements to me.

the old bugs are the best

I just demonstrated that Planet software is susceptible to poisoning by broken HTML.

I noticed the problem while reading bigbro’s blog – he had left an <i> element open, which was not caught by the Planet ILUG engine. As a result, all the following posts were in italic.

The Planet ILUG engine is based on Planet Planet, which uses Mark Pilgrim’s feed parser. The source-code of the feed parser claims to sanitise its posts, but I proved that wrong by leaving the following lines of HTML at the end of a test post which was then syndicated out to Planet ILUG:

<font color="#ffffff"><sub>

I remember coming across this bug a long time back – late 80s/early 90s, when the net was just taking off – at the time, HTML chatrooms were very popular. As a result, there were quite a few chatrooms out there that could be poisoned in a very similar way.

The only sanitising done by the feed parser seems to be to ensure that only a set list of allowed elements are let through in the code, and that other elements are removed. The parser does not appear to make sure that the let-through elements are properly closed!

On the HTML-poisoning note: I remember a long time back, when I was working for a Dublin CORBA consultancy company, they built the first ever forum powered by EJB, as a proof-of-something. They were showing off the bright and shiny new application, really proud of it. As a test, I stuck a simple line of code into a post to the forum:

<script type="text/javascript">document.location="http://contactjuggling.org";</script>

The look on the developers’ faces was priceless.

I wonder, how many other Planet engines are susceptible to this old bug?

BBC RSS Feed Confuses Techie

In the BBC Technology RSS feed, I came across this interesting description of an article:

The majority of office workers complain that computer jargon is as difficult to un user is bamboozled by jargon used .

Way to confoozle a techie, BBC.

rekog

As some people know, I’ve been thinking about robotic gardening for years. It’s about time I started on it.

The robot’s brain will consist of a few modules, some of which are:

  • A recognition engine, for distinguishing between plants I want, plants I don’t want, and other miscellaneous items (sky, dirt, people, etc).
  • A mapping engine. This engine will take multiple images as its input, and build up a 3D internal representation of the world based on those images.
  • The rest. I’ll worry about these when the time comes, but basically, these consist of a scheduling engine, code for controlling the various parts of the robot, and sundry.

I’ve started on the recognition engine, which I am calling rekog, as I’m using the KDE widget set to construct it.

In the end, the finished code will consist of a simple API for importing an image and retrieving a list of probable identities for the image’s contents.

Of course, to get to that end, I need something visual, so I’m building a visual program for importing the images and building test data.

The program will be simple to use. Simply build a list of images, create some “neurons” describing what the images contain (“vegetation”, “sky”, “road”, “grass”, “nettles”, “potatoes”), click “train”, then the engine will be reasonably ready for use with live images.

The “brain” of the engine will be a neural network, or at least, an approximation of what I think is a neural network (I’m not an educated computer scientist, so I may be wrong). In particular, it will be similar to a “Hopfield Network”.

The difference between a Hopfield network and the usual feed-forward perceptron is that a Hopfield network forms a recurrent cycle, which means that each neuron is linked to almost every other neuron (no “layers”), and a “memory” of sorts remains in the system.

An advantage to the memory effect is that an image seen just a moment ago can influence the result of the image you are looking at now. This means that if the engine is definite that the image it’s looking at contains, say, nettles, then there is a greater chance that it will recognise the nettles in the next image which is taken from a foot away.

Anyway – I’m enjoying learning visual programming – I never got the hang of GUI stuff back when I was working in C in the 20th century. The concepts I’ve learned working with Unobtrusive JavaScript and AJAX (two forms of asynchronous programming in web pages) are really helping me get the hang of it.

neurons for memory

New Scientist has an article about a study which is honing in on particular neurons which fire when a person recognises an image of a person.

What I find surprising about this is that the concept is very simple to understand, but it seems to be taking researchers decades to come to the point – they seem surprised to find single neurons firing, as a single neuron is a very simple organism, so how could it hold an abstract concept?

I’ve been doing a lot of thinking about neural networks recently, as I’m working on a robotic gardening machine, which will eventually be put to good use in my own garden to help with my farming.

During my own thinking on this, I’ve also come to the realisation that one single neuron can hold an entire complex memory. When you think of it, a neuron includes not just itself, but its connections to the neurons around it. It is the connections that give a neuron its “intelligence”. A memory, then, is the sum of a neuron’s connections.

Now, it’s not quite as simple as that… the connections take input from other neurons, which in turn are calculated from further connections. In short, a simple yes/no question is actually quite complex when you try to work it out with neurons, but when you get the answer, you can trace back on the connections and get a very rich “reason” for the solution.

For instance, the article mentions Halle Berry. Now, for me, Halle Berry rings several bells – a very nice golf swing in a certain film I can’t remember the name of being the strongest. So, for me at least, the neuron (or small group of neurons) that recognises Halle also links the recognition strongly to that scene. There is also an image of her face, and for some reason, a Michael Jackson video (did she play an Egyptian queen in a video?).

That’s at least four neurons, each of which, if I think about them, will throw up a load more connections.

I think that the various neurons help to keep the memory strong. In Artificial Neural Networks, changing a single neuron is discouraged if it has strong connections to many others, as that change will affect the results of those other neurons.

I think that this is why mnemonic memory works so well. In Mnemonics, in order to remember a single item, you try to link it with something you already know. For example, in the old Memory Palace method, you imagine a walk through your house, or another familiar place. Each room that you enter, you can associate with a certain thought. For more memories, you can associate individual points of interest in the room – shelves, windows, corners, etc.

For instance, let’s say you are to remember a shopping list of “bananas, lightbulbs, baby food, and clothes pegs”, you could associate it with my own house like this: “I walk into my house. Before I can enter, I need to push a huge inflated banana out of the way. On my left is a lavatory. In that room, the walls are covered in blinking lightbulbs. Further on, I reach the main hall. The floor is cobbled with jars of baby food. I walk over the jars into the sitting room, where my girlfriend is sitting, trying to stick as many clothespegs to her face as possible”.

Now, by associating the front door with a banana, for instance, you are doing a few things – you strengthen connections between your front door and bananas, you also connect bananas with your front door, and the absurdity of the situation impresses the connections further. Later on, when you reach the shopping market, you don’t need to remember what was on your list – you just need to go through your memory palace a room at a time.

What is very important about this is that you have used only two items of memory (your front door, and bananas) to remember a third item – that bananas are on your list.

I wonder – Is the sum of possible memories far greater than the sum of neurons available to you? It seems to me that it’s dependant more on the connections than the neurons.

Ramble finished…

thinking about thinking

As many of you may know, one great pastime of mine is thought-experiments about robotic gardening.

I’ve bought a mini-itx board for building my robot, so the obvious next step was to think about how the robot should think.

I’ve been interested in Artificial Neural Networks for a few years, and they seem like the right way to go about what I want.

The problem I decided to focus on was this:

Given a photo of what the robot is facing, make it figure out is the photo of something organic, or inorganic.

A very simplistic diagram of how the machine might do this is shown below:

The above shows a very basic neural net. I think it’s called a “feed-forward” net, because each column of units is connected directly to just the adjacent columns (note that the rightmost column is not connected to the leftmost).

In the actual net, the “input” units would correspond to individual pixels of the image. The image is most definitely not to-scale – hundreds of input units would be required, and much more than just two hidden units – possibly two or more layers would be required as well, but you get the picture.

This net, when trained, would give an adequate answer. But then, the question arose – could the same net be used to provide more detail?

ie; What if we want to know if what we’re looking at is a nettle?

Logically, it would be possible to rebuild the network with just that question in mind, but it occured to me that it may be possible to do both at the same time.

The two answers come from the same hidden data. This may end up with a little less accuracy, as the neurons are now providing answers tailored to two different end goals, instead of one.

Looking at the diagram, though, it becomes clear that the “is nettle” unit is not availing itself of all available data. One major point about nettles, is that they’re organic, so there really should be a link between the “is organic” and “is nettle” units. It would drastically aid in accuracy, I believe.

There is a subtle effect which would appear in the above network…

Let’s say that the network is looking at a photo of a brick wall. That photo is then replaced by a photo of a nettle. The units are all updated one at a time, from left column to right column, top to bottom.

A point to note here is that the “is nettle” unit would be updated before the “is organic” unit.

I expect that “is organic” would be very tightly bound to the answer to “is nettle”, so it’s weightings would be pretty high. But, as the “is organic” unit in this case would be still holding to answer to the brick wall question by the time it is polled by “is nettle”, that the “is nettle” unit would most likely not recognise the picture of a nettle for what it was.

Interestingly, it would get it right when the exact same image was put through immediately afterwards.

I think that is similar to how we ourselves take a moment to re-orient ourselves when suddenly changing focus from concentrating on one subject to another.

Expanding on that, I think it would be interesting to have every neuron connected directly to every other neuron. It would lead to some slower results, but I think that it would allow much more accurate results over time.

For example, in video, if ever frame was considered one at a time, with absolutely no memory of what had been viewed the time before, then it may be possible to get drastically different results from each frame. However, if, for example, the previous frame was of a man standing in a field, then with the new connection-based network, the network would be pre-disposed to expect a man standing in a field. I think this may be called “feed back”.

This will be very useful for my robot, as it means I can track actual live video, and not have to rely on just still frames.

using javascript folds in vim

I discovered a fantastic tool in vim recently – folding.

Now that I’ve learned to use it, I find that I’m addicted! I’ve installed Linux on a few machines in the last few weeks, and each time I do it, I don’t feel complete until I activate it.

To turn on folding for JavaScript, place the following line in your ~/.vimrc.

let javaScript_fold=1

To show you an example of how it appears, I’m working on the following page: borders.

The JavaScript for that page is getting pretty massive, so folding lets me navigate the file easily. Here’s how the script looks upon opening it with folding inactive:

/* coded by Kae - kae@verens.com */ {
/*
 I'd appreciate any feedback.
 You have the right to include this in your sites.
 Please retain this notice.
 This source has elements coded by Dean Edwards - please read his notices before copying
*/
}
function getCss(){
 var els,i;
 getCss_done=1;
 // get external stylesheets
 els=document.getElementsByTagName('link');
 for(i=0;i<els.length;++i){
  if(els[i].type=='text/css' && els[i].href){
   getCss_done=0;
   getCss_leftToDo++;
   var x=new XMLHttpRequest();
   x.open('GET',els[i].href,true);
   x.onreadystatechange=function(){
    if(x.readyState==4 && (x.status==200 || x.status==304) ){
     getCss_text+=x.responseText;
     getCss_leftToDo--;
     getCss_parseCssText();
     if(!getCss_leftToDo)getCss_done=1;
    }
   }
   x.send(null);
  }
 }
}

Reasonable, you probably think. But, what if you’re looking for a section of that file and it’s 970 lines long? That’s how long that particular script is so far. The default folding macros supplied by vim turn the above into this:

/* coded by Kae - kae@verens.com */ {
/*
 I'd appreciate any feedback.
 You have the right to include this in your sites.
 Please retain this notice.
 This source has elements coded by Dean Edwards - please read his notices before copying
*/
}
function getCss(){--------------------------------------------------------------------------------------------------------------------------------------------------------
function getCss_parseCssText(){-------------------------------------------------------------------------------------------------------------------------------------------
function borderRadius(){--------------------------------------------------------------------------------------------------------------------------------------------------
function borderRadius_waitForCss(){---------------------------------------------------------------------------------------------------------------------------------------
function borderRadius_generateCurves(){-----------------------------------------------------------------------------------------------------------------------------------
function sqrt(num){-------------------------------------------------------------------------------------------------------------------------------------------------------
function drawRect(el,x,y,w,h,bc,bi,op){-----------------------------------------------------------------------------------------------------------------------------------

Isn’t that great!? Now, to view any particular function, I don’t need to go searching for it – I can just close the one I’m working on (zc), use my arrow keys to go to the function I want, then open that with zo.

But, that’s not good enough… The borderRadius_generateCurves() function is 471 lines long, for example.

So, I took a look inside the vim macro file for JavaScript (/usr/share/vim/vim63/syntax/javascript.vim).

The language used by the syntax manager is damned ugly looking, so it was a real trial trying to do what I wanted, without screwing everything up. Eventually, I found it. Here’s the code that does the default folding:

if exists("javaScript_fold")
    syn match   javaScriptFunction      "\<function\>"
    syn region  javaScriptFunctionFold  start="\<function\>.*[^};]$" end="^\z1}.*$" transparent fold keepend

    syn sync match javaScriptSync       grouphere javaScriptFunctionFold "\<function\>"
    syn sync match javaScriptSync       grouphere NONE "^}"

    setlocal foldmethod=syntax
    setlocal foldtext=getline(v:foldstart)
else
    syn keyword javaScriptFunction      function
    syn match   javaScriptBraces           "[{}]"
endif

syn sync fromstart
syn sync maxlines=100

What I wanted, was to fold at every loop, comment, conditional, and function. It was actually quite simple in the end – just replace the above with this:

syn region myFold start="{" end="}" transparent fold
syn sync fromstart
set foldmethod=syntax
set foldtext=getline(v:foldstart)
syn sync maxlines=100

Now, the entire file was visible when I opened it:

/* coded by Kae - kae@verens.com */ {-------------------------------------------------------------------------------------------------------------------------------------
function getCss(){--------------------------------------------------------------------------------------------------------------------------------------------------------
function getCss_parseCssText(){-------------------------------------------------------------------------------------------------------------------------------------------
function borderRadius(){--------------------------------------------------------------------------------------------------------------------------------------------------
function borderRadius_waitForCss(){---------------------------------------------------------------------------------------------------------------------------------------
function borderRadius_generateCurves(){-----------------------------------------------------------------------------------------------------------------------------------
function sqrt(num){-------------------------------------------------------------------------------------------------------------------------------------------------------
function drawRect(el,x,y,w,h,bc,bi,op){-----------------------------------------------------------------------------------------------------------------------------------
/* global variables */ {--------------------------------------------------------------------------------------------------------------------------------------------------
/* load xmlhttprequest compatibility layer, if required */ {--------------------------------------------------------------------------------------------------------------
/* attach the onload event */ {-------------------------------------------------------------------------------------------------------------------------------------------

/* the following code was not written by Kae Verens. licenses have been kept */ {-----------------------------------------------------------------------------------------

When I open a function, it doesn’t automatically expand the whole thing now, making it a bit more readable. I can expand it out as I need, and keep the bits I’m not interested in hidden:

function borderRadius_generateCurves(){
 /* common variables */ {-------------------------------------------------------------------------------------------------------------------------------------------------
 for(;i<getCss_rules.length;++i){
  rules=getCss_rules[i][1];
  /* fix undefined css */ {-----------------------------------------------------------------------------------------------------------------------------------------------
  /* common variables */ {------------------------------------------------------------------------------------------------------------------------------------------------
  if(parseInt(tr[0]) || parseInt(br[0]) || parseInt(bl[0]) || parseInt(tl[0])){
   /* common variables */ {-----------------------------------------------------------------------------------------------------------------------------------------------
   for(;j<els.length;++j){ /* draw border and background */
    /* setup border array and common variables */ {-----------------------------------------------------------------------------------------------------------------------
    /* create background element */ {-------------------------------------------------------------------------------------------------------------------------------------
    /* generate curved borders */ {
     if(tr0){ // top right corner-----------------------------------------------------------------------------------------------------------------------------------------
     if(br0){ // bottom right corner
      var irx=tppBR0-tppWR,iry=tppBR1-tppWB;
      var irx2=irx*irx,tmp2=tppHeight-tppBR1;
      for(var cx=tppBR0-1;cx>-1;--cx){
       var cx2=cx*cx,ind=tppWidth-tppBR0+cx;
       var h=(cx<irx)?sqrt(iry*iry*(1-cx2/irx2)):0;
       b_arr[ind][2]=tmp2+h;
       b_arr[ind][3]=tmp2+sqrt(tppBR1*tppBR1*(1-cx2/(tppBR0*tppBR0)));
      }
     }
     if(bl0){ // bottom left corner---------------------------------------------------------------------------------------------------------------------------------------
     if(tl0){ // top left corner------------------------------------------------------------------------------------------------------------------------------------------
    }
    /* fill in the background */ {----------------------------------------------------------------------------------------------------------------------------------------
    /* draw borders */ {--------------------------------------------------------------------------------------------------------------------------------------------------
    theEl.parentNode.insertBefore(bgw,theEl);
   }
   for(j=0;j<els.length;j++){ // remove the original border and adjust the padding accordingly ---------------------------------------------------------------------------
  }
 }
 /* show timer */ {-------------------------------------------------------------------------------------------------------------------------------------------------------
}

Note that I’ve managed to contract comments as well. You do that by using the { and } symbols:

/* coded by Kae - kae@verens.com */ {
/*
 I'd appreciate any feedback.
 You have the right to include this in your sites.
 Please retain this notice.
 This source has elements coded by Dean Edwards - please read his notices before copying
*/
}

That trick can also be used to close switches as well:

   switch(parts2[0]){
    case 'background': {--------------------------------------------------------------------------------------------------------------------------------------------------
    case 'border': {------------------------------------------------------------------------------------------------------------------------------------------------------
    case 'border-color': {------------------------------------------------------------------------------------------------------------------------------------------------
    case 'border-radius': {-----------------------------------------------------------------------------------------------------------------------------------------------
    case 'border-top-right-radius': {
     m=(parts3L>1)?parts3[0]+' '+parts3[1]:parts3[0]+' '+parts3[0];
     getCss_rules[a][1]['border-top-right-radius']=m;
     break; }
    case 'border-top-left-radius': {--------------------------------------------------------------------------------------------------------------------------------------
    case 'border-bottom-right-radius': {----------------------------------------------------------------------------------------------------------------------------------
    case 'border-bottom-left-radius': {-----------------------------------------------------------------------------------------------------------------------------------
    case 'border-style': {------------------------------------------------------------------------------------------------------------------------------------------------
    case 'border-width': {------------------------------------------------------------------------------------------------------------------------------------------------
    default: {------------------------------------------------------------------------------------------------------------------------------------------------------------
   }

Well, that’s the longest thing I’ve written in a while… I hope it’s useful to someone!

Version 0.3 of WebME released

The previous releases of the CMS were pretty tricky to install, but this release should make installation of a complete WebME system as easy as falling over a rock.

See here for the WebME release announcement.

Main points:

  • New installation method – no nasty fiddling around. Just download the install script to the root of your site, make the directory and file writeable by the server, then read the file through your browser.
  • New upgrade method. From 0.3 onwards, upgrading will be as easy as a single click in the administration area. There is a new area – “Server Administration”, which has an upgrade tool which downloads upgrade scripts if they exist, and runs them, automating the migration to more recent versions of the system.
  • New theme, developed by Maria of webworks.ie. Really makes the first impressions a bit easier on the eyes than my own design efforts!

Please do try it out. I haven’t had any feedback on it yet, but I think that was because installation has been tricky, up until now.

RSS Feeds, with Firefox

I wasn’t aware of how useful RSS feeds were until yesterday, when I installed the pre-release of Firefox 1.

In fact, I remember talking to Donncha about the appropriate Mime-type for the XML used in it (still not sure – either application/xml or text/xml), while wondering to myself how many people actually find it useful.

After installing the new Firefox, though, I began noticing little RSS symbols in the bottom right of the browser on some sites. On clicking them, I discovered something wonderful: “Live Bookmarks“!

Try it and see! If you see the RSS symbol on the bottom right, click it, click “Subscribe to RSS”, then look in the Bookmarks of your browser!

When you want to update that list, just right-click on the parent folder, and click “Refresh Live Bookmark”.