Make your Backbone.js apps dance with a composite application architecture!
Pull request Compare This branch is 3040 commits behind marionettejs:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.

Make your Backbone.js apps dance with a composite application architecture!


Backbone.Marionette is a composite application library for Backbone.js that aims to simplify the construction of large scale JavaScript applications. It is largely a collection of common design and implementation patterns found in the applications that I (Derick Bailey) have been building with Backbone, and includes various peices inspired by composite application architectures, such as Microsoft's "Prism" framework.

Backbone.Marionette is designed to be a lightweigt and flexible library of tools that you can use when you want to. Like Backbone.js itself, you're not required to use all of Backbone.Marionette just because you want to use some of it.

Downloads And Source Code

You can download the raw source code above, fork the repository or use these links:

Development: backbone.marionette.js 14.53K file size (4.77K gzipped)

Production: backbone.marionette.min.js 5.21K file size (1.78K gzipped)

Annotated Source Code

For a good time, call.. err... read through the annotated source code.

Marionette's Pieces

These are the strings that you can pull to make your puppet dance:

  • Backbone.Marionette.Application: An application object that starts your app via initializers, and more
  • Backbone.Marionette.AppRouter: Reduce your routers to nothing more then configuration
  • Backbone.Marionette.ItemView: A view that renders a single item
  • Backbone.Marionette.CollectionView: A view that iterates over a collection, and renders individual ItemView instances for each model
  • Backbone.Marionette.RegionManager: Manage visual regions of your application, including display and removal of content
  • Backbone.Marionette.EventAggregator: An extension of Backbone.Events, to be used as an event-driven or pub-sub tool
  • Backbone.Marionette.BindTo: An event binding manager, to facilitate binding and unbinding of events
  • Backbone.Marionette.TemplateManager: Cache templates that are stored in <script> blocks, for faster subsequent access
  • Backbone.Marionette.Callbacks: Manage a collection of callback methods, and execute them as needed

The Application, RegionManager, ItemView and CollectionView use the extend syntax and functionality from Backbone, allowing you to define new versions of these objects with custom behavior.


The Backbone.Marionette.Application object is the hub of your composite application. It organizes, initializes and coordinate the various pieces of your app. It also provides a starting point for you to call into, from your HTML script block or from your JavaScript files directly if you prefer to go that route.

The Application is meant to be instantiate directly, although you can extend it to add your own functionality.

MyApp = new Backbone.Marionette.Application();

Adding Initializers

