diff --git a/planetstack/core/dashboard/views/home.py b/planetstack/core/dashboard/views/home.py
index 6cb25a0..ff6c445 100644
--- a/planetstack/core/dashboard/views/home.py
+++ b/planetstack/core/dashboard/views/home.py
@@ -26,14 +26,21 @@
             return self.singleDashboardView(request, name, context)
 
     def readTemplate(self, fn):
-        try:
-            template= open("/opt/planetstack/templates/admin/dashboard/%s.html" % fn, "r").read()
-            if (fn=="tenant"):
-                # fix for tenant view - it writes html to a div called tabs-5
-                template = '<div id="tabs-5"></div>' + template
-            return template
-        except:
-            return "failed to open %s" % fn
+        TEMPLATE_DIRS = ["/opt/planetstack/templates/admin/dashboard/",
+                         "/opt/planetstack/core/xoslib/dashboards/"]
+
+        for template_dir in TEMPLATE_DIRS:
+            pathname = os.path.join(template_dir, fn) + ".html"
+            if os.path.exists(pathname):
+                break
+        else:
+            return "failed to find %s in %s" % (fn, TEMPLATE_DIRS)
+
+        template= open(pathname, "r").read()
+        if (fn=="tenant"):
+            # fix for tenant view - it writes html to a div called tabs-5
+            template = '<div id="tabs-5"></div>' + template
+        return template
 
     def embedDashboard(self, url):
         if url.startswith("template:"):
@@ -41,6 +48,8 @@
             return self.readTemplate(fn)
         elif url.startswith("http"):
             return '<iframe src="%s" width="100%%" height="100%%" style="min-height: 1024px;" frameBorder="0"></iframe>' % url
+        else:
+            return "don't know how to load dashboard %s" % url
 
     def multiDashboardView(self, request, context):
         head_template = self.head_template
diff --git a/planetstack/core/dashboard/views/view_common.py b/planetstack/core/dashboard/views/view_common.py
index bf6b392..b3c0a52 100644
--- a/planetstack/core/dashboard/views/view_common.py
+++ b/planetstack/core/dashboard/views/view_common.py
@@ -142,7 +142,7 @@
         hotness = max(0.0, ((cpu*RED_LOAD) - BLUE_LOAD)/(RED_LOAD-BLUE_LOAD))
 
         try:
-           lat=float(site.location.longitude)
+           lat=float(site.location.latitude)
            long=float(site.location.longitude)
         except:
            lat=0
diff --git a/planetstack/core/fixtures/initial_data.json b/planetstack/core/fixtures/initial_data.json
index 531d5f9..1c81b7e 100644
--- a/planetstack/core/fixtures/initial_data.json
+++ b/planetstack/core/fixtures/initial_data.json
@@ -91,10 +91,10 @@
     "pk": 9, 
     "model": "core.dashboardview", 
     "fields": {
-        "url": "template:shell", 
+        "url": "template:xsh", 
         "updated": "2014-06-19T01:34:07.897Z", 
         "enacted": null, 
-        "name": "shell", 
+        "name": "xsh", 
         "created": "2014-06-19T01:34:07.897Z"
     }
 },
diff --git a/planetstack/core/xoslib/__init__.py b/planetstack/core/xoslib/__init__.py
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/planetstack/core/xoslib/__init__.py
@@ -0,0 +1 @@
+
diff --git a/planetstack/core/xoslib/dashboards/gentle.html b/planetstack/core/xoslib/dashboards/gentle.html
new file mode 100644
index 0000000..707f10e
--- /dev/null
+++ b/planetstack/core/xoslib/dashboards/gentle.html
@@ -0,0 +1,25 @@
+    <div class="navbar navbar-inverse navbar-fixed-top">
+      <div class="navbar-inner">
+        <div class="container">
+          <span class="brand">Contact manager</span>
+        </div>
+      </div>
+    </div>
+
+    <div id="main-region" class="container">
+      <p>Here is static content in the web page. You'll notice that it gets replaced by our app as soon as we start it.</p>
+    </div>
+
+    <script type="text/template" id="contact-list-item">
+      <p><%- firstName %> <%- lastName %></p>
+    </script>
+
+<script src="{{ STATIC_URL }}/js/vendor/underscore-min.js"></script>
+<script src="{{ STATIC_URL }}/js/vendor/backbone.js"></script>
+<script src="{{ STATIC_URL }}/js/vendor/backbone.wreqr.js"></script>
+<script src="{{ STATIC_URL }}/js/vendor/backbone.babysitter.js"></script>
+<script src="{{ STATIC_URL }}/js/vendor/backbone.marionette.js"></script>
+<script src="{{ STATIC_URL }}/js/xoslib/xos-backbone.js"></script>
+<script src="{{ STATIC_URL }}/js/gentle.js"></script>
+
+
diff --git a/planetstack/core/xoslib/dashboards/helloworld.html b/planetstack/core/xoslib/dashboards/helloworld.html
new file mode 100644
index 0000000..9b61487
--- /dev/null
+++ b/planetstack/core/xoslib/dashboards/helloworld.html
@@ -0,0 +1,13 @@
+<!-- /opt/planetstack/templates/admin/dashboard/helloworld.html -->
+<div>Hello, {{ user.firstname }} {{ user.lastname }}.</div>
+<div>This is the hello world view. The value of foobar is {{ foobar }}.</div>
+<div id="dynamicTableOfInterestingThings"></div>
+<p>Type a new description for the the first slice in the collection:</p>
+<input type="text" name="newDescription" id="newDescription">
+<input type="button" name="submitNewDescription" value="submit new description"  id="submitNewDescription">
+
+<script src="{{ STATIC_URL }}/js/vendor/underscore-min.js"></script>
+<script src="{{ STATIC_URL }}/js/vendor/backbone.js"></script>
+<script src="{{ STATIC_URL }}/js/xoslib/xos-backbone.js"></script>
+
+<script src="{{ STATIC_URL }}/js/helloworld.js"></script>
diff --git a/planetstack/core/xoslib/dashboards/index.html b/planetstack/core/xoslib/dashboards/index.html
new file mode 100644
index 0000000..04ef136
--- /dev/null
+++ b/planetstack/core/xoslib/dashboards/index.html
@@ -0,0 +1,15 @@
+<p>xoslib demo views</p>
+
+<table>
+<tr><td><a href="/dashboard/xosDeveloper/">xosDeveloper</a></td>
+<td>Demonstrates using xoslib + marionette to render a list of slices</td>
+</tr>
+
+<tr><td><a href="/dashboard/xosDeveloper_datatables/">xosDeveloper_datatables</a></td>
+<td>Demonstrates using xoslib + datatables to render a list of slices</td>
+</tr>
+
+<tr><td><a href="/dashboard/sliceEditor/">sliceEditor</a></td>
+<td>Demonstrates how to commit data back to the data model using xoslib</td>
+</tr>
+</table>
diff --git a/planetstack/core/xoslib/dashboards/sliceEditor.html b/planetstack/core/xoslib/dashboards/sliceEditor.html
new file mode 100644
index 0000000..bc3fa1b
--- /dev/null
+++ b/planetstack/core/xoslib/dashboards/sliceEditor.html
@@ -0,0 +1,40 @@
+<script src="{{ STATIC_URL }}/js/vendor/underscore-min.js"></script>
+<script src="{{ STATIC_URL }}/js/vendor/backbone.js"></script>
+<script src="{{ STATIC_URL }}/js/vendor/backbone.syphon.js"></script>
+<script src="{{ STATIC_URL }}/js/vendor/backbone.wreqr.js"></script>
+<script src="{{ STATIC_URL }}/js/vendor/backbone.babysitter.js"></script>
+<script src="{{ STATIC_URL }}/js/vendor/backbone.marionette.js"></script>
+
+<link rel="stylesheet" type="text/css" href="{% static 'css/sliceEditor.css' %}" media="all">
+
+<script src="{{ STATIC_URL }}/js/xoslib/xos-backbone.js"></script>
+<script src="{{ STATIC_URL }}/js/sliceEditor.js"></script>
+
+<p>This is a demo of modifying objects using xoslib. Pick a slice in the list on
+the left. Then edit any of it's fields on the right, and press the (save)
+button.</p>
+
+<table class="table table-bordered"><tr><td valign=top>
+<div id="sliceEditorList">
+</div>
+</td>
+<td valign=top>
+<div id="sliceEditorDetail">
+</div>
+</td></tr></table>
+
+<script type="text/template" id="sliceeditor-listitem-template">
+  <%= name %>
+</script>
+
+<script type="text/template" id="sliceeditor-sliceedit-template">
+  <form>
+  <table>
+  <tr><td>Slice Name:</td><td><input type="text" name="name" value="<%= name %>" id="foo"></td></tr>
+  <tr><td>Description:</td><td><input type="text" name="description" value="<%= description %>"></td></tr>
+  <tr><td colspan=2><button class="btn js-submit">Save</button></td></tr>
+  </table>
+  </form>
+
+</script>
+
diff --git a/planetstack/core/xoslib/dashboards/sliverListTest.html b/planetstack/core/xoslib/dashboards/sliverListTest.html
index 61c54cf..255cbad 100644
--- a/planetstack/core/xoslib/dashboards/sliverListTest.html
+++ b/planetstack/core/xoslib/dashboards/sliverListTest.html
@@ -1,11 +1,11 @@
 {% load mustache %}
 {% load straight_include %}
 
-<script src="{{ STATIC_URL }}/js/underscore-min.js"></script>
-<script src="{{ STATIC_URL }}/js/backbone-min.js"></script>
-<script src="{{ STATIC_URL }}/js/ICanHaz.min.js"></script>
+<script src="{{ STATIC_URL }}/js/vendor/underscore-min.js"></script>
+<script src="{{ STATIC_URL }}/js/vendor/backbone-min.js"></script>
+<script src="{{ STATIC_URL }}/js/vendor/ICanHaz.min.js"></script>
 
-<script src="{{ STATIC_URL }}/js/xos-backbone.js"></script>
+<script src="{{ STATIC_URL }}/js/xoslib/xos-backbone.js"></script>
 <script src="{{ STATIC_URL }}/js/sliverListTest.js"></script>
 
 <script type="text/html" id="sliverTemplate">
diff --git a/planetstack/core/xoslib/dashboards/xosDeveloper.html b/planetstack/core/xoslib/dashboards/xosDeveloper.html
new file mode 100644
index 0000000..58f2d08
--- /dev/null
+++ b/planetstack/core/xoslib/dashboards/xosDeveloper.html
@@ -0,0 +1,31 @@
+<script src="{{ STATIC_URL }}/js/vendor/underscore-min.js"></script>
+<script src="{{ STATIC_URL }}/js/vendor/backbone.js"></script>
+<script src="{{ STATIC_URL }}/js/vendor/backbone.wreqr.js"></script>
+<script src="{{ STATIC_URL }}/js/vendor/backbone.babysitter.js"></script>
+<script src="{{ STATIC_URL }}/js/vendor/backbone.marionette.js"></script>
+
+<script src="{{ STATIC_URL }}/js/xoslib/xos-backbone.js"></script>
+<script src="{{ STATIC_URL }}/js/xosDeveloper.js"></script>
+
+<link rel="stylesheet" type="text/css" href="{% static 'css/xosDeveloper.css' %}" media="all">
+
+<div id="developerView">
+</div>
+
+<script type="text/template" id="developer-slicetable-template">
+  <thead>
+    <tr class="developer-header">
+      <th>Slice <span class="sort" id="sort-asc-name">&#9650;</span><span class="sort" id="sort-desc-name">&#9660;</span></th>
+      <th>Privilege<span class="sort" id="sort-asc-sliceInfo.roles">&#9650;</span><span class="sort" id="sort-desc-sliceInfo.roles">&#9660;</span></th>
+      <th>Number of Slivers<span class="sort" id="sort-asc-sliceInfo.sliverCount">&#9650;</span><span class="sort" id="sort-desc-sliceInfo.sliverCount">&#9660;</span></th>
+      <th>Number of Sites<span class="sort" id="sort-asc-sliceInfo.siteCount">&#9650;</span><span class="sort" id="sort-desc-sliceInfo.siteCount">&#9660;</span></th>
+    </tr>
+  </thead>
+  <tbody>
+  </tbody>
+</script>
+
+<script type="text/template" id="developer-slicedetail-template">
+  <td><a href="http://{{request.get_host}}/admin/core/slice/<%= id %>/"><%= name %></a></td><td><%= sliceInfo.roles[0] %></td><td><%= sliceInfo.sliverCount %></td><td><%= sliceInfo.siteCount %></td>
+</script>
+
diff --git a/planetstack/core/xoslib/dashboards/xosDeveloper_datatables.html b/planetstack/core/xoslib/dashboards/xosDeveloper_datatables.html
new file mode 100644
index 0000000..d40409a
--- /dev/null
+++ b/planetstack/core/xoslib/dashboards/xosDeveloper_datatables.html
@@ -0,0 +1,16 @@
+<script src="{{ STATIC_URL }}/js/vendor/underscore-min.js"></script>
+<script src="{{ STATIC_URL }}/js/vendor/backbone.js"></script>
+<script src="{{ STATIC_URL }}/js/vendor/backbone.wreqr.js"></script>
+<script src="{{ STATIC_URL }}/js/vendor/backbone.babysitter.js"></script>
+<script src="{{ STATIC_URL }}/js/vendor/backbone.marionette.js"></script>
+
+<script src="{{ STATIC_URL }}/js/xoslib/xos-backbone.js"></script>
+<script src="{{ STATIC_URL }}/js/xosDeveloper_datatables.js"></script>
+
+<div id="developerView">Loading...
+</div>
+
+<script type="text/template" id="developer-slicedetail-template">
+  <td><a href="http://{{request.get_host}}/admin/core/slice/<%= id %>/"><%= name %></a></td><td><%= sliceInfo.roles[0] %></td><td><%= sliceInfo.sliverCount %></td><td><%= sliceInfo.siteCount %></td>
+</script>
+
diff --git a/planetstack/core/xoslib/dashboards/xsh.html b/planetstack/core/xoslib/dashboards/xsh.html
index 6e5103a..65a44da 100644
--- a/planetstack/core/xoslib/dashboards/xsh.html
+++ b/planetstack/core/xoslib/dashboards/xsh.html
@@ -6,16 +6,16 @@
 
   </div>
   <link rel="stylesheet" type="text/css" href="{% static 'shell/opencloud_shell.css' %}" media="all">
-  <script src="{{ STATIC_URL }}/js/underscore-min.js"></script>
-  <script src="{{ STATIC_URL }}/js/backbone-min.js"></script>
-  <script src="{{ STATIC_URL }}/js/ICanHaz.min.js"></script>
-  <script src="{{ STATIC_URL }}/js/xos-backbone.js"></script>
-  <script src="{% static 'xsh/xsh.js' %}"></script>
-  <script src="{% static 'xsh/object_id.js' %}"></script>
-  <script src="{% static 'xsh/constants.js' %}"></script>
-  <script src="{% static 'xsh/utils.js' %}"></script>
-  <script src="{% static 'xsh/shell_utils.js' %}"></script>
-  <script src="{% static 'xsh/tokens.js' %}"></script>
+  <script src="{{ STATIC_URL }}/js/vendor/underscore-min.js"></script>
+  <script src="{{ STATIC_URL }}/js/vendor/backbone-min.js"></script>
+  <script src="{{ STATIC_URL }}/js/vendor/ICanHaz.min.js"></script>
+  <script src="{{ STATIC_URL }}/js/xoslib/xos-backbone.js"></script>
+  <script src="{% static 'js/xsh/xsh.js' %}"></script>
+  <script src="{% static 'js/xsh/object_id.js' %}"></script>
+  <script src="{% static 'js/xsh/constants.js' %}"></script>
+  <script src="{% static 'js/xsh/utils.js' %}"></script>
+  <script src="{% static 'js/xsh/shell_utils.js' %}"></script>
+  <script src="{% static 'js/xsh/tokens.js' %}"></script>
 
 
 
