Archive for the ‘Technology’ category

Introducing the JQuery Facebook Multi-Friend Selector Plugin

August 10th, 2010

I created a new jQuery plugging that works with the new Facebook javascript SDK to present a users list of friends and allows them to select the friends they would like to do X with. That “X” is up to you; once the user has selected their friends, you call a function on the plugin that returns an array of the friends Facebook Ids. A few key points:

  • client-side, no server-side PHP blah blah blah dependencies like some of the other alternative friends selectors
  • depends on jQuery and the new Facebook Javascript API
  • only requires several lines of code to drop-in
  • Apache 2.0 license
  • Hosted at GitHib: source and demo

Quick disclaimer- as of this post, I haven’t done any testing on Windows or IE, just the latest of Chrome, Safari and Firefox on Mac. There are other features I want to include and probably a bug or two to work through, but for the most part it’s functional.

  • display all of a logged in users friends and lets you select zero to all of them
  • filter by those already selected
  • fast filter textbox that filters list quickly as you type
  • shift-select to select multiple friends at a time

To use the plugin, you need to include jQuery, the plugin javascript file, the plugin CSS (which you can change) and the Facebook javascript library

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script src="jquery.facebook.multifriend.select.js"></script>
<link rel="stylesheet" href="jquery.facebook.multifriend.select.css" />
<script src="http://connect.facebook.net/en_US/all.js"></script>

You also need to initialized your app by calling FB.init with your appId and have logged the user in, then you can load the friend selector into a container:

$("#jfmfs-container").jfmfs();

This loads the friend selector into the jfmfs-container (can be whatever you want it to be). It calls the Facebook Graph API to fetch the list of friends of the logged in user and loads them into the scrollable region. Then after the user has selected their friends, you can call getSelectedIds() on the plugin to get an array of friends Ids that were selected.

var friendSelector = $("#jfmfs-container").data('jfmfs');
var friendIds = friendSelector.getSelectedIds();

A handle to the object is stored as data of the element, so you need to call data(‘jfmfs’) on the element you loaded the selector to get a handle to the plugin object to call getSelectedIds().

Here’s a screencast demo. Let me know what you think!

JQuery Facebook Multi-Friend Selector Plugin Demo from mbrevoort on Vimeo.

Grails vs Play Application Footprint

August 5th, 2010

Today I kicked the wheels on the Play Framework a bit. Coming from several solid years of Grails experience (and a decade of Java), in many ways it felt similar. I won’t go into a comparison or my thoughts on Play in this post, but I will share a very unscientific, rough footprint comparison. So there’s your disclaimer. I’m not setting out to make any profound claims, just want to share a rough observation.

The loudest issue I’ve heard from clients with respect to Grails is that the application footprint is just too large, especially for those who run many small applications side by side. So I’m searching for a framework that:

  1. java based that can be deployed to a Weblogic/Oracle stack (no choice there)
  2. provides the same development productivity boost as Grails/Rails
  3. is stable, reliable and generally fun to work with

I started to look at Roo last night but just wasn’t too excited about developing with it. Though there seemed to be a lot of gained efficiencies including a lot of  code generation of boilerplate code and scripted, maven-backed magic, I just felt “blah” as I went through one of the tutorials.  Play on the other hand seems very innovative, a breath of fresh air and I was excited to give it a try.

The Sloppy Science

I built the same basic application on Grails 1.3 and Play 1.0. It’s very similar to the application in the screencast on playframework.org – a simple task list app with

  • one model/domain
  • one controller with 3 actions
  • one view with jQuery/JSON between the two AJAX actions

It lists all of the existing tasks, let’s you create new ones and lets you check them off, that’s it. Both apps use an in memory database.

I built these two apps as WAR files and deployed them to a local Tomcat 6 server. I deployed them separately and then ran through this script:

  1. create 3 tasks
  2. check two of them
  3. refresh to validate the “checks” were successful
  4. stop Tomcat, undeploy

Also deployed on the server was Lambda Prode which is where the screenshot below was generated.

The Results

WAR file size: the Grails WAR was actually smaller than the Play WAR. Grails 22.1Mb and Play 24Mb