Your application needs to do useful things, like displaying content in your regions, starting up your routers, and more. To accomplish these tasks and ensure that your Application is fully configured, you can add initializer callbacks to the application.

  // do useful stuff here
  var myView = new MyView({
    model: options.someModel

  new MyAppRouter();

These callbacks will be executed when you start your application, and are bound to the application object as the context for the callback. In other words, this is the MyApp object, inside of the initializer function.

The options parameters is passed from the start method (see below).

Initializer callbacks are guaranteed to run, no matter when you add them to the app object. If you add them before the app is started, they will run when the start method is called. If you add them after the app is started, they will run immediately.

Application Event;

The Application object raises a few events during its lifecycle. These events can be used to do additional processing of your application. For example, you may want to pre-process some data just before initialization happens. Or you may want to wait until your entire application is initialized to start the Backbone.history.

The events that are currently triggered, are:

  • "initialize:before": fired just before the initializers kick off
  • "initialize:after": fires just after the initializers have finished
  • "start": fires after all initializers and after the initializer events
MyApp.bind("initialize:before", function(options){
  options.moreData = "Yo dawg, I heard you like options so I put some options in your options!"

MyApp.bind("initialize:after", function(options){
  if (Backbone.history){

The options parameter is passed through the start method of the application object (see below).

Starting An Application

Once you have your application configured, you can kick everything off by calling: MyApp.start(options).

This function takes a single optional parameter. This parameter will be passed to each of your initializer functions, as well as the initialize events. This allows you to provide extra configuration for various parts of your app, at initialization/start of the app, instead of just at definition.

var options = {
  something: "some value",
  another: "#some-selector"


app.vent: Event Aggregator

Every application instances comes with an instance of Marionette.EventAggregator called app.vent.

MyApp = new Backbone.Marionette.Application();

MyApp.vent.on("foo", function(){

MyApp.vent.trigger("foo"); // => alert box "bar"

See the Marionette.EventAggregator documentation below, for more details.


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 Routes

Configure an AppRouter with appRoutes. The route definition is passed on to Backbones standard routing handlers. This means that you define routes like you normally would. Instead of providing a callback method that exists on the router, though, you provide a callback method that exists on the controller that you specify for the router instance (see below).

MyRouter = Backbone.Marionette.AppRouter.extend({
  appRoutes: {
    "some/route": "someMethod"

You can also add standard routes to an AppRouter, with methods on the router.

Specify A Controller

App routers can only use one controller object. You can either specify this directly in the router definition:

someController = {
  someMethod: function(){ /*...*/ }

  controller: someController

Or in a parameter to the contructor:

myObj = {
  someMethod: function(){ /*...*/ }

new MyRouter({
  controller: myObj


The object that is used as the controller has no requirements, other than it will contain the methods that you specified in the appRoutes.

It is reocmmended that you divide your controller objects in to smaller peices of related functionality and have multiple routers / controllers, instead of just one giant router and controller.


Region managers provide a consistent way to manage your views and show / close them in your application. They use a jQuery selector to show your views in the correct place. They also call extra methods on your views, to facilitate additional functionality.

Defining An Application Region

Regions can be added to the application by calling the addRegions method on your application instance. This method expects a single hash parameter, with named regions and either jQuery selectors or RegionManager objects. You may call this method as many times as you like, and it will continue adding regions to the app.

  mainRegion: "#main-content",
  navigationRegion: "#navigation"

As soon as you call addRegions, your region managers are available on your app object. In the above, example MyApp.mainRegion and MyApp.navigationRegion would be available for use immediately.

If you specify the same region name twice, last one in wins.

Initialize A Region Manager With An el

You can specify an el for the region manager to manage at the time that the region manager is instantiated:

var mgr = new Backbone.Marionette.RegionManager({
  el: "#someElement"

Basic Usage

Once a region manager has been defined, you can call the show and close methods on it to render and display a view, and then to close that view:

var myView = new MyView();

// render and display the view;

// closes the current view

If you replace the current view with a new view by calling show, it will automatically close the previous view.

// show the first view
var myView = new MyView();;

// replace view with another. the
// `close` method is called for you
var anotherView = new AnotherView();;

Region Manager Events

A region manager will raise a few events during it's showing and closing of views:

  • "view:show" - when the view has been rendered and displayed
  • "view:closed" - when the view has been closed

You can bind to these events and add code that needs to run with your region manager, opening and closing views.

MyApp.mainRegion.on("view:show", function(view){
  // manipulate the `view` or do something extra
  // with the region manager via `this`

MyApp.mainRegion.on("view:closed", function(view){
  // manipulate the `view` or do something extra
  // with the region manager via `this`

Defining A Custom Region Manager

You can define a custom region manager by extending from RegionManager. This allows you to create new functionality, or provide a base set of functionality for your app.

Once you define a region manager type, you can still call the addRegions method. Specify the region manager type as the value - not an instance of it, but the actual constructor function.

var FooterRegion = Backbone.Marionette.RegionManager.extend({
  el: "#footer"

MyApp.addRegions({footerRegion: FooterRegion});

Note that if you define your own RegionManager object, you must provide an el for it. If you don't, you will receive an runtime exception saying that an el is required.

Instantiate Your Own Region Manager

There may be times when you want to add a region manager to your application after your app is up and running. To do this, you'll need to extend from RegionManager as shown above and then use that constructor function on your own:

var SomeRegion = Backbone.Marionette.RegionManager.extend({
  el: "#some-div"

MyApp.someRegion = new SomeRegion();;

jQuery Deferred And Asynchronous Template Loading

The region manager show method takes advantage of jQuery's deferred cababilities, allowing for some very advanced techniques to be used for rendering views.

To use a deferred, a view that is shown via a region manager must return a jQuery deferred object from the render method:

DeferredView = Backbone.View.extend({
  render: function(){
    var that = this;
    var data = this.serializeData();
    var dfd = jQuery.Deferred();

      var html = that.renderTemplate(template, data);


      if (that.onRender){


    return dfd.promise();

var view = new DeferredView();;

The region manager will wait until the deferred object is resolved before it attached the view's el to the DOM and displays it.


An ItemView is a view that represents a single item. That item may be a Backbone.Model or may be a Backbone.Collection. Whichever it is, though, it will be treated as a single item.

ItemView render

An item view has a render method built in to it. By default it uses underscore.js templates.

The default implementation will use a template that you specify (see below) and serialize the model or collection for you (see below).

You can provide a custom implementation of a method called renderTemplate to change template engines. For example, if you want to use jQuery templates, you can do this:

  renderTemplate: function(template, data){
    return template.tmpl(data);

The template parameter is a jQuery object with the contents of the template that was specified in the view (see below).

The data parameter is the serialized data for either the model or the collection of the view (see below).

After the view has been rendered, a onRender method will be called. You can implement this in your view to provide custom code for dealing with the view's el after it has been rendered:

  onRender: function(){
    // manipulate the `el` here. it's already
    // been rendered, and is full of the view's
    // HTML, ready to go.

ItemView template

Item views should be configured with a template. The template attribute should be either a valid jQuery selector, or a function that returns a valid jQuery selector:

MyView = Backbone.Marionette.ItemView.extend({
  template: "#some-template"

AnotherView = Backbone.Marionette.ItemView.extend({
  template: function(){
    return $("#some-template")

new SomeItemView({
  template: "#some-template"

If no template is specified, an error will be throwing saying so.

ItemView serializeData

Item views will serialize a model or collection, by default, by calling .toJSON on either the model or collection. If both a model and collection are attached to an item view, the model will be used as the data source. The results of the data serialization will be passed to the template that is rendered.

If the serialization is a model, the results are passed in directly:

var myModel = new MyModel({foo: "bar"});

new MyItemView({
  template: "#myItemTemplate",
  model: myModel

<script id="myItemTemplate" type="template">
  Foo is: <%= foo %>

If the serialization is a collection, the results are passed in as an items array:

var myCollection = new MyCollection([{foo: "bar"}, {foo: "baz"}]);

new MyItemView({
  template: "#myCollectionTemplate",
  collection: myCollection

<script id="myCollectionTemplate" type="template">
  <% _.each(items, function(item){ %>
    Foo is: <%= foo %>
  <% }); %>

If you need custom serialization for your data, you can provide a serializeData method on your view. It must return a valid JSON object, as if you had called .toJSON on a model or collection.

  serializeData: function(){
    return {
      "some attribute": "some value"

ItemView events

ItemView extends Marionette.BindTo. It is recommended that you use the bindTo method to bind model and collection events.

MyView = Backbone.Marionette.ItemView.extend({
  initialize: function(){
    this.bindTo(this.model, "change:foo", this.modelChanged);
    this.bindTo(this.collection, "add", this.modelAdded);

  modelChanged: function(model, value){

  modelAdded: function(model){

The context (this) will automatically be set to the view. You can optionally set the context by passing in the context object as the 4th parameter of bindTo.

ItemView close

ItemView implements a close method, which is called by the region managers automatically. As part of the implementation, the following are performed:

  • unbind all bindTo events
  • unbind all custom view events
  • unbind all DOM events
  • remove this.el from the DOM
  • call an onClose event on the view, if one is provided

By providing an onClose event in your view definition, you can run custom code for your view that is fired after your view has been closed and cleaned up. This lets you handle any additional clean up code without having to override the close method.

  onClose: function(){
    // custom cleanup or closing code, here


The CollectionView will loop through all of the models in the specified collection, render each of them using a specified itemView, then append the results of the item view's el to the collection view's el.

After the view has been rendered, a onRender method will be called. You can implement this in your view to provide custom code for dealing with the view's el after it has been rendered:

CollectionView's itemView

Specify an itemView in your collection view definition. This must be a Backbone view object definition (not instance). It can be any Backbone.View or be derived from Marionette.ItemView.

MyItemView = Backbone.Marionette.ItemView.extend({});

  itemView: MyItemView

If you do not specify an itemView, an exception will be thrown stating that you must specify an itemView.

CollectionView: Automatic Rendering

The collection view binds to the "add", "remove" and "reset" events of the collection that is specified.

When the collection for the view is "reset", the view will call reRender on itself and re-render the entire collection.

When a model is added to the collection, the collection view will render that one model in to the collection of item views.

When a model is removed from a collection (or destroyed / deleted), the collection view will close and remove that model's item view.

CollectionView: Re-render Collection

If you need to re-render the entire collection, you can call the view.reRender method. This method takes care of closing all of the child views that may have previously been opened.

CollectionView's appendHtml

By default the collection view will call jQuery's .append to move the HTML contents from the item view instance in to the collection view's el.

You can override this by specifying an appendHtml method in your view definition. This method takes two parameters and has no return value.

Parameter el: the collection view's el, as a jQuery selector object.

Parameter html: the HTML contents that were generated by the item view.

  appendHtml: function(el, html){

Composite View

A CollectionView can be work as a composite view for scenarios where it should represent both a branch and leaf in a tree structure.

For example, if you're rendering a treeview control, you may want to render a collection view with a model and template so that it will show a parent item with children in the tree.

You can specify a modelView to use for the model. If you don't specify one, it will default to the Marionette.ItemView.

LeafView = Backbone.Marionette.ItemView.extend({
  template: "leaf-template"

CompositeView = Backbone.Marionette.CollectionView.extend({
  template: "leaf-template"
  modelView: LeafView,
  itemView: LeafView

new CompositeView({
  model: someModel,
  collection: someCollection

CollectionView close

CollectionView implements a close method, which is called by the region managers automatically. As part of the implementation, the following are performed:

  • unbind all bindTo events
  • unbind all custom view events
  • unbind all DOM events
  • unbind all item views that were rendered
  • remove this.el from the DOM
  • call an onClose event on the view, if one is provided

By providing an onClose event in your view definition, you can run custom code for your view that is fired after your view has been closed and cleaned up. This lets you handle any additional clean up code without having to override the close method.

  onClose: function(){
    // custom cleanup or closing code, here


An event aggregator is an application level pub/sub mechanism that allows various pieces of an otherwise segmented and disconnected system to communicate with each other.

Basic Usage

Backbone.Marionette provides an event aggregator with each application instance: MyApp.vent. You can also instantiate your own event aggregator:

myVent = new Backbone.Marionette.EventAggregator();

Passing an object literal of options to the constructor function will extend the event aggregator with those options:

myVent = new Backbone.Marionette.EventAggregator({foo: "bar"}); // => "bar"


The EventAggregator extends from the BindTo object (see below) to easily track and unbind all event callbacks, including inline callback functions.

The bindTo method, though, has been proxied to only take 3 arguments. It assumes that the object being bound to is the event aggregator directly, and does not allow the bound object to be specified:

vent = new Backbone.Marionette.EventAggregator();

vent.bindTo("foo", function(){


vent.trigger("foo"); // => nothing. all events have been unbound.

Decoupling With An Event-Driven Architecture

You can use an event aggregator to communicate between various modules of your application, ensuring correct decoupling while also facilitating functionality that needs more than one of your application's modules.

var vent = new Backbone.Marionette.EventAggregator();

vent.bind("some:event", function(){
  alert("Some event was fired!!!!");

For a more detailed discussion and example of using an event aggregator with Backbone applications, see the blog post: References, Routing, and The Event Aggregator: Coordinating Views In Backbone.js


The BindTo object provides event binding management and facilitates simple event binding and unbinding for any object that extends from Backbone.Events.

Bind Events

var binder = _.extend({}, Backbone.Marionette.BindTo);

var model = new MyModel();

var handler = {
  doIt: function(){}
binder.bindTo(model, "change:foo", handler.doIt);

You can optionally specify a 4th parameter as the context in which the callback method for the event will be executed:

binder.bindTo(model, "change:foo", someCallback, someContext);

Unbind All Events

You can call unbindAll to unbind all events that were bound with the bindTo method:


This even works with in-line callback functions.


The TemplateManager provides a cache for retrieving templates from script blocks in your HTML. This will improve the speed of subsequent calls to get a template.

Basic Usage

To use the TemplateManager, call it directly. It is not instantiated like other Marionette objects.

Get A Template

Templates are retrieved by jQuery selector, by default, and handed back to you via a callback method:

Backbone.Marionette.TemplateManager.get("#my-template", function(template){
 // use the template here

Making multiple calls to get the same template will retrieve the template from the cache on subsequence calls:

var a, b, c;
Backbone.Marionette.TemplateManager.get("#my-template", function(tmpl){a = tmpl});
Backbone.Marionette.TemplateManager.get("#my-template", function(tmpl){b = tmpl});
Backbone.Marionette.TemplateManager.get("#my-template", function(tmpl){c = tmpl});
a === b === c; // => true

Override Template Retrieval

The default template retrieval is to select the template contents from the DOM using jQuery. If you wish to change the way this works, you can override the loadTemplate method on the TemplateManager object.

For example, if you want to load templates asychronously from the server, instead of from the DOM, you could replace loadTemplate with a function like this:

Backbone.Marionette.TemplateManager.loadTemplate = function(templateId, callback){
  var that = this;
  $.get(templateId + ".html", function(template){, template);

This will use jQuery to asynchronously retrieve the template from the server, and then store the retrieved template in the template manager's cache.

Clear Items From cache

You can clear one or more, or all items from the cache using the clear method. Clearing a template from the cache will force it to re-load from the DOM (or from the overriden loadTemplate function) the next time it is retrieved.

If you do not specify any parameters, all items will be cleared from the cache:


// clear all templates from the cache

If you specify one or more parameters, these parameters are assumed to be the templateId used for loading / caching:


// clear 2 of 3 templates from the cache
Backbone.Marionette.TemplateManager.clear("#my-template", "#this-template")

Built In To ItemView

If you're using Marionette.ItemView, you don't need to manually call the TemplateManager. Just specify the template attribute of your view as a jQuery selector, and the ItemView will use the template manager by default.


The Callbacks object assists in managing a collection of callback methods, and executing them, in an async-safe manner.

Basic Usage

There are only three methods:

  • add
  • run
  • setOptions

The add method adds a new callback to be executed later.

The run method executes all current callbacks in, using the specified context for each of the callbacks, and supplying the provided options to the callbacks.

var callbacks = new Backbone.Marionette.Callbacks();

  alert("I'm a callback with " + options.value + "!");
});, {value: "options"});

This example will display an alert box that says "I'm a callback with options!". The executing context for each of the callback methods has been set to the someContext object, which can be any valid JavaScript object.

Advanced / Async Use

The Callbacks executes each callback in an async-friendly manner, and can be used to facilitate async callbacks. The Marionette.Application object uses Callbacks to manage initializers (see above).

It can also be used to guarantee callback execution in an event driven scenario, much like the application initializers.

Backbone.Marionette Example Apps

There are several sample apps available.


I'm building a medium sized app to demonstrate Backbone.Marionette. It's a simple clone of a GMail like interface, with email and contact management. There is no back end for data, currently. The sample app does run on top of Ruby and Sinatra, but all the data is hard coded into the HTML/JavaScript right now.

You can find BBCloneMail online at:

And you can find the source code at:

Steve Gentile' Contact Manager

Steve Gentile is building two versions of the same contact manager app. One of them runs on NodeJS as a back-end, and the other runs on ASP.NET MVC as the back-end.

The NodeJS version is here:

And the ASP.NET MVC version is here:

Quick & Dirty Sample

Here's a quick and dirty example to show how to use some of the pieces of Marionette:

// define the application
// options we pass in are copied on to the instance
MyApp = new Backbone.Marionette.Application({
  someOption: "some value";

// add a region to the app
myRegion = Backbone.Marionette.RegionManager.extend({
  el: "#my-region"
MyApp.addRegions({ myRegion: MyRegion });

// define some functionality for the app
(function(MyApp, Backbone){

  // a view to render into the region
  var SomeView = Backbone.View.extend({
    render: function(){

      // get "someOption" from the app, since we
      // passed it into the app initializer, above

    doSomething: function(){
      // the applicaiton has an event aggregator on instantiation
      // call out to the event aggregator to raise an event

  // an initializer to run this functional area 
  // when the app starts up
    var someView = new SomeView();;

})(MyApp, Backbone);

// calling start will run all of the initializers
// this can be done from your JS file directly, or
// from a script block in your HTML

Compatibility And Requirements

Theses libraries are require for the use, development, testing and documentation of Backbone.Marionette.

Runtime Requirements

Backbone.Marionette currently works with the following versions of these libraries:

  • Backbone v0.9.1
  • Underscore v1.3.1
  • jQuery v1.7.1

While support for Zepto and Enderjs has been added, it is not officially tested against these libraries at this time.

Marionette has not been tested against any other versions of these libraries. You may or may not have success if you use a version other than what it listed here.

Test Suite

Backbone.Marionette is also tested with the Jasmine JavaScript test utility, using the Jasmine Ruby gem.

To get the test suite up and running, you need a Ruby installation with the latest RubyGems. Install the 'bundler' gem and then run 'bunle install' from the project's root folder. Then run rake jasmine to run the test suite, and load up http://localhost:8888 to see the test suite in action.

Annotated Source Code

I'm using Docco to generate the annotated source code.

Release Notes


  • Don't re-render an ItemView when the view's model "change" event is triggered


  • Allow RegionManager to be instantiated with an el specified in the options
  • Change how RegionManagers are added to an Application instance, to reduce memory usage from extraneous types


  • AppRouter can have it's controller specified directly in the router definition or in the construction function call
  • Extracted Marionette.EventAggregator out in to it's own explicit object


  • CollectionView closes existing child views before re-rendering itself, when "reset" event of collection is triggered
  • CollectionView now has "initialEvents" method which configures it's initial events
  • ItemView now has "initialEvents" method which configures it's initial events


  • CollectionView renders itself when the view's collection "reset" event is fired
  • ItemView renders itself when the view's model "change" event is fired
  • ItemView renders itself when the view's collection "reset" event is fired


  • Fixed bug with RegionManagers trying to select element before DOM is ready, to lazy-select the element on first use of show


  • BREAKING: Removed the setOptions method from the Callbacks object
  • Refactored Callbacks object to use a jQuery Deferred instead of my own code
  • Fixed template manager's clear so it properly clears a single template, when only one is specified
  • Refactored the RegionManager code to support several new features
    • now support returning a jQuery deferred object from a view's render method
    • now have a close method that you can call to close the current view
    • now trigger a "view:show" and "view:close" event
    • correctly remove reference to previous views, allowing garbage collection of the view
    • now support the bindTo and unbindAll methods, for binding/unbinding region manager events


  • Minor fix to context of template manager callback, to fix issue w/ async template loading


  • BREAKING: Rewrote the template manager to be async-template loading friendly
  • BREAKING: Dropping support for Backbone v0.5.3 and below
  • Added Marionette.Callbacks to manage a collection of callbacks in an async-friendly way
  • Guarantee the execution of app initializer functions, even if they are added after the app has been started.
  • App triggers "start" event after initializers and initializer events
  • Updated to Backbone v0.9.1


  • Make region managers initialize immediately when calling app.addRegions


  • BREAKING: view.el for ItemView and CollectionView is no longer a jQuery selector object. Use view.$el instead
  • BREAKING: regionManger.el is no longer a jQuery selector object. Use regionManager.$el instead
  • Updated to use Backbone v0.9.0
  • Updated to use Underscore v1.3.1
  • Removed default itemView from the CollectionView definition
  • CollectionView now explicitly checks for an itemView defined on it, and throws an error if it's not found


  • Bind the context (this) of application initializer functions to the application object


  • Added AppRouter, to reduce boilerplate routers down to simple configuration
  • CollectionView can be treated as a composite view, rendering an model and a collection of models
  • Now works with either jQuery, Zepto, or enter.js
  • ItemView will throw an error is no template is specified


  • Return this (the view itself) from ItemView and CollectionView render method
  • Call onRender after the CollectionView has rendered itself


  • Fixed global variable leaks
  • Removed declared, but unused variables


  • Fixed binding events in the collection view to use bindTo (#6)
  • Updated specs for collection view
  • Documentation fixes (#7)


  • Added TemplateManager to cache templates
  • CollectionView binds to add/remove and updates rendering appropriately
  • ItemView uses TemplateManager for template retrieval
  • ItemView and CollectionView set this.el = $(this.el) in constructor


  • Added ItemView
  • Added CollectionView
  • Added BindTo
  • Simplified the way extend is pulled from Backbone


  • Initial release
  • Created documentation
  • Generated annotated source code

Legal Mumbo Jumbo (MIT License)

Copyright (c) 2011 Derick Bailey, Muted Solutions, LLC

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.