var org = {p3k: ({url:"http://www.villagevoice.com/syndication/events?session_name=l2e9lonlu2o3ph7sbgc71sv8k3&page=1&category=155016", xml:"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<rss version=\"2.0\">\n  <channel>\n    <title><![CDATA[Village Voice | Events]]></title>\n    <link>http://villagevoice.com</link>\n    <description><![CDATA[Village Voice: for news, music, arts, and events in New York]]></description>\n    <language>en-us</language>\n    <pubDate>Tue, 09 Feb 2010 09:48:54 -0600</pubDate>\n    <lastBuildDate>Tue, 09 Feb 2010 09:48:54 -0600</lastBuildDate>\n    <docs>http://villagevoice.com/about/syndication</docs>\n    <generator>Village Voice Media XML Feed Generator</generator>\n    <managingEditor>editor@villagevoice.com</managingEditor>\n    <webMaster>webmaster@villagevoice.com</webMaster>\n    <item>\n      <title><![CDATA[F&ecirc;tes de la Nuit]]></title>\n      <link>http://www.villagevoice.com/events/fandecirc-tes-de-la-nuit-1628410/</link>\n      <description><![CDATA[Tue., February 9, 8:00pm - Any other time of year, Paris can be an overpriced tourist trap full of hostile French people. But that takes a backseat to romance around Valentine's Day, when we can be a little more forgiving to the aphrodisiacal City of Light. That's where Obie-winning playwright Charles Mee sets his new love st...]]></description>\n      <guid>http://www.villagevoice.com/events/fandecirc-tes-de-la-nuit-1628410/</guid>\n    </item>\n    <item>\n      <title><![CDATA[The Miracle Worker]]></title>\n      <link>http://www.villagevoice.com/events/the-miracle-worker-1641221/</link>\n      <description><![CDATA[Every week Monday, Tuesday, Wednesday, Thursday, Friday, Saturday from Fri., February 12 until Wed., March 3, 8:00pm - Alison Pill hasn&#146;t performed any wonders, but she&#146;s been remarkably good in many plays. Now she&#146;ll play true-life marvel Annie Sullivan in this revival of the play about the education of Helen Keller. Kate Whoriskey, no stranger to female troubles after helming Ruined, sets her sights...]]></description>\n      <guid>http://www.villagevoice.com/events/the-miracle-worker-1641221/</guid>\n    </item>\n    <item>\n      <title><![CDATA[The Pride]]></title>\n      <link>http://www.villagevoice.com/events/the-pride-1603728/</link>\n      <description><![CDATA[Every week Sunday from Sun., January 31 until Sat., March 20, 3:00pm - In addition to Mini Coopers and breakfast teas, the U.K.'s top exports include a steady supply of slender, elegant leading men. New York has imported two such swains (and one lissome lass, Andrea Riseborough) for MCC's production of Alexi Kaye Campbell's Olivier Award&#150;winning <b>The Pride</b>, ...]]></description>\n      <guid>http://www.villagevoice.com/events/the-pride-1603728/</guid>\n    </item>\n    <item>\n      <title><![CDATA[The Myopia]]></title>\n      <link>http://www.villagevoice.com/events/the-myopia-1562952/</link>\n      <description><![CDATA[Every week Wednesday, Thursday, Friday, Saturday from Wed., January 6 until Wed., February 10, 7:30pm - The Foundry Theater has excellent vision. Whether ceding the stage to an early career artist or supporting a mid-career one, the Foundry has championed remarkable theatermakers who challenge and complicate what we consider a play. Happily, the Foundry has now turned its eagle eyes toward Obie winner...]]></description>\n      <guid>http://www.villagevoice.com/events/the-myopia-1562952/</guid>\n    </item>\n    <item>\n      <title><![CDATA[A Lie of the Mind]]></title>\n      <link>http://www.villagevoice.com/events/a-lie-of-the-mind-1617955/</link>\n      <description><![CDATA[Every week Saturday from Sat., January 30 until Tue., March 2, 2:00pm - Sam Shepard's powerful 1985 drama <i>A Lie of the Mind</i> has never had a New York revival&mdash;perhaps because it would be nearly impossible to perfect the four-hour original, which won a Drama Desk Award and received rave reviews for its cast&mdash;Harvey Keitel, Aidan Quinn, and Amanda Plummer....]]></description>\n      <guid>http://www.villagevoice.com/events/a-lie-of-the-mind-1617955/</guid>\n    </item>\n    <item>\n      <title><![CDATA[Straight Up Vampire: The History of Vampires in Colonial Pennsylvania as Performed to the Music of Paula Abdul+Outr&eacute; Island]]></title>\n      <link>http://www.villagevoice.com/events/straight-up-vampire-the-history-of-vampires-in-colonial-pennsylvania-as-performed-to-the-music-of-paula-abdul-outrandeacute-island-1641238/</link>\n      <description><![CDATA[Thu., February 11, 7:00pm - Ever wonder what life after a wildly successful pirate-puppet-rock-opera holds in store? The creators of the cult show <i>Jollyship the Whiz-Bang</i> are making the most of it. Tonight, <i>Jollyship</i>'s playwright-actor Nick Jones, and director Sam Gold and composer Raja Azar have equally whimsica...]]></description>\n      <guid>http://www.villagevoice.com/events/straight-up-vampire-the-history-of-vampires-in-colonial-pennsylvania-as-performed-to-the-music-of-paula-abdul-outrandeacute-island-1641238/</guid>\n    </item>\n    <item>\n      <title><![CDATA[Equivocation]]></title>\n      <link>http://www.villagevoice.com/events/equivocation-1628414/</link>\n      <description><![CDATA[Wed., February 24, 2:00pm - Gunpowder, treason, and plot. Well, if that&#146;s not inspiration for a rollicking drama, I don&#146;t know what is. In Bill Cain&#146;s new work, King James prompts William Shakespeare to write a play about Catholic conspirators&#146; attempt to blow up Parliament. Dramatic fireworks ensue....]]></description>\n      <guid>http://www.villagevoice.com/events/equivocation-1628414/</guid>\n    </item>\n    <item>\n      <title><![CDATA[Race]]></title>\n      <link>http://www.villagevoice.com/events/race-1479096/</link>\n      <description><![CDATA[Every week Wednesday, Saturday, 2:00pm - David Mamet and his cast have kept remarkably tight-lipped about the content of this new drama. (In a recent <i>Vogue</i> interview, costar Kerry Washington avoided the subject, fearing reprisal if she spilled details.) The little we know: the law firm&#150;set show concerns a white man accused of r...]]></description>\n      <guid>http://www.villagevoice.com/events/race-1479096/</guid>\n    </item>\n    <item>\n      <title><![CDATA[The Tempest]]></title>\n      <link>http://www.villagevoice.com/events/the-tempest-1641233/</link>\n      <description><![CDATA[Daily from Sun., February 14 until Sat., March 13 - The Bridge Project, that plucky band of Brit and American actors led by Sam Mendes, does not abjure the rough magic of Shakespeare&#146;s romance. Stephen Dillane stars as Prospero with the lissome Juliet Rylance as his daughter and Christian Camargo as an airy spirit. This brave new world runs in r...]]></description>\n      <guid>http://www.villagevoice.com/events/the-tempest-1641233/</guid>\n    </item>\n    <item>\n      <title><![CDATA[The Awesome '80s Prom]]></title>\n      <link>http://www.villagevoice.com/events/the-awesome-80s-prom-155028/</link>\n      <description><![CDATA[Every week Saturday, 8:00pm - Though I was born too late to enjoy an '80s prom myself, I may once have actively requested Bon Jovi's \"You Give Love a Bad Name\" at a junior high semiformal. Conversely, this interactive show aims to give nostalgia musicals a good name when it invites audiences to drink, dance, and vote for prom ki...]]></description>\n      <guid>http://www.villagevoice.com/events/the-awesome-80s-prom-155028/</guid>\n    </item>\n    <item>\n      <title><![CDATA[Fela!]]></title>\n      <link>http://www.villagevoice.com/events/fela--1403659/</link>\n      <description><![CDATA[Every week Saturday, 2:00pm - Fela Kuti&#146;s song titles aren&#146;t overly cheerful: &#147;Sorrow Tears & Blood,&#148; &#147;Shuffering and Shmiling,&#148; &#147;Zombie.&#148; But Bill T. Jones and his collaborators have sorted through Kuti&#146;s discography, crafting an exuberant celebration of his life and style. The Broad...]]></description>\n      <guid>http://www.villagevoice.com/events/fela--1403659/</guid>\n    </item>\n    <item>\n      <title><![CDATA[A Behanding in Spokane]]></title>\n      <link>http://www.villagevoice.com/events/a-behanding-in-spokane-1641235/</link>\n      <description><![CDATA[Every week Wednesday, Saturday from Wed., February 17 until Sun., June 6, 2:00pm - Seriously, this play had us at Christopher Walken. Add to it that <b>A Behanding in Spokane</b> follows Walken on a quest to find his missing left hand, and, well, what else do you need to know? Written by Martin McDonagh, who basically gets nominated for a Tony every time he writes a play these day...]]></description>\n      <guid>http://www.villagevoice.com/events/a-behanding-in-spokane-1641235/</guid>\n    </item>\n    <item>\n      <title><![CDATA[Daddy]]></title>\n      <link>http://www.villagevoice.com/events/daddy-1617925/</link>\n      <description><![CDATA[Every week Monday, Wednesday, Thursday, Friday, Saturday, Sunday from Thu., January 28 until Sat., February 13, 8:00pm - Don't mess with Gerald McCullouch. Playing ballistics expert Bobby Dawson on <i>CSI: Crime Scene Investigation</i> for the past decade, he might know a thing or two about putting up a fight. (Fun fact: McCullouch successfully boxed a laptop thief on the subway who threatened him with a kitchen knife...]]></description>\n      <guid>http://www.villagevoice.com/events/daddy-1617925/</guid>\n    </item>\n    <item>\n      <title><![CDATA[Trifles]]></title>\n      <link>http://www.villagevoice.com/events/trifles-1617952/</link>\n      <description><![CDATA[Every week Thursday, Friday, Saturday, Sunday from Thu., January 28 until Sun., February 14, 8:00pm - In 1899, Susan Glaspell, who would later cofound the Provincetown Players, worked for a Des Moines newspaper. She filed a score of stories about a farmer's wife who was accused of murdering her husband while he slept. In 1916, she distilled that reportage into <i>Trifles</i>, a one-act play in which...]]></description>\n      <guid>http://www.villagevoice.com/events/trifles-1617952/</guid>\n    </item>\n    <item>\n      <title><![CDATA[Lear]]></title>\n      <link>http://www.villagevoice.com/events/lear-1570830/</link>\n      <description><![CDATA[Every week Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday from Thu., January 7 until Sun., February 14, 7:30pm - The prolific playwright Young Jean Lee has accomplished quite a bit since her play, <i>The Appeal</i>, premiered at Soho Rep in 2004, but one thing she hasn&#146;t done is finish her dissertation. Lee was working toward a Ph.D. in English at UC Berkeley when she left her thesis&mdash;on Shakespeare&...]]></description>\n      <guid>http://www.villagevoice.com/events/lear-1570830/</guid>\n    </item>\n    <item>\n      <title><![CDATA[The Jackie Look]]></title>\n      <link>http://www.villagevoice.com/events/the-jackie-look-1618058/</link>\n      <description><![CDATA[Every week Saturday from Sat., January 30 until Sat., March 6, 7:30pm - Eleanor will always be remembered for her humanitarianism, Hillary for her political ambitions, and Laura for marrying a yutz. But it is perhaps Jacqueline Kennedy Onassis who takes up the most space in our collective First Lady memory bank for her impeccable sense of fashion. Performance artist Kar...]]></description>\n      <guid>http://www.villagevoice.com/events/the-jackie-look-1618058/</guid>\n    </item>\n    <item>\n      <title><![CDATA[As You Like It]]></title>\n      <link>http://www.villagevoice.com/events/as-you-like-it-1574550/</link>\n      <description><![CDATA[Daily from Tue., January 12 until Sat., March 13 - To American audiences, Sam Mendes is perhaps best known as the Oscar-winning director of <i>American Beauty</i> and the doting husband of actress Kate Winslet. But across the pond, the 44-year-old Brit is also known for his work at the Royal Shakespeare Company, where he started as a fearless young ...]]></description>\n      <guid>http://www.villagevoice.com/events/as-you-like-it-1574550/</guid>\n    </item>\n    <item>\n      <title><![CDATA[A Little Night Music]]></title>\n      <link>http://www.villagevoice.com/events/a-little-night-music-1492389/</link>\n      <description><![CDATA[Every week Tuesday, Wednesday, Thursday, Friday, Saturday, 8:00pm - Angela Lansbury has got to be the most prolific (if not the only) 84-year-old on the Broadway scene. She delighted us with her kooky-psychic dance in <i>Blithe Spirit</i> earlier this year, but kookiness takes a backseat in the new revival of Sondheim's <b>A Little Night Music</b>, a lovely tale of ...]]></description>\n      <guid>http://www.villagevoice.com/events/a-little-night-music-1492389/</guid>\n    </item>\n    <item>\n      <title><![CDATA[God of Carnage]]></title>\n      <link>http://www.villagevoice.com/events/god-of-carnage-902837/</link>\n      <description><![CDATA[Every week Wednesday, Saturday, 2:00pm - James Gandolfini has not ordered a hit on Yasmina Reza&#146;s new play, but he would very much like one. The play concerns two bourgeois couples deciding what to do about their sons. Gandolfini makes his post-Sopranos stage debut as one of the Dads. Hope Davis, Jeff Daniels, and Marcia Gay Harden ro...]]></description>\n      <guid>http://www.villagevoice.com/events/god-of-carnage-902837/</guid>\n    </item>\n    <item>\n      <title><![CDATA[Next to Normal]]></title>\n      <link>http://www.villagevoice.com/events/next-to-normal-964693/</link>\n      <description><![CDATA[Every week Tuesday, 7:00pm - Broadway is enjoying a period of irrational exuberance, responding to the recession with numerous openings. So it seems quite normal that Second Stage would choose to transfer this musical about manic depression, despite the somewhat bipolar reviews it received. Alice Ripley reprises her role as an ...]]></description>\n      <guid>http://www.villagevoice.com/events/next-to-normal-964693/</guid>\n    </item>\n    <item>\n      <title><![CDATA[A View from the Bridge]]></title>\n      <link>http://www.villagevoice.com/events/a-view-from-the-bridge-1542384/</link>\n      <description><![CDATA[Every week Wednesday, Saturday from Wed., December 30 until Sun., April 4, 2:00pm - Arthur Miller&#146;s dark 1955 drama A View From the Bridge transports you to the rundown Red Hook tenement of Eddie Carbone, a longshoreman who displays more than an avuncular fondness for his 17-year-old orphan niece, Catherine, when she falls in love with a handsome immigrant newcomer. Though we ...]]></description>\n      <guid>http://www.villagevoice.com/events/a-view-from-the-bridge-1542384/</guid>\n    </item>\n    <item>\n      <title><![CDATA[Hair: The American Tribal Love-Rock Musical]]></title>\n      <link>http://www.villagevoice.com/events/hair-the-american-tribal-love-rock-musical-916568/</link>\n      <description><![CDATA[Every week Wednesday, Saturday, 2:00pm - &#147;I got life, mother/I got laughs, sister/I got freedom, brother/I got good times, man,&#148; declares this 1968 musical. Last summer&#146;s revival of <i>Hair</i>, directed by Diane Paulus had all that and more, yet until recently it didn&#146;t have sufficient funds for a Broadway transfer. Bu...]]></description>\n      <guid>http://www.villagevoice.com/events/hair-the-american-tribal-love-rock-musical-916568/</guid>\n    </item>\n    <item>\n      <title><![CDATA[First Time, Long Time]]></title>\n      <link>http://www.villagevoice.com/events/first-time-long-time-1603594/</link>\n      <description><![CDATA[Every week Wednesday from Wed., January 20 until Wed., February 10, 8:00pm]]></description>\n      <guid>http://www.villagevoice.com/events/first-time-long-time-1603594/</guid>\n    </item>\n    <item>\n      <title><![CDATA[Red Noir]]></title>\n      <link>http://www.villagevoice.com/events/red-noir-1503950/</link>\n      <description><![CDATA[Mon., December 7, 8:00pm]]></description>\n      <guid>http://www.villagevoice.com/events/red-noir-1503950/</guid>\n    </item>\n    <item>\n      <title><![CDATA[Tea with Chachaji]]></title>\n      <link>http://www.villagevoice.com/events/tea-with-chachaji-1603636/</link>\n      <description><![CDATA[Daily from Mon., January 25 until Thu., February 11]]></description>\n      <guid>http://www.villagevoice.com/events/tea-with-chachaji-1603636/</guid>\n    </item>\n  </channel>\n</rss>\n", message:undefined, modified:(new Date(1265730541962)), baseUri:"http://p3k.org/rss/", query:"frameColor=black&textColor=black&_=1257875281857&titleBarColor=lightblue&compact=&fontFace=&align=left&showXmlButton=true&maxItems=7&boxFillColor=white&titleBarTextColor=black&width=200&url=http://www.villagevoice.com/syndication/events?session_name=l2e9lonlu2o3ph7sbgc71sv8k3&page=1&category=155016&", param:{textColor:"black", width:"200", align:"left", fontFace:"", url:"http://www.villagevoice.com/syndication/events?session_name=l2e9lonlu2o3ph7sbgc71sv8k3&page=1&category=155016", compact:"", frameColor:"black", showXmlButton:"true", boxFillColor:"white", _:"1257875281857", titleBarColor:"lightblue", maxItems:"7", titleBarTextColor:"black"}, box:"<table class=\"rssBox\" width=\"${width}\" bgcolor=\"${frameColor}\" \n      style=\"table-layout: fixed; overflow: hidden; font-family: ${fontFace};\" \n      align=\"${align}\" cellspacing=\"1\" cellpadding=\"7\" border=\"0\">\n<tr bgcolor=\"${titleBarColor}\">\n<td>\n   ${xmlButton}\n   <strong>${title}</strong>\n   <div>\n      <small style=\"color: ${titleBarTextColor};\">${date}</small>\n   </div>\n</td>\n</tr>\n<tr bgcolor=\"${boxFillColor}\">\n<td class=\"rssBoxContent\" style=\"color: ${textColor};\">\n   ${image}\n   ${items}\n   ${input}\n   <div class=\"rssBoxPromo\" style=\"margin-top: 0px; text-align: left; \n         font: 9px verdana, sans-serif\">\n      RSS box by <a href=\"http://p3k.org/rss\">p3k.org</a>.\n   </div>\n</td>\n</tr>\n</table>\n\n", image:"<a href=\"${link}\"><img src=\"${source}\" width=\"${width}\" height=\"${height}\" \nalt=\"${title}\" title=\"${title}\" align=\"${align}\" valign=\"${valign}\" \nhspace=\"${hspace}\" vspace=\"${vspace}\" border=\"0\" /></a>\n\n", input:"<form method=\"get\" action=\"${link}\">\n${description}\n<input type=\"text\" name=\"${name}\" size=\"15\" /> <input type=\"submit\" \nvalue=\"${title}\" />\n</form>\n\n", item:"<div class=\"rssBoxItemContent\">\n${title}\n${break}\n${description}\n${buttons}\n</div><br />\n\n", date:"${year}-${month}-${day}, ${hours}:${minutes}h\n\n", link:"<a class=\"${class}\" href=\"${link}\" style=\"${style}\">${text}</a>\n", error:"<?xml version=\"1.0\"?>\n<rss version=\"error\">\n   <channel>\n      <title>RSS Box Error</title>\n      <link>${link}</link>\n      <description>This output was automatically generated to report an error \n      that occurred during a request to the JavaScript RSS Box Viewer.</description>\n      <item>\n         <title>Oops, something went wrong...</title>\n         <description>An error occurred while processing the request to the \n         JavaScript RSS Box Viewer.</description>\n      </item>\n      <item>\n         <title>An error message was returned by the server.</title>\n         <description>${message}</description>\n      </item>\n      <item>\n         <description>Most likely, this might have happened because of a \n         non-existent or invalid RSS feed URL. Please check and possibly correct \n         your input, then try again.</description>\n      </item>\n   </channel>\n</rss>\n\n"})};
function debug(str) {
   return document.write('<p><span style="background-color: yellow;">', 
         str, '</span><p>');
}