diff --git a/planetstack/core/xoslib/methods/__init__.py b/planetstack/core/xoslib/methods/__init__.py
new file mode 100644
index 0000000..0b891eb
--- /dev/null
+++ b/planetstack/core/xoslib/methods/__init__.py
@@ -0,0 +1,45 @@
+from django.views.generic import View
+from django.conf.urls import patterns, url
+import os, sys
+import inspect
+import importlib
+
+# XXX based on core/dashboard/views/__init__.py
+
+# Find all modules in the current directory that have descendents of the View
+# object, and add them as globals to this module. Also, build up a list of urls
+# based on the "url" field of the view classes.
+
+urlpatterns=[]
+
+sys_path_save = sys.path
+try:
+    # __import__() and importlib.import_module() both import modules from
+    # sys.path. So we make sure that the path where we can find the views is
+    # the first thing in sys.path.
+    view_dir = os.path.dirname(os.path.abspath(__file__))
+    sys.path = [view_dir] + sys.path
+    view_urls = []
+    for fn in os.listdir(view_dir):
+        pathname = os.path.join(view_dir,fn)
+        if os.path.isfile(pathname) and fn.endswith(".py") and (fn!="__init__.py"):
+            module = __import__(fn[:-3])
+            for classname in dir(module):
+                c = getattr(module, classname, None)
+
+                if inspect.isclass(c) and issubclass(c, View) and (classname not in globals()):
+                    globals()[classname] = c
+
+                    method_kind = getattr(c, "method_kind", None)
+                    method_name = getattr(c, "method_name", None)
+                    if method_kind and method_name:
+                        view_urls.append( (method_kind, method_name, classname, c) )
+
+    for view_url in view_urls:
+        if view_url[0] == "list":
+           urlpatterns.append(url(r'^' + view_url[1] + '/$',  view_url[3].as_view(), name=view_url[1]+'list'))
+        elif view_url[0] == "detail":
+           urlpatterns.append(url(r'^' + view_url[1] + '/(?P<pk>[a-zA-Z0-9\-]+)/$',  view_url[3].as_view(), name=view_url[1]+'detail'))
+
+finally:
+    sys.path = sys_path_save
diff --git a/planetstack/core/xoslib/methods/sliceplus.py b/planetstack/core/xoslib/methods/sliceplus.py
new file mode 100644
index 0000000..f990275
--- /dev/null
+++ b/planetstack/core/xoslib/methods/sliceplus.py
@@ -0,0 +1,65 @@
+from rest_framework.decorators import api_view
+from rest_framework.response import Response
+from rest_framework.reverse import reverse
+from rest_framework import serializers
+from rest_framework import generics
+from core.models import *
+from django.forms import widgets
+from core.xoslib.objects.sliceplus import SlicePlus
+
+class SlicePlusIdSerializer(serializers.ModelSerializer):
+        id = serializers.Field()
+
+        sliceInfo = serializers.SerializerMethodField("getSliceInfo")
+
+        def getSliceInfo(self, slice):
+            return slice.getSliceInfo(user=self.context['request'].user)
+
+        networks = serializers.HyperlinkedRelatedField(many=True, read_only=True, view_name='network-detail')
+        availableNetworks = serializers.HyperlinkedRelatedField(many=True, read_only=True, view_name='network-detail')
+
+        class Meta:
+            model = SlicePlus
+            fields = ('id','created','updated','enacted','name','enabled','omf_friendly','description','slice_url','site','max_slivers','imagePreference','service','network','mountDataSets','serviceClass','creator','networks','availableNetworks','sliceInfo')
+
+class SlicePlusList(generics.ListCreateAPIView):
+    queryset = SlicePlus.objects.select_related().all()
+    serializer_class = SlicePlusIdSerializer
+
+    method_kind = "list"
+    method_name = "slicesplus"
+
+    def get_queryset(self):
+        return SlicePlus.select_by_user(self.request.user)
+
+    def create(self, request, *args, **kwargs):
+        obj = self.get_object()
+        obj.caller = request.user
+        if obj.can_update(request.user):
+            return super(SliceList, self).create(request, *args, **kwargs)
+        else:
+            return Response(status=status.HTTP_400_BAD_REQUEST)
+
+class SlicePlusDetail(generics.RetrieveUpdateDestroyAPIView):
+    queryset = SlicePlus.objects.select_related().all()
+    serializer_class = SlicePlusIdSerializer
+
+    method_kind = "detail"
+    method_name = "slicesplus"
+
+    def get_queryset(self):
+        return SlicePlus.select_by_user(self.request.user)
+
+    def update(self, request, *args, **kwargs):
+        obj = self.get_object()
+        if obj.can_update(request.user):
+            return super(SlicePlusDetail, self).update(request, *args, **kwargs)
+        else:
+            return Response(status=status.HTTP_400_BAD_REQUEST)
+
+    def destroy(self, request, *args, **kwargs):
+        obj = self.get_object()
+        if obj.can_update(request.user):
+            return super(SlicePlusDetail, self).destroy(request, *args, **kwargs)
+        else:
+            return Response(status=status.HTTP_400_BAD_REQUEST)
diff --git a/planetstack/core/xoslib/objects/__init__.py b/planetstack/core/xoslib/objects/__init__.py
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/planetstack/core/xoslib/objects/__init__.py
@@ -0,0 +1 @@
+
diff --git a/planetstack/core/xoslib/objects/sliceplus.py b/planetstack/core/xoslib/objects/sliceplus.py
new file mode 100644
index 0000000..2542fd7
--- /dev/null
+++ b/planetstack/core/xoslib/objects/sliceplus.py
@@ -0,0 +1,35 @@
+from core.models.slice import Slice
+
+class SlicePlus(Slice):
+    class Meta:
+        proxy = True
+
+    def getSliceInfo(self, user=None):
+        used_sites = {}
+        used_deployments = {}
+        sliverCount = 0
+        for sliver in self.slivers.all():
+            site = sliver.node.site
+            deployment = sliver.node.deployment
+            used_sites[site.name] = used_sites.get(site.name, 0) + 1
+            used_deployments[deployment.name] = used_deployments.get(deployment.name, 0) + 1
+            sliverCount = sliverCount + 1
+
+        roles = []
+        if (user!=None):
+            roles = [x.role for x in self.slice_privileges.filter(user=user)]
+
+        return {"sitesUsed": used_sites,
+                "deploymentsUsed": used_deployments,
+                "sliverCount": sliverCount,
+                "siteCount": len(used_sites.keys()),
+                "roles": roles}
+
+    @staticmethod
+    def select_by_user(user):
+        if user.is_admin:
+            qs = SlicePlus.objects.all()
+        else:
+            slice_ids = [sp.slice.id for sp in SlicePrivilege.objects.filter(user=user)]
+            qs = SlicePlus.objects.filter(id__in=slice_ids)
+        return qs
diff --git a/planetstack/core/xoslib/static/css/sliceEditor.css b/planetstack/core/xoslib/static/css/sliceEditor.css
new file mode 100644
index 0000000..9825efc
--- /dev/null
+++ b/planetstack/core/xoslib/static/css/sliceEditor.css
@@ -0,0 +1,3 @@
+.sliceeditor-listitem { cursor: pointer; color: blue; }
+
+.sliceeditor-listitem:hover { font-weight: bold; }
diff --git a/planetstack/core/xoslib/static/css/xosDeveloper.css b/planetstack/core/xoslib/static/css/xosDeveloper.css
new file mode 100644
index 0000000..1bce877
--- /dev/null
+++ b/planetstack/core/xoslib/static/css/xosDeveloper.css
@@ -0,0 +1 @@
+#developerView .sort { cursor: pointer; }
diff --git a/planetstack/core/xoslib/static/js/gentle.js b/planetstack/core/xoslib/static/js/gentle.js
new file mode 100644
index 0000000..f79bde2
--- /dev/null
+++ b/planetstack/core/xoslib/static/js/gentle.js
@@ -0,0 +1,49 @@
+var ContactManager = new Marionette.Application();
+
+ContactManager.addRegions({
+    mainRegion: "#main-region"
+});
+
+ContactManager.Contact = Backbone.Model.extend({});
+
+ContactManager.ContactCollection = Backbone.Collection.extend({
+    model: ContactManager.Contact
+});
+
+ContactManager.ContactItemView = Marionette.ItemView.extend({
+    tagName: "li",
+    template: "#contact-list-item"
+});
+
+ContactManager.ContactsView = Marionette.CollectionView.extend({
+    tagName: "ul",
+    childView: ContactManager.ContactItemView
+});
+
+ContactManager.on("start", function(){
+    var contacts = new ContactManager.ContactCollection([
+        {
+            firstName: "Bob",
+            lastName: "Brigham",
+            phoneNumber: "555-0163"
+        },
+        {
+            firstName: "Alice",
+            lastName: "Arten",
+            phoneNumber: "555-0184"
+        },
+        {
+            firstName: "Charlie",
+            lastName: "Campbell",
+            phoneNumber: "555-0129"
+        }
+    ]);
+
+    var contactsView = new ContactManager.ContactsView({
+        collection: contacts
+    });
+
+    ContactManager.mainRegion.show(contactsView);
+});
+
+ContactManager.start();
diff --git a/planetstack/core/xoslib/static/js/helloworld.js b/planetstack/core/xoslib/static/js/helloworld.js
new file mode 100644
index 0000000..1563094
--- /dev/null
+++ b/planetstack/core/xoslib/static/js/helloworld.js
@@ -0,0 +1,27 @@
+// helloworld.js
+function updateHelloWorldData() {
+    var html = "<table class='table table-bordered table-striped'>";
+    for (var slicekey in xos.slices.models) {
+        slice = xos.slices.models[slicekey]
+        html = html + "<tr><td>" + slice.get("name") + "</td><td>" + slice.get("description") + "</td></tr>";
+    }
+    html = html + "</table>";
+    $('#dynamicTableOfInterestingThings').html(html);
+}
+
+$(document).ready(function(){
+    xos.slices.on("change", function() { updateHelloWorldData(); });
+    xos.slices.on("remove", function() { updateHelloWorldData(); });
+    xos.slices.on("sort", function() { updateHelloWorldData();  });
+
+    xos.slices.startPolling();
+});
+
+// helloworld.js
+$(document).ready(function() {
+    $('#submitNewDescription').bind('click', function() {
+        newDescription = $("#newDescription").val();
+        xos.slices.models[0].set("description", newDescription);
+        xos.slices.models[0].save();
+    });
+});
diff --git a/planetstack/core/xoslib/static/js/sliceEditor.js b/planetstack/core/xoslib/static/js/sliceEditor.js
new file mode 100644
index 0000000..c629944
--- /dev/null
+++ b/planetstack/core/xoslib/static/js/sliceEditor.js
@@ -0,0 +1,110 @@
+/* This is a demo of using xoslib with Marionette
+
+   The main window is split into two halves. The left half has a CollectionView
+   (SliceListView) that lists all slices the user has access to. The right half
+   has an ItemView (SliceDetailView) that allows the user to edit the
+   name and description of a slice, as well as a <Save> button to save it.
+*/
+
+SliceEditorApp = new Marionette.Application();
+
+SliceEditorApp.addRegions({
+  sliceList: "#sliceEditorList",
+  sliceDetail: "#sliceEditorDetail",
+});
+
+/* SliceListItemView: This is the item view that is used by SliceListView to
+   display slice names.
+*/
+
+SliceEditorApp.SliceListItemView = Marionette.ItemView.extend({
+  template: "#sliceeditor-listitem-template",
+  tagName: 'li',
+  className: 'sliceeditor-listitem',
+
+  events: {"click": "changeSlice"},
+
+  changeSlice: function(e) {
+        e.preventDefault();
+        e.stopPropagation();
+
+        if (SliceEditorApp.sliceDetail.currentView && SliceEditorApp.sliceDetail.currentView.dirty) {
+            if (!confirm("discard current changes?")) {
+                return;
+            }
+        }
+
+        /* create a new SliceDetailView and set the sliceDetail region to
+           display it.
+        */
+
+        var sliceDetailView = new SliceEditorApp.SliceDetailView({
+            model: this.model,
+        });
+        SliceEditorApp.sliceDetail.show(sliceDetailView);
+  },
+});
+
+/* SliceListView: This displays a list of slice names.
+*/
+
+SliceEditorApp.SliceListView = Marionette.CollectionView.extend({
+  tagName: "ul",
+  childView: SliceEditorApp.SliceListItemView,
+
+  initialize: function() {
+      /* CollectionViews don't automatically listen for change events, but we
+         want to, so we pick up changes from the DetailView, and we pick up
+         changes from the server.
+      */
+      this.listenTo(this.collection, 'change', this._renderChildren);
+  },
+
+  attachHtml: function(compositeView, childView, index) {
+      // The REST API will let admin users see everything. For the developer
+      // view we still want to hide slices we are not members of.
+      if (childView.model.get("sliceInfo").roles.length == 0) {
+          return;
+      }
+      SliceEditorApp.SliceListView.__super__.attachHtml(compositeView, childView, index);
+  },
+});
+
+/* SliceDetailView: Display the slice and allow it to be edited */
+
+SliceEditorApp.SliceDetailView = Marionette.ItemView.extend({
+    template: "#sliceeditor-sliceedit-template",
+    tagName: 'div',
+
+    events: {"click button.js-submit": "submitClicked",
+             "change input": "inputChanged"},
+
+    /* inputChanged is watching the onChange events of the input controls. We
+       do this to track when this view is 'dirty', so we can throw up a warning
+       if the user tries to change his slices without saving first.
+    */
+
+    inputChanged: function(e) {
+        this.dirty = true;
+    },
+
+    submitClicked: function(e) {
+        e.preventDefault();
+        var data = Backbone.Syphon.serialize(this);
+        this.model.save(data);
+        this.dirty = false;
+    },
+});
+
+SliceEditorApp.on("start", function() {
+  var sliceListView = new SliceEditorApp.SliceListView({
+    collection: xos.slicesPlus
+  });
+  SliceEditorApp.sliceList.show(sliceListView);
+  xos.slicesPlus.startPolling();
+});
+
+$(document).ready(function(){
+  SliceEditorApp.start();
+});
+
diff --git a/planetstack/core/xoslib/static/js/ICanHaz.min.js b/planetstack/core/xoslib/static/js/vendor/ICanHaz.min.js
similarity index 100%
rename from planetstack/core/xoslib/static/js/ICanHaz.min.js
rename to planetstack/core/xoslib/static/js/vendor/ICanHaz.min.js
diff --git a/planetstack/core/xoslib/static/js/backbone-min.js b/planetstack/core/xoslib/static/js/vendor/backbone-min.js
similarity index 100%
rename from planetstack/core/xoslib/static/js/backbone-min.js
rename to planetstack/core/xoslib/static/js/vendor/backbone-min.js
diff --git a/planetstack/core/xoslib/static/js/backbone-tastypie.js b/planetstack/core/xoslib/static/js/vendor/backbone-tastypie.js
similarity index 100%
rename from planetstack/core/xoslib/static/js/backbone-tastypie.js
rename to planetstack/core/xoslib/static/js/vendor/backbone-tastypie.js
diff --git a/planetstack/core/xoslib/static/js/vendor/backbone.babysitter.js b/planetstack/core/xoslib/static/js/vendor/backbone.babysitter.js
new file mode 100644
index 0000000..eeb92a2
--- /dev/null
+++ b/planetstack/core/xoslib/static/js/vendor/backbone.babysitter.js
@@ -0,0 +1,190 @@
+// Backbone.BabySitter
+// -------------------
+// v0.1.4
+//
+// Copyright (c)2014 Derick Bailey, Muted Solutions, LLC.
+// Distributed under MIT license
+//
+// http://github.com/marionettejs/backbone.babysitter
+
+(function(root, factory) {
+
+  if (typeof define === 'function' && define.amd) {
+    define(['backbone', 'underscore'], function(Backbone, _) {
+      return factory(Backbone, _);
+    });
+  } else if (typeof exports !== 'undefined') {
+    var Backbone = require('backbone');
+    var _ = require('underscore');
+    module.exports = factory(Backbone, _);
+  } else {
+    factory(root.Backbone, root._);
+  }
+
+}(this, function(Backbone, _) {
+  'use strict';
+
+  var previousChildViewContainer = Backbone.ChildViewContainer;
+
+  // BabySitter.ChildViewContainer
+  // -----------------------------
+  //
+  // Provide a container to store, retrieve and
+  // shut down child views.
+  
+  Backbone.ChildViewContainer = (function (Backbone, _) {
+  
+    // Container Constructor
+    // ---------------------
+  
+    var Container = function(views){
+      this._views = {};
+      this._indexByModel = {};
+      this._indexByCustom = {};
+      this._updateLength();
+  
+      _.each(views, this.add, this);
+    };
+  
+    // Container Methods
+    // -----------------
+  
+    _.extend(Container.prototype, {
+  
+      // Add a view to this container. Stores the view
+      // by `cid` and makes it searchable by the model
+      // cid (and model itself). Optionally specify
+      // a custom key to store an retrieve the view.
+      add: function(view, customIndex){
+        var viewCid = view.cid;
+  
+        // store the view
+        this._views[viewCid] = view;
+  
+        // index it by model
+        if (view.model){
+          this._indexByModel[view.model.cid] = viewCid;
+        }
+  
+        // index by custom
+        if (customIndex){
+          this._indexByCustom[customIndex] = viewCid;
+        }
+  
+        this._updateLength();
+        return this;
+      },
+  
+      // Find a view by the model that was attached to
+      // it. Uses the model's `cid` to find it.
+      findByModel: function(model){
+        return this.findByModelCid(model.cid);
+      },
+  
+      // Find a view by the `cid` of the model that was attached to
+      // it. Uses the model's `cid` to find the view `cid` and
+      // retrieve the view using it.
+      findByModelCid: function(modelCid){
+        var viewCid = this._indexByModel[modelCid];
+        return this.findByCid(viewCid);
+      },
+  
+      // Find a view by a custom indexer.
+      findByCustom: function(index){
+        var viewCid = this._indexByCustom[index];
+        return this.findByCid(viewCid);
+      },
+  
+      // Find by index. This is not guaranteed to be a
+      // stable index.
+      findByIndex: function(index){
+        return _.values(this._views)[index];
+      },
+  
+      // retrieve a view by its `cid` directly
+      findByCid: function(cid){
+        return this._views[cid];
+      },
+  
+      // Remove a view
+      remove: function(view){
+        var viewCid = view.cid;
+  
+        // delete model index
+        if (view.model){
+          delete this._indexByModel[view.model.cid];
+        }
+  
+        // delete custom index
+        _.any(this._indexByCustom, function(cid, key) {
+          if (cid === viewCid) {
+            delete this._indexByCustom[key];
+            return true;
+          }
+        }, this);
+  
+        // remove the view from the container
+        delete this._views[viewCid];
+  
+        // update the length
+        this._updateLength();
+        return this;
+      },
+  
+      // Call a method on every view in the container,
+      // passing parameters to the call method one at a
+      // time, like `function.call`.
+      call: function(method){
+        this.apply(method, _.tail(arguments));
+      },
+  
+      // Apply a method on every view in the container,
+      // passing parameters to the call method one at a
+      // time, like `function.apply`.
+      apply: function(method, args){
+        _.each(this._views, function(view){
+          if (_.isFunction(view[method])){
+            view[method].apply(view, args || []);
+          }
+        });
+      },
+  
+      // Update the `.length` attribute on this container
+      _updateLength: function(){
+        this.length = _.size(this._views);
+      }
+    });
+  
+    // Borrowing this code from Backbone.Collection:
+    // http://backbonejs.org/docs/backbone.html#section-106
+    //
+    // Mix in methods from Underscore, for iteration, and other
+    // collection related features.
+    var methods = ['forEach', 'each', 'map', 'find', 'detect', 'filter',
+      'select', 'reject', 'every', 'all', 'some', 'any', 'include',
+      'contains', 'invoke', 'toArray', 'first', 'initial', 'rest',
+      'last', 'without', 'isEmpty', 'pluck'];
+  
+    _.each(methods, function(method) {
+      Container.prototype[method] = function() {
+        var views = _.values(this._views);
+        var args = [views].concat(_.toArray(arguments));
+        return _[method].apply(_, args);
+      };
+    });
+  
+    // return the public API
+    return Container;
+  })(Backbone, _);
+  
+
+  Backbone.ChildViewContainer.VERSION = '0.1.4';
+
+  Backbone.ChildViewContainer.noConflict = function () {
+    Backbone.ChildViewContainer = previousChildViewContainer;
+    return this;
+  };
+
+  return Backbone.ChildViewContainer;
+
+}));
diff --git a/planetstack/core/xoslib/static/js/vendor/backbone.js b/planetstack/core/xoslib/static/js/vendor/backbone.js
new file mode 100644
index 0000000..24a550a
--- /dev/null
+++ b/planetstack/core/xoslib/static/js/vendor/backbone.js
@@ -0,0 +1,1608 @@
+//     Backbone.js 1.1.2
+
+//     (c) 2010-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+//     Backbone may be freely distributed under the MIT license.
+//     For all details and documentation:
+//     http://backbonejs.org
+
+(function(root, factory) {
+
+  // Set up Backbone appropriately for the environment. Start with AMD.
+  if (typeof define === 'function' && define.amd) {
+    define(['underscore', 'jquery', 'exports'], function(_, $, exports) {
+      // Export global even in AMD case in case this script is loaded with
+      // others that may still expect a global Backbone.
+      root.Backbone = factory(root, exports, _, $);
+    });
+
+  // Next for Node.js or CommonJS. jQuery may not be needed as a module.
+  } else if (typeof exports !== 'undefined') {
+    var _ = require('underscore');
+    factory(root, exports, _);
+
+  // Finally, as a browser global.
+  } else {
+    root.Backbone = factory(root, {}, root._, (root.jQuery || root.Zepto || root.ender || root.$));
+  }
+
+}(this, function(root, Backbone, _, $) {
+
+  // Initial Setup
+  // -------------
+
+  // Save the previous value of the `Backbone` variable, so that it can be
+  // restored later on, if `noConflict` is used.
+  var previousBackbone = root.Backbone;
+
+  // Create local references to array methods we'll want to use later.
+  var array = [];
+  var push = array.push;
+  var slice = array.slice;
+  var splice = array.splice;
+
+  // Current version of the library. Keep in sync with `package.json`.
+  Backbone.VERSION = '1.1.2';
+
+  // For Backbone's purposes, jQuery, Zepto, Ender, or My Library (kidding) owns
+  // the `$` variable.
+  Backbone.$ = $;
+
+  // Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable
+  // to its previous owner. Returns a reference to this Backbone object.
+  Backbone.noConflict = function() {
+    root.Backbone = previousBackbone;
+    return this;
+  };
+
+  // Turn on `emulateHTTP` to support legacy HTTP servers. Setting this option
+  // will fake `"PATCH"`, `"PUT"` and `"DELETE"` requests via the `_method` parameter and
+  // set a `X-Http-Method-Override` header.
+  Backbone.emulateHTTP = false;
+
+  // Turn on `emulateJSON` to support legacy servers that can't deal with direct
+  // `application/json` requests ... will encode the body as
+  // `application/x-www-form-urlencoded` instead and will send the model in a
+  // form param named `model`.
+  Backbone.emulateJSON = false;
+
+  // Backbone.Events
+  // ---------------
+
+  // A module that can be mixed in to *any object* in order to provide it with
+  // custom events. You may bind with `on` or remove with `off` callback
+  // functions to an event; `trigger`-ing an event fires all callbacks in
+  // succession.
+  //
+  //     var object = {};
+  //     _.extend(object, Backbone.Events);
+  //     object.on('expand', function(){ alert('expanded'); });
+  //     object.trigger('expand');
+  //
+  var Events = Backbone.Events = {
+
+    // Bind an event to a `callback` function. Passing `"all"` will bind
+    // the callback to all events fired.
+    on: function(name, callback, context) {
+      if (!eventsApi(this, 'on', name, [callback, context]) || !callback) return this;
+      this._events || (this._events = {});
+      var events = this._events[name] || (this._events[name] = []);
+      events.push({callback: callback, context: context, ctx: context || this});
+      return this;
+    },
+
+    // Bind an event to only be triggered a single time. After the first time
+    // the callback is invoked, it will be removed.
+    once: function(name, callback, context) {
+      if (!eventsApi(this, 'once', name, [callback, context]) || !callback) return this;
+      var self = this;
+      var once = _.once(function() {
+        self.off(name, once);
+        callback.apply(this, arguments);
+      });
+      once._callback = callback;
+      return this.on(name, once, context);
+    },
+
+    // Remove one or many callbacks. If `context` is null, removes all
+    // callbacks with that function. If `callback` is null, removes all
+    // callbacks for the event. If `name` is null, removes all bound
+    // callbacks for all events.
+    off: function(name, callback, context) {
+      var retain, ev, events, names, i, l, j, k;
+      if (!this._events || !eventsApi(this, 'off', name, [callback, context])) return this;
+      if (!name && !callback && !context) {
+        this._events = void 0;
+        return this;
+      }
+      names = name ? [name] : _.keys(this._events);
+      for (i = 0, l = names.length; i < l; i++) {
+        name = names[i];
+        if (events = this._events[name]) {
+          this._events[name] = retain = [];
+          if (callback || context) {
+            for (j = 0, k = events.length; j < k; j++) {
+              ev = events[j];
+              if ((callback && callback !== ev.callback && callback !== ev.callback._callback) ||
+                  (context && context !== ev.context)) {
+                retain.push(ev);
+              }
+            }
+          }
+          if (!retain.length) delete this._events[name];
+        }
+      }
+
+      return this;
+    },
+
+    // Trigger one or many events, firing all bound callbacks. Callbacks are
+    // passed the same arguments as `trigger` is, apart from the event name
+    // (unless you're listening on `"all"`, which will cause your callback to
+    // receive the true name of the event as the first argument).
+    trigger: function(name) {
+      if (!this._events) return this;
+      var args = slice.call(arguments, 1);
+      if (!eventsApi(this, 'trigger', name, args)) return this;
+      var events = this._events[name];
+      var allEvents = this._events.all;
+      if (events) triggerEvents(events, args);
+      if (allEvents) triggerEvents(allEvents, arguments);
+      return this;
+    },
+
+    // Tell this object to stop listening to either specific events ... or
+    // to every object it's currently listening to.
+    stopListening: function(obj, name, callback) {
+      var listeningTo = this._listeningTo;
+      if (!listeningTo) return this;
+      var remove = !name && !callback;
+      if (!callback && typeof name === 'object') callback = this;
+      if (obj) (listeningTo = {})[obj._listenId] = obj;
+      for (var id in listeningTo) {
+        obj = listeningTo[id];
+        obj.off(name, callback, this);
+        if (remove || _.isEmpty(obj._events)) delete this._listeningTo[id];
+      }
+      return this;
+    }
+
+  };
+
+  // Regular expression used to split event strings.
+  var eventSplitter = /\s+/;
+
+  // Implement fancy features of the Events API such as multiple event
+  // names `"change blur"` and jQuery-style event maps `{change: action}`
+  // in terms of the existing API.
+  var eventsApi = function(obj, action, name, rest) {
+    if (!name) return true;
+
+    // Handle event maps.
+    if (typeof name === 'object') {
+      for (var key in name) {
+        obj[action].apply(obj, [key, name[key]].concat(rest));
+      }
+      return false;
+    }
+
+    // Handle space separated event names.
+    if (eventSplitter.test(name)) {
+      var names = name.split(eventSplitter);
+      for (var i = 0, l = names.length; i < l; i++) {
+        obj[action].apply(obj, [names[i]].concat(rest));
+      }
+      return false;
+    }
+
+    return true;
+  };
+
+  // A difficult-to-believe, but optimized internal dispatch function for
+  // triggering events. Tries to keep the usual cases speedy (most internal
+  // Backbone events have 3 arguments).
+  var triggerEvents = function(events, args) {
+    var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2];
+    switch (args.length) {
+      case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return;
+      case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return;
+      case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return;
+      case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return;
+      default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args); return;
+    }
+  };
+
+  var listenMethods = {listenTo: 'on', listenToOnce: 'once'};
+
+  // Inversion-of-control versions of `on` and `once`. Tell *this* object to
+  // listen to an event in another object ... keeping track of what it's
+  // listening to.
+  _.each(listenMethods, function(implementation, method) {
+    Events[method] = function(obj, name, callback) {
+      var listeningTo = this._listeningTo || (this._listeningTo = {});
+      var id = obj._listenId || (obj._listenId = _.uniqueId('l'));
+      listeningTo[id] = obj;
+      if (!callback && typeof name === 'object') callback = this;
+      obj[implementation](name, callback, this);
+      return this;
+    };
+  });
+
+  // Aliases for backwards compatibility.
+  Events.bind   = Events.on;
+  Events.unbind = Events.off;
+
+  // Allow the `Backbone` object to serve as a global event bus, for folks who
+  // want global "pubsub" in a convenient place.
+  _.extend(Backbone, Events);
+
+  // Backbone.Model
+  // --------------
+
+  // Backbone **Models** are the basic data object in the framework --
+  // frequently representing a row in a table in a database on your server.
+  // A discrete chunk of data and a bunch of useful, related methods for
+  // performing computations and transformations on that data.
+
+  // Create a new model with the specified attributes. A client id (`cid`)
+  // is automatically generated and assigned for you.
+  var Model = Backbone.Model = function(attributes, options) {
+    var attrs = attributes || {};
+    options || (options = {});
+    this.cid = _.uniqueId('c');
+    this.attributes = {};
+    if (options.collection) this.collection = options.collection;
+    if (options.parse) attrs = this.parse(attrs, options) || {};
+    attrs = _.defaults({}, attrs, _.result(this, 'defaults'));
+    this.set(attrs, options);
+    this.changed = {};
+    this.initialize.apply(this, arguments);
+  };
+
+  // Attach all inheritable methods to the Model prototype.
+  _.extend(Model.prototype, Events, {
+
+    // A hash of attributes whose current and previous value differ.
+    changed: null,
+
+    // The value returned during the last failed validation.
+    validationError: null,
+
+    // The default name for the JSON `id` attribute is `"id"`. MongoDB and
+    // CouchDB users may want to set this to `"_id"`.
+    idAttribute: 'id',
+
+    // Initialize is an empty function by default. Override it with your own
+    // initialization logic.
+    initialize: function(){},
+
+    // Return a copy of the model's `attributes` object.
+    toJSON: function(options) {
+      return _.clone(this.attributes);
+    },
+
+    // Proxy `Backbone.sync` by default -- but override this if you need
+    // custom syncing semantics for *this* particular model.
+    sync: function() {
+      return Backbone.sync.apply(this, arguments);
+    },
+
+    // Get the value of an attribute.
+    get: function(attr) {
+      return this.attributes[attr];
+    },
+
+    // Get the HTML-escaped value of an attribute.
+    escape: function(attr) {
+      return _.escape(this.get(attr));
+    },
+
+    // Returns `true` if the attribute contains a value that is not null
+    // or undefined.
+    has: function(attr) {
+      return this.get(attr) != null;
+    },
+
+    // Set a hash of model attributes on the object, firing `"change"`. This is
+    // the core primitive operation of a model, updating the data and notifying
+    // anyone who needs to know about the change in state. The heart of the beast.
+    set: function(key, val, options) {
+      var attr, attrs, unset, changes, silent, changing, prev, current;
+      if (key == null) return this;
+
+      // Handle both `"key", value` and `{key: value}` -style arguments.
+      if (typeof key === 'object') {
+        attrs = key;
+        options = val;
+      } else {
+        (attrs = {})[key] = val;
+      }
+
+      options || (options = {});
+
+      // Run validation.
+      if (!this._validate(attrs, options)) return false;
+
+      // Extract attributes and options.
+      unset           = options.unset;
+      silent          = options.silent;
+      changes         = [];
+      changing        = this._changing;
+      this._changing  = true;
+
+      if (!changing) {
+        this._previousAttributes = _.clone(this.attributes);
+        this.changed = {};
+      }
+      current = this.attributes, prev = this._previousAttributes;
+
+      // Check for changes of `id`.
+      if (this.idAttribute in attrs) this.id = attrs[this.idAttribute];
+
+      // For each `set` attribute, update or delete the current value.
+      for (attr in attrs) {
+        val = attrs[attr];
+        if (!_.isEqual(current[attr], val)) changes.push(attr);
+        if (!_.isEqual(prev[attr], val)) {
+          this.changed[attr] = val;
+        } else {
+          delete this.changed[attr];
+        }
+        unset ? delete current[attr] : current[attr] = val;
+      }
+
+      // Trigger all relevant attribute changes.
+      if (!silent) {
+        if (changes.length) this._pending = options;
+        for (var i = 0, l = changes.length; i < l; i++) {
+          this.trigger('change:' + changes[i], this, current[changes[i]], options);
+        }
+      }
+
+      // You might be wondering why there's a `while` loop here. Changes can
+      // be recursively nested within `"change"` events.
+      if (changing) return this;
+      if (!silent) {
+        while (this._pending) {
+          options = this._pending;
+          this._pending = false;
+          this.trigger('change', this, options);
+        }
+      }
+      this._pending = false;
+      this._changing = false;
+      return this;
+    },
+
+    // Remove an attribute from the model, firing `"change"`. `unset` is a noop
+    // if the attribute doesn't exist.
+    unset: function(attr, options) {
+      return this.set(attr, void 0, _.extend({}, options, {unset: true}));
+    },
+
+    // Clear all attributes on the model, firing `"change"`.
+    clear: function(options) {
+      var attrs = {};
+      for (var key in this.attributes) attrs[key] = void 0;
+      return this.set(attrs, _.extend({}, options, {unset: true}));
+    },
+
+    // Determine if the model has changed since the last `"change"` event.
+    // If you specify an attribute name, determine if that attribute has changed.
+    hasChanged: function(attr) {
+      if (attr == null) return !_.isEmpty(this.changed);
+      return _.has(this.changed, attr);
+    },
+
+    // Return an object containing all the attributes that have changed, or
+    // false if there are no changed attributes. Useful for determining what
+    // parts of a view need to be updated and/or what attributes need to be
+    // persisted to the server. Unset attributes will be set to undefined.
+    // You can also pass an attributes object to diff against the model,
+    // determining if there *would be* a change.
+    changedAttributes: function(diff) {
+      if (!diff) return this.hasChanged() ? _.clone(this.changed) : false;
+      var val, changed = false;
+      var old = this._changing ? this._previousAttributes : this.attributes;
+      for (var attr in diff) {
+        if (_.isEqual(old[attr], (val = diff[attr]))) continue;
+        (changed || (changed = {}))[attr] = val;
+      }
+      return changed;
+    },
+
+    // Get the previous value of an attribute, recorded at the time the last
+    // `"change"` event was fired.
+    previous: function(attr) {
+      if (attr == null || !this._previousAttributes) return null;
+      return this._previousAttributes[attr];
+    },
+
+    // Get all of the attributes of the model at the time of the previous
+    // `"change"` event.
+    previousAttributes: function() {
+      return _.clone(this._previousAttributes);
+    },
+
+    // Fetch the model from the server. If the server's representation of the
+    // model differs from its current attributes, they will be overridden,
+    // triggering a `"change"` event.
+    fetch: function(options) {
+      options = options ? _.clone(options) : {};
+      if (options.parse === void 0) options.parse = true;
+      var model = this;
+      var success = options.success;
+      options.success = function(resp) {
+        if (!model.set(model.parse(resp, options), options)) return false;
+        if (success) success(model, resp, options);
+        model.trigger('sync', model, resp, options);
+      };
+      wrapError(this, options);
+      return this.sync('read', this, options);
+    },
+
+    // Set a hash of model attributes, and sync the model to the server.
+    // If the server returns an attributes hash that differs, the model's
+    // state will be `set` again.
+    save: function(key, val, options) {
+      var attrs, method, xhr, attributes = this.attributes;
+
+      // Handle both `"key", value` and `{key: value}` -style arguments.
+      if (key == null || typeof key === 'object') {
+        attrs = key;
+        options = val;
+      } else {
+        (attrs = {})[key] = val;
+      }
+
+      options = _.extend({validate: true}, options);
+
+      // If we're not waiting and attributes exist, save acts as
+      // `set(attr).save(null, opts)` with validation. Otherwise, check if
+      // the model will be valid when the attributes, if any, are set.
+      if (attrs && !options.wait) {
+        if (!this.set(attrs, options)) return false;
+      } else {
+        if (!this._validate(attrs, options)) return false;
+      }
+
+      // Set temporary attributes if `{wait: true}`.
+      if (attrs && options.wait) {
+        this.attributes = _.extend({}, attributes, attrs);
+      }
+
+      // After a successful server-side save, the client is (optionally)
+      // updated with the server-side state.
+      if (options.parse === void 0) options.parse = true;
+      var model = this;
+      var success = options.success;
+      options.success = function(resp) {
+        // Ensure attributes are restored during synchronous saves.
+        model.attributes = attributes;
+        var serverAttrs = model.parse(resp, options);
+        if (options.wait) serverAttrs = _.extend(attrs || {}, serverAttrs);
+        if (_.isObject(serverAttrs) && !model.set(serverAttrs, options)) {
+          return false;
+        }
+        if (success) success(model, resp, options);
+        model.trigger('sync', model, resp, options);
+      };
+      wrapError(this, options);
+
+      method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update');
+      if (method === 'patch') options.attrs = attrs;
+      xhr = this.sync(method, this, options);
+
+      // Restore attributes.
+      if (attrs && options.wait) this.attributes = attributes;
+
+      return xhr;
+    },
+
+    // Destroy this model on the server if it was already persisted.
+    // Optimistically removes the model from its collection, if it has one.
+    // If `wait: true` is passed, waits for the server to respond before removal.
+    destroy: function(options) {
+      options = options ? _.clone(options) : {};
+      var model = this;
+      var success = options.success;
+
+      var destroy = function() {
+        model.trigger('destroy', model, model.collection, options);
+      };
+
+      options.success = function(resp) {
+        if (options.wait || model.isNew()) destroy();
+        if (success) success(model, resp, options);
+        if (!model.isNew()) model.trigger('sync', model, resp, options);
+      };
+
+      if (this.isNew()) {
+        options.success();
+        return false;
+      }
+      wrapError(this, options);
+
+      var xhr = this.sync('delete', this, options);
+      if (!options.wait) destroy();
+      return xhr;
+    },
+
+    // Default URL for the model's representation on the server -- if you're
+    // using Backbone's restful methods, override this to change the endpoint
+    // that will be called.
+    url: function() {
+      var base =
+        _.result(this, 'urlRoot') ||
+        _.result(this.collection, 'url') ||
+        urlError();
+      if (this.isNew()) return base;
+      return base.replace(/([^\/])$/, '$1/') + encodeURIComponent(this.id);
+    },
+
+    // **parse** converts a response into the hash of attributes to be `set` on
+    // the model. The default implementation is just to pass the response along.
+    parse: function(resp, options) {
+      return resp;
+    },
+
+    // Create a new model with identical attributes to this one.
+    clone: function() {
+      return new this.constructor(this.attributes);
+    },
+
+    // A model is new if it has never been saved to the server, and lacks an id.
+    isNew: function() {
+      return !this.has(this.idAttribute);
+    },
+
+    // Check if the model is currently in a valid state.
+    isValid: function(options) {
+      return this._validate({}, _.extend(options || {}, { validate: true }));
+    },
+
+    // Run validation against the next complete set of model attributes,
+    // returning `true` if all is well. Otherwise, fire an `"invalid"` event.
+    _validate: function(attrs, options) {
+      if (!options.validate || !this.validate) return true;
+      attrs = _.extend({}, this.attributes, attrs);
+      var error = this.validationError = this.validate(attrs, options) || null;
+      if (!error) return true;
+      this.trigger('invalid', this, error, _.extend(options, {validationError: error}));
+      return false;
+    }
+
+  });
+
+  // Underscore methods that we want to implement on the Model.
+  var modelMethods = ['keys', 'values', 'pairs', 'invert', 'pick', 'omit'];
+
+  // Mix in each Underscore method as a proxy to `Model#attributes`.
+  _.each(modelMethods, function(method) {
+    Model.prototype[method] = function() {
+      var args = slice.call(arguments);
+      args.unshift(this.attributes);
+      return _[method].apply(_, args);
+    };
+  });
+
+  // Backbone.Collection
+  // -------------------
+
+  // If models tend to represent a single row of data, a Backbone Collection is
+  // more analagous to a table full of data ... or a small slice or page of that
+  // table, or a collection of rows that belong together for a particular reason
+  // -- all of the messages in this particular folder, all of the documents
+  // belonging to this particular author, and so on. Collections maintain
+  // indexes of their models, both in order, and for lookup by `id`.
+
+  // Create a new **Collection**, perhaps to contain a specific type of `model`.
+  // If a `comparator` is specified, the Collection will maintain
+  // its models in sort order, as they're added and removed.
+  var Collection = Backbone.Collection = function(models, options) {
+    options || (options = {});
+    if (options.model) this.model = options.model;
+    if (options.comparator !== void 0) this.comparator = options.comparator;
+    this._reset();
+    this.initialize.apply(this, arguments);
+    if (models) this.reset(models, _.extend({silent: true}, options));
+  };
+
+  // Default options for `Collection#set`.
+  var setOptions = {add: true, remove: true, merge: true};
+  var addOptions = {add: true, remove: false};
+
+  // Define the Collection's inheritable methods.
+  _.extend(Collection.prototype, Events, {
+
+    // The default model for a collection is just a **Backbone.Model**.
+    // This should be overridden in most cases.
+    model: Model,
+
+    // Initialize is an empty function by default. Override it with your own
+    // initialization logic.
+    initialize: function(){},
+
+    // The JSON representation of a Collection is an array of the
+    // models' attributes.
+    toJSON: function(options) {
+      return this.map(function(model){ return model.toJSON(options); });
+    },
+
+    // Proxy `Backbone.sync` by default.
+    sync: function() {
+      return Backbone.sync.apply(this, arguments);
+    },
+
+    // Add a model, or list of models to the set.
+    add: function(models, options) {
+      return this.set(models, _.extend({merge: false}, options, addOptions));
+    },
+
+    // Remove a model, or a list of models from the set.
+    remove: function(models, options) {
+      var singular = !_.isArray(models);
+      models = singular ? [models] : _.clone(models);
+      options || (options = {});
+      var i, l, index, model;
+      for (i = 0, l = models.length; i < l; i++) {
+        model = models[i] = this.get(models[i]);
+        if (!model) continue;
+        delete this._byId[model.id];
+        delete this._byId[model.cid];
+        index = this.indexOf(model);
+        this.models.splice(index, 1);
+        this.length--;
+        if (!options.silent) {
+          options.index = index;
+          model.trigger('remove', model, this, options);
+        }
+        this._removeReference(model, options);
+      }
+      return singular ? models[0] : models;
+    },
+
+    // Update a collection by `set`-ing a new list of models, adding new ones,
+    // removing models that are no longer present, and merging models that
+    // already exist in the collection, as necessary. Similar to **Model#set**,
+    // the core operation for updating the data contained by the collection.
+    set: function(models, options) {
+      options = _.defaults({}, options, setOptions);
+      if (options.parse) models = this.parse(models, options);
+      var singular = !_.isArray(models);
+      models = singular ? (models ? [models] : []) : _.clone(models);
+      var i, l, id, model, attrs, existing, sort;
+      var at = options.at;
+      var targetModel = this.model;
+      var sortable = this.comparator && (at == null) && options.sort !== false;
+      var sortAttr = _.isString(this.comparator) ? this.comparator : null;
+      var toAdd = [], toRemove = [], modelMap = {};
+      var add = options.add, merge = options.merge, remove = options.remove;
+      var order = !sortable && add && remove ? [] : false;
+
+      // Turn bare objects into model references, and prevent invalid models
+      // from being added.
+      for (i = 0, l = models.length; i < l; i++) {
+        attrs = models[i] || {};
+        if (attrs instanceof Model) {
+          id = model = attrs;
+        } else {
+          id = attrs[targetModel.prototype.idAttribute || 'id'];
+        }
+
+        // If a duplicate is found, prevent it from being added and
+        // optionally merge it into the existing model.
+        if (existing = this.get(id)) {
+          if (remove) modelMap[existing.cid] = true;
+          if (merge) {
+            attrs = attrs === model ? model.attributes : attrs;
+            if (options.parse) attrs = existing.parse(attrs, options);
+            existing.set(attrs, options);
+            if (sortable && !sort && existing.hasChanged(sortAttr)) sort = true;
+          }
+          models[i] = existing;
+
+        // If this is a new, valid model, push it to the `toAdd` list.
+        } else if (add) {
+          model = models[i] = this._prepareModel(attrs, options);
+          if (!model) continue;
+          toAdd.push(model);
+          this._addReference(model, options);
+        }
+
+        // Do not add multiple models with the same `id`.
+        model = existing || model;
+        if (order && (model.isNew() || !modelMap[model.id])) order.push(model);
+        modelMap[model.id] = true;
+      }
+
+      // Remove nonexistent models if appropriate.
+      if (remove) {
+        for (i = 0, l = this.length; i < l; ++i) {
+          if (!modelMap[(model = this.models[i]).cid]) toRemove.push(model);
+        }
+        if (toRemove.length) this.remove(toRemove, options);
+      }
+
+      // See if sorting is needed, update `length` and splice in new models.
+      if (toAdd.length || (order && order.length)) {
+        if (sortable) sort = true;
+        this.length += toAdd.length;
+        if (at != null) {
+          for (i = 0, l = toAdd.length; i < l; i++) {
+            this.models.splice(at + i, 0, toAdd[i]);
+          }
+        } else {
+          if (order) this.models.length = 0;
+          var orderedModels = order || toAdd;
+          for (i = 0, l = orderedModels.length; i < l; i++) {
+            this.models.push(orderedModels[i]);
+          }
+        }
+      }
+
+      // Silently sort the collection if appropriate.
+      if (sort) this.sort({silent: true});
+
+      // Unless silenced, it's time to fire all appropriate add/sort events.
+      if (!options.silent) {
+        for (i = 0, l = toAdd.length; i < l; i++) {
+          (model = toAdd[i]).trigger('add', model, this, options);
+        }
+        if (sort || (order && order.length)) this.trigger('sort', this, options);
+      }
+
+      // Return the added (or merged) model (or models).
+      return singular ? models[0] : models;
+    },
+
+    // When you have more items than you want to add or remove individually,
+    // you can reset the entire set with a new list of models, without firing
+    // any granular `add` or `remove` events. Fires `reset` when finished.
+    // Useful for bulk operations and optimizations.
+    reset: function(models, options) {
+      options || (options = {});
+      for (var i = 0, l = this.models.length; i < l; i++) {
+        this._removeReference(this.models[i], options);
+      }
+      options.previousModels = this.models;
+      this._reset();
+      models = this.add(models, _.extend({silent: true}, options));
+      if (!options.silent) this.trigger('reset', this, options);
+      return models;
+    },
+
+    // Add a model to the end of the collection.
+    push: function(model, options) {
+      return this.add(model, _.extend({at: this.length}, options));
+    },
+
+    // Remove a model from the end of the collection.
+    pop: function(options) {
+      var model = this.at(this.length - 1);
+      this.remove(model, options);
+      return model;
+    },
+
+    // Add a model to the beginning of the collection.
+    unshift: function(model, options) {
+      return this.add(model, _.extend({at: 0}, options));
+    },
+
+    // Remove a model from the beginning of the collection.
+    shift: function(options) {
+      var model = this.at(0);
+      this.remove(model, options);
+      return model;
+    },
+
+    // Slice out a sub-array of models from the collection.
+    slice: function() {
+      return slice.apply(this.models, arguments);
+    },
+
+    // Get a model from the set by id.
+    get: function(obj) {
+      if (obj == null) return void 0;
+      return this._byId[obj] || this._byId[obj.id] || this._byId[obj.cid];
+    },
+
+    // Get the model at the given index.
+    at: function(index) {
+      return this.models[index];
+    },
+
+    // Return models with matching attributes. Useful for simple cases of
+    // `filter`.
+    where: function(attrs, first) {
+      if (_.isEmpty(attrs)) return first ? void 0 : [];
+      return this[first ? 'find' : 'filter'](function(model) {
+        for (var key in attrs) {
+          if (attrs[key] !== model.get(key)) return false;
+        }
+        return true;
+      });
+    },
+
+    // Return the first model with matching attributes. Useful for simple cases
+    // of `find`.
+    findWhere: function(attrs) {
+      return this.where(attrs, true);
+    },
+
+    // Force the collection to re-sort itself. You don't need to call this under
+    // normal circumstances, as the set will maintain sort order as each item
+    // is added.
+    sort: function(options) {
+      if (!this.comparator) throw new Error('Cannot sort a set without a comparator');
+      options || (options = {});
+
+      // Run sort based on type of `comparator`.
+      if (_.isString(this.comparator) || this.comparator.length === 1) {
+        this.models = this.sortBy(this.comparator, this);
+      } else {
+        this.models.sort(_.bind(this.comparator, this));
+      }
+
+      if (!options.silent) this.trigger('sort', this, options);
+      return this;
+    },
+
+    // Pluck an attribute from each model in the collection.
+    pluck: function(attr) {
+      return _.invoke(this.models, 'get', attr);
+    },
+
+    // Fetch the default set of models for this collection, resetting the
+    // collection when they arrive. If `reset: true` is passed, the response
+    // data will be passed through the `reset` method instead of `set`.
+    fetch: function(options) {
+      options = options ? _.clone(options) : {};
+      if (options.parse === void 0) options.parse = true;
+      var success = options.success;
+      var collection = this;
+      options.success = function(resp) {
+        var method = options.reset ? 'reset' : 'set';
+        collection[method](resp, options);
+        if (success) success(collection, resp, options);
+        collection.trigger('sync', collection, resp, options);
+      };
+      wrapError(this, options);
+      return this.sync('read', this, options);
+    },
+
+    // Create a new instance of a model in this collection. Add the model to the
+    // collection immediately, unless `wait: true` is passed, in which case we
+    // wait for the server to agree.
+    create: function(model, options) {
+      options = options ? _.clone(options) : {};
+      if (!(model = this._prepareModel(model, options))) return false;
+      if (!options.wait) this.add(model, options);
+      var collection = this;
+      var success = options.success;
+      options.success = function(model, resp) {
+        if (options.wait) collection.add(model, options);
+        if (success) success(model, resp, options);
+      };
+      model.save(null, options);
+      return model;
+    },
+
+    // **parse** converts a response into a list of models to be added to the
+    // collection. The default implementation is just to pass it through.
+    parse: function(resp, options) {
+      return resp;
+    },
+
+    // Create a new collection with an identical list of models as this one.
+    clone: function() {
+      return new this.constructor(this.models);
+    },
+
+    // Private method to reset all internal state. Called when the collection
+    // is first initialized or reset.
+    _reset: function() {
+      this.length = 0;
+      this.models = [];
+      this._byId  = {};
+    },
+
+    // Prepare a hash of attributes (or other model) to be added to this
+    // collection.
+    _prepareModel: function(attrs, options) {
+      if (attrs instanceof Model) return attrs;
+      options = options ? _.clone(options) : {};
+      options.collection = this;
+      var model = new this.model(attrs, options);
+      if (!model.validationError) return model;
+      this.trigger('invalid', this, model.validationError, options);
+      return false;
+    },
+
+    // Internal method to create a model's ties to a collection.
+    _addReference: function(model, options) {
+      this._byId[model.cid] = model;
+      if (model.id != null) this._byId[model.id] = model;
+      if (!model.collection) model.collection = this;
+      model.on('all', this._onModelEvent, this);
+    },
+
+    // Internal method to sever a model's ties to a collection.
+    _removeReference: function(model, options) {
+      if (this === model.collection) delete model.collection;
+      model.off('all', this._onModelEvent, this);
+    },
+
+    // Internal method called every time a model in the set fires an event.
+    // Sets need to update their indexes when models change ids. All other
+    // events simply proxy through. "add" and "remove" events that originate
+    // in other collections are ignored.
+    _onModelEvent: function(event, model, collection, options) {
+      if ((event === 'add' || event === 'remove') && collection !== this) return;
+      if (event === 'destroy') this.remove(model, options);
+      if (model && event === 'change:' + model.idAttribute) {
+        delete this._byId[model.previous(model.idAttribute)];
+        if (model.id != null) this._byId[model.id] = model;
+      }
+      this.trigger.apply(this, arguments);
+    }
+
+  });
+
+  // Underscore methods that we want to implement on the Collection.
+  // 90% of the core usefulness of Backbone Collections is actually implemented
+  // right here:
+  var methods = ['forEach', 'each', 'map', 'collect', 'reduce', 'foldl',
+    'inject', 'reduceRight', 'foldr', 'find', 'detect', 'filter', 'select',
+    'reject', 'every', 'all', 'some', 'any', 'include', 'contains', 'invoke',
+    'max', 'min', 'toArray', 'size', 'first', 'head', 'take', 'initial', 'rest',
+    'tail', 'drop', 'last', 'without', 'difference', 'indexOf', 'shuffle',
+    'lastIndexOf', 'isEmpty', 'chain', 'sample'];
+
+  // Mix in each Underscore method as a proxy to `Collection#models`.
+  _.each(methods, function(method) {
+    Collection.prototype[method] = function() {
+      var args = slice.call(arguments);
+      args.unshift(this.models);
+      return _[method].apply(_, args);
+    };
+  });
+
+  // Underscore methods that take a property name as an argument.
+  var attributeMethods = ['groupBy', 'countBy', 'sortBy', 'indexBy'];
+
+  // Use attributes instead of properties.
+  _.each(attributeMethods, function(method) {
+    Collection.prototype[method] = function(value, context) {
+      var iterator = _.isFunction(value) ? value : function(model) {
+        return model.get(value);
+      };
+      return _[method](this.models, iterator, context);
+    };
+  });
+
+  // Backbone.View
+  // -------------
+
+  // Backbone Views are almost more convention than they are actual code. A View
+  // is simply a JavaScript object that represents a logical chunk of UI in the
+  // DOM. This might be a single item, an entire list, a sidebar or panel, or
+  // even the surrounding frame which wraps your whole app. Defining a chunk of
+  // UI as a **View** allows you to define your DOM events declaratively, without
+  // having to worry about render order ... and makes it easy for the view to
+  // react to specific changes in the state of your models.
+
+  // Creating a Backbone.View creates its initial element outside of the DOM,
+  // if an existing element is not provided...
+  var View = Backbone.View = function(options) {
+    this.cid = _.uniqueId('view');
+    options || (options = {});
+    _.extend(this, _.pick(options, viewOptions));
+    this._ensureElement();
+    this.initialize.apply(this, arguments);
+    this.delegateEvents();
+  };
+
+  // Cached regex to split keys for `delegate`.
+  var delegateEventSplitter = /^(\S+)\s*(.*)$/;
+
+  // List of view options to be merged as properties.
+  var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events'];
+
+  // Set up all inheritable **Backbone.View** properties and methods.
+  _.extend(View.prototype, Events, {
+
+    // The default `tagName` of a View's element is `"div"`.
+    tagName: 'div',
+
+    // jQuery delegate for element lookup, scoped to DOM elements within the
+    // current view. This should be preferred to global lookups where possible.
+    $: function(selector) {
+      return this.$el.find(selector);
+    },
+
+    // Initialize is an empty function by default. Override it with your own
+    // initialization logic.
+    initialize: function(){},
+
+    // **render** is the core function that your view should override, in order
+    // to populate its element (`this.el`), with the appropriate HTML. The
+    // convention is for **render** to always return `this`.
+    render: function() {
+      return this;
+    },
+
+    // Remove this view by taking the element out of the DOM, and removing any
+    // applicable Backbone.Events listeners.
+    remove: function() {
+      this.$el.remove();
+      this.stopListening();
+      return this;
+    },
+
+    // Change the view's element (`this.el` property), including event
+    // re-delegation.
+    setElement: function(element, delegate) {
+      if (this.$el) this.undelegateEvents();
+      this.$el = element instanceof Backbone.$ ? element : Backbone.$(element);
+      this.el = this.$el[0];
+      if (delegate !== false) this.delegateEvents();
+      return this;
+    },
+
+    // Set callbacks, where `this.events` is a hash of
+    //
+    // *{"event selector": "callback"}*
+    //
+    //     {
+    //       'mousedown .title':  'edit',
+    //       'click .button':     'save',
+    //       'click .open':       function(e) { ... }
+    //     }
+    //
+    // pairs. Callbacks will be bound to the view, with `this` set properly.
+    // Uses event delegation for efficiency.
+    // Omitting the selector binds the event to `this.el`.
+    // This only works for delegate-able events: not `focus`, `blur`, and
+    // not `change`, `submit`, and `reset` in Internet Explorer.
+    delegateEvents: function(events) {
+      if (!(events || (events = _.result(this, 'events')))) return this;
+      this.undelegateEvents();
+      for (var key in events) {
+        var method = events[key];
+        if (!_.isFunction(method)) method = this[events[key]];
+        if (!method) continue;
+
+        var match = key.match(delegateEventSplitter);
+        var eventName = match[1], selector = match[2];
+        method = _.bind(method, this);
+        eventName += '.delegateEvents' + this.cid;
+        if (selector === '') {
+          this.$el.on(eventName, method);
+        } else {
+          this.$el.on(eventName, selector, method);
+        }
+      }
+      return this;
+    },
+
+    // Clears all callbacks previously bound to the view with `delegateEvents`.
+    // You usually don't need to use this, but may wish to if you have multiple
+    // Backbone views attached to the same DOM element.
+    undelegateEvents: function() {
+      this.$el.off('.delegateEvents' + this.cid);
+      return this;
+    },
+
+    // Ensure that the View has a DOM element to render into.
+    // If `this.el` is a string, pass it through `$()`, take the first
+    // matching element, and re-assign it to `el`. Otherwise, create
+    // an element from the `id`, `className` and `tagName` properties.
+    _ensureElement: function() {
+      if (!this.el) {
+        var attrs = _.extend({}, _.result(this, 'attributes'));
+        if (this.id) attrs.id = _.result(this, 'id');
+        if (this.className) attrs['class'] = _.result(this, 'className');
+        var $el = Backbone.$('<' + _.result(this, 'tagName') + '>').attr(attrs);
+        this.setElement($el, false);
+      } else {
+        this.setElement(_.result(this, 'el'), false);
+      }
+    }
+
+  });
+
+  // Backbone.sync
+  // -------------
+
+  // Override this function to change the manner in which Backbone persists
+  // models to the server. You will be passed the type of request, and the
+  // model in question. By default, makes a RESTful Ajax request
+  // to the model's `url()`. Some possible customizations could be:
+  //
+  // * Use `setTimeout` to batch rapid-fire updates into a single request.
+  // * Send up the models as XML instead of JSON.
+  // * Persist models via WebSockets instead of Ajax.
+  //
+  // Turn on `Backbone.emulateHTTP` in order to send `PUT` and `DELETE` requests
+  // as `POST`, with a `_method` parameter containing the true HTTP method,
+  // as well as all requests with the body as `application/x-www-form-urlencoded`
+  // instead of `application/json` with the model in a param named `model`.
+  // Useful when interfacing with server-side languages like **PHP** that make
+  // it difficult to read the body of `PUT` requests.
+  Backbone.sync = function(method, model, options) {
+    var type = methodMap[method];
+
+    // Default options, unless specified.
+    _.defaults(options || (options = {}), {
+      emulateHTTP: Backbone.emulateHTTP,
+      emulateJSON: Backbone.emulateJSON
+    });
+
+    // Default JSON-request options.
+    var params = {type: type, dataType: 'json'};
+
+    // Ensure that we have a URL.
+    if (!options.url) {
+      params.url = _.result(model, 'url') || urlError();
+    }
+
+    // Ensure that we have the appropriate request data.
+    if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) {
+      params.contentType = 'application/json';
+      params.data = JSON.stringify(options.attrs || model.toJSON(options));
+    }
+
+    // For older servers, emulate JSON by encoding the request into an HTML-form.
+    if (options.emulateJSON) {
+      params.contentType = 'application/x-www-form-urlencoded';
+      params.data = params.data ? {model: params.data} : {};
+    }
+
+    // For older servers, emulate HTTP by mimicking the HTTP method with `_method`
+    // And an `X-HTTP-Method-Override` header.
+    if (options.emulateHTTP && (type === 'PUT' || type === 'DELETE' || type === 'PATCH')) {
+      params.type = 'POST';
+      if (options.emulateJSON) params.data._method = type;
+      var beforeSend = options.beforeSend;
+      options.beforeSend = function(xhr) {
+        xhr.setRequestHeader('X-HTTP-Method-Override', type);
+        if (beforeSend) return beforeSend.apply(this, arguments);
+      };
+    }
+
+    // Don't process data on a non-GET request.
+    if (params.type !== 'GET' && !options.emulateJSON) {
+      params.processData = false;
+    }
+
+    // If we're sending a `PATCH` request, and we're in an old Internet Explorer
+    // that still has ActiveX enabled by default, override jQuery to use that
+    // for XHR instead. Remove this line when jQuery supports `PATCH` on IE8.
+    if (params.type === 'PATCH' && noXhrPatch) {
+      params.xhr = function() {
+        return new ActiveXObject("Microsoft.XMLHTTP");
+      };
+    }
+
+    // Make the request, allowing the user to override any Ajax options.
+    var xhr = options.xhr = Backbone.ajax(_.extend(params, options));
+    model.trigger('request', model, xhr, options);
+    return xhr;
+  };
+
+  var noXhrPatch =
+    typeof window !== 'undefined' && !!window.ActiveXObject &&
+      !(window.XMLHttpRequest && (new XMLHttpRequest).dispatchEvent);
+
+  // Map from CRUD to HTTP for our default `Backbone.sync` implementation.
+  var methodMap = {
+    'create': 'POST',
+    'update': 'PUT',
+    'patch':  'PATCH',
+    'delete': 'DELETE',
+    'read':   'GET'
+  };
+
+  // Set the default implementation of `Backbone.ajax` to proxy through to `$`.
+  // Override this if you'd like to use a different library.
+  Backbone.ajax = function() {
+    return Backbone.$.ajax.apply(Backbone.$, arguments);
+  };
+
+  // Backbone.Router
+  // ---------------
+
+  // Routers map faux-URLs to actions, and fire events when routes are
+  // matched. Creating a new one sets its `routes` hash, if not set statically.
+  var Router = Backbone.Router = function(options) {
+    options || (options = {});
+    if (options.routes) this.routes = options.routes;
+    this._bindRoutes();
+    this.initialize.apply(this, arguments);
+  };
+
+  // Cached regular expressions for matching named param parts and splatted
+  // parts of route strings.
+  var optionalParam = /\((.*?)\)/g;
+  var namedParam    = /(\(\?)?:\w+/g;
+  var splatParam    = /\*\w+/g;
+  var escapeRegExp  = /[\-{}\[\]+?.,\\\^$|#\s]/g;
+
+  // Set up all inheritable **Backbone.Router** properties and methods.
+  _.extend(Router.prototype, Events, {
+
+    // Initialize is an empty function by default. Override it with your own
+    // initialization logic.
+    initialize: function(){},
+
+    // Manually bind a single named route to a callback. For example:
+    //
+    //     this.route('search/:query/p:num', 'search', function(query, num) {
+    //       ...
+    //     });
+    //
+    route: function(route, name, callback) {
+      if (!_.isRegExp(route)) route = this._routeToRegExp(route);
+      if (_.isFunction(name)) {
+        callback = name;
+        name = '';
+      }
+      if (!callback) callback = this[name];
+      var router = this;
+      Backbone.history.route(route, function(fragment) {
+        var args = router._extractParameters(route, fragment);
+        router.execute(callback, args);
+        router.trigger.apply(router, ['route:' + name].concat(args));
+        router.trigger('route', name, args);
+        Backbone.history.trigger('route', router, name, args);
+      });
+      return this;
+    },
+
+    // Execute a route handler with the provided parameters.  This is an
+    // excellent place to do pre-route setup or post-route cleanup.
+    execute: function(callback, args) {
+      if (callback) callback.apply(this, args);
+    },
+
+    // Simple proxy to `Backbone.history` to save a fragment into the history.
+    navigate: function(fragment, options) {
+      Backbone.history.navigate(fragment, options);
+      return this;
+    },
+
+    // Bind all defined routes to `Backbone.history`. We have to reverse the
+    // order of the routes here to support behavior where the most general
+    // routes can be defined at the bottom of the route map.
+    _bindRoutes: function() {
+      if (!this.routes) return;
+      this.routes = _.result(this, 'routes');
+      var route, routes = _.keys(this.routes);
+      while ((route = routes.pop()) != null) {
+        this.route(route, this.routes[route]);
+      }
+    },
+
+    // Convert a route string into a regular expression, suitable for matching
+    // against the current location hash.
+    _routeToRegExp: function(route) {
+      route = route.replace(escapeRegExp, '\\$&')
+                   .replace(optionalParam, '(?:$1)?')
+                   .replace(namedParam, function(match, optional) {
+                     return optional ? match : '([^/?]+)';
+                   })
+                   .replace(splatParam, '([^?]*?)');
+      return new RegExp('^' + route + '(?:\\?([\\s\\S]*))?$');
+    },
+
+    // Given a route, and a URL fragment that it matches, return the array of
+    // extracted decoded parameters. Empty or unmatched parameters will be
+    // treated as `null` to normalize cross-browser behavior.
+    _extractParameters: function(route, fragment) {
+      var params = route.exec(fragment).slice(1);
+      return _.map(params, function(param, i) {
+        // Don't decode the search params.
+        if (i === params.length - 1) return param || null;
+        return param ? decodeURIComponent(param) : null;
+      });
+    }
+
+  });
+
+  // Backbone.History
+  // ----------------
+
+  // Handles cross-browser history management, based on either
+  // [pushState](http://diveintohtml5.info/history.html) and real URLs, or
+  // [onhashchange](https://developer.mozilla.org/en-US/docs/DOM/window.onhashchange)
+  // and URL fragments. If the browser supports neither (old IE, natch),
+  // falls back to polling.
+  var History = Backbone.History = function() {
+    this.handlers = [];
+    _.bindAll(this, 'checkUrl');
+
+    // Ensure that `History` can be used outside of the browser.
+    if (typeof window !== 'undefined') {
+      this.location = window.location;
+      this.history = window.history;
+    }
+  };
+
+  // Cached regex for stripping a leading hash/slash and trailing space.
+  var routeStripper = /^[#\/]|\s+$/g;
+
+  // Cached regex for stripping leading and trailing slashes.
+  var rootStripper = /^\/+|\/+$/g;
+
+  // Cached regex for detecting MSIE.
+  var isExplorer = /msie [\w.]+/;
+
+  // Cached regex for removing a trailing slash.
+  var trailingSlash = /\/$/;
+
+  // Cached regex for stripping urls of hash.
+  var pathStripper = /#.*$/;
+
+  // Has the history handling already been started?
+  History.started = false;
+
+  // Set up all inheritable **Backbone.History** properties and methods.
+  _.extend(History.prototype, Events, {
+
+    // The default interval to poll for hash changes, if necessary, is
+    // twenty times a second.
+    interval: 50,
+
+    // Are we at the app root?
+    atRoot: function() {
+      return this.location.pathname.replace(/[^\/]$/, '$&/') === this.root;
+    },
+
+    // Gets the true hash value. Cannot use location.hash directly due to bug
+    // in Firefox where location.hash will always be decoded.
+    getHash: function(window) {
+      var match = (window || this).location.href.match(/#(.*)$/);
+      return match ? match[1] : '';
+    },
+
+    // Get the cross-browser normalized URL fragment, either from the URL,
+    // the hash, or the override.
+    getFragment: function(fragment, forcePushState) {
+      if (fragment == null) {
+        if (this._hasPushState || !this._wantsHashChange || forcePushState) {
+          fragment = decodeURI(this.location.pathname + this.location.search);
+          var root = this.root.replace(trailingSlash, '');
+          if (!fragment.indexOf(root)) fragment = fragment.slice(root.length);
+        } else {
+          fragment = this.getHash();
+        }
+      }
+      return fragment.replace(routeStripper, '');
+    },
+
+    // Start the hash change handling, returning `true` if the current URL matches
+    // an existing route, and `false` otherwise.
+    start: function(options) {
+      if (History.started) throw new Error("Backbone.history has already been started");
+      History.started = true;
+
+      // Figure out the initial configuration. Do we need an iframe?
+      // Is pushState desired ... is it available?
+      this.options          = _.extend({root: '/'}, this.options, options);
+      this.root             = this.options.root;
+      this._wantsHashChange = this.options.hashChange !== false;
+      this._wantsPushState  = !!this.options.pushState;
+      this._hasPushState    = !!(this.options.pushState && this.history && this.history.pushState);
+      var fragment          = this.getFragment();
+      var docMode           = document.documentMode;
+      var oldIE             = (isExplorer.exec(navigator.userAgent.toLowerCase()) && (!docMode || docMode <= 7));
+
+      // Normalize root to always include a leading and trailing slash.
+      this.root = ('/' + this.root + '/').replace(rootStripper, '/');
+
+      if (oldIE && this._wantsHashChange) {
+        var frame = Backbone.$('<iframe src="javascript:0" tabindex="-1">');
+        this.iframe = frame.hide().appendTo('body')[0].contentWindow;
+        this.navigate(fragment);
+      }
+
+      // Depending on whether we're using pushState or hashes, and whether
+      // 'onhashchange' is supported, determine how we check the URL state.
+      if (this._hasPushState) {
+        Backbone.$(window).on('popstate', this.checkUrl);
+      } else if (this._wantsHashChange && ('onhashchange' in window) && !oldIE) {
+        Backbone.$(window).on('hashchange', this.checkUrl);
+      } else if (this._wantsHashChange) {
+        this._checkUrlInterval = setInterval(this.checkUrl, this.interval);
+      }
+
+      // Determine if we need to change the base url, for a pushState link
+      // opened by a non-pushState browser.
+      this.fragment = fragment;
+      var loc = this.location;
+
+      // Transition from hashChange to pushState or vice versa if both are
+      // requested.
+      if (this._wantsHashChange && this._wantsPushState) {
+
+        // If we've started off with a route from a `pushState`-enabled
+        // browser, but we're currently in a browser that doesn't support it...
+        if (!this._hasPushState && !this.atRoot()) {
+          this.fragment = this.getFragment(null, true);
+          this.location.replace(this.root + '#' + this.fragment);
+          // Return immediately as browser will do redirect to new url
+          return true;
+
+        // Or if we've started out with a hash-based route, but we're currently
+        // in a browser where it could be `pushState`-based instead...
+        } else if (this._hasPushState && this.atRoot() && loc.hash) {
+          this.fragment = this.getHash().replace(routeStripper, '');
+          this.history.replaceState({}, document.title, this.root + this.fragment);
+        }
+
+      }
+
+      if (!this.options.silent) return this.loadUrl();
+    },
+
+    // Disable Backbone.history, perhaps temporarily. Not useful in a real app,
+    // but possibly useful for unit testing Routers.
+    stop: function() {
+      Backbone.$(window).off('popstate', this.checkUrl).off('hashchange', this.checkUrl);
+      if (this._checkUrlInterval) clearInterval(this._checkUrlInterval);
+      History.started = false;
+    },
+
+    // Add a route to be tested when the fragment changes. Routes added later
+    // may override previous routes.
+    route: function(route, callback) {
+      this.handlers.unshift({route: route, callback: callback});
+    },
+
+    // Checks the current URL to see if it has changed, and if it has,
+    // calls `loadUrl`, normalizing across the hidden iframe.
+    checkUrl: function(e) {
+      var current = this.getFragment();
+      if (current === this.fragment && this.iframe) {
+        current = this.getFragment(this.getHash(this.iframe));
+      }
+      if (current === this.fragment) return false;
+      if (this.iframe) this.navigate(current);
+      this.loadUrl();
+    },
+
+    // Attempt to load the current URL fragment. If a route succeeds with a
+    // match, returns `true`. If no defined routes matches the fragment,
+    // returns `false`.
+    loadUrl: function(fragment) {
+      fragment = this.fragment = this.getFragment(fragment);
+      return _.any(this.handlers, function(handler) {
+        if (handler.route.test(fragment)) {
+          handler.callback(fragment);
+          return true;
+        }
+      });
+    },
+
+    // Save a fragment into the hash history, or replace the URL state if the
+    // 'replace' option is passed. You are responsible for properly URL-encoding
+    // the fragment in advance.
+    //
+    // The options object can contain `trigger: true` if you wish to have the
+    // route callback be fired (not usually desirable), or `replace: true`, if
+    // you wish to modify the current URL without adding an entry to the history.
+    navigate: function(fragment, options) {
+      if (!History.started) return false;
+      if (!options || options === true) options = {trigger: !!options};
+
+      var url = this.root + (fragment = this.getFragment(fragment || ''));
+
+      // Strip the hash for matching.
+      fragment = fragment.replace(pathStripper, '');
+
+      if (this.fragment === fragment) return;
+      this.fragment = fragment;
+
+      // Don't include a trailing slash on the root.
+      if (fragment === '' && url !== '/') url = url.slice(0, -1);
+
+      // If pushState is available, we use it to set the fragment as a real URL.
+      if (this._hasPushState) {
+        this.history[options.replace ? 'replaceState' : 'pushState']({}, document.title, url);
+
+      // If hash changes haven't been explicitly disabled, update the hash
+      // fragment to store history.
+      } else if (this._wantsHashChange) {
+        this._updateHash(this.location, fragment, options.replace);
+        if (this.iframe && (fragment !== this.getFragment(this.getHash(this.iframe)))) {
+          // Opening and closing the iframe tricks IE7 and earlier to push a
+          // history entry on hash-tag change.  When replace is true, we don't
+          // want this.
+          if(!options.replace) this.iframe.document.open().close();
+          this._updateHash(this.iframe.location, fragment, options.replace);
+        }
+
+      // If you've told us that you explicitly don't want fallback hashchange-
+      // based history, then `navigate` becomes a page refresh.
+      } else {
+        return this.location.assign(url);
+      }
+      if (options.trigger) return this.loadUrl(fragment);
+    },
+
+    // Update the hash location, either replacing the current entry, or adding
+    // a new one to the browser history.
+    _updateHash: function(location, fragment, replace) {
+      if (replace) {
+        var href = location.href.replace(/(javascript:|#).*$/, '');
+        location.replace(href + '#' + fragment);
+      } else {
+        // Some browsers require that `hash` contains a leading #.
+        location.hash = '#' + fragment;
+      }
+    }
+
+  });
+
+  // Create the default Backbone.history.
+  Backbone.history = new History;
+
+  // Helpers
+  // -------
+
+  // Helper function to correctly set up the prototype chain, for subclasses.
+  // Similar to `goog.inherits`, but uses a hash of prototype properties and
+  // class properties to be extended.
+  var extend = function(protoProps, staticProps) {
+    var parent = this;
+    var child;
+
+    // The constructor function for the new subclass is either defined by you
+    // (the "constructor" property in your `extend` definition), or defaulted
+    // by us to simply call the parent's constructor.
+    if (protoProps && _.has(protoProps, 'constructor')) {
+      child = protoProps.constructor;
+    } else {
+      child = function(){ return parent.apply(this, arguments); };
+    }
+
+    // Add static properties to the constructor function, if supplied.
+    _.extend(child, parent, staticProps);
+
+    // Set the prototype chain to inherit from `parent`, without calling
+    // `parent`'s constructor function.
+    var Surrogate = function(){ this.constructor = child; };
+    Surrogate.prototype = parent.prototype;
+    child.prototype = new Surrogate;
+
+    // Add prototype properties (instance properties) to the subclass,
+    // if supplied.
+    if (protoProps) _.extend(child.prototype, protoProps);
+
+    // Set a convenience property in case the parent's prototype is needed
+    // later.
+    child.__super__ = parent.prototype;
+
+    return child;
+  };
+
+  // Set up inheritance for the model, collection, router, view and history.
+  Model.extend = Collection.extend = Router.extend = View.extend = History.extend = extend;
+
+  // Throw an error when a URL is needed, and none is supplied.
+  var urlError = function() {
+    throw new Error('A "url" property or function must be specified');
+  };
+
+  // Wrap an optional error callback with a fallback error event.
+  var wrapError = function(model, options) {
+    var error = options.error;
+    options.error = function(resp) {
+      if (error) error(model, resp, options);
+      model.trigger('error', model, resp, options);
+    };
+  };
+
+  return Backbone;
+
+}));
diff --git a/planetstack/core/xoslib/static/js/vendor/backbone.marionette.js b/planetstack/core/xoslib/static/js/vendor/backbone.marionette.js
new file mode 100644
index 0000000..cebd22b
--- /dev/null
+++ b/planetstack/core/xoslib/static/js/vendor/backbone.marionette.js
@@ -0,0 +1,2793 @@
+// MarionetteJS (Backbone.Marionette)
+// ----------------------------------
+// v2.0.1
+//
+// Copyright (c)2014 Derick Bailey, Muted Solutions, LLC.
+// Distributed under MIT license
+//
+// http://marionettejs.com
+
+(function(root, factory) {
+
+  if (typeof define === 'function' && define.amd) {
+    define(['backbone', 'underscore', 'backbone.wreqr', 'backbone.babysitter'], function(Backbone, _) {
+      return (root.Marionette = factory(root, Backbone, _));
+    });
+  } else if (typeof exports !== 'undefined') {
+    var Backbone = require('backbone');
+    var _ = require('underscore');
+    var Wreqr = require('backbone.wreqr');
+    var BabySitter = require('backbone.babysitter');
+    module.exports = factory(root, Backbone, _);
+  } else {
+    root.Marionette = factory(root, root.Backbone, root._);
+  }
+
+}(this, function(root, Backbone, _) {
+  'use strict';
+
+  var previousMarionette = root.Marionette;
+
+  var Marionette = Backbone.Marionette = {};
+
+  Marionette.VERSION = '2.0.1';
+
+  Marionette.noConflict = function() {
+    root.Marionette = previousMarionette;
+    return this;
+  };
+
+  // Get the Deferred creator for later use
+  Marionette.Deferred = Backbone.$.Deferred;
+
+  /* jshint unused: false */
+  
+  // Helpers
+  // -------
+  
+  // For slicing `arguments` in functions
+  var slice = Array.prototype.slice;
+  
+  function throwError(message, name) {
+    var error = new Error(message);
+    error.name = name || 'Error';
+    throw error;
+  }
+  
+  // Marionette.extend
+  // -----------------
+  
+  // Borrow the Backbone `extend` method so we can use it as needed
+  Marionette.extend = Backbone.Model.extend;
+  
+  // Marionette.getOption
+  // --------------------
+  
+  // Retrieve an object, function or other value from a target
+  // object or its `options`, with `options` taking precedence.
+  Marionette.getOption = function(target, optionName) {
+    if (!target || !optionName) { return; }
+    var value;
+  
+    if (target.options && (target.options[optionName] !== undefined)) {
+      value = target.options[optionName];
+    } else {
+      value = target[optionName];
+    }
+  
+    return value;
+  };
+  
+  // Proxy `Marionette.getOption`
+  Marionette.proxyGetOption = function(optionName) {
+    return Marionette.getOption(this, optionName);
+  };
+  
+  // Marionette.normalizeMethods
+  // ----------------------
+  
+  // Pass in a mapping of events => functions or function names
+  // and return a mapping of events => functions
+  Marionette.normalizeMethods = function(hash) {
+    var normalizedHash = {}, method;
+    _.each(hash, function(fn, name) {
+      method = fn;
+      if (!_.isFunction(method)) {
+        method = this[method];
+      }
+      if (!method) {
+        return;
+      }
+      normalizedHash[name] = method;
+    }, this);
+    return normalizedHash;
+  };
+  
+  
+  // allows for the use of the @ui. syntax within
+  // a given key for triggers and events
+  // swaps the @ui with the associated selector
+  Marionette.normalizeUIKeys = function(hash, ui) {
+    if (typeof(hash) === 'undefined') {
+      return;
+    }
+  
+    _.each(_.keys(hash), function(v) {
+      var pattern = /@ui.[a-zA-Z_$0-9]*/g;
+      if (v.match(pattern)) {
+        hash[v.replace(pattern, function(r) {
+          return ui[r.slice(4)];
+        })] = hash[v];
+        delete hash[v];
+      }
+    });
+  
+    return hash;
+  };
+  
+  // Mix in methods from Underscore, for iteration, and other
+  // collection related features.
+  // Borrowing this code from Backbone.Collection:
+  // http://backbonejs.org/docs/backbone.html#section-106
+  Marionette.actAsCollection = function(object, listProperty) {
+    var methods = ['forEach', 'each', 'map', 'find', 'detect', 'filter',
+      'select', 'reject', 'every', 'all', 'some', 'any', 'include',
+      'contains', 'invoke', 'toArray', 'first', 'initial', 'rest',
+      'last', 'without', 'isEmpty', 'pluck'];
+  
+    _.each(methods, function(method) {
+      object[method] = function() {
+        var list = _.values(_.result(this, listProperty));
+        var args = [list].concat(_.toArray(arguments));
+        return _[method].apply(_, args);
+      };
+    });
+  };
+  
+  // Trigger an event and/or a corresponding method name. Examples:
+  //
+  // `this.triggerMethod("foo")` will trigger the "foo" event and
+  // call the "onFoo" method.
+  //
+  // `this.triggerMethod("foo:bar")` will trigger the "foo:bar" event and
+  // call the "onFooBar" method.
+  Marionette.triggerMethod = (function() {
+  
+    // split the event name on the ":"
+    var splitter = /(^|:)(\w)/gi;
+  
+    // take the event section ("section1:section2:section3")
+    // and turn it in to uppercase name
+    function getEventName(match, prefix, eventName) {
+      return eventName.toUpperCase();
+    }
+  
+    // actual triggerMethod implementation
+    var triggerMethod = function(event) {
+      // get the method name from the event name
+      var methodName = 'on' + event.replace(splitter, getEventName);
+      var method = this[methodName];
+      var result;
+  
+      // call the onMethodName if it exists
+      if (_.isFunction(method)) {
+        // pass all arguments, except the event name
+        result = method.apply(this, _.tail(arguments));
+      }
+  
+      // trigger the event, if a trigger method exists
+      if (_.isFunction(this.trigger)) {
+        this.trigger.apply(this, arguments);
+      }
+  
+      return result;
+    };
+  
+    return triggerMethod;
+  })();
+  
+  // DOMRefresh
+  // ----------
+  //
+  // Monitor a view's state, and after it has been rendered and shown
+  // in the DOM, trigger a "dom:refresh" event every time it is
+  // re-rendered.
+  
+  Marionette.MonitorDOMRefresh = (function(documentElement) {
+    // track when the view has been shown in the DOM,
+    // using a Marionette.Region (or by other means of triggering "show")
+    function handleShow(view) {
+      view._isShown = true;
+      triggerDOMRefresh(view);
+    }
+  
+    // track when the view has been rendered
+    function handleRender(view) {
+      view._isRendered = true;
+      triggerDOMRefresh(view);
+    }
+  
+    // Trigger the "dom:refresh" event and corresponding "onDomRefresh" method
+    function triggerDOMRefresh(view) {
+      if (view._isShown && view._isRendered && isInDOM(view)) {
+        if (_.isFunction(view.triggerMethod)) {
+          view.triggerMethod('dom:refresh');
+        }
+      }
+    }
+  
+    function isInDOM(view) {
+      return documentElement.contains(view.el);
+    }
+  
+    // Export public API
+    return function(view) {
+      view.listenTo(view, 'show', function() {
+        handleShow(view);
+      });
+  
+      view.listenTo(view, 'render', function() {
+        handleRender(view);
+      });
+    };
+  })(document.documentElement);
+  
+
+  /* jshint maxparams: 5 */
+  
+  // Marionette.bindEntityEvents & unbindEntityEvents
+  // ---------------------------
+  //
+  // These methods are used to bind/unbind a backbone "entity" (collection/model)
+  // to methods on a target object.
+  //
+  // The first parameter, `target`, must have a `listenTo` method from the
+  // EventBinder object.
+  //
+  // The second parameter is the entity (Backbone.Model or Backbone.Collection)
+  // to bind the events from.
+  //
+  // The third parameter is a hash of { "event:name": "eventHandler" }
+  // configuration. Multiple handlers can be separated by a space. A
+  // function can be supplied instead of a string handler name.
+  
+  (function(Marionette) {
+    'use strict';
+  
+    // Bind the event to handlers specified as a string of
+    // handler names on the target object
+    function bindFromStrings(target, entity, evt, methods) {
+      var methodNames = methods.split(/\s+/);
+  
+      _.each(methodNames, function(methodName) {
+  
+        var method = target[methodName];
+        if (!method) {
+          throwError('Method "' + methodName +
+            '" was configured as an event handler, but does not exist.');
+        }
+  
+        target.listenTo(entity, evt, method);
+      });
+    }
+  
+    // Bind the event to a supplied callback function
+    function bindToFunction(target, entity, evt, method) {
+      target.listenTo(entity, evt, method);
+    }
+  
+    // Bind the event to handlers specified as a string of
+    // handler names on the target object
+    function unbindFromStrings(target, entity, evt, methods) {
+      var methodNames = methods.split(/\s+/);
+  
+      _.each(methodNames, function(methodName) {
+        var method = target[methodName];
+        target.stopListening(entity, evt, method);
+      });
+    }
+  
+    // Bind the event to a supplied callback function
+    function unbindToFunction(target, entity, evt, method) {
+      target.stopListening(entity, evt, method);
+    }
+  
+  
+    // generic looping function
+    function iterateEvents(target, entity, bindings, functionCallback, stringCallback) {
+      if (!entity || !bindings) { return; }
+  
+      // allow the bindings to be a function
+      if (_.isFunction(bindings)) {
+        bindings = bindings.call(target);
+      }
+  
+      // iterate the bindings and bind them
+      _.each(bindings, function(methods, evt) {
+  
+        // allow for a function as the handler,
+        // or a list of event names as a string
+        if (_.isFunction(methods)) {
+          functionCallback(target, entity, evt, methods);
+        } else {
+          stringCallback(target, entity, evt, methods);
+        }
+  
+      });
+    }
+  
+    // Export Public API
+    Marionette.bindEntityEvents = function(target, entity, bindings) {
+      iterateEvents(target, entity, bindings, bindToFunction, bindFromStrings);
+    };
+  
+    Marionette.unbindEntityEvents = function(target, entity, bindings) {
+      iterateEvents(target, entity, bindings, unbindToFunction, unbindFromStrings);
+    };
+  
+    // Proxy `bindEntityEvents`
+    Marionette.proxyBindEntityEvents = function(entity, bindings) {
+      return Marionette.bindEntityEvents(this, entity, bindings);
+    };
+  
+    // Proxy `unbindEntityEvents`
+    Marionette.proxyUnbindEntityEvents = function(entity, bindings) {
+      return Marionette.unbindEntityEvents(this, entity, bindings);
+    };
+  })(Marionette);
+  
+
+  // Callbacks
+  // ---------
+  
+  // A simple way of managing a collection of callbacks
+  // and executing them at a later point in time, using jQuery's
+  // `Deferred` object.
+  Marionette.Callbacks = function() {
+    this._deferred = Marionette.Deferred();
+    this._callbacks = [];
+  };
+  
+  _.extend(Marionette.Callbacks.prototype, {
+  
+    // Add a callback to be executed. Callbacks added here are
+    // guaranteed to execute, even if they are added after the
+    // `run` method is called.
+    add: function(callback, contextOverride) {
+      var promise = _.result(this._deferred, 'promise');
+  
+      this._callbacks.push({cb: callback, ctx: contextOverride});
+  
+      promise.then(function(args) {
+        if (contextOverride){ args.context = contextOverride; }
+        callback.call(args.context, args.options);
+      });
+    },
+  
+    // Run all registered callbacks with the context specified.
+    // Additional callbacks can be added after this has been run
+    // and they will still be executed.
+    run: function(options, context) {
+      this._deferred.resolve({
+        options: options,
+        context: context
+      });
+    },
+  
+    // Resets the list of callbacks to be run, allowing the same list
+    // to be run multiple times - whenever the `run` method is called.
+    reset: function() {
+      var callbacks = this._callbacks;
+      this._deferred = Marionette.Deferred();
+      this._callbacks = [];
+  
+      _.each(callbacks, function(cb) {
+        this.add(cb.cb, cb.ctx);
+      }, this);
+    }
+  });
+  
+  // Marionette Controller
+  // ---------------------
+  //
+  // A multi-purpose object to use as a controller for
+  // modules and routers, and as a mediator for workflow
+  // and coordination of other objects, views, and more.
+  Marionette.Controller = function(options) {
+    this.triggerMethod = Marionette.triggerMethod;
+    this.options = options || {};
+  
+    if (_.isFunction(this.initialize)) {
+      this.initialize(this.options);
+    }
+  };
+  
+  Marionette.Controller.extend = Marionette.extend;
+  
+  // Controller Methods
+  // --------------
+  
+  // Ensure it can trigger events with Backbone.Events
+  _.extend(Marionette.Controller.prototype, Backbone.Events, {
+    destroy: function() {
+      var args = Array.prototype.slice.call(arguments);
+      this.triggerMethod.apply(this, ['before:destroy'].concat(args));
+      this.triggerMethod.apply(this, ['destroy'].concat(args));
+  
+      this.stopListening();
+      this.off();
+    },
+  
+    // import the `triggerMethod` to trigger events with corresponding
+    // methods if the method exists
+    triggerMethod: Marionette.triggerMethod,
+  
+    // Proxy `getOption` to enable getting options from this or this.options by name.
+    getOption: Marionette.proxyGetOption
+  
+  });
+  
+  /* jshint maxcomplexity: 10, maxstatements: 27 */
+  
+  // Region
+  // ------
+  //
+  // Manage the visual regions of your composite application. See
+  // http://lostechies.com/derickbailey/2011/12/12/composite-js-apps-regions-and-region-managers/
+  
+  Marionette.Region = function(options) {
+    this.options = options || {};
+    this.el = this.getOption('el');
+  
+    // Handle when this.el is passed in as a $ wrapped element.
+    this.el = this.el instanceof Backbone.$ ? this.el[0] : this.el;
+  
+    if (!this.el) {
+      throwError('An "el" must be specified for a region.', 'NoElError');
+    }
+  
+    this.$el = this.getEl(this.el);
+  
+    if (this.initialize) {
+      var args = Array.prototype.slice.apply(arguments);
+      this.initialize.apply(this, args);
+    }
+  };
+  
+  
+  // Region Class methods
+  // -------------------
+  
+  _.extend(Marionette.Region, {
+  
+    // Build an instance of a region by passing in a configuration object
+    // and a default region class to use if none is specified in the config.
+    //
+    // The config object should either be a string as a jQuery DOM selector,
+    // a Region class directly, or an object literal that specifies both
+    // a selector and regionClass:
+    //
+    // ```js
+    // {
+    //   selector: "#foo",
+    //   regionClass: MyCustomRegion
+    // }
+    // ```
+    //
+    buildRegion: function(regionConfig, defaultRegionClass) {
+      var regionIsString = _.isString(regionConfig);
+      var regionSelectorIsString = _.isString(regionConfig.selector);
+      var regionClassIsUndefined = _.isUndefined(regionConfig.regionClass);
+      var regionIsClass = _.isFunction(regionConfig);
+  
+      if (!regionIsClass && !regionIsString && !regionSelectorIsString) {
+        throwError('Region must be specified as a Region class,' +
+          'a selector string or an object with selector property');
+      }
+  
+      var selector, RegionClass;
+  
+      // get the selector for the region
+  
+      if (regionIsString) {
+        selector = regionConfig;
+      }
+  
+      if (regionConfig.selector) {
+        selector = regionConfig.selector;
+        delete regionConfig.selector;
+      }
+  
+      // get the class for the region
+  
+      if (regionIsClass) {
+        RegionClass = regionConfig;
+      }
+  
+      if (!regionIsClass && regionClassIsUndefined) {
+        RegionClass = defaultRegionClass;
+      }
+  
+      if (regionConfig.regionClass) {
+        RegionClass = regionConfig.regionClass;
+        delete regionConfig.regionClass;
+      }
+  
+      if (regionIsString || regionIsClass) {
+        regionConfig = {};
+      }
+  
+      regionConfig.el = selector;
+  
+      // build the region instance
+      var region = new RegionClass(regionConfig);
+  
+      // override the `getEl` function if we have a parentEl
+      // this must be overridden to ensure the selector is found
+      // on the first use of the region. if we try to assign the
+      // region's `el` to `parentEl.find(selector)` in the object
+      // literal to build the region, the element will not be
+      // guaranteed to be in the DOM already, and will cause problems
+      if (regionConfig.parentEl) {
+        region.getEl = function(el) {
+          if (_.isObject(el)) {
+            return Backbone.$(el);
+          }
+          var parentEl = regionConfig.parentEl;
+          if (_.isFunction(parentEl)) {
+            parentEl = parentEl();
+          }
+          return parentEl.find(el);
+        };
+      }
+  
+      return region;
+    }
+  
+  });
+  
+  // Region Instance Methods
+  // -----------------------
+  
+  _.extend(Marionette.Region.prototype, Backbone.Events, {
+  
+    // Displays a backbone view instance inside of the region.
+    // Handles calling the `render` method for you. Reads content
+    // directly from the `el` attribute. Also calls an optional
+    // `onShow` and `onDestroy` method on your view, just after showing
+    // or just before destroying the view, respectively.
+    // The `preventDestroy` option can be used to prevent a view from
+    // the old view being destroyed on show.
+    // The `forceShow` option can be used to force a view to be
+    // re-rendered if it's already shown in the region.
+  
+    show: function(view, options){
+      this._ensureElement();
+  
+      var showOptions = options || {};
+      var isDifferentView = view !== this.currentView;
+      var preventDestroy =  !!showOptions.preventDestroy;
+      var forceShow = !!showOptions.forceShow;
+  
+      // we are only changing the view if there is a view to change to begin with
+      var isChangingView = !!this.currentView;
+  
+      // only destroy the view if we don't want to preventDestroy and the view is different
+      var _shouldDestroyView = !preventDestroy && isDifferentView;
+  
+      if (_shouldDestroyView) {
+        this.empty();
+      }
+  
+      // show the view if the view is different or if you want to re-show the view
+      var _shouldShowView = isDifferentView || forceShow;
+  
+      if (_shouldShowView) {
+        view.render();
+  
+        if (isChangingView) {
+          this.triggerMethod('before:swap', view);
+        }
+  
+        this.triggerMethod('before:show', view);
+        this.triggerMethod.call(view, 'before:show');
+  
+        this.attachHtml(view);
+        this.currentView = view;
+  
+        if (isChangingView) {
+          this.triggerMethod('swap', view);
+        }
+  
+        this.triggerMethod('show', view);
+  
+        if (_.isFunction(view.triggerMethod)) {
+          view.triggerMethod('show');
+        } else {
+          this.triggerMethod.call(view, 'show');
+        }
+  
+        return this;
+      }
+  
+      return this;
+    },
+  
+    _ensureElement: function(){
+      if (!_.isObject(this.el)) {
+        this.$el = this.getEl(this.el);
+        this.el = this.$el[0];
+      }
+  
+      if (!this.$el || this.$el.length === 0) {
+        throwError('An "el" ' + this.$el.selector + ' must exist in DOM');
+      }
+    },
+  
+    // Override this method to change how the region finds the
+    // DOM element that it manages. Return a jQuery selector object.
+    getEl: function(el) {
+      return Backbone.$(el);
+    },
+  
+    // Override this method to change how the new view is
+    // appended to the `$el` that the region is managing
+    attachHtml: function(view) {
+      // empty the node and append new view
+      this.el.innerHTML='';
+      this.el.appendChild(view.el);
+    },
+  
+    // Destroy the current view, if there is one. If there is no
+    // current view, it does nothing and returns immediately.
+    empty: function() {
+      var view = this.currentView;
+      if (!view || view.isDestroyed) { return; }
+  
+      this.triggerMethod('before:empty', view);
+  
+      // call 'destroy' or 'remove', depending on which is found
+      if (view.destroy) { view.destroy(); }
+      else if (view.remove) { view.remove(); }
+  
+      this.triggerMethod('empty', view);
+  
+      delete this.currentView;
+    },
+  
+    // Attach an existing view to the region. This
+    // will not call `render` or `onShow` for the new view,
+    // and will not replace the current HTML for the `el`
+    // of the region.
+    attachView: function(view) {
+      this.currentView = view;
+    },
+  
+    // Reset the region by destroying any existing view and
+    // clearing out the cached `$el`. The next time a view
+    // is shown via this region, the region will re-query the
+    // DOM for the region's `el`.
+    reset: function() {
+      this.empty();
+  
+      if (this.$el) {
+        this.el = this.$el.selector;
+      }
+  
+      delete this.$el;
+    },
+  
+    // Proxy `getOption` to enable getting options from this or this.options by name.
+    getOption: Marionette.proxyGetOption,
+  
+    // import the `triggerMethod` to trigger events with corresponding
+    // methods if the method exists
+    triggerMethod: Marionette.triggerMethod
+  });
+  
+  // Copy the `extend` function used by Backbone's classes
+  Marionette.Region.extend = Marionette.extend;
+  
+  // Marionette.RegionManager
+  // ------------------------
+  //
+  // Manage one or more related `Marionette.Region` objects.
+  Marionette.RegionManager = (function(Marionette) {
+  
+    var RegionManager = Marionette.Controller.extend({
+      constructor: function(options) {
+        this._regions = {};
+        Marionette.Controller.call(this, options);
+      },
+  
+      // Add multiple regions using an object literal, where
+      // each key becomes the region name, and each value is
+      // the region definition.
+      addRegions: function(regionDefinitions, defaults) {
+        var regions = {};
+  
+        _.each(regionDefinitions, function(definition, name) {
+          if (_.isString(definition)) {
+            definition = {selector: definition};
+          }
+  
+          if (definition.selector) {
+            definition = _.defaults({}, definition, defaults);
+          }
+  
+          var region = this.addRegion(name, definition);
+          regions[name] = region;
+        }, this);
+  
+        return regions;
+      },
+  
+      // Add an individual region to the region manager,
+      // and return the region instance
+      addRegion: function(name, definition) {
+        var region;
+  
+        var isObject = _.isObject(definition);
+        var isString = _.isString(definition);
+        var hasSelector = !!definition.selector;
+  
+        if (isString || (isObject && hasSelector)) {
+          region = Marionette.Region.buildRegion(definition, Marionette.Region);
+        } else if (_.isFunction(definition)) {
+          region = Marionette.Region.buildRegion(definition, Marionette.Region);
+        } else {
+          region = definition;
+        }
+  
+        this.triggerMethod('before:add:region', name, region);
+  
+        this._store(name, region);
+  
+        this.triggerMethod('add:region', name, region);
+        return region;
+      },
+  
+      // Get a region by name
+      get: function(name) {
+        return this._regions[name];
+      },
+  
+      // Gets all the regions contained within
+      // the `regionManager` instance.
+      getRegions: function(){
+        return _.clone(this._regions);
+      },
+  
+      // Remove a region by name
+      removeRegion: function(name) {
+        var region = this._regions[name];
+        this._remove(name, region);
+      },
+  
+      // Empty all regions in the region manager, and
+      // remove them
+      removeRegions: function() {
+        _.each(this._regions, function(region, name) {
+          this._remove(name, region);
+        }, this);
+      },
+  
+      // Empty all regions in the region manager, but
+      // leave them attached
+      emptyRegions: function() {
+        _.each(this._regions, function(region) {
+          region.empty();
+        }, this);
+      },
+  
+      // Destroy all regions and shut down the region
+      // manager entirely
+      destroy: function() {
+        this.removeRegions();
+        Marionette.Controller.prototype.destroy.apply(this, arguments);
+      },
+  
+      // internal method to store regions
+      _store: function(name, region) {
+        this._regions[name] = region;
+        this._setLength();
+      },
+  
+      // internal method to remove a region
+      _remove: function(name, region) {
+        this.triggerMethod('before:remove:region', name, region);
+        region.empty();
+        region.stopListening();
+        delete this._regions[name];
+        this._setLength();
+        this.triggerMethod('remove:region', name, region);
+      },
+  
+      // set the number of regions current held
+      _setLength: function() {
+        this.length = _.size(this._regions);
+      }
+  
+    });
+  
+    Marionette.actAsCollection(RegionManager.prototype, '_regions');
+  
+    return RegionManager;
+  })(Marionette);
+  
+
+  // Template Cache
+  // --------------
+  
+  // Manage templates stored in `<script>` blocks,
+  // caching them for faster access.
+  Marionette.TemplateCache = function(templateId) {
+    this.templateId = templateId;
+  };
+  
+  // TemplateCache object-level methods. Manage the template
+  // caches from these method calls instead of creating
+  // your own TemplateCache instances
+  _.extend(Marionette.TemplateCache, {
+    templateCaches: {},
+  
+    // Get the specified template by id. Either
+    // retrieves the cached version, or loads it
+    // from the DOM.
+    get: function(templateId) {
+      var cachedTemplate = this.templateCaches[templateId];
+  
+      if (!cachedTemplate) {
+        cachedTemplate = new Marionette.TemplateCache(templateId);
+        this.templateCaches[templateId] = cachedTemplate;
+      }
+  
+      return cachedTemplate.load();
+    },
+  
+    // Clear templates from the cache. If no arguments
+    // are specified, clears all templates:
+    // `clear()`
+    //
+    // If arguments are specified, clears each of the
+    // specified templates from the cache:
+    // `clear("#t1", "#t2", "...")`
+    clear: function() {
+      var i;
+      var args = slice.call(arguments);
+      var length = args.length;
+  
+      if (length > 0) {
+        for (i = 0; i < length; i++) {
+          delete this.templateCaches[args[i]];
+        }
+      } else {
+        this.templateCaches = {};
+      }
+    }
+  });
+  
+  // TemplateCache instance methods, allowing each
+  // template cache object to manage its own state
+  // and know whether or not it has been loaded
+  _.extend(Marionette.TemplateCache.prototype, {
+  
+    // Internal method to load the template
+    load: function() {
+      // Guard clause to prevent loading this template more than once
+      if (this.compiledTemplate) {
+        return this.compiledTemplate;
+      }
+  
+      // Load the template and compile it
+      var template = this.loadTemplate(this.templateId);
+      this.compiledTemplate = this.compileTemplate(template);
+  
+      return this.compiledTemplate;
+    },
+  
+    // Load a template from the DOM, by default. Override
+    // this method to provide your own template retrieval
+    // For asynchronous loading with AMD/RequireJS, consider
+    // using a template-loader plugin as described here:
+    // https://github.com/marionettejs/backbone.marionette/wiki/Using-marionette-with-requirejs
+    loadTemplate: function(templateId) {
+      var template = Backbone.$(templateId).html();
+  
+      if (!template || template.length === 0) {
+        throwError('Could not find template: "' + templateId + '"', 'NoTemplateError');
+      }
+  
+      return template;
+    },
+  
+    // Pre-compile the template before caching it. Override
+    // this method if you do not need to pre-compile a template
+    // (JST / RequireJS for example) or if you want to change
+    // the template engine used (Handebars, etc).
+    compileTemplate: function(rawTemplate) {
+      return _.template(rawTemplate);
+    }
+  });
+  
+  // Renderer
+  // --------
+  
+  // Render a template with data by passing in the template
+  // selector and the data to render.
+  Marionette.Renderer = {
+  
+    // Render a template with data. The `template` parameter is
+    // passed to the `TemplateCache` object to retrieve the
+    // template function. Override this method to provide your own
+    // custom rendering and template handling for all of Marionette.
+    render: function(template, data) {
+      if (!template) {
+        throwError('Cannot render the template since its false, null or undefined.',
+          'TemplateNotFoundError');
+      }
+  
+      var templateFunc;
+      if (typeof template === 'function') {
+        templateFunc = template;
+      } else {
+        templateFunc = Marionette.TemplateCache.get(template);
+      }
+  
+      return templateFunc(data);
+    }
+  };
+  
+
+  /* jshint maxlen: 114, nonew: false */
+  // Marionette.View
+  // ---------------
+  
+  // The core view class that other Marionette views extend from.
+  Marionette.View = Backbone.View.extend({
+  
+    constructor: function(options) {
+      _.bindAll(this, 'render');
+  
+      // this exposes view options to the view initializer
+      // this is a backfill since backbone removed the assignment
+      // of this.options
+      // at some point however this may be removed
+      this.options = _.extend({}, _.result(this, 'options'), _.isFunction(options) ? options.call(this) : options);
+      // parses out the @ui DSL for events
+      this.events = this.normalizeUIKeys(_.result(this, 'events'));
+  
+      if (_.isObject(this.behaviors)) {
+        new Marionette.Behaviors(this);
+      }
+  
+      Backbone.View.apply(this, arguments);
+  
+      Marionette.MonitorDOMRefresh(this);
+      this.listenTo(this, 'show', this.onShowCalled);
+    },
+  
+    // Get the template for this view
+    // instance. You can set a `template` attribute in the view
+    // definition or pass a `template: "whatever"` parameter in
+    // to the constructor options.
+    getTemplate: function() {
+      return this.getOption('template');
+    },
+  
+    // Mix in template helper methods. Looks for a
+    // `templateHelpers` attribute, which can either be an
+    // object literal, or a function that returns an object
+    // literal. All methods and attributes from this object
+    // are copies to the object passed in.
+    mixinTemplateHelpers: function(target) {
+      target = target || {};
+      var templateHelpers = this.getOption('templateHelpers');
+      if (_.isFunction(templateHelpers)) {
+        templateHelpers = templateHelpers.call(this);
+      }
+      return _.extend(target, templateHelpers);
+    },
+  
+  
+    normalizeUIKeys: function(hash) {
+      var ui = _.result(this, 'ui');
+      var uiBindings = _.result(this, '_uiBindings');
+      return Marionette.normalizeUIKeys(hash, uiBindings || ui);
+    },
+  
+    // Configure `triggers` to forward DOM events to view
+    // events. `triggers: {"click .foo": "do:foo"}`
+    configureTriggers: function() {
+      if (!this.triggers) { return; }
+  
+      var triggerEvents = {};
+  
+      // Allow `triggers` to be configured as a function
+      var triggers = this.normalizeUIKeys(_.result(this, 'triggers'));
+  
+      // Configure the triggers, prevent default
+      // action and stop propagation of DOM events
+      _.each(triggers, function(value, key) {
+  
+        var hasOptions = _.isObject(value);
+        var eventName = hasOptions ? value.event : value;
+  
+        // build the event handler function for the DOM event
+        triggerEvents[key] = function(e) {
+  
+          // stop the event in its tracks
+          if (e) {
+            var prevent = e.preventDefault;
+            var stop = e.stopPropagation;
+  
+            var shouldPrevent = hasOptions ? value.preventDefault : prevent;
+            var shouldStop = hasOptions ? value.stopPropagation : stop;
+  
+            if (shouldPrevent && prevent) { prevent.apply(e); }
+            if (shouldStop && stop) { stop.apply(e); }
+          }
+  
+          // build the args for the event
+          var args = {
+            view: this,
+            model: this.model,
+            collection: this.collection
+          };
+  
+          // trigger the event
+          this.triggerMethod(eventName, args);
+        };
+  
+      }, this);
+  
+      return triggerEvents;
+    },
+  
+    // Overriding Backbone.View's delegateEvents to handle
+    // the `triggers`, `modelEvents`, and `collectionEvents` configuration
+    delegateEvents: function(events) {
+      this._delegateDOMEvents(events);
+      this.bindEntityEvents(this.model, this.getOption('modelEvents'));
+      this.bindEntityEvents(this.collection, this.getOption('collectionEvents'));
+    },
+  
+    // internal method to delegate DOM events and triggers
+    _delegateDOMEvents: function(events) {
+      events = events || this.events;
+      if (_.isFunction(events)) { events = events.call(this); }
+  
+      // normalize ui keys
+      events = this.normalizeUIKeys(events);
+  
+      var combinedEvents = {};
+  
+      // look up if this view has behavior events
+      var behaviorEvents = _.result(this, 'behaviorEvents') || {};
+      var triggers = this.configureTriggers();
+  
+      // behavior events will be overriden by view events and or triggers
+      _.extend(combinedEvents, behaviorEvents, events, triggers);
+  
+      Backbone.View.prototype.delegateEvents.call(this, combinedEvents);
+    },
+  
+    // Overriding Backbone.View's undelegateEvents to handle unbinding
+    // the `triggers`, `modelEvents`, and `collectionEvents` config
+    undelegateEvents: function() {
+      var args = Array.prototype.slice.call(arguments);
+      Backbone.View.prototype.undelegateEvents.apply(this, args);
+      this.unbindEntityEvents(this.model, this.getOption('modelEvents'));
+      this.unbindEntityEvents(this.collection, this.getOption('collectionEvents'));
+    },
+  
+    // Internal method, handles the `show` event.
+    onShowCalled: function() {},
+  
+    // Internal helper method to verify whether the view hasn't been destroyed
+    _ensureViewIsIntact: function() {
+      if (this.isDestroyed) {
+        var err = new Error('Cannot use a view thats already been destroyed.');
+        err.name = 'ViewDestroyedError';
+        throw err;
+      }
+    },
+  
+    // Default `destroy` implementation, for removing a view from the
+    // DOM and unbinding it. Regions will call this method
+    // for you. You can specify an `onDestroy` method in your view to
+    // add custom code that is called after the view is destroyed.
+    destroy: function() {
+      if (this.isDestroyed) { return; }
+  
+      var args = Array.prototype.slice.call(arguments);
+  
+      this.triggerMethod.apply(this, ['before:destroy'].concat(args));
+  
+      // mark as destroyed before doing the actual destroy, to
+      // prevent infinite loops within "destroy" event handlers
+      // that are trying to destroy other views
+      this.isDestroyed = true;
+      this.triggerMethod.apply(this, ['destroy'].concat(args));
+  
+      // unbind UI elements
+      this.unbindUIElements();
+  
+      // remove the view from the DOM
+      this.remove();
+    },
+  
+    // This method binds the elements specified in the "ui" hash inside the view's code with
+    // the associated jQuery selectors.
+    bindUIElements: function() {
+      if (!this.ui) { return; }
+  
+      // store the ui hash in _uiBindings so they can be reset later
+      // and so re-rendering the view will be able to find the bindings
+      if (!this._uiBindings) {
+        this._uiBindings = this.ui;
+      }
+  
+      // get the bindings result, as a function or otherwise
+      var bindings = _.result(this, '_uiBindings');
+  
+      // empty the ui so we don't have anything to start with
+      this.ui = {};
+  
+      // bind each of the selectors
+      _.each(_.keys(bindings), function(key) {
+        var selector = bindings[key];
+        this.ui[key] = this.$(selector);
+      }, this);
+    },
+  
+    // This method unbinds the elements specified in the "ui" hash
+    unbindUIElements: function() {
+      if (!this.ui || !this._uiBindings) { return; }
+  
+      // delete all of the existing ui bindings
+      _.each(this.ui, function($el, name) {
+        delete this.ui[name];
+      }, this);
+  
+      // reset the ui element to the original bindings configuration
+      this.ui = this._uiBindings;
+      delete this._uiBindings;
+    },
+  
+    // import the `triggerMethod` to trigger events with corresponding
+    // methods if the method exists
+    triggerMethod: Marionette.triggerMethod,
+  
+    // Imports the "normalizeMethods" to transform hashes of
+    // events=>function references/names to a hash of events=>function references
+    normalizeMethods: Marionette.normalizeMethods,
+  
+    // Proxy `getOption` to enable getting options from this or this.options by name.
+    getOption: Marionette.proxyGetOption,
+  
+    // Proxy `unbindEntityEvents` to enable binding view's events from another entity.
+    bindEntityEvents: Marionette.proxyBindEntityEvents,
+  
+    // Proxy `unbindEntityEvents` to enable unbinding view's events from another entity.
+    unbindEntityEvents: Marionette.proxyUnbindEntityEvents
+  });
+  
+  // Item View
+  // ---------
+  
+  // A single item view implementation that contains code for rendering
+  // with underscore.js templates, serializing the view's model or collection,
+  // and calling several methods on extended views, such as `onRender`.
+  Marionette.ItemView = Marionette.View.extend({
+  
+    // Setting up the inheritance chain which allows changes to
+    // Marionette.View.prototype.constructor which allows overriding
+    constructor: function() {
+      Marionette.View.apply(this, arguments);
+    },
+  
+    // Serialize the model or collection for the view. If a model is
+    // found, `.toJSON()` is called. If a collection is found, `.toJSON()`
+    // is also called, but is used to populate an `items` array in the
+    // resulting data. If both are found, defaults to the model.
+    // You can override the `serializeData` method in your own view
+    // definition, to provide custom serialization for your view's data.
+    serializeData: function() {
+      var data = {};
+  
+      if (this.model) {
+        data = this.model.toJSON();
+      }
+      else if (this.collection) {
+        data = {items: this.collection.toJSON()};
+      }
+  
+      return data;
+    },
+  
+    // Render the view, defaulting to underscore.js templates.
+    // You can override this in your view definition to provide
+    // a very specific rendering for your view. In general, though,
+    // you should override the `Marionette.Renderer` object to
+    // change how Marionette renders views.
+    render: function() {
+      this._ensureViewIsIntact();
+  
+      this.triggerMethod('before:render', this);
+  
+      var data = this.serializeData();
+      data = this.mixinTemplateHelpers(data);
+  
+      var template = this.getTemplate();
+      var html = Marionette.Renderer.render(template, data);
+      this.attachElContent(html);
+      this.bindUIElements();
+  
+      this.triggerMethod('render', this);
+  
+      return this;
+    },
+  
+    // Attaches the content of a given view.
+    // This method can be overriden to optimize rendering,
+    // or to render in a non standard way.
+    //
+    // For example, using `innerHTML` instead of `$el.html`
+    //
+    // ```js
+    // attachElContent: function(html) {
+    //   this.el.innerHTML = html;
+    //   return this;
+    // }
+    // ```
+    attachElContent: function(html) {
+      this.$el.html(html);
+  
+      return this;
+    },
+  
+    // Override the default destroy event to add a few
+    // more events that are triggered.
+    destroy: function() {
+      if (this.isDestroyed) { return; }
+  
+      Marionette.View.prototype.destroy.apply(this, arguments);
+    }
+  });
+  
+  /* jshint maxstatements: 14 */
+  
+  // Collection View
+  // ---------------
+  
+  // A view that iterates over a Backbone.Collection
+  // and renders an individual child view for each model.
+  Marionette.CollectionView = Marionette.View.extend({
+  
+    // used as the prefix for child view events
+    // that are forwarded through the collectionview
+    childViewEventPrefix: 'childview',
+  
+    // constructor
+    // option to pass `{sort: false}` to prevent the `CollectionView` from
+    // maintaining the sorted order of the collection.
+    // This will fallback onto appending childView's to the end.
+    constructor: function(options){
+      var initOptions = options || {};
+      this.sort = _.isUndefined(initOptions.sort) ? true : initOptions.sort;
+  
+      this._initChildViewStorage();
+  
+      Marionette.View.apply(this, arguments);
+  
+      this._initialEvents();
+      this.initRenderBuffer();
+    },
+  
+    // Instead of inserting elements one by one into the page,
+    // it's much more performant to insert elements into a document
+    // fragment and then insert that document fragment into the page
+    initRenderBuffer: function() {
+      this.elBuffer = document.createDocumentFragment();
+      this._bufferedChildren = [];
+    },
+  
+    startBuffering: function() {
+      this.initRenderBuffer();
+      this.isBuffering = true;
+    },
+  
+    endBuffering: function() {
+      this.isBuffering = false;
+      this._triggerBeforeShowBufferedChildren();
+      this.attachBuffer(this, this.elBuffer);
+      this._triggerShowBufferedChildren();
+      this.initRenderBuffer();
+    },
+  
+    _triggerBeforeShowBufferedChildren: function() {
+      if (this._isShown) {
+        _.invoke(this._bufferedChildren, 'triggerMethod', 'before:show');
+      }
+    },
+  
+    _triggerShowBufferedChildren: function() {
+      if (this._isShown) {
+        _.each(this._bufferedChildren, function (child) {
+          if (_.isFunction(child.triggerMethod)) {
+            child.triggerMethod('show');
+          } else {
+            Marionette.triggerMethod.call(child, 'show');
+          }
+        });
+        this._bufferedChildren = [];
+      }
+    },
+  
+    // Configured the initial events that the collection view
+    // binds to.
+    _initialEvents: function() {
+      if (this.collection) {
+        this.listenTo(this.collection, 'add', this._onCollectionAdd);
+        this.listenTo(this.collection, 'remove', this._onCollectionRemove);
+        this.listenTo(this.collection, 'reset', this.render);
+  
+        if (this.sort) {
+          this.listenTo(this.collection, 'sort', this._sortViews);
+        }
+      }
+    },
+  
+    // Handle a child added to the collection
+    _onCollectionAdd: function(child, collection, options) {
+      this.destroyEmptyView();
+      var ChildView = this.getChildView(child);
+      var index = this.collection.indexOf(child);
+      this.addChild(child, ChildView, index);
+    },
+  
+    // get the child view by model it holds, and remove it
+    _onCollectionRemove: function(model) {
+      var view = this.children.findByModel(model);
+      this.removeChildView(view);
+      this.checkEmpty();
+    },
+  
+    // Override from `Marionette.View` to trigger show on child views
+    onShowCalled: function(){
+      this.children.each(function(child){
+        if (_.isFunction(child.triggerMethod)) {
+          child.triggerMethod('show');
+        } else {
+          Marionette.triggerMethod.call(child, 'show');
+        }
+      });
+    },
+  
+    // Render children views. Override this method to
+    // provide your own implementation of a render function for
+    // the collection view.
+    render: function() {
+      this._ensureViewIsIntact();
+      this.triggerMethod('before:render', this);
+      this._renderChildren();
+      this.triggerMethod('render', this);
+      return this;
+    },
+  
+    // Internal method. This checks for any changes in the order of the collection.
+    // If the index of any view doesn't match, it will render.
+    _sortViews: function(){
+      // check for any changes in sort order of views
+      var orderChanged = this.collection.find(function(item, index){
+        var view = this.children.findByModel(item);
+        return view && view._index !== index;
+      }, this);
+  
+      if (orderChanged) {
+        this.render();
+      }
+    },
+  
+    // Internal method. Separated so that CompositeView can have
+    // more control over events being triggered, around the rendering
+    // process
+    _renderChildren: function() {
+      this.startBuffering();
+  
+      this.destroyEmptyView();
+      this.destroyChildren();
+  
+      if (!this.isEmpty(this.collection)) {
+        this.triggerMethod('before:render:collection', this);
+        this.showCollection();
+        this.triggerMethod('render:collection', this);
+      } else {
+        this.showEmptyView();
+      }
+  
+      this.endBuffering();
+    },
+  
+    // Internal method to loop through collection and show each child view.
+    showCollection: function() {
+      var ChildView;
+      this.collection.each(function(child, index) {
+        ChildView = this.getChildView(child);
+        this.addChild(child, ChildView, index);
+      }, this);
+    },
+  
+    // Internal method to show an empty view in place of
+    // a collection of child views, when the collection is empty
+    showEmptyView: function() {
+      var EmptyView = this.getEmptyView();
+  
+      if (EmptyView && !this._showingEmptyView) {
+        this.triggerMethod('before:render:empty');
+  
+        this._showingEmptyView = true;
+        var model = new Backbone.Model();
+        this.addEmptyView(model, EmptyView);
+  
+        this.triggerMethod('render:empty');
+      }
+    },
+  
+    // Internal method to destroy an existing emptyView instance
+    // if one exists. Called when a collection view has been
+    // rendered empty, and then a child is added to the collection.
+    destroyEmptyView: function() {
+      if (this._showingEmptyView) {
+        this.destroyChildren();
+        delete this._showingEmptyView;
+      }
+    },
+  
+    // Retrieve the empty view class
+    getEmptyView: function() {
+      return this.getOption('emptyView');
+    },
+  
+    // Render and show the emptyView. Similar to addChild method
+    // but "child:added" events are not fired, and the event from
+    // emptyView are not forwarded
+    addEmptyView: function(child, EmptyView){
+  
+      // get the emptyViewOptions, falling back to childViewOptions
+      var emptyViewOptions = this.getOption('emptyViewOptions') ||
+                            this.getOption('childViewOptions');
+  
+      if (_.isFunction(emptyViewOptions)){
+        emptyViewOptions = emptyViewOptions.call(this);
+      }
+  
+      // build the empty view
+      var view = this.buildChildView(child, EmptyView, emptyViewOptions);
+  
+      // trigger the 'before:show' event on `view` if the collection view
+      // has already been shown
+      if (this._isShown){
+        this.triggerMethod.call(view, 'before:show');
+      }
+  
+      // Store the `emptyView` like a `childView` so we can properly
+      // remove and/or close it later
+      this.children.add(view);
+  
+      // Render it and show it
+      this.renderChildView(view, -1);
+  
+      // call the 'show' method if the collection view
+      // has already been shown
+      if (this._isShown){
+        this.triggerMethod.call(view, 'show');
+      }
+    },
+  
+    // Retrieve the childView class, either from `this.options.childView`
+    // or from the `childView` in the object definition. The "options"
+    // takes precedence.
+    getChildView: function(child) {
+      var childView = this.getOption('childView');
+  
+      if (!childView) {
+        throwError('A "childView" must be specified', 'NoChildViewError');
+      }
+  
+      return childView;
+    },
+  
+    // Render the child's view and add it to the
+    // HTML for the collection view at a given index.
+    // This will also update the indices of later views in the collection
+    // in order to keep the children in sync with the collection.
+    addChild: function(child, ChildView, index) {
+      var childViewOptions = this.getOption('childViewOptions');
+      if (_.isFunction(childViewOptions)) {
+        childViewOptions = childViewOptions.call(this, child, index);
+      }
+  
+      var view = this.buildChildView(child, ChildView, childViewOptions);
+  
+      // increment indices of views after this one
+      this._updateIndices(view, true, index);
+  
+      this._addChildView(view, index);
+  
+      return view;
+    },
+  
+    // Internal method. This decrements or increments the indices of views after the
+    // added/removed view to keep in sync with the collection.
+    _updateIndices: function(view, increment, index) {
+      if (!this.sort) {
+        return;
+      }
+  
+      if (increment) {
+        // assign the index to the view
+        view._index = index;
+  
+        // increment the index of views after this one
+        this.children.each(function (laterView) {
+          if (laterView._index >= view._index) {
+            laterView._index++;
+          }
+        });
+      }
+      else {
+        // decrement the index of views after this one
+        this.children.each(function (laterView) {
+          if (laterView._index >= view._index) {
+            laterView._index--;
+          }
+        });
+      }
+    },
+  
+  
+    // Internal Method. Add the view to children and render it at
+    // the given index.
+    _addChildView: function(view, index) {
+      // set up the child view event forwarding
+      this.proxyChildEvents(view);
+  
+      this.triggerMethod('before:add:child', view);
+  
+      // Store the child view itself so we can properly
+      // remove and/or destroy it later
+      this.children.add(view);
+      this.renderChildView(view, index);
+  
+      if (this._isShown && !this.isBuffering){
+        if (_.isFunction(view.triggerMethod)) {
+          view.triggerMethod('show');
+        } else {
+          Marionette.triggerMethod.call(view, 'show');
+        }
+      }
+  
+      this.triggerMethod('add:child', view);
+    },
+  
+    // render the child view
+    renderChildView: function(view, index) {
+      view.render();
+      this.attachHtml(this, view, index);
+    },
+  
+    // Build a `childView` for a model in the collection.
+    buildChildView: function(child, ChildViewClass, childViewOptions) {
+      var options = _.extend({model: child}, childViewOptions);
+      return new ChildViewClass(options);
+    },
+  
+    // Remove the child view and destroy it.
+    // This function also updates the indices of
+    // later views in the collection in order to keep
+    // the children in sync with the collection.
+    removeChildView: function(view) {
+  
+      if (view) {
+        this.triggerMethod('before:remove:child', view);
+        // call 'destroy' or 'remove', depending on which is found
+        if (view.destroy) { view.destroy(); }
+        else if (view.remove) { view.remove(); }
+  
+        this.stopListening(view);
+        this.children.remove(view);
+        this.triggerMethod('remove:child', view);
+  
+        // decrement the index of views after this one
+        this._updateIndices(view, false);
+      }
+  
+    },
+  
+    // check if the collection is empty
+    isEmpty: function(collection) {
+      return !this.collection || this.collection.length === 0;
+    },
+  
+    // If empty, show the empty view
+    checkEmpty: function() {
+      if (this.isEmpty(this.collection)) {
+        this.showEmptyView();
+      }
+    },
+  
+    // You might need to override this if you've overridden attachHtml
+    attachBuffer: function(collectionView, buffer) {
+      collectionView.$el.append(buffer);
+    },
+  
+    // Append the HTML to the collection's `el`.
+    // Override this method to do something other
+    // than `.append`.
+    attachHtml: function(collectionView, childView, index) {
+      if (collectionView.isBuffering) {
+        // buffering happens on reset events and initial renders
+        // in order to reduce the number of inserts into the
+        // document, which are expensive.
+        collectionView.elBuffer.appendChild(childView.el);
+        collectionView._bufferedChildren.push(childView);
+      }
+      else {
+        // If we've already rendered the main collection, append
+        // the new child into the correct order if we need to. Otherwise
+        // append to the end.
+        if (!collectionView._insertBefore(childView, index)){
+          collectionView._insertAfter(childView);
+        }
+      }
+    },
+  
+    // Internal method. Check whether we need to insert the view into
+    // the correct position.
+    _insertBefore: function(childView, index) {
+      var currentView;
+      var findPosition = this.sort && (index < this.children.length - 1);
+      if (findPosition) {
+        // Find the view after this one
+        currentView = this.children.find(function (view) {
+          return view._index === index + 1;
+        });
+      }
+  
+      if (currentView) {
+        currentView.$el.before(childView.el);
+        return true;
+      }
+  
+      return false;
+    },
+  
+    // Internal method. Append a view to the end of the $el
+    _insertAfter: function(childView) {
+      this.$el.append(childView.el);
+    },
+  
+    // Internal method to set up the `children` object for
+    // storing all of the child views
+    _initChildViewStorage: function() {
+      this.children = new Backbone.ChildViewContainer();
+    },
+  
+    // Handle cleanup and other destroying needs for the collection of views
+    destroy: function() {
+      if (this.isDestroyed) { return; }
+  
+      this.triggerMethod('before:destroy:collection');
+      this.destroyChildren();
+      this.triggerMethod('destroy:collection');
+  
+      Marionette.View.prototype.destroy.apply(this, arguments);
+    },
+  
+    // Destroy the child views that this collection view
+    // is holding on to, if any
+    destroyChildren: function() {
+      this.children.each(this.removeChildView, this);
+      this.checkEmpty();
+    },
+  
+    // Set up the child view event forwarding. Uses a "childview:"
+    // prefix in front of all forwarded events.
+    proxyChildEvents: function(view) {
+      var prefix = this.getOption('childViewEventPrefix');
+  
+      // Forward all child view events through the parent,
+      // prepending "childview:" to the event name
+      this.listenTo(view, 'all', function() {
+        var args = Array.prototype.slice.call(arguments);
+        var rootEvent = args[0];
+        var childEvents = this.normalizeMethods(_.result(this, 'childEvents'));
+  
+        args[0] = prefix + ':' + rootEvent;
+        args.splice(1, 0, view);
+  
+        // call collectionView childEvent if defined
+        if (typeof childEvents !== 'undefined' && _.isFunction(childEvents[rootEvent])) {
+          childEvents[rootEvent].apply(this, args.slice(1));
+        }
+  
+        this.triggerMethod.apply(this, args);
+      }, this);
+    }
+  });
+  
+  /* jshint maxstatements: 17, maxlen: 117 */
+  
+  // Composite View
+  // --------------
+  
+  // Used for rendering a branch-leaf, hierarchical structure.
+  // Extends directly from CollectionView and also renders an
+  // a child view as `modelView`, for the top leaf
+  Marionette.CompositeView = Marionette.CollectionView.extend({
+  
+    // Setting up the inheritance chain which allows changes to
+    // Marionette.CollectionView.prototype.constructor which allows overriding
+    // option to pass '{sort: false}' to prevent the CompositeView from
+    // maintaining the sorted order of the collection.
+    // This will fallback onto appending childView's to the end.
+    constructor: function() {
+      Marionette.CollectionView.apply(this, arguments);
+    },
+  
+    // Configured the initial events that the composite view
+    // binds to. Override this method to prevent the initial
+    // events, or to add your own initial events.
+    _initialEvents: function() {
+  
+      // Bind only after composite view is rendered to avoid adding child views
+      // to nonexistent childViewContainer
+      this.once('render', function() {
+        if (this.collection) {
+          this.listenTo(this.collection, 'add', this._onCollectionAdd);
+          this.listenTo(this.collection, 'remove', this._onCollectionRemove);
+          this.listenTo(this.collection, 'reset', this._renderChildren);
+  
+          if (this.sort) {
+            this.listenTo(this.collection, 'sort', this._sortViews);
+          }
+        }
+      });
+  
+    },
+  
+    // Retrieve the `childView` to be used when rendering each of
+    // the items in the collection. The default is to return
+    // `this.childView` or Marionette.CompositeView if no `childView`
+    // has been defined
+    getChildView: function(child) {
+      var childView = this.getOption('childView') || this.constructor;
+  
+      if (!childView) {
+        throwError('A "childView" must be specified', 'NoChildViewError');
+      }
+  
+      return childView;
+    },
+  
+    // Serialize the collection for the view.
+    // You can override the `serializeData` method in your own view
+    // definition, to provide custom serialization for your view's data.
+    serializeData: function() {
+      var data = {};
+  
+      if (this.model) {
+        data = this.model.toJSON();
+      }
+  
+      return data;
+    },
+  
+    // Renders the model once, and the collection once. Calling
+    // this again will tell the model's view to re-render itself
+    // but the collection will not re-render.
+    render: function() {
+      this._ensureViewIsIntact();
+      this.isRendered = true;
+      this.resetChildViewContainer();
+  
+      this.triggerMethod('before:render', this);
+  
+      this._renderRoot();
+      this._renderChildren();
+  
+      this.triggerMethod('render', this);
+      return this;
+    },
+  
+    _renderChildren: function() {
+      if (this.isRendered) {
+        Marionette.CollectionView.prototype._renderChildren.call(this);
+      }
+    },
+  
+    // Render the root template that the children
+    // views are appended to
+    _renderRoot: function() {
+      var data = {};
+      data = this.serializeData();
+      data = this.mixinTemplateHelpers(data);
+  
+      this.triggerMethod('before:render:template');
+  
+      var template = this.getTemplate();
+      var html = Marionette.Renderer.render(template, data);
+      this.attachElContent(html);
+  
+      // the ui bindings is done here and not at the end of render since they
+      // will not be available until after the model is rendered, but should be
+      // available before the collection is rendered.
+      this.bindUIElements();
+      this.triggerMethod('render:template');
+    },
+  
+    // Attaches the content of the root.
+    // This method can be overriden to optimize rendering,
+    // or to render in a non standard way.
+    //
+    // For example, using `innerHTML` instead of `$el.html`
+    //
+    // ```js
+    // attachElContent: function(html) {
+    //   this.el.innerHTML = html;
+    //   return this;
+    // }
+    // ```
+    attachElContent: function(html) {
+      this.$el.html(html);
+  
+      return this;
+    },
+  
+    // You might need to override this if you've overridden attachHtml
+    attachBuffer: function(compositeView, buffer) {
+      var $container = this.getChildViewContainer(compositeView);
+      $container.append(buffer);
+    },
+  
+    // Internal method. Append a view to the end of the $el.
+    // Overidden from CollectionView to ensure view is appended to
+    // childViewContainer
+    _insertAfter: function (childView) {
+      var $container = this.getChildViewContainer(this);
+      $container.append(childView.el);
+    },
+  
+    // Internal method to ensure an `$childViewContainer` exists, for the
+    // `attachHtml` method to use.
+    getChildViewContainer: function(containerView) {
+      if ('$childViewContainer' in containerView) {
+        return containerView.$childViewContainer;
+      }
+  
+      var container;
+      var childViewContainer = Marionette.getOption(containerView, 'childViewContainer');
+      if (childViewContainer) {
+  
+        var selector = _.isFunction(childViewContainer) ? childViewContainer.call(containerView) : childViewContainer;
+  
+        if (selector.charAt(0) === '@' && containerView.ui) {
+          container = containerView.ui[selector.substr(4)];
+        } else {
+          container = containerView.$(selector);
+        }
+  
+        if (container.length <= 0) {
+          throwError('The specified "childViewContainer" was not found: ' +
+            containerView.childViewContainer, 'ChildViewContainerMissingError');
+        }
+  
+      } else {
+        container = containerView.$el;
+      }
+  
+      containerView.$childViewContainer = container;
+      return container;
+    },
+  
+    // Internal method to reset the `$childViewContainer` on render
+    resetChildViewContainer: function() {
+      if (this.$childViewContainer) {
+        delete this.$childViewContainer;
+      }
+    }
+  });
+  
+  // LayoutView
+  // ----------
+  
+  // Used for managing application layoutViews, nested layoutViews and
+  // multiple regions within an application or sub-application.
+  //
+  // A specialized view class that renders an area of HTML and then
+  // attaches `Region` instances to the specified `regions`.
+  // Used for composite view management and sub-application areas.
+  Marionette.LayoutView = Marionette.ItemView.extend({
+    regionClass: Marionette.Region,
+  
+    // Ensure the regions are available when the `initialize` method
+    // is called.
+    constructor: function(options) {
+      options = options || {};
+  
+      this._firstRender = true;
+      this._initializeRegions(options);
+  
+      Marionette.ItemView.call(this, options);
+    },
+  
+    // LayoutView's render will use the existing region objects the
+    // first time it is called. Subsequent calls will destroy the
+    // views that the regions are showing and then reset the `el`
+    // for the regions to the newly rendered DOM elements.
+    render: function() {
+      this._ensureViewIsIntact();
+  
+      if (this._firstRender) {
+        // if this is the first render, don't do anything to
+        // reset the regions
+        this._firstRender = false;
+      } else {
+        // If this is not the first render call, then we need to
+        // re-initialize the `el` for each region
+        this._reInitializeRegions();
+      }
+  
+      return Marionette.ItemView.prototype.render.apply(this, arguments);
+    },
+  
+    // Handle destroying regions, and then destroy the view itself.
+    destroy: function() {
+      if (this.isDestroyed) { return; }
+  
+      this.regionManager.destroy();
+      Marionette.ItemView.prototype.destroy.apply(this, arguments);
+    },
+  
+    // Add a single region, by name, to the layoutView
+    addRegion: function(name, definition) {
+      this.triggerMethod('before:region:add', name);
+      var regions = {};
+      regions[name] = definition;
+      return this._buildRegions(regions)[name];
+    },
+  
+    // Add multiple regions as a {name: definition, name2: def2} object literal
+    addRegions: function(regions) {
+      this.regions = _.extend({}, this.regions, regions);
+      return this._buildRegions(regions);
+    },
+  
+    // Remove a single region from the LayoutView, by name
+    removeRegion: function(name) {
+      this.triggerMethod('before:region:remove', name);
+      delete this.regions[name];
+      return this.regionManager.removeRegion(name);
+    },
+  
+    // Provides alternative access to regions
+    // Accepts the region name
+    // getRegion('main')
+    getRegion: function(region) {
+      return this.regionManager.get(region);
+    },
+  
+    // Get all regions
+    getRegions: function(){
+      return this.regionManager.getRegions();
+    },
+  
+    // internal method to build regions
+    _buildRegions: function(regions) {
+      var that = this;
+  
+      var defaults = {
+        regionClass: this.getOption('regionClass'),
+        parentEl: function() { return that.$el; }
+      };
+  
+      return this.regionManager.addRegions(regions, defaults);
+    },
+  
+    // Internal method to initialize the regions that have been defined in a
+    // `regions` attribute on this layoutView.
+    _initializeRegions: function(options) {
+      var regions;
+      this._initRegionManager();
+  
+      if (_.isFunction(this.regions)) {
+        regions = this.regions(options);
+      } else {
+        regions = this.regions || {};
+      }
+  
+      // Enable users to define `regions` as instance options.
+      var regionOptions = this.getOption.call(options, 'regions');
+  
+      // enable region options to be a function
+      if (_.isFunction(regionOptions)) {
+        regionOptions = regionOptions.call(this, options);
+      }
+  
+      _.extend(regions, regionOptions);
+  
+      this.addRegions(regions);
+    },
+  
+    // Internal method to re-initialize all of the regions by updating the `el` that
+    // they point to
+    _reInitializeRegions: function() {
+      this.regionManager.emptyRegions();
+      this.regionManager.each(function(region) {
+        region.reset();
+      });
+    },
+  
+    // Enable easy overiding of the default `RegionManager`
+    // for customized region interactions and buisness specific
+    // view logic for better control over single regions.
+    getRegionManager: function() {
+      return new Marionette.RegionManager();
+    },
+  
+    // Internal method to initialize the region manager
+    // and all regions in it
+    _initRegionManager: function() {
+      this.regionManager = this.getRegionManager();
+  
+      this.listenTo(this.regionManager, 'before:add:region', function(name) {
+        this.triggerMethod('before:add:region', name);
+      });
+  
+      this.listenTo(this.regionManager, 'add:region', function(name, region) {
+        this[name] = region;
+        this.triggerMethod('add:region', name, region);
+      });
+  
+      this.listenTo(this.regionManager, 'before:remove:region', function(name) {
+        this.triggerMethod('before:remove:region', name);
+      });
+  
+      this.listenTo(this.regionManager, 'remove:region', function(name, region) {
+        delete this[name];
+        this.triggerMethod('remove:region', name, region);
+      });
+    }
+  });
+  
+
+  // Behavior
+  // -----------
+  
+  // A Behavior is an isolated set of DOM /
+  // user interactions that can be mixed into any View.
+  // Behaviors allow you to blackbox View specific interactions
+  // into portable logical chunks, keeping your views simple and your code DRY.
+  
+  Marionette.Behavior = (function(_, Backbone) {
+    function Behavior(options, view) {
+      // Setup reference to the view.
+      // this comes in handle when a behavior
+      // wants to directly talk up the chain
+      // to the view.
+      this.view = view;
+      this.defaults = _.result(this, 'defaults') || {};
+      this.options  = _.extend({}, this.defaults, options);
+  
+      // proxy behavior $ method to the view
+      // this is useful for doing jquery DOM lookups
+      // scoped to behaviors view.
+      this.$ = function() {
+        return this.view.$.apply(this.view, arguments);
+      };
+  
+      // Call the initialize method passing
+      // the arguments from the instance constructor
+      this.initialize.apply(this, arguments);
+    }
+  
+    _.extend(Behavior.prototype, Backbone.Events, {
+      initialize: function() {},
+  
+      // stopListening to behavior `onListen` events.
+      destroy: function() {
+        this.stopListening();
+      },
+  
+      // import the `triggerMethod` to trigger events with corresponding
+      // methods if the method exists
+      triggerMethod: Marionette.triggerMethod,
+  
+      // Proxy `getOption` to enable getting options from this or this.options by name.
+      getOption: Marionette.proxyGetOption,
+  
+      // Proxy `unbindEntityEvents` to enable binding view's events from another entity.
+      bindEntityEvents: Marionette.proxyBindEntityEvents,
+  
+      // Proxy `unbindEntityEvents` to enable unbinding view's events from another entity.
+      unbindEntityEvents: Marionette.proxyUnbindEntityEvents
+    });
+  
+    // Borrow Backbones extend implementation
+    // this allows us to setup a proper
+    // inheritence pattern that follow in suite
+    // with the rest of Marionette views.
+    Behavior.extend = Marionette.extend;
+  
+    return Behavior;
+  })(_, Backbone);
+  
+  /* jshint maxlen: 143, nonew: false */
+  // Marionette.Behaviors
+  // --------
+  
+  // Behaviors is a utility class that takes care of
+  // glueing your behavior instances to their given View.
+  // The most important part of this class is that you
+  // **MUST** override the class level behaviorsLookup
+  // method for things to work properly.
+  
+  Marionette.Behaviors = (function(Marionette, _) {
+  
+    function Behaviors(view, behaviors) {
+      // Behaviors defined on a view can be a flat object literal
+      // or it can be a function that returns an object.
+      behaviors = Behaviors.parseBehaviors(view, behaviors || _.result(view, 'behaviors'));
+  
+      // Wraps several of the view's methods
+      // calling the methods first on each behavior
+      // and then eventually calling the method on the view.
+      Behaviors.wrap(view, behaviors, [
+        'bindUIElements', 'unbindUIElements',
+        'delegateEvents', 'undelegateEvents',
+        'behaviorEvents', 'triggerMethod',
+        'setElement', 'destroy'
+      ]);
+    }
+  
+    var methods = {
+      setElement: function(setElement, behaviors) {
+        setElement.apply(this, _.tail(arguments, 2));
+  
+        // proxy behavior $el to the view's $el.
+        // This is needed because a view's $el proxy
+        // is not set until after setElement is called.
+        _.each(behaviors, function(b) {
+          b.$el = this.$el;
+        }, this);
+      },
+  
+      destroy: function(destroy, behaviors) {
+        var args = _.tail(arguments, 2);
+        destroy.apply(this, args);
+  
+        // Call destroy on each behavior after
+        // destroying the view.
+        // This unbinds event listeners
+        // that behaviors have registerd for.
+        _.invoke(behaviors, 'destroy', args);
+      },
+  
+      bindUIElements: function(bindUIElements, behaviors) {
+        bindUIElements.apply(this);
+        _.invoke(behaviors, bindUIElements);
+      },
+  
+      unbindUIElements: function(unbindUIElements, behaviors) {
+        unbindUIElements.apply(this);
+        _.invoke(behaviors, unbindUIElements);
+      },
+  
+      triggerMethod: function(triggerMethod, behaviors) {
+        var args = _.tail(arguments, 2);
+        triggerMethod.apply(this, args);
+  
+        _.each(behaviors, function(b) {
+          triggerMethod.apply(b, args);
+        });
+      },
+  
+      delegateEvents: function(delegateEvents, behaviors) {
+        var args = _.tail(arguments, 2);
+        delegateEvents.apply(this, args);
+  
+        _.each(behaviors, function(b) {
+          Marionette.bindEntityEvents(b, this.model, Marionette.getOption(b, 'modelEvents'));
+          Marionette.bindEntityEvents(b, this.collection, Marionette.getOption(b, 'collectionEvents'));
+        }, this);
+      },
+  
+      undelegateEvents: function(undelegateEvents, behaviors) {
+        var args = _.tail(arguments, 2);
+        undelegateEvents.apply(this, args);
+  
+        _.each(behaviors, function(b) {
+          Marionette.unbindEntityEvents(b, this.model, Marionette.getOption(b, 'modelEvents'));
+          Marionette.unbindEntityEvents(b, this.collection, Marionette.getOption(b, 'collectionEvents'));
+        }, this);
+      },
+  
+      behaviorEvents: function(behaviorEvents, behaviors) {
+        var _behaviorsEvents = {};
+        var viewUI = _.result(this, 'ui');
+  
+        _.each(behaviors, function(b, i) {
+          var _events = {};
+          var behaviorEvents = _.clone(_.result(b, 'events')) || {};
+          var behaviorUI = _.result(b, 'ui');
+  
+          // Construct an internal UI hash first using
+          // the views UI hash and then the behaviors UI hash.
+          // This allows the user to use UI hash elements
+          // defined in the parent view as well as those
+          // defined in the given behavior.
+          var ui = _.extend({}, viewUI, behaviorUI);
+  
+          // Normalize behavior events hash to allow
+          // a user to use the @ui. syntax.
+          behaviorEvents = Marionette.normalizeUIKeys(behaviorEvents, ui);
+  
+          _.each(_.keys(behaviorEvents), function(key) {
+            // Append white-space at the end of each key to prevent behavior key collisions.
+            // This is relying on the fact that backbone events considers "click .foo" the same as
+            // "click .foo ".
+  
+            // +2 is used because new Array(1) or 0 is "" and not " "
+            var whitespace = (new Array(i + 2)).join(' ');
+            var eventKey   = key + whitespace;
+            var handler    = _.isFunction(behaviorEvents[key]) ? behaviorEvents[key] : b[behaviorEvents[key]];
+  
+            _events[eventKey] = _.bind(handler, b);
+          });
+  
+          _behaviorsEvents = _.extend(_behaviorsEvents, _events);
+        });
+  
+        return _behaviorsEvents;
+      }
+    };
+  
+    _.extend(Behaviors, {
+  
+      // Placeholder method to be extended by the user.
+      // The method should define the object that stores the behaviors.
+      // i.e.
+      //
+      // ```js
+      // Marionette.Behaviors.behaviorsLookup: function() {
+      //   return App.Behaviors
+      // }
+      // ```
+      behaviorsLookup: function() {
+        throw new Error('You must define where your behaviors are stored.' +
+          'See https://github.com/marionettejs/backbone.marionette' +
+          '/blob/master/docs/marionette.behaviors.md#behaviorslookup');
+      },
+  
+      // Takes care of getting the behavior class
+      // given options and a key.
+      // If a user passes in options.behaviorClass
+      // default to using that. Otherwise delegate
+      // the lookup to the users `behaviorsLookup` implementation.
+      getBehaviorClass: function(options, key) {
+        if (options.behaviorClass) {
+          return options.behaviorClass;
+        }
+  
+        // Get behavior class can be either a flat object or a method
+        return _.isFunction(Behaviors.behaviorsLookup) ? Behaviors.behaviorsLookup.apply(this, arguments)[key] : Behaviors.behaviorsLookup[key];
+      },
+  
+      // Iterate over the behaviors object, for each behavior
+      // instantiate it and get its grouped behaviors.
+      parseBehaviors: function(view, behaviors) {
+        return _.chain(behaviors).map(function(options, key) {
+          var BehaviorClass = Behaviors.getBehaviorClass(options, key);
+  
+          var behavior = new BehaviorClass(options, view);
+          var nestedBehaviors = Behaviors.parseBehaviors(view, _.result(behavior, 'behaviors'));
+  
+          return [behavior].concat(nestedBehaviors);
+        }).flatten().value();
+      },
+  
+      // Wrap view internal methods so that they delegate to behaviors. For example,
+      // `onDestroy` should trigger destroy on all of the behaviors and then destroy itself.
+      // i.e.
+      //
+      // `view.delegateEvents = _.partial(methods.delegateEvents, view.delegateEvents, behaviors);`
+      wrap: function(view, behaviors, methodNames) {
+        _.each(methodNames, function(methodName) {
+          view[methodName] = _.partial(methods[methodName], view[methodName], behaviors);
+        });
+      }
+    });
+  
+    return Behaviors;
+  
+  })(Marionette, _);
+  
+
+  // AppRouter
+  // ---------
+  
+  // Reduce the boilerplate code of handling route events
+  // and then calling a single method on another object.
+  // Have your routers configured to call the method on
+  // your object, directly.
+  //
+  // Configure an AppRouter with `appRoutes`.
+  //
+  // App routers can only take one `controller` object.
+  // It is recommended that you divide your controller
+  // objects in to smaller pieces of related functionality
+  // and have multiple routers / controllers, instead of
+  // just one giant router and controller.
+  //
+  // You can also add standard routes to an AppRouter.
+  
+  Marionette.AppRouter = Backbone.Router.extend({
+  
+    constructor: function(options) {
+      Backbone.Router.apply(this, arguments);
+  
+      this.options = options || {};
+  
+      var appRoutes = this.getOption('appRoutes');
+      var controller = this._getController();
+      this.processAppRoutes(controller, appRoutes);
+      this.on('route', this._processOnRoute, this);
+    },
+  
+    // Similar to route method on a Backbone Router but
+    // method is called on the controller
+    appRoute: function(route, methodName) {
+      var controller = this._getController();
+      this._addAppRoute(controller, route, methodName);
+    },
+  
+    // process the route event and trigger the onRoute
+    // method call, if it exists
+    _processOnRoute: function(routeName, routeArgs) {
+      // find the path that matched
+      var routePath = _.invert(this.appRoutes)[routeName];
+  
+      // make sure an onRoute is there, and call it
+      if (_.isFunction(this.onRoute)) {
+        this.onRoute(routeName, routePath, routeArgs);
+      }
+    },
+  
+    // Internal method to process the `appRoutes` for the
+    // router, and turn them in to routes that trigger the
+    // specified method on the specified `controller`.
+    processAppRoutes: function(controller, appRoutes) {
+      if (!appRoutes) { return; }
+  
+      var routeNames = _.keys(appRoutes).reverse(); // Backbone requires reverted order of routes
+  
+      _.each(routeNames, function(route) {
+        this._addAppRoute(controller, route, appRoutes[route]);
+      }, this);
+    },
+  
+    _getController: function() {
+      return this.getOption('controller');
+    },
+  
+    _addAppRoute: function(controller, route, methodName) {
+      var method = controller[methodName];
+  
+      if (!method) {
+        throwError('Method "' + methodName + '" was not found on the controller');
+      }
+  
+      this.route(route, methodName, _.bind(method, controller));
+    },
+  
+    // Proxy `getOption` to enable getting options from this or this.options by name.
+    getOption: Marionette.proxyGetOption
+  });
+  
+  // Application
+  // -----------
+  
+  // Contain and manage the composite application as a whole.
+  // Stores and starts up `Region` objects, includes an
+  // event aggregator as `app.vent`
+  Marionette.Application = function(options) {
+    this._initRegionManager();
+    this._initCallbacks = new Marionette.Callbacks();
+    var globalCh = Backbone.Wreqr.radio.channel('global');
+    this.vent = globalCh.vent;
+    this.commands = globalCh.commands;
+    this.reqres = globalCh.reqres;
+    this.submodules = {};
+  
+    _.extend(this, options);
+  };
+  
+  _.extend(Marionette.Application.prototype, Backbone.Events, {
+    // Command execution, facilitated by Backbone.Wreqr.Commands
+    execute: function() {
+      this.commands.execute.apply(this.commands, arguments);
+    },
+  
+    // Request/response, facilitated by Backbone.Wreqr.RequestResponse
+    request: function() {
+      return this.reqres.request.apply(this.reqres, arguments);
+    },
+  
+    // Add an initializer that is either run at when the `start`
+    // method is called, or run immediately if added after `start`
+    // has already been called.
+    addInitializer: function(initializer) {
+      this._initCallbacks.add(initializer);
+    },
+  
+    // kick off all of the application's processes.
+    // initializes all of the regions that have been added
+    // to the app, and runs all of the initializer functions
+    start: function(options) {
+      this.triggerMethod('before:start', options);
+      this._initCallbacks.run(options, this);
+      this.triggerMethod('start', options);
+    },
+  
+    // Add regions to your app.
+    // Accepts a hash of named strings or Region objects
+    // addRegions({something: "#someRegion"})
+    // addRegions({something: Region.extend({el: "#someRegion"}) });
+    addRegions: function(regions) {
+      return this._regionManager.addRegions(regions);
+    },
+  
+    // Empty all regions in the app, without removing them
+    emptyRegions: function() {
+      this._regionManager.emptyRegions();
+    },
+  
+    // Removes a region from your app, by name
+    // Accepts the regions name
+    // removeRegion('myRegion')
+    removeRegion: function(region) {
+      this._regionManager.removeRegion(region);
+    },
+  
+    // Provides alternative access to regions
+    // Accepts the region name
+    // getRegion('main')
+    getRegion: function(region) {
+      return this._regionManager.get(region);
+    },
+  
+    // Get all the regions from the region manager
+    getRegions: function(){
+      return this._regionManager.getRegions();
+    },
+  
+    // Create a module, attached to the application
+    module: function(moduleNames, moduleDefinition) {
+  
+      // Overwrite the module class if the user specifies one
+      var ModuleClass = Marionette.Module.getClass(moduleDefinition);
+  
+      // slice the args, and add this application object as the
+      // first argument of the array
+      var args = slice.call(arguments);
+      args.unshift(this);
+  
+      // see the Marionette.Module object for more information
+      return ModuleClass.create.apply(ModuleClass, args);
+    },
+  
+    // Internal method to set up the region manager
+    _initRegionManager: function() {
+      this._regionManager = new Marionette.RegionManager();
+  
+      this.listenTo(this._regionManager, 'before:add:region', function(name) {
+        this.triggerMethod('before:add:region', name);
+      });
+  
+      this.listenTo(this._regionManager, 'add:region', function(name, region) {
+        this[name] = region;
+        this.triggerMethod('add:region', name, region);
+      });
+  
+      this.listenTo(this._regionManager, 'before:remove:region', function(name) {
+        this.triggerMethod('before:remove:region', name);
+      });
+  
+      this.listenTo(this._regionManager, 'remove:region', function(name, region) {
+        delete this[name];
+        this.triggerMethod('remove:region', name, region);
+      });
+    },
+  
+    // import the `triggerMethod` to trigger events with corresponding
+    // methods if the method exists
+    triggerMethod: Marionette.triggerMethod
+  });
+  
+  // Copy the `extend` function used by Backbone's classes
+  Marionette.Application.extend = Marionette.extend;
+  
+  /* jshint maxparams: 9 */
+  
+  // Module
+  // ------
+  
+  // A simple module system, used to create privacy and encapsulation in
+  // Marionette applications
+  Marionette.Module = function(moduleName, app, options) {
+    this.moduleName = moduleName;
+    this.options = _.extend({}, this.options, options);
+    // Allow for a user to overide the initialize
+    // for a given module instance.
+    this.initialize = options.initialize || this.initialize;
+  
+    // Set up an internal store for sub-modules.
+    this.submodules = {};
+  
+    this._setupInitializersAndFinalizers();
+  
+    // Set an internal reference to the app
+    // within a module.
+    this.app = app;
+  
+    // By default modules start with their parents.
+    this.startWithParent = true;
+  
+    if (_.isFunction(this.initialize)) {
+      this.initialize(moduleName, app, this.options);
+    }
+  };
+  
+  Marionette.Module.extend = Marionette.extend;
+  
+  // Extend the Module prototype with events / listenTo, so that the module
+  // can be used as an event aggregator or pub/sub.
+  _.extend(Marionette.Module.prototype, Backbone.Events, {
+  
+    // Initialize is an empty function by default. Override it with your own
+    // initialization logic when extending Marionette.Module.
+    initialize: function() {},
+  
+    // Initializer for a specific module. Initializers are run when the
+    // module's `start` method is called.
+    addInitializer: function(callback) {
+      this._initializerCallbacks.add(callback);
+    },
+  
+    // Finalizers are run when a module is stopped. They are used to teardown
+    // and finalize any variables, references, events and other code that the
+    // module had set up.
+    addFinalizer: function(callback) {
+      this._finalizerCallbacks.add(callback);
+    },
+  
+    // Start the module, and run all of its initializers
+    start: function(options) {
+      // Prevent re-starting a module that is already started
+      if (this._isInitialized) { return; }
+  
+      // start the sub-modules (depth-first hierarchy)
+      _.each(this.submodules, function(mod) {
+        // check to see if we should start the sub-module with this parent
+        if (mod.startWithParent) {
+          mod.start(options);
+        }
+      });
+  
+      // run the callbacks to "start" the current module
+      this.triggerMethod('before:start', options);
+  
+      this._initializerCallbacks.run(options, this);
+      this._isInitialized = true;
+  
+      this.triggerMethod('start', options);
+    },
+  
+    // Stop this module by running its finalizers and then stop all of
+    // the sub-modules for this module
+    stop: function() {
+      // if we are not initialized, don't bother finalizing
+      if (!this._isInitialized) { return; }
+      this._isInitialized = false;
+  
+      this.triggerMethod('before:stop');
+  
+      // stop the sub-modules; depth-first, to make sure the
+      // sub-modules are stopped / finalized before parents
+      _.each(this.submodules, function(mod) { mod.stop(); });
+  
+      // run the finalizers
+      this._finalizerCallbacks.run(undefined, this);
+  
+      // reset the initializers and finalizers
+      this._initializerCallbacks.reset();
+      this._finalizerCallbacks.reset();
+  
+      this.triggerMethod('stop');
+    },
+  
+    // Configure the module with a definition function and any custom args
+    // that are to be passed in to the definition function
+    addDefinition: function(moduleDefinition, customArgs) {
+      this._runModuleDefinition(moduleDefinition, customArgs);
+    },
+  
+    // Internal method: run the module definition function with the correct
+    // arguments
+    _runModuleDefinition: function(definition, customArgs) {
+      // If there is no definition short circut the method.
+      if (!definition) { return; }
+  
+      // build the correct list of arguments for the module definition
+      var args = _.flatten([
+        this,
+        this.app,
+        Backbone,
+        Marionette,
+        Backbone.$, _,
+        customArgs
+      ]);
+  
+      definition.apply(this, args);
+    },
+  
+    // Internal method: set up new copies of initializers and finalizers.
+    // Calling this method will wipe out all existing initializers and
+    // finalizers.
+    _setupInitializersAndFinalizers: function() {
+      this._initializerCallbacks = new Marionette.Callbacks();
+      this._finalizerCallbacks = new Marionette.Callbacks();
+    },
+  
+    // import the `triggerMethod` to trigger events with corresponding
+    // methods if the method exists
+    triggerMethod: Marionette.triggerMethod
+  });
+  
+  // Class methods to create modules
+  _.extend(Marionette.Module, {
+  
+    // Create a module, hanging off the app parameter as the parent object.
+    create: function(app, moduleNames, moduleDefinition) {
+      var module = app;
+  
+      // get the custom args passed in after the module definition and
+      // get rid of the module name and definition function
+      var customArgs = slice.call(arguments);
+      customArgs.splice(0, 3);
+  
+      // Split the module names and get the number of submodules.
+      // i.e. an example module name of `Doge.Wow.Amaze` would
+      // then have the potential for 3 module definitions.
+      moduleNames = moduleNames.split('.');
+      var length = moduleNames.length;
+  
+      // store the module definition for the last module in the chain
+      var moduleDefinitions = [];
+      moduleDefinitions[length - 1] = moduleDefinition;
+  
+      // Loop through all the parts of the module definition
+      _.each(moduleNames, function(moduleName, i) {
+        var parentModule = module;
+        module = this._getModule(parentModule, moduleName, app, moduleDefinition);
+        this._addModuleDefinition(parentModule, module, moduleDefinitions[i], customArgs);
+      }, this);
+  
+      // Return the last module in the definition chain
+      return module;
+    },
+  
+    _getModule: function(parentModule, moduleName, app, def, args) {
+      var options = _.extend({}, def);
+      var ModuleClass = this.getClass(def);
+  
+      // Get an existing module of this name if we have one
+      var module = parentModule[moduleName];
+  
+      if (!module) {
+        // Create a new module if we don't have one
+        module = new ModuleClass(moduleName, app, options);
+        parentModule[moduleName] = module;
+        // store the module on the parent
+        parentModule.submodules[moduleName] = module;
+      }
+  
+      return module;
+    },
+  
+    // ## Module Classes
+    //
+    // Module classes can be used as an alternative to the define pattern.
+    // The extend function of a Module is identical to the extend functions
+    // on other Backbone and Marionette classes.
+    // This allows module lifecyle events like `onStart` and `onStop` to be called directly.
+    getClass: function(moduleDefinition) {
+      var ModuleClass = Marionette.Module;
+  
+      if (!moduleDefinition) {
+        return ModuleClass;
+      }
+  
+      // If all of the module's functionality is defined inside its class,
+      // then the class can be passed in directly. `MyApp.module("Foo", FooModule)`.
+      if (moduleDefinition.prototype instanceof ModuleClass) {
+        return moduleDefinition;
+      }
+  
+      return moduleDefinition.moduleClass || ModuleClass;
+    },
+  
+    // Add the module definition and add a startWithParent initializer function.
+    // This is complicated because module definitions are heavily overloaded
+    // and support an anonymous function, module class, or options object
+    _addModuleDefinition: function(parentModule, module, def, args) {
+      var fn = this._getDefine(def);
+      var startWithParent = this._getStartWithParent(def, module);
+  
+      if (fn) {
+        module.addDefinition(fn, args);
+      }
+  
+      this._addStartWithParent(parentModule, module, startWithParent);
+    },
+  
+    _getStartWithParent: function(def, module) {
+      var swp;
+  
+      if (_.isFunction(def) && (def.prototype instanceof Marionette.Module)) {
+        swp = module.constructor.prototype.startWithParent;
+        return _.isUndefined(swp) ? true : swp;
+      }
+  
+      if (_.isObject(def)) {
+        swp = def.startWithParent;
+        return _.isUndefined(swp) ? true : swp;
+      }
+  
+      return true;
+    },
+  
+    _getDefine: function(def) {
+      if (_.isFunction(def) && !(def.prototype instanceof Marionette.Module)) {
+        return def;
+      }
+  
+      if (_.isObject(def)) {
+        return def.define;
+      }
+  
+      return null;
+    },
+  
+    _addStartWithParent: function(parentModule, module, startWithParent) {
+      module.startWithParent = module.startWithParent && startWithParent;
+  
+      if (!module.startWithParent || !!module.startWithParentIsConfigured) {
+        return;
+      }
+  
+      module.startWithParentIsConfigured = true;
+  
+      parentModule.addInitializer(function(options) {
+        if (module.startWithParent) {
+          module.start(options);
+        }
+      });
+    }
+  });
+  
+
+  return Marionette;
+}));
diff --git a/planetstack/core/xoslib/static/js/vendor/backbone.marionette.min.js b/planetstack/core/xoslib/static/js/vendor/backbone.marionette.min.js
new file mode 100644
index 0000000..29fe58c
--- /dev/null
+++ b/planetstack/core/xoslib/static/js/vendor/backbone.marionette.min.js
@@ -0,0 +1,2 @@
+!function(a,b){if("function"==typeof define&&define.amd)define(["backbone","underscore","backbone.wreqr","backbone.babysitter"],function(c,d){return a.Marionette=b(a,c,d)});else if("undefined"!=typeof exports){{var c=require("backbone"),d=require("underscore");require("backbone.wreqr"),require("backbone.babysitter")}module.exports=b(a,c,d)}else a.Marionette=b(a,a.Backbone,a._)}(this,function(a,b,c){"use strict";function d(a,b){var c=new Error(a);throw c.name=b||"Error",c}var e=a.Marionette,f=b.Marionette={};f.VERSION="2.0.1",f.noConflict=function(){return a.Marionette=e,this},f.Deferred=b.$.Deferred;var g=Array.prototype.slice;return f.extend=b.Model.extend,f.getOption=function(a,b){if(a&&b){var c;return c=a.options&&void 0!==a.options[b]?a.options[b]:a[b]}},f.proxyGetOption=function(a){return f.getOption(this,a)},f.normalizeMethods=function(a){var b,d={};return c.each(a,function(a,e){b=a,c.isFunction(b)||(b=this[b]),b&&(d[e]=b)},this),d},f.normalizeUIKeys=function(a,b){return"undefined"!=typeof a?(c.each(c.keys(a),function(c){var d=/@ui.[a-zA-Z_$0-9]*/g;c.match(d)&&(a[c.replace(d,function(a){return b[a.slice(4)]})]=a[c],delete a[c])}),a):void 0},f.actAsCollection=function(a,b){var d=["forEach","each","map","find","detect","filter","select","reject","every","all","some","any","include","contains","invoke","toArray","first","initial","rest","last","without","isEmpty","pluck"];c.each(d,function(d){a[d]=function(){var a=c.values(c.result(this,b)),e=[a].concat(c.toArray(arguments));return c[d].apply(c,e)}})},f.triggerMethod=function(){function a(a,b,c){return c.toUpperCase()}var b=/(^|:)(\w)/gi,d=function(d){var e,f="on"+d.replace(b,a),g=this[f];return c.isFunction(g)&&(e=g.apply(this,c.tail(arguments))),c.isFunction(this.trigger)&&this.trigger.apply(this,arguments),e};return d}(),f.MonitorDOMRefresh=function(a){function b(a){a._isShown=!0,e(a)}function d(a){a._isRendered=!0,e(a)}function e(a){a._isShown&&a._isRendered&&f(a)&&c.isFunction(a.triggerMethod)&&a.triggerMethod("dom:refresh")}function f(b){return a.contains(b.el)}return function(a){a.listenTo(a,"show",function(){b(a)}),a.listenTo(a,"render",function(){d(a)})}}(document.documentElement),function(a){function b(a,b,e,f){var g=f.split(/\s+/);c.each(g,function(c){var f=a[c];f||d('Method "'+c+'" was configured as an event handler, but does not exist.'),a.listenTo(b,e,f)})}function e(a,b,c,d){a.listenTo(b,c,d)}function f(a,b,d,e){var f=e.split(/\s+/);c.each(f,function(c){var e=a[c];a.stopListening(b,d,e)})}function g(a,b,c,d){a.stopListening(b,c,d)}function h(a,b,d,e,f){b&&d&&(c.isFunction(d)&&(d=d.call(a)),c.each(d,function(d,g){c.isFunction(d)?e(a,b,g,d):f(a,b,g,d)}))}a.bindEntityEvents=function(a,c,d){h(a,c,d,e,b)},a.unbindEntityEvents=function(a,b,c){h(a,b,c,g,f)},a.proxyBindEntityEvents=function(b,c){return a.bindEntityEvents(this,b,c)},a.proxyUnbindEntityEvents=function(b,c){return a.unbindEntityEvents(this,b,c)}}(f),f.Callbacks=function(){this._deferred=f.Deferred(),this._callbacks=[]},c.extend(f.Callbacks.prototype,{add:function(a,b){var d=c.result(this._deferred,"promise");this._callbacks.push({cb:a,ctx:b}),d.then(function(c){b&&(c.context=b),a.call(c.context,c.options)})},run:function(a,b){this._deferred.resolve({options:a,context:b})},reset:function(){var a=this._callbacks;this._deferred=f.Deferred(),this._callbacks=[],c.each(a,function(a){this.add(a.cb,a.ctx)},this)}}),f.Controller=function(a){this.triggerMethod=f.triggerMethod,this.options=a||{},c.isFunction(this.initialize)&&this.initialize(this.options)},f.Controller.extend=f.extend,c.extend(f.Controller.prototype,b.Events,{destroy:function(){var a=Array.prototype.slice.call(arguments);this.triggerMethod.apply(this,["before:destroy"].concat(a)),this.triggerMethod.apply(this,["destroy"].concat(a)),this.stopListening(),this.off()},triggerMethod:f.triggerMethod,getOption:f.proxyGetOption}),f.Region=function(a){if(this.options=a||{},this.el=this.getOption("el"),this.el=this.el instanceof b.$?this.el[0]:this.el,this.el||d('An "el" must be specified for a region.',"NoElError"),this.$el=this.getEl(this.el),this.initialize){var c=Array.prototype.slice.apply(arguments);this.initialize.apply(this,c)}},c.extend(f.Region,{buildRegion:function(a,e){var f=c.isString(a),g=c.isString(a.selector),h=c.isUndefined(a.regionClass),i=c.isFunction(a);i||f||g||d("Region must be specified as a Region class,a selector string or an object with selector property");var j,k;f&&(j=a),a.selector&&(j=a.selector,delete a.selector),i&&(k=a),!i&&h&&(k=e),a.regionClass&&(k=a.regionClass,delete a.regionClass),(f||i)&&(a={}),a.el=j;var l=new k(a);return a.parentEl&&(l.getEl=function(d){if(c.isObject(d))return b.$(d);var e=a.parentEl;return c.isFunction(e)&&(e=e()),e.find(d)}),l}}),c.extend(f.Region.prototype,b.Events,{show:function(a,b){this._ensureElement();var d=b||{},e=a!==this.currentView,f=!!d.preventDestroy,g=!!d.forceShow,h=!!this.currentView,i=!f&&e;i&&this.empty();var j=e||g;return j?(a.render(),h&&this.triggerMethod("before:swap",a),this.triggerMethod("before:show",a),this.triggerMethod.call(a,"before:show"),this.attachHtml(a),this.currentView=a,h&&this.triggerMethod("swap",a),this.triggerMethod("show",a),c.isFunction(a.triggerMethod)?a.triggerMethod("show"):this.triggerMethod.call(a,"show"),this):this},_ensureElement:function(){c.isObject(this.el)||(this.$el=this.getEl(this.el),this.el=this.$el[0]),this.$el&&0!==this.$el.length||d('An "el" '+this.$el.selector+" must exist in DOM")},getEl:function(a){return b.$(a)},attachHtml:function(a){this.el.innerHTML="",this.el.appendChild(a.el)},empty:function(){var a=this.currentView;a&&!a.isDestroyed&&(this.triggerMethod("before:empty",a),a.destroy?a.destroy():a.remove&&a.remove(),this.triggerMethod("empty",a),delete this.currentView)},attachView:function(a){this.currentView=a},reset:function(){this.empty(),this.$el&&(this.el=this.$el.selector),delete this.$el},getOption:f.proxyGetOption,triggerMethod:f.triggerMethod}),f.Region.extend=f.extend,f.RegionManager=function(a){var b=a.Controller.extend({constructor:function(b){this._regions={},a.Controller.call(this,b)},addRegions:function(a,b){var d={};return c.each(a,function(a,e){c.isString(a)&&(a={selector:a}),a.selector&&(a=c.defaults({},a,b));var f=this.addRegion(e,a);d[e]=f},this),d},addRegion:function(b,d){var e,f=c.isObject(d),g=c.isString(d),h=!!d.selector;return e=g||f&&h?a.Region.buildRegion(d,a.Region):c.isFunction(d)?a.Region.buildRegion(d,a.Region):d,this.triggerMethod("before:add:region",b,e),this._store(b,e),this.triggerMethod("add:region",b,e),e},get:function(a){return this._regions[a]},getRegions:function(){return c.clone(this._regions)},removeRegion:function(a){var b=this._regions[a];this._remove(a,b)},removeRegions:function(){c.each(this._regions,function(a,b){this._remove(b,a)},this)},emptyRegions:function(){c.each(this._regions,function(a){a.empty()},this)},destroy:function(){this.removeRegions(),a.Controller.prototype.destroy.apply(this,arguments)},_store:function(a,b){this._regions[a]=b,this._setLength()},_remove:function(a,b){this.triggerMethod("before:remove:region",a,b),b.empty(),b.stopListening(),delete this._regions[a],this._setLength(),this.triggerMethod("remove:region",a,b)},_setLength:function(){this.length=c.size(this._regions)}});return a.actAsCollection(b.prototype,"_regions"),b}(f),f.TemplateCache=function(a){this.templateId=a},c.extend(f.TemplateCache,{templateCaches:{},get:function(a){var b=this.templateCaches[a];return b||(b=new f.TemplateCache(a),this.templateCaches[a]=b),b.load()},clear:function(){var a,b=g.call(arguments),c=b.length;if(c>0)for(a=0;c>a;a++)delete this.templateCaches[b[a]];else this.templateCaches={}}}),c.extend(f.TemplateCache.prototype,{load:function(){if(this.compiledTemplate)return this.compiledTemplate;var a=this.loadTemplate(this.templateId);return this.compiledTemplate=this.compileTemplate(a),this.compiledTemplate},loadTemplate:function(a){var c=b.$(a).html();return c&&0!==c.length||d('Could not find template: "'+a+'"',"NoTemplateError"),c},compileTemplate:function(a){return c.template(a)}}),f.Renderer={render:function(a,b){a||d("Cannot render the template since its false, null or undefined.","TemplateNotFoundError");var c;return(c="function"==typeof a?a:f.TemplateCache.get(a))(b)}},f.View=b.View.extend({constructor:function(a){c.bindAll(this,"render"),this.options=c.extend({},c.result(this,"options"),c.isFunction(a)?a.call(this):a),this.events=this.normalizeUIKeys(c.result(this,"events")),c.isObject(this.behaviors)&&new f.Behaviors(this),b.View.apply(this,arguments),f.MonitorDOMRefresh(this),this.listenTo(this,"show",this.onShowCalled)},getTemplate:function(){return this.getOption("template")},mixinTemplateHelpers:function(a){a=a||{};var b=this.getOption("templateHelpers");return c.isFunction(b)&&(b=b.call(this)),c.extend(a,b)},normalizeUIKeys:function(a){var b=c.result(this,"ui"),d=c.result(this,"_uiBindings");return f.normalizeUIKeys(a,d||b)},configureTriggers:function(){if(this.triggers){var a={},b=this.normalizeUIKeys(c.result(this,"triggers"));return c.each(b,function(b,d){var e=c.isObject(b),f=e?b.event:b;a[d]=function(a){if(a){var c=a.preventDefault,d=a.stopPropagation,g=e?b.preventDefault:c,h=e?b.stopPropagation:d;g&&c&&c.apply(a),h&&d&&d.apply(a)}var i={view:this,model:this.model,collection:this.collection};this.triggerMethod(f,i)}},this),a}},delegateEvents:function(a){this._delegateDOMEvents(a),this.bindEntityEvents(this.model,this.getOption("modelEvents")),this.bindEntityEvents(this.collection,this.getOption("collectionEvents"))},_delegateDOMEvents:function(a){a=a||this.events,c.isFunction(a)&&(a=a.call(this)),a=this.normalizeUIKeys(a);var d={},e=c.result(this,"behaviorEvents")||{},f=this.configureTriggers();c.extend(d,e,a,f),b.View.prototype.delegateEvents.call(this,d)},undelegateEvents:function(){var a=Array.prototype.slice.call(arguments);b.View.prototype.undelegateEvents.apply(this,a),this.unbindEntityEvents(this.model,this.getOption("modelEvents")),this.unbindEntityEvents(this.collection,this.getOption("collectionEvents"))},onShowCalled:function(){},_ensureViewIsIntact:function(){if(this.isDestroyed){var a=new Error("Cannot use a view thats already been destroyed.");throw a.name="ViewDestroyedError",a}},destroy:function(){if(!this.isDestroyed){var a=Array.prototype.slice.call(arguments);this.triggerMethod.apply(this,["before:destroy"].concat(a)),this.isDestroyed=!0,this.triggerMethod.apply(this,["destroy"].concat(a)),this.unbindUIElements(),this.remove()}},bindUIElements:function(){if(this.ui){this._uiBindings||(this._uiBindings=this.ui);var a=c.result(this,"_uiBindings");this.ui={},c.each(c.keys(a),function(b){var c=a[b];this.ui[b]=this.$(c)},this)}},unbindUIElements:function(){this.ui&&this._uiBindings&&(c.each(this.ui,function(a,b){delete this.ui[b]},this),this.ui=this._uiBindings,delete this._uiBindings)},triggerMethod:f.triggerMethod,normalizeMethods:f.normalizeMethods,getOption:f.proxyGetOption,bindEntityEvents:f.proxyBindEntityEvents,unbindEntityEvents:f.proxyUnbindEntityEvents}),f.ItemView=f.View.extend({constructor:function(){f.View.apply(this,arguments)},serializeData:function(){var a={};return this.model?a=this.model.toJSON():this.collection&&(a={items:this.collection.toJSON()}),a},render:function(){this._ensureViewIsIntact(),this.triggerMethod("before:render",this);var a=this.serializeData();a=this.mixinTemplateHelpers(a);var b=this.getTemplate(),c=f.Renderer.render(b,a);return this.attachElContent(c),this.bindUIElements(),this.triggerMethod("render",this),this},attachElContent:function(a){return this.$el.html(a),this},destroy:function(){this.isDestroyed||f.View.prototype.destroy.apply(this,arguments)}}),f.CollectionView=f.View.extend({childViewEventPrefix:"childview",constructor:function(a){var b=a||{};this.sort=c.isUndefined(b.sort)?!0:b.sort,this._initChildViewStorage(),f.View.apply(this,arguments),this._initialEvents(),this.initRenderBuffer()},initRenderBuffer:function(){this.elBuffer=document.createDocumentFragment(),this._bufferedChildren=[]},startBuffering:function(){this.initRenderBuffer(),this.isBuffering=!0},endBuffering:function(){this.isBuffering=!1,this._triggerBeforeShowBufferedChildren(),this.attachBuffer(this,this.elBuffer),this._triggerShowBufferedChildren(),this.initRenderBuffer()},_triggerBeforeShowBufferedChildren:function(){this._isShown&&c.invoke(this._bufferedChildren,"triggerMethod","before:show")},_triggerShowBufferedChildren:function(){this._isShown&&(c.each(this._bufferedChildren,function(a){c.isFunction(a.triggerMethod)?a.triggerMethod("show"):f.triggerMethod.call(a,"show")}),this._bufferedChildren=[])},_initialEvents:function(){this.collection&&(this.listenTo(this.collection,"add",this._onCollectionAdd),this.listenTo(this.collection,"remove",this._onCollectionRemove),this.listenTo(this.collection,"reset",this.render),this.sort&&this.listenTo(this.collection,"sort",this._sortViews))},_onCollectionAdd:function(a){this.destroyEmptyView();var b=this.getChildView(a),c=this.collection.indexOf(a);this.addChild(a,b,c)},_onCollectionRemove:function(a){var b=this.children.findByModel(a);this.removeChildView(b),this.checkEmpty()},onShowCalled:function(){this.children.each(function(a){c.isFunction(a.triggerMethod)?a.triggerMethod("show"):f.triggerMethod.call(a,"show")})},render:function(){return this._ensureViewIsIntact(),this.triggerMethod("before:render",this),this._renderChildren(),this.triggerMethod("render",this),this},_sortViews:function(){var a=this.collection.find(function(a,b){var c=this.children.findByModel(a);return c&&c._index!==b},this);a&&this.render()},_renderChildren:function(){this.startBuffering(),this.destroyEmptyView(),this.destroyChildren(),this.isEmpty(this.collection)?this.showEmptyView():(this.triggerMethod("before:render:collection",this),this.showCollection(),this.triggerMethod("render:collection",this)),this.endBuffering()},showCollection:function(){var a;this.collection.each(function(b,c){a=this.getChildView(b),this.addChild(b,a,c)},this)},showEmptyView:function(){var a=this.getEmptyView();if(a&&!this._showingEmptyView){this.triggerMethod("before:render:empty"),this._showingEmptyView=!0;var c=new b.Model;this.addEmptyView(c,a),this.triggerMethod("render:empty")}},destroyEmptyView:function(){this._showingEmptyView&&(this.destroyChildren(),delete this._showingEmptyView)},getEmptyView:function(){return this.getOption("emptyView")},addEmptyView:function(a,b){var d=this.getOption("emptyViewOptions")||this.getOption("childViewOptions");c.isFunction(d)&&(d=d.call(this));var e=this.buildChildView(a,b,d);this._isShown&&this.triggerMethod.call(e,"before:show"),this.children.add(e),this.renderChildView(e,-1),this._isShown&&this.triggerMethod.call(e,"show")},getChildView:function(){var a=this.getOption("childView");return a||d('A "childView" must be specified',"NoChildViewError"),a},addChild:function(a,b,d){var e=this.getOption("childViewOptions");c.isFunction(e)&&(e=e.call(this,a,d));var f=this.buildChildView(a,b,e);return this._updateIndices(f,!0,d),this._addChildView(f,d),f},_updateIndices:function(a,b,c){this.sort&&(b?(a._index=c,this.children.each(function(b){b._index>=a._index&&b._index++})):this.children.each(function(b){b._index>=a._index&&b._index--}))},_addChildView:function(a,b){this.proxyChildEvents(a),this.triggerMethod("before:add:child",a),this.children.add(a),this.renderChildView(a,b),this._isShown&&!this.isBuffering&&(c.isFunction(a.triggerMethod)?a.triggerMethod("show"):f.triggerMethod.call(a,"show")),this.triggerMethod("add:child",a)},renderChildView:function(a,b){a.render(),this.attachHtml(this,a,b)},buildChildView:function(a,b,d){var e=c.extend({model:a},d);return new b(e)},removeChildView:function(a){a&&(this.triggerMethod("before:remove:child",a),a.destroy?a.destroy():a.remove&&a.remove(),this.stopListening(a),this.children.remove(a),this.triggerMethod("remove:child",a),this._updateIndices(a,!1))},isEmpty:function(){return!this.collection||0===this.collection.length},checkEmpty:function(){this.isEmpty(this.collection)&&this.showEmptyView()},attachBuffer:function(a,b){a.$el.append(b)},attachHtml:function(a,b,c){a.isBuffering?(a.elBuffer.appendChild(b.el),a._bufferedChildren.push(b)):a._insertBefore(b,c)||a._insertAfter(b)},_insertBefore:function(a,b){var c,d=this.sort&&b<this.children.length-1;return d&&(c=this.children.find(function(a){return a._index===b+1})),c?(c.$el.before(a.el),!0):!1},_insertAfter:function(a){this.$el.append(a.el)},_initChildViewStorage:function(){this.children=new b.ChildViewContainer},destroy:function(){this.isDestroyed||(this.triggerMethod("before:destroy:collection"),this.destroyChildren(),this.triggerMethod("destroy:collection"),f.View.prototype.destroy.apply(this,arguments))},destroyChildren:function(){this.children.each(this.removeChildView,this),this.checkEmpty()},proxyChildEvents:function(a){var b=this.getOption("childViewEventPrefix");this.listenTo(a,"all",function(){var d=Array.prototype.slice.call(arguments),e=d[0],f=this.normalizeMethods(c.result(this,"childEvents"));d[0]=b+":"+e,d.splice(1,0,a),"undefined"!=typeof f&&c.isFunction(f[e])&&f[e].apply(this,d.slice(1)),this.triggerMethod.apply(this,d)},this)}}),f.CompositeView=f.CollectionView.extend({constructor:function(){f.CollectionView.apply(this,arguments)},_initialEvents:function(){this.once("render",function(){this.collection&&(this.listenTo(this.collection,"add",this._onCollectionAdd),this.listenTo(this.collection,"remove",this._onCollectionRemove),this.listenTo(this.collection,"reset",this._renderChildren),this.sort&&this.listenTo(this.collection,"sort",this._sortViews))})},getChildView:function(){var a=this.getOption("childView")||this.constructor;return a||d('A "childView" must be specified',"NoChildViewError"),a},serializeData:function(){var a={};return this.model&&(a=this.model.toJSON()),a},render:function(){return this._ensureViewIsIntact(),this.isRendered=!0,this.resetChildViewContainer(),this.triggerMethod("before:render",this),this._renderRoot(),this._renderChildren(),this.triggerMethod("render",this),this},_renderChildren:function(){this.isRendered&&f.CollectionView.prototype._renderChildren.call(this)},_renderRoot:function(){var a={};a=this.serializeData(),a=this.mixinTemplateHelpers(a),this.triggerMethod("before:render:template");var b=this.getTemplate(),c=f.Renderer.render(b,a);this.attachElContent(c),this.bindUIElements(),this.triggerMethod("render:template")},attachElContent:function(a){return this.$el.html(a),this},attachBuffer:function(a,b){var c=this.getChildViewContainer(a);c.append(b)},_insertAfter:function(a){var b=this.getChildViewContainer(this);b.append(a.el)},getChildViewContainer:function(a){if("$childViewContainer"in a)return a.$childViewContainer;var b,e=f.getOption(a,"childViewContainer");if(e){var g=c.isFunction(e)?e.call(a):e;b="@"===g.charAt(0)&&a.ui?a.ui[g.substr(4)]:a.$(g),b.length<=0&&d('The specified "childViewContainer" was not found: '+a.childViewContainer,"ChildViewContainerMissingError")}else b=a.$el;return a.$childViewContainer=b,b},resetChildViewContainer:function(){this.$childViewContainer&&delete this.$childViewContainer}}),f.LayoutView=f.ItemView.extend({regionClass:f.Region,constructor:function(a){a=a||{},this._firstRender=!0,this._initializeRegions(a),f.ItemView.call(this,a)},render:function(){return this._ensureViewIsIntact(),this._firstRender?this._firstRender=!1:this._reInitializeRegions(),f.ItemView.prototype.render.apply(this,arguments)},destroy:function(){this.isDestroyed||(this.regionManager.destroy(),f.ItemView.prototype.destroy.apply(this,arguments))},addRegion:function(a,b){this.triggerMethod("before:region:add",a);var c={};return c[a]=b,this._buildRegions(c)[a]},addRegions:function(a){return this.regions=c.extend({},this.regions,a),this._buildRegions(a)},removeRegion:function(a){return this.triggerMethod("before:region:remove",a),delete this.regions[a],this.regionManager.removeRegion(a)},getRegion:function(a){return this.regionManager.get(a)},getRegions:function(){return this.regionManager.getRegions()},_buildRegions:function(a){var b=this,c={regionClass:this.getOption("regionClass"),parentEl:function(){return b.$el}};return this.regionManager.addRegions(a,c)},_initializeRegions:function(a){var b;this._initRegionManager(),b=c.isFunction(this.regions)?this.regions(a):this.regions||{};var d=this.getOption.call(a,"regions");c.isFunction(d)&&(d=d.call(this,a)),c.extend(b,d),this.addRegions(b)},_reInitializeRegions:function(){this.regionManager.emptyRegions(),this.regionManager.each(function(a){a.reset()})},getRegionManager:function(){return new f.RegionManager},_initRegionManager:function(){this.regionManager=this.getRegionManager(),this.listenTo(this.regionManager,"before:add:region",function(a){this.triggerMethod("before:add:region",a)}),this.listenTo(this.regionManager,"add:region",function(a,b){this[a]=b,this.triggerMethod("add:region",a,b)}),this.listenTo(this.regionManager,"before:remove:region",function(a){this.triggerMethod("before:remove:region",a)}),this.listenTo(this.regionManager,"remove:region",function(a,b){delete this[a],this.triggerMethod("remove:region",a,b)})}}),f.Behavior=function(a,b){function c(b,c){this.view=c,this.defaults=a.result(this,"defaults")||{},this.options=a.extend({},this.defaults,b),this.$=function(){return this.view.$.apply(this.view,arguments)},this.initialize.apply(this,arguments)}return a.extend(c.prototype,b.Events,{initialize:function(){},destroy:function(){this.stopListening()},triggerMethod:f.triggerMethod,getOption:f.proxyGetOption,bindEntityEvents:f.proxyBindEntityEvents,unbindEntityEvents:f.proxyUnbindEntityEvents}),c.extend=f.extend,c}(c,b),f.Behaviors=function(a,b){function c(a,d){d=c.parseBehaviors(a,d||b.result(a,"behaviors")),c.wrap(a,d,["bindUIElements","unbindUIElements","delegateEvents","undelegateEvents","behaviorEvents","triggerMethod","setElement","destroy"])}var d={setElement:function(a,c){a.apply(this,b.tail(arguments,2)),b.each(c,function(a){a.$el=this.$el},this)},destroy:function(a,c){var d=b.tail(arguments,2);a.apply(this,d),b.invoke(c,"destroy",d)},bindUIElements:function(a,c){a.apply(this),b.invoke(c,a)},unbindUIElements:function(a,c){a.apply(this),b.invoke(c,a)},triggerMethod:function(a,c){var d=b.tail(arguments,2);a.apply(this,d),b.each(c,function(b){a.apply(b,d)})},delegateEvents:function(c,d){var e=b.tail(arguments,2);c.apply(this,e),b.each(d,function(b){a.bindEntityEvents(b,this.model,a.getOption(b,"modelEvents")),a.bindEntityEvents(b,this.collection,a.getOption(b,"collectionEvents"))},this)},undelegateEvents:function(c,d){var e=b.tail(arguments,2);c.apply(this,e),b.each(d,function(b){a.unbindEntityEvents(b,this.model,a.getOption(b,"modelEvents")),a.unbindEntityEvents(b,this.collection,a.getOption(b,"collectionEvents"))},this)},behaviorEvents:function(c,d){var e={},f=b.result(this,"ui");return b.each(d,function(c,d){var g={},h=b.clone(b.result(c,"events"))||{},i=b.result(c,"ui"),j=b.extend({},f,i);h=a.normalizeUIKeys(h,j),b.each(b.keys(h),function(a){var e=new Array(d+2).join(" "),f=a+e,i=b.isFunction(h[a])?h[a]:c[h[a]];g[f]=b.bind(i,c)}),e=b.extend(e,g)}),e}};return b.extend(c,{behaviorsLookup:function(){throw new Error("You must define where your behaviors are stored.See https://github.com/marionettejs/backbone.marionette/blob/master/docs/marionette.behaviors.md#behaviorslookup")},getBehaviorClass:function(a,d){return a.behaviorClass?a.behaviorClass:b.isFunction(c.behaviorsLookup)?c.behaviorsLookup.apply(this,arguments)[d]:c.behaviorsLookup[d]},parseBehaviors:function(a,d){return b.chain(d).map(function(d,e){var f=c.getBehaviorClass(d,e),g=new f(d,a),h=c.parseBehaviors(a,b.result(g,"behaviors"));return[g].concat(h)}).flatten().value()},wrap:function(a,c,e){b.each(e,function(e){a[e]=b.partial(d[e],a[e],c)})}}),c}(f,c),f.AppRouter=b.Router.extend({constructor:function(a){b.Router.apply(this,arguments),this.options=a||{};var c=this.getOption("appRoutes"),d=this._getController();this.processAppRoutes(d,c),this.on("route",this._processOnRoute,this)},appRoute:function(a,b){var c=this._getController();this._addAppRoute(c,a,b)},_processOnRoute:function(a,b){var d=c.invert(this.appRoutes)[a];c.isFunction(this.onRoute)&&this.onRoute(a,d,b)},processAppRoutes:function(a,b){if(b){var d=c.keys(b).reverse();c.each(d,function(c){this._addAppRoute(a,c,b[c])},this)}},_getController:function(){return this.getOption("controller")},_addAppRoute:function(a,b,e){var f=a[e];f||d('Method "'+e+'" was not found on the controller'),this.route(b,e,c.bind(f,a))},getOption:f.proxyGetOption}),f.Application=function(a){this._initRegionManager(),this._initCallbacks=new f.Callbacks;var d=b.Wreqr.radio.channel("global");this.vent=d.vent,this.commands=d.commands,this.reqres=d.reqres,this.submodules={},c.extend(this,a)},c.extend(f.Application.prototype,b.Events,{execute:function(){this.commands.execute.apply(this.commands,arguments)},request:function(){return this.reqres.request.apply(this.reqres,arguments)},addInitializer:function(a){this._initCallbacks.add(a)},start:function(a){this.triggerMethod("before:start",a),this._initCallbacks.run(a,this),this.triggerMethod("start",a)},addRegions:function(a){return this._regionManager.addRegions(a)},emptyRegions:function(){this._regionManager.emptyRegions()},removeRegion:function(a){this._regionManager.removeRegion(a)},getRegion:function(a){return this._regionManager.get(a)},getRegions:function(){return this._regionManager.getRegions()},module:function(a,b){var c=f.Module.getClass(b),d=g.call(arguments);return d.unshift(this),c.create.apply(c,d)},_initRegionManager:function(){this._regionManager=new f.RegionManager,this.listenTo(this._regionManager,"before:add:region",function(a){this.triggerMethod("before:add:region",a)}),this.listenTo(this._regionManager,"add:region",function(a,b){this[a]=b,this.triggerMethod("add:region",a,b)}),this.listenTo(this._regionManager,"before:remove:region",function(a){this.triggerMethod("before:remove:region",a)}),this.listenTo(this._regionManager,"remove:region",function(a,b){delete this[a],this.triggerMethod("remove:region",a,b)})},triggerMethod:f.triggerMethod}),f.Application.extend=f.extend,f.Module=function(a,b,d){this.moduleName=a,this.options=c.extend({},this.options,d),this.initialize=d.initialize||this.initialize,this.submodules={},this._setupInitializersAndFinalizers(),this.app=b,this.startWithParent=!0,c.isFunction(this.initialize)&&this.initialize(a,b,this.options)},f.Module.extend=f.extend,c.extend(f.Module.prototype,b.Events,{initialize:function(){},addInitializer:function(a){this._initializerCallbacks.add(a)},addFinalizer:function(a){this._finalizerCallbacks.add(a)},start:function(a){this._isInitialized||(c.each(this.submodules,function(b){b.startWithParent&&b.start(a)}),this.triggerMethod("before:start",a),this._initializerCallbacks.run(a,this),this._isInitialized=!0,this.triggerMethod("start",a))},stop:function(){this._isInitialized&&(this._isInitialized=!1,this.triggerMethod("before:stop"),c.each(this.submodules,function(a){a.stop()}),this._finalizerCallbacks.run(void 0,this),this._initializerCallbacks.reset(),this._finalizerCallbacks.reset(),this.triggerMethod("stop"))},addDefinition:function(a,b){this._runModuleDefinition(a,b)},_runModuleDefinition:function(a,d){if(a){var e=c.flatten([this,this.app,b,f,b.$,c,d]);a.apply(this,e)}},_setupInitializersAndFinalizers:function(){this._initializerCallbacks=new f.Callbacks,this._finalizerCallbacks=new f.Callbacks},triggerMethod:f.triggerMethod}),c.extend(f.Module,{create:function(a,b,d){var e=a,f=g.call(arguments);f.splice(0,3),b=b.split(".");var h=b.length,i=[];return i[h-1]=d,c.each(b,function(b,c){var g=e;e=this._getModule(g,b,a,d),this._addModuleDefinition(g,e,i[c],f)},this),e},_getModule:function(a,b,d,e){var f=c.extend({},e),g=this.getClass(e),h=a[b];return h||(h=new g(b,d,f),a[b]=h,a.submodules[b]=h),h},getClass:function(a){var b=f.Module;return a?a.prototype instanceof b?a:a.moduleClass||b:b},_addModuleDefinition:function(a,b,c,d){var e=this._getDefine(c),f=this._getStartWithParent(c,b);e&&b.addDefinition(e,d),this._addStartWithParent(a,b,f)},_getStartWithParent:function(a,b){var d;return c.isFunction(a)&&a.prototype instanceof f.Module?(d=b.constructor.prototype.startWithParent,c.isUndefined(d)?!0:d):c.isObject(a)?(d=a.startWithParent,c.isUndefined(d)?!0:d):!0},_getDefine:function(a){return!c.isFunction(a)||a.prototype instanceof f.Module?c.isObject(a)?a.define:null:a},_addStartWithParent:function(a,b,c){b.startWithParent=b.startWithParent&&c,b.startWithParent&&!b.startWithParentIsConfigured&&(b.startWithParentIsConfigured=!0,a.addInitializer(function(a){b.startWithParent&&b.start(a)}))}}),f});
+//# sourceMappingURL=backbone.marionette.map
\ No newline at end of file
diff --git a/planetstack/core/xoslib/static/js/vendor/backbone.wreqr.js b/planetstack/core/xoslib/static/js/vendor/backbone.wreqr.js
new file mode 100644
index 0000000..66de72f
--- /dev/null
+++ b/planetstack/core/xoslib/static/js/vendor/backbone.wreqr.js
@@ -0,0 +1,440 @@
+// Backbone.Wreqr (Backbone.Marionette)
+// ----------------------------------
+// v1.3.1
+//
+// Copyright (c)2014 Derick Bailey, Muted Solutions, LLC.
+// Distributed under MIT license
+//
+// http://github.com/marionettejs/backbone.wreqr
+
+
+(function(root, factory) {
+
+  if (typeof define === 'function' && define.amd) {
+    define(['backbone', 'underscore'], function(Backbone, _) {
+      return factory(Backbone, _);
+    });
+  } else if (typeof exports !== 'undefined') {
+    var Backbone = require('backbone');
+    var _ = require('underscore');
+    module.exports = factory(Backbone, _);
+  } else {
+    factory(root.Backbone, root._);
+  }
+
+}(this, function(Backbone, _) {
+  "use strict";
+
+  var previousWreqr = Backbone.Wreqr;
+
+  var Wreqr = Backbone.Wreqr = {};
+
+  Backbone.Wreqr.VERSION = '1.3.1';
+
+  Backbone.Wreqr.noConflict = function () {
+    Backbone.Wreqr = previousWreqr;
+    return this;
+  };
+
+  // Handlers
+  // --------
+  // A registry of functions to call, given a name
+  
+  Wreqr.Handlers = (function(Backbone, _){
+    "use strict";
+    
+    // Constructor
+    // -----------
+  
+    var Handlers = function(options){
+      this.options = options;
+      this._wreqrHandlers = {};
+      
+      if (_.isFunction(this.initialize)){
+        this.initialize(options);
+      }
+    };
+  
+    Handlers.extend = Backbone.Model.extend;
+  
+    // Instance Members
+    // ----------------
+  
+    _.extend(Handlers.prototype, Backbone.Events, {
+  
+      // Add multiple handlers using an object literal configuration
+      setHandlers: function(handlers){
+        _.each(handlers, function(handler, name){
+          var context = null;
+  
+          if (_.isObject(handler) && !_.isFunction(handler)){
+            context = handler.context;
+            handler = handler.callback;
+          }
+  
+          this.setHandler(name, handler, context);
+        }, this);
+      },
+  
+      // Add a handler for the given name, with an
+      // optional context to run the handler within
+      setHandler: function(name, handler, context){
+        var config = {
+          callback: handler,
+          context: context
+        };
+  
+        this._wreqrHandlers[name] = config;
+  
+        this.trigger("handler:add", name, handler, context);
+      },
+  
+      // Determine whether or not a handler is registered
+      hasHandler: function(name){
+        return !! this._wreqrHandlers[name];
+      },
+  
+      // Get the currently registered handler for
+      // the specified name. Throws an exception if
+      // no handler is found.
+      getHandler: function(name){
+        var config = this._wreqrHandlers[name];
+  
+        if (!config){
+          return;
+        }
+  
+        return function(){
+          var args = Array.prototype.slice.apply(arguments);
+          return config.callback.apply(config.context, args);
+        };
+      },
+  
+      // Remove a handler for the specified name
+      removeHandler: function(name){
+        delete this._wreqrHandlers[name];
+      },
+  
+      // Remove all handlers from this registry
+      removeAllHandlers: function(){
+        this._wreqrHandlers = {};
+      }
+    });
+  
+    return Handlers;
+  })(Backbone, _);
+  
+  // Wreqr.CommandStorage
+  // --------------------
+  //
+  // Store and retrieve commands for execution.
+  Wreqr.CommandStorage = (function(){
+    "use strict";
+  
+    // Constructor function
+    var CommandStorage = function(options){
+      this.options = options;
+      this._commands = {};
+  
+      if (_.isFunction(this.initialize)){
+        this.initialize(options);
+      }
+    };
+  
+    // Instance methods
+    _.extend(CommandStorage.prototype, Backbone.Events, {
+  
+      // Get an object literal by command name, that contains
+      // the `commandName` and the `instances` of all commands
+      // represented as an array of arguments to process
+      getCommands: function(commandName){
+        var commands = this._commands[commandName];
+  
+        // we don't have it, so add it
+        if (!commands){
+  
+          // build the configuration
+          commands = {
+            command: commandName, 
+            instances: []
+          };
+  
+          // store it
+          this._commands[commandName] = commands;
+        }
+  
+        return commands;
+      },
+  
+      // Add a command by name, to the storage and store the
+      // args for the command
+      addCommand: function(commandName, args){
+        var command = this.getCommands(commandName);
+        command.instances.push(args);
+      },
+  
+      // Clear all commands for the given `commandName`
+      clearCommands: function(commandName){
+        var command = this.getCommands(commandName);
+        command.instances = [];
+      }
+    });
+  
+    return CommandStorage;
+  })();
+  
+  // Wreqr.Commands
+  // --------------
+  //
+  // A simple command pattern implementation. Register a command
+  // handler and execute it.
+  Wreqr.Commands = (function(Wreqr){
+    "use strict";
+  
+    return Wreqr.Handlers.extend({
+      // default storage type
+      storageType: Wreqr.CommandStorage,
+  
+      constructor: function(options){
+        this.options = options || {};
+  
+        this._initializeStorage(this.options);
+        this.on("handler:add", this._executeCommands, this);
+  
+        var args = Array.prototype.slice.call(arguments);
+        Wreqr.Handlers.prototype.constructor.apply(this, args);
+      },
+  
+      // Execute a named command with the supplied args
+      execute: function(name, args){
+        name = arguments[0];
+        args = Array.prototype.slice.call(arguments, 1);
+  
+        if (this.hasHandler(name)){
+          this.getHandler(name).apply(this, args);
+        } else {
+          this.storage.addCommand(name, args);
+        }
+  
+      },
+  
+      // Internal method to handle bulk execution of stored commands
+      _executeCommands: function(name, handler, context){
+        var command = this.storage.getCommands(name);
+  
+        // loop through and execute all the stored command instances
+        _.each(command.instances, function(args){
+          handler.apply(context, args);
+        });
+  
+        this.storage.clearCommands(name);
+      },
+  
+      // Internal method to initialize storage either from the type's
+      // `storageType` or the instance `options.storageType`.
+      _initializeStorage: function(options){
+        var storage;
+  
+        var StorageType = options.storageType || this.storageType;
+        if (_.isFunction(StorageType)){
+          storage = new StorageType();
+        } else {
+          storage = StorageType;
+        }
+  
+        this.storage = storage;
+      }
+    });
+  
+  })(Wreqr);
+  
+  // Wreqr.RequestResponse
+  // ---------------------
+  //
+  // A simple request/response implementation. Register a
+  // request handler, and return a response from it
+  Wreqr.RequestResponse = (function(Wreqr){
+    "use strict";
+  
+    return Wreqr.Handlers.extend({
+      request: function(){
+        var name = arguments[0];
+        var args = Array.prototype.slice.call(arguments, 1);
+        if (this.hasHandler(name)) {
+          return this.getHandler(name).apply(this, args);
+        }
+      }
+    });
+  
+  })(Wreqr);
+  
+  // Event Aggregator
+  // ----------------
+  // A pub-sub object that can be used to decouple various parts
+  // of an application through event-driven architecture.
+  
+  Wreqr.EventAggregator = (function(Backbone, _){
+    "use strict";
+    var EA = function(){};
+  
+    // Copy the `extend` function used by Backbone's classes
+    EA.extend = Backbone.Model.extend;
+  
+    // Copy the basic Backbone.Events on to the event aggregator
+    _.extend(EA.prototype, Backbone.Events);
+  
+    return EA;
+  })(Backbone, _);
+  
+  // Wreqr.Channel
+  // --------------
+  //
+  // An object that wraps the three messaging systems:
+  // EventAggregator, RequestResponse, Commands
+  Wreqr.Channel = (function(Wreqr){
+    "use strict";
+  
+    var Channel = function(channelName) {
+      this.vent        = new Backbone.Wreqr.EventAggregator();
+      this.reqres      = new Backbone.Wreqr.RequestResponse();
+      this.commands    = new Backbone.Wreqr.Commands();
+      this.channelName = channelName;
+    };
+  
+    _.extend(Channel.prototype, {
+  
+      // Remove all handlers from the messaging systems of this channel
+      reset: function() {
+        this.vent.off();
+        this.vent.stopListening();
+        this.reqres.removeAllHandlers();
+        this.commands.removeAllHandlers();
+        return this;
+      },
+  
+      // Connect a hash of events; one for each messaging system
+      connectEvents: function(hash, context) {
+        this._connect('vent', hash, context);
+        return this;
+      },
+  
+      connectCommands: function(hash, context) {
+        this._connect('commands', hash, context);
+        return this;
+      },
+  
+      connectRequests: function(hash, context) {
+        this._connect('reqres', hash, context);
+        return this;
+      },
+  
+      // Attach the handlers to a given message system `type`
+      _connect: function(type, hash, context) {
+        if (!hash) {
+          return;
+        }
+  
+        context = context || this;
+        var method = (type === 'vent') ? 'on' : 'setHandler';
+  
+        _.each(hash, function(fn, eventName) {
+          this[type][method](eventName, _.bind(fn, context));
+        }, this);
+      }
+    });
+  
+  
+    return Channel;
+  })(Wreqr);
+  
+  // Wreqr.Radio
+  // --------------
+  //
+  // An object that lets you communicate with many channels.
+  Wreqr.radio = (function(Wreqr){
+    "use strict";
+  
+    var Radio = function() {
+      this._channels = {};
+      this.vent = {};
+      this.commands = {};
+      this.reqres = {};
+      this._proxyMethods();
+    };
+  
+    _.extend(Radio.prototype, {
+  
+      channel: function(channelName) {
+        if (!channelName) {
+          throw new Error('Channel must receive a name');
+        }
+  
+        return this._getChannel( channelName );
+      },
+  
+      _getChannel: function(channelName) {
+        var channel = this._channels[channelName];
+  
+        if(!channel) {
+          channel = new Wreqr.Channel(channelName);
+          this._channels[channelName] = channel;
+        }
+  
+        return channel;
+      },
+  
+      _proxyMethods: function() {
+        _.each(['vent', 'commands', 'reqres'], function(system) {
+          _.each( messageSystems[system], function(method) {
+            this[system][method] = proxyMethod(this, system, method);
+          }, this);
+        }, this);
+      }
+    });
+  
+  
+    var messageSystems = {
+      vent: [
+        'on',
+        'off',
+        'trigger',
+        'once',
+        'stopListening',
+        'listenTo',
+        'listenToOnce'
+      ],
+  
+      commands: [
+        'execute',
+        'setHandler',
+        'setHandlers',
+        'removeHandler',
+        'removeAllHandlers'
+      ],
+  
+      reqres: [
+        'request',
+        'setHandler',
+        'setHandlers',
+        'removeHandler',
+        'removeAllHandlers'
+      ]
+    };
+  
+    var proxyMethod = function(radio, system, method) {
+      return function(channelName) {
+        var messageSystem = radio._getChannel(channelName)[system];
+        var args = Array.prototype.slice.call(arguments, 1);
+  
+        return messageSystem[method].apply(messageSystem, args);
+      };
+    };
+  
+    return new Radio();
+  
+  })(Wreqr);
+  
+
+  return Backbone.Wreqr;
+
+}));
diff --git a/planetstack/core/xoslib/static/js/underscore-min.js b/planetstack/core/xoslib/static/js/vendor/underscore-min.js
similarity index 100%
rename from planetstack/core/xoslib/static/js/underscore-min.js
rename to planetstack/core/xoslib/static/js/vendor/underscore-min.js
diff --git a/planetstack/core/xoslib/static/js/xos-backbone.js b/planetstack/core/xoslib/static/js/xos-backbone.js
deleted file mode 100644
index 0f6c1e4..0000000
--- a/planetstack/core/xoslib/static/js/xos-backbone.js
+++ /dev/null
@@ -1,129 +0,0 @@
-SLIVER_API = "/plstackapi/slivers/";
-SLICE_API = "/plstackapi/slices/";
-NODE_API = "/plstackapi/nodes/";
-SITE_API = "/plstackapi/sites/";
-USER_API = "/plstackapi/users/";
-DEPLOYMENT_API = "/plstackapi/deployments";
-
-XOSModel = Backbone.Model.extend({
-    /* from backbone-tastypie.js */
-    idAttribute: 'resource_uri',
-
-    /* from backbone-tastypie.js */
-    url: function() {
-		// Use the id if possible
-		var url = this.id;
-
-		// If there's no idAttribute, try to have the collection construct a url. Fallback to 'urlRoot'.
-		if ( !url ) {
-			url = this.collection && ( _.isFunction( this.collection.url ) ? this.collection.url() : this.collection.url );
-                        console.log(url);
-			url = url || this.urlRoot;
-		}
-
-		url && ( url += ( url.length > 0 && url.charAt( url.length - 1 ) === '/' ) ? '' : '/' );
-
-                url && ( url += "?no_hyperlinks=1" );
-
-		return url;
-	},
-});
-
-XOSCollection = Backbone.Collection.extend({
-    objects: function() {
-                return this.models.map(function(element) { return element.attributes; });
-             },
-
-    maybeFetch: function(options){
-            // Helper function to fetch only if this collection has not been fetched before.
-        if(this._fetched){
-                // If this has already been fetched, call the success, if it exists
-            options.success && options.success();
-            console.log("alreadyFetched");
-            return;
-        }
-
-            // when the original success function completes mark this collection as fetched
-        var self = this,
-        successWrapper = function(success){
-            return function(){
-                self._fetched = true;
-                success && success.apply(this, arguments);
-            };
-        };
-        options.success = successWrapper(options.success);
-        console.log("call fetch");
-        this.fetch(options);
-    },
-
-    getOrFetch: function(id, options){
-            // Helper function to use this collection as a cache for models on the server
-        var model = this.get(id);
-
-        if(model){
-            options.success && options.success(model);
-            return;
-        }
-
-        model = new this.model({
-            resource_uri: id
-        });
-
-        model.fetch(options);
-    },
-
-    /* from backbone-tastypie.js */
-    url: function( models ) {
-		var url = this.urlRoot || ( models && models.length && models[0].urlRoot );
-		url && ( url += ( url.length > 0 && url.charAt( url.length - 1 ) === '/' ) ? '' : '/' );
-
-		// Build a url to retrieve a set of models. This assume the last part of each model's idAttribute
-		// (set to 'resource_uri') contains the model's id.
-		if ( models && models.length ) {
-			var ids = _.map( models, function( model ) {
-					var parts = _.compact( model.id.split('/') );
-					return parts[ parts.length - 1 ];
-				});
-			url += 'set/' + ids.join(';') + '/';
-		}
-
-                url && ( url += "?no_hyperlinks=1" );
-
-		return url;
-	},
-});
-
-function xoslib() {
-    this.sliver = XOSModel.extend({ urlRoot: SLIVER_API });
-    this.sliverCollection = XOSCollection.extend({ urlRoot: SLIVER_API,
-                                                   model: this.sliver});
-    this.slivers = new this.sliverCollection();
-
-    this.slice = XOSModel.extend({ urlRoot: SLICE_API });
-    this.sliceCollection = XOSCollection.extend({ urlRoot: SLICE_API,
-                                                   model: this.slice});
-    this.slices = new this.sliceCollection();
-
-    this.node = XOSModel.extend({ urlRoot: NODE_API });
-    this.nodeCollection = XOSCollection.extend({ urlRoot: NODE_API,
-                                                   model: this.node});
-    this.nodes = new this.nodeCollection();
-
-    this.site = XOSModel.extend({ urlRoot: SITE_API });
-    this.siteCollection = XOSCollection.extend({ urlRoot: SITE_API,
-                                                   model: this.site});
-    this.sites = new this.siteCollection();
-
-    this.user = XOSModel.extend({ urlRoot: USER_API });
-    this.userCollection = XOSCollection.extend({ urlRoot: USER_API,
-                                                   model: this.user});
-    this.users = new this.userCollection();
-
-    this.deployment = XOSModel.extend({ urlRoot: DEPLOYMENT_API });
-    this.deploymentCollection = XOSCollection.extend({ urlRoot: DEPLOYMENT_API,
-                                                       model: this.deployment});
-    this.deployments = new this.deploymentCollection();
-};
-
-xos = new xoslib();
-
diff --git a/planetstack/core/xoslib/static/js/xosDeveloper.js b/planetstack/core/xoslib/static/js/xosDeveloper.js
new file mode 100644
index 0000000..aef640e
--- /dev/null
+++ b/planetstack/core/xoslib/static/js/xosDeveloper.js
@@ -0,0 +1,62 @@
+/* This is an example that uses xoslib + marionette to display the developer
+   view.
+
+   For an example that uses xoslib + datatables, see xosDeveloper_datatables.js
+*/
+
+DeveloperApp = new Marionette.Application();
+
+DeveloperApp.addRegions({
+  mainRegion: "#developerView"
+});
+
+DeveloperApp.SliceDetailView = Marionette.ItemView.extend({
+  template: "#developer-slicedetail-template",
+  tagName: 'tr',
+  className: 'developer_slicedetail'
+});
+
+DeveloperApp.SliceListView = Marionette.CompositeView.extend({
+  tagName: "table",
+  className: "table table-bordered table-striped",
+  template: "#developer-slicetable-template",
+  childView: DeveloperApp.SliceDetailView,
+  childViewContainer: "tbody",
+
+  events: {"click .sort": "changeSort"},
+
+  initialize: function() {
+      this.listenTo(this.collection, 'change', this._renderChildren);
+  },
+
+  changeSort: function(e) {
+      parts=$(e.currentTarget).attr("id").split('-');
+      order=parts[1];
+      fieldName=parts[2];
+      this.collection.sortVar = fieldName;
+      this.collection.sortOrder = order;
+      this.collection.sort();
+  },
+
+  attachHtml: function(compositeView, childView, index) {
+      // The REST API will let admin users see everything. For the developer
+      // view we still want to hide slices we are not members of.
+      if (childView.model.get("sliceInfo").roles.length == 0) {
+          return;
+      }
+      DeveloperApp.SliceListView.__super__.attachHtml(compositeView, childView, index);
+  },
+});
+
+DeveloperApp.on("start", function() {
+  var developerSliceListView = new DeveloperApp.SliceListView({
+    collection: xos.slicesPlus
+  });
+  DeveloperApp.mainRegion.show(developerSliceListView);
+  xos.slicesPlus.startPolling();
+});
+
+$(document).ready(function(){
+  DeveloperApp.start();
+});
+
diff --git a/planetstack/core/xoslib/static/js/xosDeveloper_datatables.js b/planetstack/core/xoslib/static/js/xosDeveloper_datatables.js
new file mode 100644
index 0000000..f0f92bf
--- /dev/null
+++ b/planetstack/core/xoslib/static/js/xosDeveloper_datatables.js
@@ -0,0 +1,46 @@
+/* This is an example that uses xoslib + datatables to display the developer
+   view.
+
+   For an example that uses xoslib + marionette, see xosDeveloper.js
+*/
+
+function updateSliceTable(data) {
+    $('#developerView').html( '<table cellpadding="0" cellspacing="0" border="0" class="display" id="dynamicusersliceinfo"></table>' );
+    var actualEntries = [];
+
+    for (rowkey in data.models) {
+        row = data.models[rowkey];
+        slicename = row.get("name");
+        sliceid = row.get("id");
+        role = row.get("sliceInfo").roles[0];
+        slivercount = row.get("sliceInfo").sliverCount;
+        sitecount = row.get("sliceInfo").siteCount;
+
+        if (! role) {
+            continue;
+        }
+
+        actualEntries.push(['<a href="/admin/core/slice/' + sliceid + '">' + slicename + '</a>',
+                            role, slivercount, sitecount]);
+    }
+    oTable = $('#dynamicusersliceinfo').dataTable( {
+        "bJQueryUI": true,
+        "aaData":  actualEntries ,
+        "bStateSave": true,
+        "aoColumns": [
+            { "sTitle": "Slice" },
+            { "sTitle": "Privilege" , sClass: "alignCenter"},
+            { "sTitle": "Number of Slivers" , sClass: "alignCenter"},
+            { "sTitle": "Number of Sites" , sClass: "alignCenter"},
+        ]
+    } );
+}
+
+$(document).ready(function(){
+    xos.slicesPlus.on("change", function() { /*console.log("change");*/ updateSliceTable(xos.slicesPlus); });
+    xos.slicesPlus.on("remove", function() { /*console.log("sort");*/ updateSliceTable(xos.slicesPlus); });
+    xos.slicesPlus.on("sort", function() { /*console.log("sort");*/ updateSliceTable(xos.slicesPlus); });
+
+    xos.slicesPlus.startPolling();
+});
+
diff --git a/planetstack/core/xoslib/static/js/xoslib/xos-backbone.js b/planetstack/core/xoslib/static/js/xoslib/xos-backbone.js
new file mode 100644
index 0000000..f18d303
--- /dev/null
+++ b/planetstack/core/xoslib/static/js/xoslib/xos-backbone.js
@@ -0,0 +1,205 @@
+if (! window.XOSLIB_LOADED ) {
+    window.XOSLIB_LOADED=true;
+
+    SLIVER_API = "/plstackapi/slivers/";
+    SLICE_API = "/plstackapi/slices/";
+    NODE_API = "/plstackapi/nodes/";
+    SITE_API = "/plstackapi/sites/";
+    USER_API = "/plstackapi/users/";
+    DEPLOYMENT_API = "/plstackapi/deployments";
+
+    SLICEPLUS_API = "/xoslib/slicesplus/";
+
+    XOSModel = Backbone.Model.extend({
+        /* from backbone-tastypie.js */
+        //idAttribute: 'resource_uri',
+
+        /* from backbone-tastypie.js */
+        url: function() {
+                    var url = this.attributes.resource_uri;
+
+                    if (!url) {
+                        url = this.urlRoot + this.id;
+                    }
+
+                    if (!url) {
+                        // XXX I'm not sure this does anything useful
+                        url = ( _.isFunction( this.collection.url ) ? this.collection.url() : this.collection.url );
+                        url = url || this.urlRoot;
+                    }
+
+                    // remove any existing query parameters
+                    url && ( url.indexOf("?") > -1 ) && ( url = url.split("?")[0] );
+
+                    url && ( url += ( url.length > 0 && url.charAt( url.length - 1 ) === '/' ) ? '' : '/' );
+
+                    url && ( url += "?no_hyperlinks=1" );
+
+                    return url;
+            },
+
+            listMethods: function() {
+                var res = [];
+                for(var m in this) {
+                    if(typeof this[m] == "function") {
+                        res.push(m)
+                    }
+                }
+                return res;
+            }
+    });
+
+    XOSCollection = Backbone.Collection.extend({
+        objects: function() {
+                    return this.models.map(function(element) { return element.attributes; });
+                 },
+
+        initialize: function(){
+          this.sortVar = 'name';
+          this.sortOrder = 'asc';
+        },
+
+        simpleComparator: function( model ){
+          parts=this.sortVar.split(".");
+          result = model.get(parts[0]);
+          for (index=1; index<parts.length; ++index) {
+              result=result[parts[index]];
+          }
+          return result;
+        },
+
+        comparator: function (left, right) {
+            var l = this.simpleComparator(left);
+            var r = this.simpleComparator(right);
+
+            if (l === void 0) return -1;
+            if (r === void 0) return 1;
+
+            if (this.sortOrder=="desc") {
+                return l < r ? 1 : l > r ? -1 : 0;
+            } else {
+                return l < r ? -1 : l > r ? 1 : 0;
+            }
+        },
+
+        startPolling: function() {
+            if (!this._polling) {
+                collection=this;
+                setInterval(function() { collection.fetch(); }, 10000);
+                this._polling=true;
+                this.fetch();
+            }
+        },
+
+        maybeFetch: function(options){
+                // Helper function to fetch only if this collection has not been fetched before.
+            if(this._fetched){
+                    // If this has already been fetched, call the success, if it exists
+                options.success && options.success();
+                console.log("alreadyFetched");
+                return;
+            }
+
+                // when the original success function completes mark this collection as fetched
+            var self = this,
+            successWrapper = function(success){
+                return function(){
+                    self._fetched = true;
+                    success && success.apply(this, arguments);
+                };
+            };
+            options.success = successWrapper(options.success);
+            console.log("call fetch");
+            this.fetch(options);
+        },
+
+        getOrFetch: function(id, options){
+                // Helper function to use this collection as a cache for models on the server
+            var model = this.get(id);
+
+            if(model){
+                options.success && options.success(model);
+                return;
+            }
+
+            model = new this.model({
+                resource_uri: id
+            });
+
+            model.fetch(options);
+        },
+
+        /* from backbone-tastypie.js */
+        url: function( models ) {
+                    var url = this.urlRoot || ( models && models.length && models[0].urlRoot );
+                    url && ( url += ( url.length > 0 && url.charAt( url.length - 1 ) === '/' ) ? '' : '/' );
+
+                    // Build a url to retrieve a set of models. This assume the last part of each model's idAttribute
+                    // (set to 'resource_uri') contains the model's id.
+                    if ( models && models.length ) {
+                            var ids = _.map( models, function( model ) {
+                                            var parts = _.compact( model.id.split('/') );
+                                            return parts[ parts.length - 1 ];
+                                    });
+                            url += 'set/' + ids.join(';') + '/';
+                    }
+
+                    url && ( url += "?no_hyperlinks=1" );
+
+                    return url;
+            },
+
+            listMethods: function() {
+                var res = [];
+                for(var m in this) {
+                    if(typeof this[m] == "function") {
+                        res.push(m)
+                    }
+                }
+                return res;
+            }
+    });
+
+    function xoslib() {
+        // basic REST
+        this.sliver = XOSModel.extend({ urlRoot: SLIVER_API });
+        this.sliverCollection = XOSCollection.extend({ urlRoot: SLIVER_API,
+                                                       model: this.sliver});
+        this.slivers = new this.sliverCollection();
+
+        this.slice = XOSModel.extend({ urlRoot: SLICE_API });
+        this.sliceCollection = XOSCollection.extend({ urlRoot: SLICE_API,
+                                                       model: this.slice});
+        this.slices = new this.sliceCollection();
+
+        this.node = XOSModel.extend({ urlRoot: NODE_API });
+        this.nodeCollection = XOSCollection.extend({ urlRoot: NODE_API,
+                                                       model: this.node});
+        this.nodes = new this.nodeCollection();
+
+        this.site = XOSModel.extend({ urlRoot: SITE_API });
+        this.siteCollection = XOSCollection.extend({ urlRoot: SITE_API,
+                                                       model: this.site});
+        this.sites = new this.siteCollection();
+
+        this.user = XOSModel.extend({ urlRoot: USER_API });
+        this.userCollection = XOSCollection.extend({ urlRoot: USER_API,
+                                                       model: this.user});
+        this.users = new this.userCollection();
+
+        this.deployment = XOSModel.extend({ urlRoot: DEPLOYMENT_API });
+        this.deploymentCollection = XOSCollection.extend({ urlRoot: DEPLOYMENT_API,
+                                                           model: this.deployment});
+        this.deployments = new this.deploymentCollection();
+
+        // enhanced REST
+        this.slicePlus = XOSModel.extend({ urlRoot: SLICEPLUS_API });
+        this.slicePlusCollection = XOSCollection.extend({ urlRoot: SLICEPLUS_API,
+                                                          model: this.slicePlus});
+        this.slicesPlus = new this.slicePlusCollection();
+
+        this.listObjects = function() { return ["slivers", "slices", "nodes", "sites", "users", "deployments"]; };
+    };
+
+    xos = new xoslib();
+}
diff --git a/planetstack/core/xoslib/static/xsh/constants.js b/planetstack/core/xoslib/static/js/xsh/constants.js
similarity index 100%
rename from planetstack/core/xoslib/static/xsh/constants.js
rename to planetstack/core/xoslib/static/js/xsh/constants.js
diff --git a/planetstack/core/xoslib/static/xsh/object_id.js b/planetstack/core/xoslib/static/js/xsh/object_id.js
similarity index 100%
rename from planetstack/core/xoslib/static/xsh/object_id.js
rename to planetstack/core/xoslib/static/js/xsh/object_id.js
diff --git a/planetstack/core/xoslib/static/xsh/shell_utils.js b/planetstack/core/xoslib/static/js/xsh/shell_utils.js
similarity index 100%
rename from planetstack/core/xoslib/static/xsh/shell_utils.js
rename to planetstack/core/xoslib/static/js/xsh/shell_utils.js
diff --git a/planetstack/core/xoslib/static/xsh/tokens.js b/planetstack/core/xoslib/static/js/xsh/tokens.js
similarity index 100%
rename from planetstack/core/xoslib/static/xsh/tokens.js
rename to planetstack/core/xoslib/static/js/xsh/tokens.js
diff --git a/planetstack/core/xoslib/static/xsh/utils.js b/planetstack/core/xoslib/static/js/xsh/utils.js
similarity index 100%
rename from planetstack/core/xoslib/static/xsh/utils.js
rename to planetstack/core/xoslib/static/js/xsh/utils.js
diff --git a/planetstack/core/xoslib/static/xsh/xsh.js b/planetstack/core/xoslib/static/js/xsh/xsh.js
similarity index 98%
rename from planetstack/core/xoslib/static/xsh/xsh.js
rename to planetstack/core/xoslib/static/js/xsh/xsh.js
index e439be0..758559f 100644
--- a/planetstack/core/xoslib/static/xsh/xsh.js
+++ b/planetstack/core/xoslib/static/js/xsh/xsh.js
@@ -299,7 +299,7 @@
 
   _t2: function() {
     this._tutorialPtr = 2;
-    return PTAG('2. The API is asynchronous') +
+    return PTAG('2. Reading from the server is asynchronous') +
            PTAG('Try these:') +
            PTAG('    xos.slices.models;') +
            PTAG('    // the above should have printed empty list') +
@@ -323,8 +323,8 @@
     this._tutorialPtr = 4;
     return PTAG('4. Available xos objects and methods') +
            PTAG('Try these:') +
-           PTAG('    xos;') +
-           PTAG('    xos.slices;');
+           PTAG('    xos.listObjects();') +
+           PTAG('    xos.slices.listMethods();');
 
   },
 
diff --git a/planetstack/observer/steps/sync_site_privileges.py b/planetstack/observer/steps/sync_site_privileges.py
index c229257..8724841 100644
--- a/planetstack/observer/steps/sync_site_privileges.py
+++ b/planetstack/observer/steps/sync_site_privileges.py
@@ -13,11 +13,6 @@
         return SitePrivilege.objects.filter(Q(enacted__lt=F('updated')) | Q(enacted=None))
 
     def sync_record(self, site_priv):
-        if site_priv.user.kuser_id and site_priv.site.tenant_id:
-            self.driver.add_user_role(site_priv.user.kuser_id,
-                                      site_priv.site.tenant_id,
-                                      site_priv.role.role) 
-
         # sync site privileges at all site deployments
         site_deployments = SiteDeployments.objects.filter(site=site_priv.site)
         for site_deployment in site_deployments:
diff --git a/planetstack/planetstack/settings.py b/planetstack/planetstack/settings.py
index c9c4cf3..215501a 100644
--- a/planetstack/planetstack/settings.py
+++ b/planetstack/planetstack/settings.py
@@ -81,6 +81,7 @@
 
 # Additional locations of static files
 STATICFILES_DIRS = ( "/opt/planetstack/core/static/",
+                     "/opt/planetstack/core/xoslib/static/",
     # Put strings here, like "/home/html/static" or "C:/www/django/static".
     # Always use forward slashes, even on Windows.
     # Don't forget to use absolute paths, not relative paths.
@@ -124,6 +125,7 @@
     # Always use forward slashes, even on Windows.
     # Don't forget to use absolute paths, not relative paths.
     "/opt/planetstack/templates",
+    "/opt/planetstack/core/xoslib/templates",    
 )
 
 INSTALLED_APPS = (
diff --git a/planetstack/planetstack/urls.py b/planetstack/planetstack/urls.py
index eb7f40c..3513a38 100644
--- a/planetstack/planetstack/urls.py
+++ b/planetstack/planetstack/urls.py
@@ -12,6 +12,7 @@
 from rest_framework import generics
 from core.dashboard.sites import SitePlus
 from django.http import HttpResponseRedirect
+#from core.xoslib import XOSLibDataView
 
 admin.site = SitePlus()
 admin.autodiscover()
@@ -34,6 +35,8 @@
     url(r'^', include(admin.site.urls)),
     #url(r'^profile/home', 'core.views.home'),
 
+#    url(r'^admin/xoslib/(?P<name>\w+)/$', XOSLibDataView.as_view(), name="xoslib"),
+
     url(r'^plstackapi/$', api_root),
 
     url(r'^plstackapi/dashboardviews/$', DashboardViewList.as_view(), name='dashboardview-list'),
@@ -119,5 +122,7 @@
 
     #Adding in rest_framework urls
     url(r'^plstackapi/', include('rest_framework.urls', namespace='rest_framework')),
-    
+
+    # XOSLib rest methods
+    url(r'^xoslib/', include('core.xoslib.methods', namespace='xoslib')),    
 )
diff --git a/planetstack/templates/admin/dashboard/developer.html b/planetstack/templates/admin/dashboard/developer.html
index 00c49c7..13f178f 100644
--- a/planetstack/templates/admin/dashboard/developer.html
+++ b/planetstack/templates/admin/dashboard/developer.html
@@ -29,7 +29,7 @@
 
     $('#developerview').html( '<table cellpadding="0" cellspacing="0" border="0" class="display" id="dynamicusersliceinfo"></table>' );
     var actualEntries = [];
-    log.debug(data['userSliceInfo']['rows'][0]['slicename']);
+    //log.debug(data['userSliceInfo']['rows'][0]['slicename']);
 
     var rows = data['userSliceInfo']['rows'];
     for (row in rows) {