As you can see below, the baseline memory footprint of the Grails app was significantly greater than the Play app.  To some extent I think this is a non issue for typical, medium to large applications. But in the case where you have many small apps sharing the same resources, the additional overhead adds up.

MarkLogic Demos

August 3rd, 2010


Over the last three or four months I’ve taken a deep dive into MarkLogic, ramping up faster and then working on several interesting projects. Along the way I built a demo for the 2010 MarkLogic Users Conference Demojam (totally last minute over the course of several days), and I won! It’s was a real time twitter search and workflow system with geospatial capabilities. Afterwards, I recorded this screencast overview of what I built.



I also found a demo I recorded after my 1st week of tinkering with MarkLogic. This is a simple demonstration of the read/write capabilities and benefits of XML being both ordered and hierarchical. The demo uses jQuery to wire together some ajax calls to reorder lists of items.

I feel like I’m cleaning out the closet…

Gluing Confluence Activity to Socialcast with Google App Engine / Gaelyk

August 2nd, 2010

I’ve been experimenting with ways to tie the activity of some of the systems we use together. In this case I would like activity information from Confluence to be streamed into Socialcast. There are several ways to go about this but none are perfect or “out of the box”.

Before I go on, here’s what this looks like in Socialcast with the verb and actor mentioned and object name and link:

A Little Background

You could configure a stream import in Socialcast with an RSS feed from Confluence though there are two problems with this. First, Confluence requires authentication and doesn’t support any token type convention so you have to hardcode the username and password of an account that has access to the activity you’re interested in in Confluence. Second, Socialcast appears to truncate long URLs for RSS feeds (consider this a reported bug ;) ). So the only way I got this to work was to use a URL shortener like bit.ly but a Confluence username and password was hardcoded at bit.ly and the bit.ly URL was used in the RSS feed import. And finally what was imported wasn’t linkable back to Confluence. So there were many stumbling blocks in this, though the simplest approach.

Second I created a confluence-bot user account in both Confluence and Socialcast (with the account in Socialcast having the email address that Confluence would send from) and set this account as a watcher to all of the spaces I wanted activity information to be published. Then I created a group in Socialcast where activity would be published. The email address of the confluence-bot account was set to the email address of the Socialcast group. So when Confluence sent the watch emails out for confluence-bot, they would be sent to the Socialcast group. For some reason this just didn’t work; the emails were never arriving. I suspect Socialcast was filtering the emails as spam, as they contained a ‘Precedence: bulk’ header. It was worth a try but much too kludgy without any control so not worth pursuing in my opinion.

Ideally I wish Confluence had more dynamic notification options. More specifically I wish I could register a webhook in confluence that would let me process watch events or notifications. Even cooler would be to let each user configure a webhook URL. This would decouple the notification from the event and eliminate the need to write a Confluence plugin to handle something like this. For example, if I wanted to get Growl notifications on my desktop for Confluence activity, I could configure a webhook to post to Jeff Lindsay’s Noftify.io service (awesome by the way!).

Anyway, in lieu of that, I decided to hack together watcher emails from Confluence to Socialcast using Gaelyk on Google App Engine and the Socialcast API.

Confluence -> GAE -> Socialcast

Using Gaelyk and Google App Engine as the Glue

Confluence can send out email notifications based on watched content, and Google App Engine applications can act as an SMTP endpoint so since I’m a Groovy fan and been looking for an excuse to kick the tires on Gaelyk, I created a very simple Gaelyk application with an email handler that parsed incoming messages from Confluence and called the RESTful Socialcast API to create new messages. Unfortunately the HTML email Confluence produces isn’t valid xhtml, with unclosed tags and such, so I can’t just parse the XML and pull out the bits I need. I used some quick and dirty regular expressions to grab what I needed, making assumptions that the format of the emails wouldn’t change. I suppose I could fix the Confluence email templates, but I’m trying not to touch Confluence programmatically in this case. He’s a stripped down version of the email handler (<my_project>/war/WEB-INF/groovy/email.groovy):