org.p3k.RssBox = function() {
   var ref;
   var ISOPATTERN = /([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9:]+).*$/;
   
   var data = org.p3k;
   data.defaults = {
      url: "http://blog.p3k.org/rss",
      maxItems: 7,
      width: 200,
      align: "",
      frameColor: "black",
      titleBarColor: "lightblue",
      titleBarTextColor: "black",
      boxFillColor: "white",
      textColor: "black",
      showXmlButton: "",
      compact: ""
   };
   
   var baseUri = data.baseUri;
    
   var getColor = function(str) {
      if (str.length === 6 && parseInt(str, 16) && str.indexOf("#") !== 0) {
         str = "#" + str;
      }
      return str.toLowerCase();
   }

   var value;
   for (var i in data.defaults) {
      value = data.param[i];
      if (!value || value.length === 0) {
         data.param[i] = data.defaults[i];
      } else if (i.indexOf("Color") > 0) {
         data.param[i] = getColor(value);
      }
   }

   // FIXME: Ugly work-around for many boxes using too small width 
   // values because the former version did not show the exact output.
   if (data.param.javascript && data.param.width < 200) {
      data.param.width = 200;
   }
   // Remove obsolete parameters from param and query
   delete data.param.javascript;
   data.query = data.query.replace("javascript=true", "");   

   var NAMESPACES = {
      dc: "http://purl.org/dc/elements/1.1/",
      rdf: "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   };

   var getUrl = function(url) {
      url = baseUri + "proxy.r?" + encodeURIComponent(url);
   
      var HttpRequest = function() {
         return (typeof XMLHttpRequest !== "undefined") ?
            new XMLHttpRequest() : new ActiveXObject("Msxml2.XMLHTTP");
      }
   
      var request = new HttpRequest();
      request.open("GET", url, false);
      request.send(null);   
      if (!request.getResponseHeader("Date")) {
         var cached = request;
         var ifModifiedSince = cached.getResponseHeader("Last-Modified") || 
               new Date(0); // January 1, 1970
         request = new HttpRequest();
         request.open("GET", url, false);
         request.setRequestHeader("If-Modified-Since", ifModifiedSince);
         request.send("");
         if (request.status === 304) {
            request = cached; 
         }
      }
      return request;
   }
   
   var getDocument = function(source) {
      if (source) {
         if (document.implementation.createDocument) {
            var parser = new DOMParser();
            var doc = parser.parseFromString(source, "text/xml");
            return doc;
         } else if (window.ActiveXObject) {
            var doc = new ActiveXObject("Microsoft.XMLDOM");
            doc.async = "false";
            doc.loadXML(source);
            return doc;
         }
      }
      return null;
   }
   
   var getError = function() {
      var msg = null, root;
      if (!xml || data.message) {
         msg = data.message || "Unknown error.";
      } else if (xml.parseError && xml.parseError.errorCode) {
         msg = xml.parseError.reason; // IExplore
      } else if (root = xml.documentElement) {
         var errorNode;
         if (root.nodeName === "parsererror") {
            msg = xml.documentElement.textContent; // Mozilla
         } else if ((errorNode = root.childNodes[0]) && 
               errorNode.nodeName === "parsererror") {
            msg = errorNode.textContent; // Safari
         } else if (!/rss|rdf|scriptingNews/i.test(xml.documentElement.nodeName)) {
            msg = "Incompatible data format. Are you sure this is an RSS feed?";
         }
      }
      return msg;
   }
   
   var getNode = function(parent, name, namespace) {
      if (namespace) {
         if (typeof parent.getElementsByTagNameNS === "undefined") {
            var elements = parent.getElementsByTagName(namespace + ":" + name);
         } else {
            var elements = parent.getElementsByTagNameNS(NAMESPACES[namespace], name);
         }
      } else {
         var elements = parent.getElementsByTagName(name);
      }
      if (elements && elements[0]) {
         return elements[0];
      }
      return null;
   }
   
   var getText = function(node) {
      if (node && node.childNodes && node.childNodes.length > 0) {
         return node.childNodes[0].nodeValue || "";
      }
      return "";
   }
   
   var trim = function(str) {
      if (str) {
         return str.replace(/^\s*(\S*)\s*$/, "$1");
      }
      return "";
   }
   
   var padZero = function(n) {
      if (n < 10) {
         return "0" + n
      }
      return n;
   }

   var encodeXml = function(str) {
      if (!str) {
         return "";
      }
      return str.replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/&/g, "&amp;");
   }
      
   var render = function(template, param) {
      if (!template || !param) {
         return template;
      }
      template = template.replace(/\$\{([^}]+)\}/g, function() {
         var key = arguments[1];
         return param[key] || "";
      });
      return template;
   }
   
   var renderDate = function(date) {
      if (date.constructor !== Date) {
         var str = String(date);
         var millis = Date.parse(str.replace(ISOPATTERN, "$1/$2/$3 $4"));
         if (millis) {
            date = new Date(millis);
         } else {
            date = new Date;
         }
      }

      return render(data.date, {
         year: date.getFullYear(),
         month: padZero(date.getMonth() + 1),
         day: padZero(date.getDate()),
         hours: padZero(date.getHours()),
         minutes: padZero(date.getMinutes()),
         seconds: padZero(date.getSeconds()),
         timeZone: "" // date.getTimezoneOffset()
      });
   }
   
   var renderButtons = function(enclosure, source) {
      var result = "";
      if (enclosure && enclosure.link) {
         result += render(data.image, {
            source: baseUri + "enclosure.gif",
            title: enclosure.type,
            link: encodeURI(enclosure.link),
            width: 13,
            height: 16
         });
      }
      if (source && source.link) {
         result += render(data.image, {
            source: baseUri + "source.gif",
            title: source.title,
            link: encodeURI(source.link),
            width: 15,
            height: 15
         });
      }
      return result;         
   }
   
   var param = data.param;
   var rss = data.rss = {items: []};
   var xml = getDocument(data.xml);

   rss.error = getError();
   if (rss.error !== null) {
      xml = getDocument(render(data.error, {
         link: baseUri + "?" + encodeXml(data.query),
         message: encodeXml(rss.error)
      }));
      param.compact = 0;
      param.showXmlButton = 1;
   }

   var root = xml.documentElement;
   var type = root.nodeName;

   if (type === "scriptingNews") {
      var channel = getNode(xml, "header");
      rss.format = "Scripting News";
      rss.version = getText(getNode(channel, "scriptingNewsVersion"));
      rss.title = getText(getNode(channel, "channelTitle"));
      rss.description = getText(getNode(channel, "channelDescription"));
      rss.link = getText(getNode(channel, "channelLink"));
      if (ref = getText(getNode(channel, "imageUrl"))) {
         ref = rss.image = {source: ref};
         ref.title = getText(getNode(channel, "imageTitle"));
         ref.link = getText(getNode(channel, "imageLink"));
         ref.width = getText(getNode(channel, "imageWidth"));
         ref.height = getText(getNode(channel, "imageHeight"));
         ref.description = getText(getNode(channel, "imageCaption"));
      }
   } else {
      var channel = getNode(xml, "channel");
      rss.format = "RSS";
      rss.version = (type === "rdf:RDF") ? "1.0" : 
            root.getAttribute("version");
      rss.title = getText(getNode(channel, "title"));
      rss.description = getText(getNode(channel, "description"));
      rss.link = getText(getNode(channel, "link"));
      var image = getNode(xml, "image");
      if (image) {
         ref = rss.image = {};
         ref.source = getText(getNode(image, "url"));
         ref.title = getText(getNode(image, "title"));
         ref.link = getText(getNode(image, "link"));
         ref.width = getText(getNode(image, "width"));
         ref.height = getText(getNode(image, "height"));
         ref.description = getText(getNode(image, "description"));
      }
   }
   
   if (type === "rdf:RDF") {
      rss.date = renderDate(getText(getNode(channel, "date", "dc")) || data.modified);
      rss.rights = getText(getNode(channel, "creator", "dc"));
      var input = getNode(root, "textinput");
      if (input && !getNode(input, "link")) {
         input = root.getElementsByTagName("textinput")[1];
      }
      if (input) {
         ref = rss.input = {};
         ref.link = getText(getNode(input, "link"));
         ref.description = getText(getNode(input, "description"));
         ref.name = getText(getNode(input, "name"));
         ref.title = getText(getNode(input, "title"));
      }
   } else {
      rss.date = renderDate(getText(getNode(channel, "lastBuildDate") || getText(getNode(channel, "pubDate"))) || data.modified);
      rss.rights = getText(getNode(channel, "copyright"));
   }
   
   var item, text, node;
   var items = xml.getElementsByTagName("item");

   for (var i=0; i<Math.min(items.length, param.maxItems); i+=1) {
      item = items[i];

      if (type === "scriptingNews") {
         ref = {title: ""};
         ref.description = getText(getNode(item, "text")).replace(/\n/g, " ");
         ref.link = getText(getNode(item, "link"));
         if (text = trim(getText(getNode(item, "linetext")).replace(/\n/g, " "))) {
            ref.description = ref.description.replace(new RegExp(text), 
                  '<a href="' + getText(getNode(item, "url")) + '">' + text + '</a>');
         }
      } else {
         ref = {
            title: getText(getNode(item, "title")),
            description: getText(getNode(item, "description")),
            link: getText(getNode(item, "link") || getNode(item, "guid"))
         };
     }

     if (node = getNode(item, "source")) {
        ref.source = {
           link: node.getAttribute("url"),
           title: getText(node)
        }
     }
     
     if (node = getNode(item, "enclosure")) {
        ref.enclosure = {
           link: node.getAttribute("url"),
           length: node.getAttribute("length"),
           type: node.getAttribute("type")
        }
     }
     
     if (node = getNode(item, "category")) {
        ref.category = {
           domain: node.getAttribute("domain") || "",
           content: getText(node)
        }
     }
     
     rss.items.push(ref);
   }
   
   var item, items = "";
   for (var i=0; i<rss.items.length; i+=1) {
      item = rss.items[i];
      items += render(data.item, {
         title: new function() {
            var title = (!param.compact ? "<strong>" : "");
            if (item.link) {
               title += render(data.link, {
                  link: encodeURI(item.link),
                  text: item.title,
                  'class': "rssBoxItemTitle"
               });
            } else {
               title += item.title;
            }
            !param.compact && (title += "</strong>");
            return new String(title); // FIXME: Funny, title alone will be rendered as [object]
         }(),
         'break': item.title && item.description ? "<br />" : "",
         description: (!param.compact || !item.title) && item.description,
         buttons: renderButtons(item.enclosure, item.source)
      });
   }
   
   var box = render(data.box, {
      title: rss.link ? render(data.link, {
         link: encodeURI(rss.link),
         text: rss.title,
         'class': "rssBoxTitle",
         style: "color: " + param.titleBarTextColor
      }) : rss.title,
      description: rss.description,
      items: items,

      xmlButton: param.showXmlButton && render(data.image, {
         link: param.url,
         source: baseUri + "rss.png",
         title: rss.format + " " + rss.version,
         width: 16,
         height: 16,
         align: "right",
         hspace: 3
      }),
      
      image: !param.compact && rss.image && render(data.image, {
         link: encodeURI(rss.image.link),
         source: rss.image.source,
         width: rss.image.width,
         height: rss.image.height,
         title: rss.image.title,
         align: "right",
         valign: "baseline",
         hspace: 5,
         vspace: 5
      }),
      
      input: !param.compact && rss.input && render(data.input, {
         link: encodeURI(rss.input.link),
         description: rss.input.description,
         name: rss.input.name,
         title: rss.input.title
      }),
      
      date: rss.date,
      width: param.width,
      frameColor: param.frameColor,
      fontFace: param.fontFace,
      align: param.align,
      titleBarColor: param.titleBarColor,
      titleBarTextColor: param.titleBarTextColor,
      boxFillColor: param.boxFillColor,
      textColor: param.textColor
   });

   if (!window.rssBoxSetup) {
      document.write(box);
   }
   
   return box;
};

org.p3k.RssBox();