// have access to message object of javax.mail.internet.MimeMessage
import groovyx.gaelyk.logging.GroovyLogger
import java.io.BufferedReader;
import java.io.OutputStreamWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Authenticator;
import java.net.PasswordAuthentication;
import java.net.URL;
import java.net.HttpURLConnection;

def log = new GroovyLogger("emailLogger")

// the email notification message from confluence is a bit messy, try to pull out the important bits from it
def theLink = ""
def m1 = message.content =~ /<\/?(?i:a)(.|\n)*?>/
if(m1?.size() > 0) {
    def firstAnchor = m1[0][0]
    def m2 = firstAnchor =~  /href="(.)*"/
    if(m2?.size() > 0) {
        theLink = m2[0][0] - "href=\"" - "\""
    }
}

String content = message.content;
int start = content.indexOf("<h4>") + 4;
int end = content.indexOf("</h4>");
def details = content.substring(start, end).replaceAll(/<\/?(?i:a|b)(.|\n)*?>/, '')

def user = "confluence-bot@mydomain.com";
def pass = "mypassword";
def addr = "https://mydomain.socialcast.com/api/messages.xml"

def authString = "${user}:${pass}".getBytes().encodeBase64().toString()
def conn = addr.toURL().openConnection()
conn.setRequestProperty("Authorization", "Basic ${authString}")
conn.setRequestMethod("POST")
conn.doOutput = true

def queryString = "message[title]=${URLEncoder.encode(message.subject)}&" + "message[body]=${URLEncoder.encode(details)}" + "&message[url]=${URLEncoder.encode(theLink)}" + "&message[group_id]=6845";

def writer = new OutputStreamWriter(conn.outputStream)
writer.write(queryString)
writer.flush()
writer.close()
conn.connect()

def res = conn.content.text
log.info(res)

There’s some configuration required to turn on the inbound email service and map the incoming email to the proper Groovlet.

Add this to your appengine-web.xml:

<inbound-services>
    <service>mail</service>
</inbound-services>

In your web.xml file, add the new servlet mapping and security constraint:

...
<servlet>
    <servlet-name>EmailServlet</servlet-name>
    <servlet-class>groovyx.gaelyk.GaelykIncomingEmailServlet</servlet-class>
</servlet>
...
<servlet-mapping>
    <servlet-name>EmailServlet</servlet-name>
    <url-pattern>/_ah/mail/*</url-pattern>
</servlet-mapping>
...
<!-- Only allow the SDK and administrators to have access to the incoming email endpoint -->
<security-constraint>
    <web-resource-collection>
        <url-pattern>/_ah/mail/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>admin</role-name>
    </auth-constraint>
</security-constraint>
...

There are obvious improvements that can be made to this approach and much better ways to go about this, along with a lot of considerations that I ignored (e.g. security/permissions) but for a few hours of hacking this is hard to beat!

Partly Cloudy with a Chance of Hype

April 30th, 2010

Last night I gave a presentation at the Colorado Springs Open Source Users Group on the topic of cloud computing called “Partly Cloudy with a Chance of Hype.”  If you were there, I’d love to here your feedback! The slides are posted to Slideshare.

Actionable Activity Streams

April 21st, 2010

Since writing my last article for TheNextWeb on Socialcast and my conversation with Tim Young, I’ve been thinking about the bidirectional, actionable activity stream concept. It’s less relevant to human constructed messages and more related to machine generated activity messages, specifically exceptions raised from the system. When a source system generates an exception based message that’s put into an activity stream, then generally they require some action or acknowledgement . This is where things can get interesting.

For example, let’s say there is an expense management system for managing employee expense reports and payments. Employee Joe submits an expense report with $750 in miscellaneous “entertainment” expenses which raises an exception. The expense management system is integrated with an activity stream engine; it posts a new message into a stream alerting Jim of the exception (this is where permissions, users, groups, identity, etc get tricky – ignoring that here).

So that’s well and good, Jim is alerted to the exception but now what? Wouldn’t it be great if Jim could act on the message in context?

For example, he could discuss the exception with Joe in context of message in the activity steam. “@joe I need more details on the $750 entertainment charge, and it better be good!” Joe replies, “whoops! sorry that should have been $75, please reject and I will fix.” Jim then rejects the expense report in context of the stream and inherently passes along the stream conversation back to the expense management system as notes to the expense report.

Traditionally, Jim may have received the exception notification via email. He then would have logged into the expense management system, looked at the expense report and either rejected it, notating his question about the entertainment expense or would have emailed Joe asking for details on the expense. Joe then might have replied to Jim or logged into the expense system to add a note and fix the error. This doesn’t sound that bad in this simple scenario, but Jim is very busy and receives hundreds of emails a day and the notification from the system might likely be passed over or Jim just didn’t have time to interrupt what he was doing to go log into the expense management system.

The exception based activity stream use case is more powerful if it allows action to be taken in context. So how might you handle this? Now I’m no activity stream expert, and I’ve had no involvement with any of the standards like activitystrea.ms; I’m just a guy thinking aloud….

What really got me thinking about this use case was a presentation given by Neal Ford at the last social on Implementing Evolutionary Enterprise Architecture. It was primarily based on the Richardson Maturity Model, a model of breaking down REST into three steps that introduces resources, http verbs and hypermedia controls. A hypermedia service enforces a protocol by advertising legitimate interactions with relevant resources at runtime.

In the context of the machine generated activity stream message, the payload of the message would contain a representation of state with respect to the source system activity and links that define possible interactions.

The point of the hypermedia controls is to tell us what we can do next, and the URI of the resource we need to do it. For example, in the example above. The entry might look something like this, with two links – one for approve and the other for reject.

This is a loosely coupled way to provide actions for a given activity. The activity stream system can present the activity message in the stream with the options made available in the payload of the message and selectable actions. This makes no assumption of what type of interface you are viewing the activity stream message through, be it browser, mobile, API rendered, etc. The activity stream system would likely need to abstract the actions in it’s API allowing calls to be made back through the APIs in proxy to the source system.

You could obviously take this concept much further, adding a sequence of actions based on the previous action taken on an activity. For example, if you approve the expense report, the REST call response might return a new list of actions like “view’ the updated expense report.

Like I alluded to above, there are many complexities to this including authentication/identity, authorization, the capabilities of the source system, the capabilities of the activity stream system, etc.

I really have no bandwidth to pursue this idea, but it’s been on my mind for that last few weeks so I thought I’d write it up and see what people think.

Grails Solr Plugin Progress Screencast

March 3rd, 2010

I started work on this plugin back in December based on the work I did for Patheos.com and by the graces of my employer Avalon Consulting LLC and Patheos, they allowed me to open source the plugin and continue working on it. This week I had some time to get back to it, and today I started creating a basic reference implementation application that will accompany the documentation. Below is a screencast demo of this application which indexes an export of songs from my iTunes library metadata and makes them searchable.

The code for the plugin is at Github and is still a work in progress.  I’m pushing towards a 0.1 release next week with the bulk of the work I still need to do in the form of documentation and clean-up.

So please watch the screencast, and I would love feedback.  I will certainly take offers to help continue the development of the plugin but would like to get 0.1 out first to round out my train of thought and not further delay that basic milestone.

Grails Solr Plugin pre-0.1 Demo from mbrevoort on Vimeo.

Issue negotiating SSL connections from Weblogic

February 16th, 2010

This was one of those tough to track down issues that yielded very little in terms of actionable solutions vs. confirmation of similar problems while I Googled the problem symptoms.  I recently upgraded a Grails app from Weblogic 8 to 10.3. The app allowed users to upload videos to Youtube using the Youtube APIs, using ClientLogin for authentication. The problem was after the upgrade the connection to https://www.google.com/accounts/ClientLogin was failing during the SSL negotiation phase.  The errors in the log were

java.lang.IllegalStateException: Cipher not initialized
at javax.crypto.Cipher.c(DashoA13*..)
at javax.crypto.Cipher.update(DashoA13*..)
at com.certicom.tls.provider.Cipher.update(Unknown Source)

and

java.security.InvalidKeyException: Illegal key size

Thankfully I found this thread on a Korean Oracle forum. The solution is to add this JVM parameter:

-Dweblogic.security.SSL.nojce=true

This enables Weblogic to use a FIPS 140-2 compliant crypto module in the server’s SSL implementation.  FIPS 140-2 is a standard that describes U.S. Federal government requirements for sensitive, but unclassified use.

If you have this problem, I hope you stumble upon this post and it helps you.


DOSUG Solr in 5 Minutes Ingnite Presentation

February 4th, 2010

On Tuesday (2/2/2010) I participated in the Denver Open Source User Group’s first Ignite night. My presentation was an quick overview of Solr, the java based open-source search engine. This was my first Ignite style presentation, and the format is challenging! The presentations were each 5 minutes with a 20 slide deck auto advancing every 15 seconds. I stumbled a bit out of the gate with the cold start but was able to get it back on the rails though I felt as if I was trying to dig myself out of quicksand through the rest of it. Overall it was a lot of fun.

The room was packed, somewhere in the neighborhood of 100 people, and overall the quality of the presentations were very good. You can check out the slide decks on Slideshare here. Here are my slides:

And here is a dry-run of my presentation I recorded while practicing the day of:

This is Not Comcastic

October 10th, 2009

I wrote a script that pings the IP of the first node outside of my house into Comcast’s network. It pings every two seconds and logs when the connection is up or down based on the ping success. Last week Comcast came and checked my line and said everything looked great and that it may be the onslaught of the cold weather. I’ve been working through Comcast support via Twitter which has been sporadic but convenient when they respond. Today I couldn’t get a response from them (@comcastmelissa and @comcaststeve) and today sucked:

Fri Oct 09 08:20:12 MDT 2009 DOWN!
Fri Oct 09 08:23:41 MDT 2009 UP
Fri Oct 09 09:31:39 MDT 2009 DOWN!
Fri Oct 09 09:31:39 MDT 2009 UP
Fri Oct 09 09:32:15 MDT 2009 DOWN!
Fri Oct 09 09:32:26 MDT 2009 UP
Fri Oct 09 09:33:27 MDT 2009 DOWN!
Fri Oct 09 09:33:27 MDT 2009 UP
Fri Oct 09 09:33:48 MDT 2009 DOWN!
Fri Oct 09 09:33:48 MDT 2009 UP
Fri Oct 09 09:34:14 MDT 2009 DOWN!
Fri Oct 09 09:34:14 MDT 2009 UP
Fri Oct 09 09:34:30 MDT 2009 DOWN!
Fri Oct 09 09:34:30 MDT 2009 UP
Fri Oct 09 09:34:56 MDT 2009 DOWN!
Fri Oct 09 09:34:56 MDT 2009 UP
Fri Oct 09 09:36:13 MDT 2009 DOWN!
Fri Oct 09 09:36:13 MDT 2009 UP
Fri Oct 09 09:37:24 MDT 2009 DOWN!
Fri Oct 09 09:37:46 MDT 2009 UP
Fri Oct 09 09:38:42 MDT 2009 DOWN!
Fri Oct 09 09:38:42 MDT 2009 UP
Fri Oct 09 09:39:28 MDT 2009 DOWN!
Fri Oct 09 09:39:51 MDT 2009 UP
Fri Oct 09 09:41:37 MDT 2009 DOWN!
Fri Oct 09 09:41:37 MDT 2009 UP
Fri Oct 09 09:42:43 MDT 2009 DOWN!
Fri Oct 09 09:42:43 MDT 2009 UP
Fri Oct 09 09:44:50 MDT 2009 DOWN!
Fri Oct 09 09:44:50 MDT 2009 UP
Fri Oct 09 09:45:21 MDT 2009 DOWN!
Fri Oct 09 09:45:21 MDT 2009 UP
Fri Oct 09 09:46:02 MDT 2009 DOWN!
Fri Oct 09 09:46:13 MDT 2009 UP
Fri Oct 09 09:47:25 MDT 2009 DOWN!
Fri Oct 09 09:47:25 MDT 2009 UP
Fri Oct 09 09:47:56 MDT 2009 DOWN!
Fri Oct 09 09:47:56 MDT 2009 UP
Fri Oct 09 09:48:22 MDT 2009 DOWN!
Fri Oct 09 09:48:22 MDT 2009 UP
Fri Oct 09 09:50:08 MDT 2009 DOWN!
Fri Oct 09 09:50:08 MDT 2009 UP
Fri Oct 09 09:51:40 MDT 2009 DOWN!
Fri Oct 09 09:51:40 MDT 2009 UP
Fri Oct 09 09:52:06 MDT 2009 DOWN!
Fri Oct 09 09:52:06 MDT 2009 UP
Fri Oct 09 09:52:37 MDT 2009 DOWN!
Fri Oct 09 09:52:37 MDT 2009 UP
Fri Oct 09 09:53:08 MDT 2009 DOWN!
Fri Oct 09 09:53:08 MDT 2009 UP
Fri Oct 09 09:53:44 MDT 2009 DOWN!
Fri Oct 09 09:53:44 MDT 2009 UP
Fri Oct 09 09:54:25 MDT 2009 DOWN!
Fri Oct 09 09:54:25 MDT 2009 UP
Fri Oct 09 09:54:51 MDT 2009 DOWN!
Fri Oct 09 09:54:51 MDT 2009 UP
Fri Oct 09 09:55:38 MDT 2009 DOWN!
Fri Oct 09 09:55:49 MDT 2009 UP
Fri Oct 09 09:57:00 MDT 2009 DOWN!
Fri Oct 09 09:57:00 MDT 2009 UP
Fri Oct 09 09:57:16 MDT 2009 DOWN!
Fri Oct 09 09:57:16 MDT 2009 UP
Fri Oct 09 09:57:42 MDT 2009 DOWN!
Fri Oct 09 09:57:42 MDT 2009 UP
Fri Oct 09 09:57:58 MDT 2009 DOWN!
Fri Oct 09 09:57:58 MDT 2009 UP
Fri Oct 09 09:58:39 MDT 2009 DOWN!
Fri Oct 09 09:59:12 MDT 2009 UP
Fri Oct 09 09:59:28 MDT 2009 DOWN!
Fri Oct 09 09:59:28 MDT 2009 UP
Fri Oct 09 09:59:55 MDT 2009 DOWN!
Fri Oct 09 10:00:17 MDT 2009 UP
Fri Oct 09 10:00:43 MDT 2009 DOWN!
Fri Oct 09 10:00:43 MDT 2009 UP
Fri Oct 09 10:02:24 MDT 2009 DOWN!
Fri Oct 09 10:02:24 MDT 2009 UP
Fri Oct 09 10:02:45 MDT 2009 DOWN!
Fri Oct 09 10:02:45 MDT 2009 UP
Fri Oct 09 10:03:11 MDT 2009 DOWN!
Fri Oct 09 10:03:11 MDT 2009 UP
Fri Oct 09 10:03:37 MDT 2009 DOWN!
Fri Oct 09 10:03:37 MDT 2009 UP
Fri Oct 09 10:04:14 MDT 2009 DOWN!
Fri Oct 09 10:04:25 MDT 2009 UP
Fri Oct 09 10:04:56 MDT 2009 DOWN!
Fri Oct 09 10:04:56 MDT 2009 UP
Fri Oct 09 10:05:12 MDT 2009 DOWN!
Fri Oct 09 10:05:12 MDT 2009 UP
Fri Oct 09 10:05:33 MDT 2009 DOWN!
Fri Oct 09 10:05:55 MDT 2009 UP
Fri Oct 09 10:06:11 MDT 2009 DOWN!
Fri Oct 09 10:06:11 MDT 2009 UP
Fri Oct 09 10:06:27 MDT 2009 DOWN!
Fri Oct 09 10:06:49 MDT 2009 UP
Fri Oct 09 10:07:05 MDT 2009 DOWN!
Fri Oct 09 10:07:05 MDT 2009 UP
Fri Oct 09 10:07:21 MDT 2009 DOWN!
Fri Oct 09 10:07:32 MDT 2009 UP
Fri Oct 09 10:07:48 MDT 2009 DOWN!
Fri Oct 09 10:07:59 MDT 2009 UP
Fri Oct 09 10:08:15 MDT 2009 DOWN!
Fri Oct 09 10:08:37 MDT 2009 UP
Fri Oct 09 10:08:53 MDT 2009 DOWN!
Fri Oct 09 10:08:53 MDT 2009 UP
Fri Oct 09 10:09:14 MDT 2009 DOWN!
Fri Oct 09 10:09:14 MDT 2009 UP
Fri Oct 09 10:10:10 MDT 2009 DOWN!
Fri Oct 09 10:10:11 MDT 2009 UP
Fri Oct 09 10:10:37 MDT 2009 DOWN!
Fri Oct 09 10:10:37 MDT 2009 UP
Fri Oct 09 10:11:38 MDT 2009 DOWN!
Fri Oct 09 10:11:38 MDT 2009 UP
Fri Oct 09 10:13:04 MDT 2009 DOWN!
Fri Oct 09 10:13:04 MDT 2009 UP
Fri Oct 09 10:14:21 MDT 2009 DOWN!
Fri Oct 09 10:14:21 MDT 2009 UP
Fri Oct 09 10:15:07 MDT 2009 DOWN!
Fri Oct 09 10:15:07 MDT 2009 UP
Fri Oct 09 10:15:43 MDT 2009 DOWN!
Fri Oct 09 10:15:43 MDT 2009 UP
Fri Oct 09 10:15:59 MDT 2009 DOWN!
Fri Oct 09 10:15:59 MDT 2009 UP
Fri Oct 09 10:30:30 MDT 2009 DOWN!
Fri Oct 09 10:30:30 MDT 2009 UP
Fri Oct 09 10:30:56 MDT 2009 DOWN!
Fri Oct 09 10:30:56 MDT 2009 UP
Fri Oct 09 10:32:07 MDT 2009 DOWN!
Fri Oct 09 10:32:07 MDT 2009 UP
Fri Oct 09 10:33:18 MDT 2009 DOWN!
Fri Oct 09 10:33:18 MDT 2009 UP
Fri Oct 09 10:33:34 MDT 2009 DOWN!
Fri Oct 09 10:33:34 MDT 2009 UP
Fri Oct 09 10:36:26 MDT 2009 DOWN!
Fri Oct 09 10:36:26 MDT 2009 UP
Fri Oct 09 13:12:12 MDT 2009 DOWN!
Fri Oct 09 13:15:30 MDT 2009 UP
Fri Oct 09 13:52:12 MDT 2009 DOWN!
Fri Oct 09 13:53:08 MDT 2009 UP
Fri Oct 09 14:34:14 MDT 2009 DOWN!
Fri Oct 09 14:35:09 MDT 2009 UP
Fri Oct 09 15:08:11 MDT 2009 DOWN!
Fri Oct 09 15:11:29 MDT 2009 UP
Fri Oct 09 16:26:15 MDT 2009 DOWN!
Fri Oct 09 16:29:22 MDT 2009 UP
Fri Oct 09 17:26:26 MDT 2009 DOWN!
Fri Oct 09 17:26:26 MDT 2009 UP
Fri Oct 09 17:27:17 MDT 2009 DOWN!
Fri Oct 09 17:27:17 MDT 2009 UP
Fri Oct 09 17:29:14 MDT 2009 DOWN!
Fri Oct 09 17:29:14 MDT 2009 UP
Fri Oct 09 17:30:35 MDT 2009 DOWN!
Fri Oct 09 17:30:35 MDT 2009 UP
Fri Oct 09 17:31:21 MDT 2009 DOWN!
Fri Oct 09 17:31:22 MDT 2009 UP
Fri Oct 09 17:31:58 MDT 2009 DOWN!
Fri Oct 09 17:31:58 MDT 2009 UP
Fri Oct 09 17:33:14 MDT 2009 DOWN!
Fri Oct 09 17:33:14 MDT 2009 UP
Fri Oct 09 18:25:03 MDT 2009 DOWN!
Fri Oct 09 18:25:03 MDT 2009 UP

Powered by Web Design Company Plugins

Switch to our mobile site