Don't expose jQuery to `window` with AMD #557

Closed
wants to merge 1 commit into
from

Conversation

Projects
None yet
9 participants

Ticket: http://bugs.jquery.com/ticket/10545

One of the great features of AMD is not touching the global namespace outside of require and define.

I don't want my team and I to use jQuery w/o deliberating requiring it into a module, additionally the RequireJS optimizer will know to include it.

For people requiring from a CDN, they just configure the paths, no need for a global jQuery object in an AMD environment:

var require = {
  paths: {
    "jquery": "http://code.jquery.com/jquery-1.7b2.js"
  }
};
Member

rwaldron commented Oct 20, 2011

@rpflorence can you file a ticket for this? http://bugs.jquery.com

Ticket filed, added to first comment - http://bugs.jquery.com/ticket/10545

Owner

timmywil commented Oct 20, 2011

I agree this is the way it should be done.

@ryanflorence ryanflorence commented on the diff Oct 20, 2011

src/core.js
@@ -935,20 +935,6 @@ function doScrollCheck() {
jQuery.ready();
}
-// Expose jQuery as an AMD module, but only for AMD loaders that
@ryanflorence

ryanflorence Oct 20, 2011

Removed from core.js because outro is where the jQuery object is "exported".

Member

addyosmani commented Oct 20, 2011

Agreed - ticket marked as valid. http://bugs.jquery.com/ticket/10545

Member

rwaldron commented Oct 20, 2011

@rpflorence thanks for filing the ticket :)

Contributor

jrburke commented Oct 20, 2011

I appreciate wanting to do this, but I'm not sure it is safe to do so given how much jQuery is used. One of the reasons the original AMD patch was pulled from 1.6 was concerns about how multiple versions of jQuery would interact with AMD, since some pages can inadvertently load more than one version of jQuery.

The define.amd.jQuery was added so that an AMD loader could broadcast that it knew there could be a few jQuerys loaded on a page and had mitigations so that the developer who was using an AMD loader could receive the correct one. In requirejs, there is multversion support and also a way in the config to specify only accepting a specific version of jquery in the define call.

My concern with this patch is that a third party lib that uses jQuery is loaded on a page with an AMD loader. This patch would mean the AMD loader would get that version of jQuery but the third party lib would not see a global jQuery object, and errors would occur. What is worse, the AMD loader may just outright reject that jQuery registration call if it is looking for a different jQuery version.

If jQuery were not as popular as it is now, or started off always with this logic, it would not be that much of a concern. In fact if it was any other JS library out there, the approach in this patch is the right one. However, for jQuery, I believe it will lead to errors and elevated support requests.

I do not have a complete understanding of the magnitude of this hazard, the jQuery core folks can answer that better. But this concern is what lead me doing the AMD registration as it is today.

For AMD folks that do not want to export a global, they can do an optimized build and call jQuery.noConflict() to get this effect (with the build there should not be a window when the AMD-desired jQuery interferes with another one in the page). Not the ideal, but sometimes these kinds of things are needed to upgrade the web.

It would be good to get feedback on what people think is the relative threat of problems as outlined above, but I think given jQuery's special status doing the dual registration is the less disruptive route.

Thanks James, that's why I pulled you in, I was sure there might be some issues.

My concern with this patch is that a third party lib that uses jQuery is loaded on a page with an AMD loader. This patch would mean the AMD loader would get that version of jQuery but the third party lib would not see a global jQuery object, and errors would occur.

A quick jQuery.noConflict() in the main.js is the safest bet, for sure. However, I believe that if somebody is building their app with AMD, they will be aware of this. I feel like if you're going to support AMD, support AMD all the way, incentivizing third party libs to support AMD as well.

I'm also curious what the repercussions would be and (hope) they're worth it.

Contributor

jrburke commented Oct 20, 2011

A quick jQuery.noConflict() in the main.js is the safest bet, for sure. However, I believe that if somebody is building their app with AMD, they will be aware of this. I feel like if you're going to support AMD, support AMD all the way, incentivizing third party libs to support AMD as well.

The problem is the code change hurts people that are not opting in to AMD, which at the moment is a larger set of people, and the error may be tricky for them to track down, indeed it can break code that no longer has an owner. I think, in jQuery's case, having the people embracing the future do a little bit more work is the less disruptive path, and maybe by a jQuery 2.0 the behavior could be changed to this logic of either/or.

But it would be good to get a read from the jQuery core members on their assessment of the risk. I would be happy to go this either/or path if the core folks felt the risk is manageable.

Maybe I am overestimating how much jQuery is used in third party code that ends up on pages, and maybe we just need to document how they can temporarily override define() while their bundled code executes to avoid the issue, then set back define() when done.

Owner

timmywil commented Oct 20, 2011

I suppose jQuery.noConflict(true) is an easy solution. I would like to see it completely modular, but @jrburke's prediction of many support requests would certainly be true.

Given the sheer number of jQuery plugins, it would be difficult to require editing each one to conform to AMD. And yet, not impossible. If you're using an AMD loader, you already know how it works and I'm sure you already have several concerns if you're loading multiple versions of jQuery on the page.

Anyway, I'm flipflopping.

Owner

dmethvin commented Nov 6, 2011

Per http://bugs.jquery.com/ticket/10545 we are destroying that flipflopper timmywil's political career.

dmethvin closed this Nov 6, 2011

I agree, this is probably the best decision after further thought. I still think, however, that the AMD stuff should move into the outro so all "exporting" of jQuery is done in the same place.

On Nov 6, 2011, at 2:45 PM, Dave Methvin wrote:

Per http://bugs.jquery.com/ticket/10545 we are destroying that flipflopper timmywil's political career.


Reply to this email directly or view it on GitHub:
#557 (comment)

Contributor

jrburke commented Nov 7, 2011

I still think, however, that the AMD stuff should move into the outro so all "exporting" of jQuery is done in the same place.

@rpflorence, I think it still may move to the outro to help with the issue found as described in this ticket, even if the global is kept.

Member

SlexAxton commented Nov 7, 2011

I didn't know about this ticket, but as someone who uses AMD jQuery in production on lots of third party sites, I'm glad that I'm the one in control of the noConflicting and globals. People add all kinds of crazy stuff to their pages, and I think the group that we should target to do the extra work is the one that likely knows more about what they're doing. So +1 to moving to the outro, but keeping the global (even though I destroy it everytime).

Contributor

jrburke commented Nov 7, 2011

Now that I think about it a bit more, I'm not sure the noConflict call will work in the AMD case, at least for loaders that immediately call dependencies once define is called (so curl, not requirejs) until the define call happens after the window assignment in outro. I'll work up a patch.

I'm having an issue that's related to this. My company makes a widget that includes jQuery and gets put on our customer's pages. We recently switched to using require.js instead of just concatenating all of our script files, and got an angry phonecall from one of our customers shortly after deploying this change that we were breaking their pages:

Basically, what happened is that during the 4 ms between when our jQuery's define() is called and when my main.js's require() is called, our copy of jQuery is the global one and it's "stealing" the customer's jQuery plugins. When our main code calls jQuery.noConflict(true), it's too late and our copy already has their plugin.

Here's a trimmed-down example of the issue: http://nfriedly.com/stuff/jquery-requirejs-noconflict-issue/example.html? (Note that the issue is depends on timing. If it doesn't occur initially, try clicking the 'Reset' link at the bottom.)

I fixed it for my use-case by editing jQuery as seen in http://nfriedly.com/stuff/jquery-requirejs-noconflict-issue/example.html?patched

I'd like to see this changed even if it has to wait for a fairly major release.

Owner

dmethvin commented Mar 15, 2013

Per the discussion above, the problem is that if we don't expose window.jQuery then most of the plugins on the face of the planet won't work unless you are willing to modify them to not expect a global jQuery. If you're willing to do that, just modify jQuery as well.

dslatten commented Jun 8, 2013

One of the main selling points of AMD is that it respects the global namespace. Therefore, a common use case is: developers who need a way to reliably load their app/widget (and its dependencies) in an uncontrolled, unpredictable (browser) environment--without impacting that environment's namespace. Yet jQuery's AMD implementation makes this common use case extremely difficult, if not impossible, to achieve.

As @nfriedly pointed out, forcing jQuery into the global namespace of a page that already has jQuery + plugins on it--even if those globals are immediately removed (or rolled back) by jQuery.noConflict(true)--still creates a situation where the native jQuery plugins can erroneously attach to the AMD-loaded jQuery global and break the page. Another major selling point of AMD is that it allows for asynchronous loading. Why then does asynchronously loading jQuery and/or jQuery plugins lead to global namespace collisions?

It sounds like respect for the global namespace and asynchronous loading are, at best, mutually exclusive when working with AMD + jQuery (in the browser). To top it all off, jQuery defines itself as the named module, jquery, thus imposing unnecessary restrictions on jQuery's modularity. I'm starting to wonder if AMD + jQuery has any benefits at all. It's just like regular jQuery...but you have to wait for RequireJS to load first...?

Anyway, I've been working with AMD and jQuery for like...at least 3 weeks now, so I feel perhaps I should leverage that expertise and propose a new solution.

After glancing at jquery/src/exports.js, I notice that the conditions for pulverizing loading the globals are pretty generic:

if ( typeof window === "object" && typeof window.document === "object" ) {
    window.jQuery = window.$ = jQuery;
}

And just before that is the part where jQuery defines itself as AMD-ready:

if ( typeof define === "function" && define.amd ) {
    define( "jquery", [], function () { return jQuery; } );
}

Here's what I propose. We (and by that I mean @jrburke) define a new piece of the define.amd spec that says something like this:

An example of how `define.amd` may be defined for an implementation that does not modify the global namespace:
define.amd = {
    noconflict: true
};

Then change the pulverizing conditions to something like this:

if ( typeof window === "object" && typeof window.document === "object" && !define.amd.noconflict ) {
    window.jQuery = window.$ = jQuery;
}

The idea here being: allow an AMD loader to use the define.amd global to communicate to jQuery that it wishes to "opt out" of window.jQuery = window.$ = jQuery;

Contributor

jrburke commented Jun 8, 2013

@dslatten: the current structure is a result of the limits of scripts loading (particularly in IE where it does not match up script execution directly followed by a script load event) and the numerous ways in which developers add jQuery to a page. A lot of this will get better when ECMAScript 6 modules come out -- in particular, the ability to create Module Loader instances that can set separate objects for the "global" for each loader.

Here is what could be done today though, for the global setting, as a result of work that has happened since this ticket first opened:

AMD module config could be used to indicate the noConflict behavior. So an AMD-based project could register this config:

require.config({
  config: {
    'jquery': {
      noConflict: true
    }
  }
});

Then, the jQuery exports.js file could look something like this (note the makeGlobal use, comments removed to make the code snippet smaller):

var makeGlobal = true;
if ( typeof module === "object" && module && typeof module.exports === "object" ) {
    module.exports = jQuery;
} else {
    if ( typeof define === "function" && define.amd ) {
        define( "jquery", ["module"], function (module) { 
            if ( module.config && module.config().noConflict ) {
                makeGlobal = false;
            }
            return jQuery; 
        } );
    }
}

if ( makeGlobal && typeof window === "object" && typeof window.document === "object" ) {
    window.jQuery = window.$ = jQuery;
}

If that is something you think might be useful, then I suggest opening a new, targeted ticket about this noConflict approach using module config. Something like "Use AMD module config to avoid setting jQuery global" and keep that ticket focused on just that aspect of AMD/jQuery interaction.

dslatten commented Jun 8, 2013

I definitely think it would be useful. But unless I'm mistaken, your code example assumes that jQuery's module ID will always be jquery, and that conflicts with another change I'd like to see happen: stop assuming that jQuery's module ID will always be jquery.

Contributor

jrburke commented Jun 8, 2013

The code change mentioned to skip making a global is separate from deciding if jQuery should register as an anonymous module, and is why I suggested breaking it out as a separate, targeted bug, because it can be done regardless of the anon module choice. The module config just needs to match whatever module ID the module ends up with.

Removing the named jquery would provide less benefit than you may initially perceive though and likely will result in more error reports:

Anonymous modules work by being able to tie a script execution to a script tag. This is very difficult to do if a developer just adds jQuery to the page as an HTML script tag manually after an AMD loader is in the page. In that case, the loader can neither reliably ignore that define call nor give it a name, given how browsers execute scripts and how they fire any script onload/readystate events. It will cause some sort of error.

Anon registration is still recommended for most modules, but given how many sites embed jQuery by default and in weird CMS-driven ways, the named 'jquery' avoids those issues.

On the possible benefit of an anonymous jQuery:

  • If you use another third party library that needs jQuery as a dependency, that dependency will likely be using 'jquery' as the dependency name. So, jQuery registering as 'jquery' is not an issue once you have one of those libraries in your project: you should be placing jQuery under the 'jquery' modules ID. Projects that use a module ID like 'vendor/jquery-1.9.1' is an AMD anti-pattern.
  • If creating a standalone library that embeds jQuery and that library does not need to do dynamic loading for its internal parts, then using a build with almond and wrapping that file in a closure will avoid any issues with conflicts with another jQuery on the page.
  • There are things like multiversion contexts and AMD namespace renaming available for standalone libraries that need dynamic loading.

There are definitely use cases that could benefit from jQuery not naming itself. However, the likelihood of errors being caused by manually authored HTML script tags for jquery.js are greater to me, and would lead to more support costs to jQuery and AMD loaders as people would report those errors. If one of those use cases is super important to you, you always have the option to modify your local copy of jquery.js and remove the string yourself.

I do see this as a non-ideal setup, but upgrading the web in the wild is difficult and it is about measuring trade-offs, particularly when relying on uneven script loading capabilities across browsers. The real solution as mentioned before will be ES module loaders, which will not suffer from the "pair anonymous module with ID" limitations that script tags have today.

All that said, I am not a jQuery maintainer, and they could decide differently and be fine with the tradeoffs, go with an anonymous call and point people who report errors to AMD loader sites. I do think they will get reports of issues with that change, but if they are fine with processing those reports with a standard boilerplate of "go talk to your AMD loader of choice for suggestions on how to deal with it", that would be a way to deal with that support cost.

But the choice to create a global via module config vs. switching to an anon call should be tracked and discussed as separate issues.

This is my understanding so far:

  • If an AMD-compatible script (one that initiates a define call if an AMD loader is detected) is loaded (via a <script> tag) after an AMD loader--and the AMD loader didn't specify that script as a dependency (i.e., assign it a module ID)--then errors will occur.
  • The workaround is to make sure that AMD-compatible scripts (not native AMD modules) use a named define call. This allows the AMD loader to safely ignore define calls that it didn't initiate.
  • The only JavaScript library that is expected to implement this workaround is jQuery. Less-popular libraries should choose between (1) not being AMD-compatible, or (2) not being <script>-compatible on pages that use an AMD loader (unless loaded before it).
  • Only the first define call (e.g., for jquery) is accepted by the AMD loader. Subsequent define calls are safely ignored. As a result, AMD modules that depend on jQuery cannot reliably execute in an uncontrolled environment, because there's no guarantee that jquery will return the correct version of jQuery. In fact, there's no guarantee that jquery will return _any_ version of jQuery; it's entirely possible that another script has already defined a module called jquery and mapped it to some arbitrary custom script.
If you use another third party library that needs jQuery as a dependency, that dependency will likely be using 'jquery' as the dependency name.

This is only likely because it's hard-coded into jQuery itself! Otherwise, the most-likely choice would be the filename that jQuery is distributed by (minus the .js extension), because it requires the least amount of effort (e.g., path configuration or renaming files).

So, jQuery registering as 'jquery' is not an issue once you have one of those libraries in your project...

Based on my understanding, it's still an issue in at least 2 cases:

  1. Different versions of jQuery are needed within the same page (by different AMD modules that are unaware of the other's existence).
  2. Someone customizes a copy of jQuery, but doesn't change the part that defines it as the jquery module.
...you should be placing jQuery under the 'jquery' modules ID. Projects that use a module ID like 'vendor/jquery-1.9.1' is an AMD anti-pattern.

So in an effort to encourage modular/reusable/interoperable code, AMD recommends a best practice that all-but-guarantees namespace collisions and interoperability limitations?

If creating a standalone library that embeds jQuery and that library does not need to do dynamic loading for its internal parts, then using a build with almond and wrapping that file in a closure will avoid any issues with conflicts with another jQuery on the page.

So if I create an app according to the Asynchrous Module Definition specs, and I need my app to asynchronously load JavaScript modules (including jQuery), then my only option is to build a version that isn't modular and doesn't load asynchronously?

I don't know...it seems like the more I learn about AMD, the less it makes sense.

Now that jQuery is starting to support custom builds, perhaps both the global definition & the named module parts could be configured at build time?

That way 99% of jQuery users can keep the current behavior, but those of us that need a private jQuery can have a reliable, automated method of getting it.

I don't mind having an extra step in my JS build process as long as it can be automated. What I don't like is the current situation where I have to remember to manually edit a third-party library whenever I upgrade it to a new version. (And I especially don't like cases like this where the mistake won't be immediately apparent, so it's more likely to make it through QA and not get noticed until it starts breaking production websites.)

Contributor

jrburke commented Jun 11, 2013

If you use another third party library that needs jQuery as a dependency, that dependency will likely be using 'jquery' as the dependency name.

This is only likely because it's hard-coded into jQuery itself! Otherwise, the most-likely choice would be the filename that jQuery is distributed by (minus the .js extension), because it requires the least amount of effort (e.g., path configuration or renaming files).

For third party libraries that depend on jQuery, they need a name to refer to jQuery. Backbone is a good example. In an AMD version of it, it would depend on 'jquery' and 'underscore'. It uses these top level IDs because it cannot possibly know the path to the file that is used in projects. All jQuery plugins in a modular world would use 'jquery' as the dependency name for similar reasons.

So, jQuery registering as 'jquery' is not an issue once you have one of those libraries in your project...

Based on my understanding, it's still an issue in at least 2 cases:

  1. Different versions of jQuery are needed within the same page (by different AMD modules that are unaware of the other's existence).
  2. Someone customizes a copy of jQuery, but doesn't change the part that defines it as the jquery module.

For both of those situations, they likely need full module namespace separation. Not just jQuery, but the plugins each one uses. It is unlikely the user would try to also rename all the modules used for the two different versions of jQuery to avoid conflicts. That is what the aforementioned multiversion support and namespace building provides. Complete namespace separation without needing to manually modify the source files.

...you should be placing jQuery under the 'jquery' modules ID. Projects that use a module ID like 'vendor/jquery-1.9.1' is an AMD anti-pattern.

So in an effort to encourage modular/reusable/interoperable code, AMD recommends a best practice that all-but-guarantees namespace collisions and interoperability limitations?

See above about the tools available to contain namespaces. Those are available without needing the actual modules to do anything special. Once IDs are strings, instead of globals, it allows those approaches.

The interop limitations stem from the uneven tech in browsers and a lack of a true module system that can give real, isolated spaces like the ES Module Loader API can.

So if I create an app according to the Asynchrous Module Definition specs, and I need my app to asynchronously load JavaScript modules (including jQuery), then my only option is to build a version that isn't modular and doesn't load asynchronously?

Please see the above multiversion and namespace builds as options for containment. They still allow for async loading.

I don't know...it seems like the more I learn about AMD, the less it makes sense.

Feel free to wait for ES modules. Nothing else today will do better though, and a lot of the same ideas will still be in play with ES modules. ES modules will have a much stronger isolation story though since it has the option to change the language and the browser.

All that said, I think your suggestion about getting some mechanism to avoid setting a global can be addressed, and I think that still may be worth pursuing separately in a targeted ticket.

For build options, I can see allowing options for those things, but for a standard build, I would like to see the module config support for skipping the global and the named jquery as the default options.

...for a standard build, I would like to see the module config support for skipping the global and the named jquery as the default options.

I forgot to mention it in my previous comment, but I'd be happy with this as well.

Owner

timmywil commented Jun 12, 2013

For build options, I can see allowing options for those things, but for a standard build, I would like to see the module config support for skipping the global and the named jquery as the default options.

This is a great idea.

Owner

timmywil commented Jun 12, 2013

I've opened a ticket for this. Please continue discussion there. http://bugs.jquery.com/ticket/14016

@yamkazu yamkazu referenced this pull request in yamkazu/gaiden Jun 20, 2014

@yamkazu yamkazu [from now] 2014/06/20 18:31:01
diff --git a/src/dist/assets/scripts/angular-resource.js b/src/dist/assets/scripts/angular-resource.js
new file mode 100644
index 0000000..935800e
--- /dev/null
+++ b/src/dist/assets/scripts/angular-resource.js
@@ -0,0 +1,607 @@
+/**
+ * @license AngularJS v1.2.15
+ * (c) 2010-2014 Google, Inc. http://angularjs.org
+ * License: MIT
+ */
+(function(window, angular, undefined) {'use strict';
+
+var $resourceMinErr = angular.$$minErr('$resource');
+
+// Helper functions and regex to lookup a dotted path on an object
+// stopping at undefined/null.  The path must be composed of ASCII
+// identifiers (just like $parse)
+var MEMBER_NAME_REGEX = /^(\.[a-zA-Z_$][0-9a-zA-Z_$]*)+$/;
+
+function isValidDottedPath(path) {
+  return (path != null && path !== '' && path !== 'hasOwnProperty' &&
+      MEMBER_NAME_REGEX.test('.' + path));
+}
+
+function lookupDottedPath(obj, path) {
+  if (!isValidDottedPath(path)) {
+    throw $resourceMinErr('badmember', 'Dotted member path "@{0}" is invalid.', path);
+  }
+  var keys = path.split('.');
+  for (var i = 0, ii = keys.length; i < ii && obj !== undefined; i++) {
+    var key = keys[i];
+    obj = (obj !== null) ? obj[key] : undefined;
+  }
+  return obj;
+}
+
+/**
+ * Create a shallow copy of an object and clear other fields from the destination
+ */
+function shallowClearAndCopy(src, dst) {
+  dst = dst || {};
+
+  angular.forEach(dst, function(value, key){
+    delete dst[key];
+  });
+
+  for (var key in src) {
+    if (src.hasOwnProperty(key) && !(key.charAt(0) === '$' && key.charAt(1) === '$')) {
+      dst[key] = src[key];
+    }
+  }
+
+  return dst;
+}
+
+/**
+ * @ngdoc module
+ * @name ngResource
+ * @description
+ *
+ * # ngResource
+ *
+ * The `ngResource` module provides interaction support with RESTful services
+ * via the $resource service.
+ *
+ *
+ * <div doc-module-components="ngResource"></div>
+ *
+ * See {@link ngResource.$resource `$resource`} for usage.
+ */
+
+/**
+ * @ngdoc service
+ * @name $resource
+ * @requires $http
+ *
+ * @description
+ * A factory which creates a resource object that lets you interact with
+ * [RESTful](http://en.wikipedia.org/wiki/Representational_State_Transfer) server-side data sources.
+ *
+ * The returned resource object has action methods which provide high-level behaviors without
+ * the need to interact with the low level {@link ng.$http $http} service.
+ *
+ * Requires the {@link ngResource `ngResource`} module to be installed.
+ *
+ * @param {string} url A parametrized URL template with parameters prefixed by `:` as in
+ *   `/user/:username`. If you are using a URL with a port number (e.g.
+ *   `http://example.com:8080/api`), it will be respected.
+ *
+ *   If you are using a url with a suffix, just add the suffix, like this:
+ *   `$resource('http://example.com/resource.json')` or `$resource('http://example.com/:id.json')`
+ *   or even `$resource('http://example.com/resource/:resource_id.:format')`
+ *   If the parameter before the suffix is empty, :resource_id in this case, then the `/.` will be
+ *   collapsed down to a single `.`.  If you need this sequence to appear and not collapse then you
+ *   can escape it with `/\.`.
+ *
+ * @param {Object=} paramDefaults Default values for `url` parameters. These can be overridden in
+ *   `actions` methods. If any of the parameter value is a function, it will be executed every time
+ *   when a param value needs to be obtained for a request (unless the param was overridden).
+ *
+ *   Each key value in the parameter object is first bound to url template if present and then any
+ *   excess keys are appended to the url search query after the `?`.
+ *
+ *   Given a template `/path/:verb` and parameter `{verb:'greet', salutation:'Hello'}` results in
+ *   URL `/path/greet?salutation=Hello`.
+ *
+ *   If the parameter value is prefixed with `@` then the value of that parameter is extracted from
+ *   the data object (useful for non-GET operations).
+ *
+ * @param {Object.<Object>=} actions Hash with declaration of custom action that should extend
+ *   the default set of resource actions. The declaration should be created in the format of {@link
+ *   ng.$http#usage_parameters $http.config}:
+ *
+ *       {action1: {method:?, params:?, isArray:?, headers:?, ...},
+ *        action2: {method:?, params:?, isArray:?, headers:?, ...},
+ *        ...}
+ *
+ *   Where:
+ *
+ *   - **`action`** – {string} – The name of action. This name becomes the name of the method on
+ *     your resource object.
+ *   - **`method`** – {string} – HTTP request method. Valid methods are: `GET`, `POST`, `PUT`,
+ *     `DELETE`, and `JSONP`.
+ *   - **`params`** – {Object=} – Optional set of pre-bound parameters for this action. If any of
+ *     the parameter value is a function, it will be executed every time when a param value needs to
+ *     be obtained for a request (unless the param was overridden).
+ *   - **`url`** – {string} – action specific `url` override. The url templating is supported just
+ *     like for the resource-level urls.
+ *   - **`isArray`** – {boolean=} – If true then the returned object for this action is an array,
+ *     see `returns` section.
+ *   - **`transformRequest`** –
+ *     `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
+ *     transform function or an array of such functions. The transform function takes the http
+ *     request body and headers and returns its transformed (typically serialized) version.
+ *   - **`transformResponse`** –
+ *     `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
+ *     transform function or an array of such functions. The transform function takes the http
+ *     response body and headers and returns its transformed (typically deserialized) version.
+ *   - **`cache`** – `{boolean|Cache}` – If true, a default $http cache will be used to cache the
+ *     GET request, otherwise if a cache instance built with
+ *     {@link ng.$cacheFactory $cacheFactory}, this cache will be used for
+ *     caching.
+ *   - **`timeout`** – `{number|Promise}` – timeout in milliseconds, or {@link ng.$q promise} that
+ *     should abort the request when resolved.
+ *   - **`withCredentials`** - `{boolean}` - whether to set the `withCredentials` flag on the
+ *     XHR object. See
+ *     [requests with credentials](https://developer.mozilla.org/en/http_access_control#section_5)
+ *     for more information.
+ *   - **`responseType`** - `{string}` - see
+ *     [requestType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType).
+ *   - **`interceptor`** - `{Object=}` - The interceptor object has two optional methods -
+ *     `response` and `responseError`. Both `response` and `responseError` interceptors get called
+ *     with `http response` object. See {@link ng.$http $http interceptors}.
+ *
+ * @returns {Object} A resource "class" object with methods for the default set of resource actions
+ *   optionally extended with custom `actions`. The default set contains these actions:
+ *   ```js
+ *   { 'get':    {method:'GET'},
+ *     'save':   {method:'POST'},
+ *     'query':  {method:'GET', isArray:true},
+ *     'remove': {method:'DELETE'},
+ *     'delete': {method:'DELETE'} };
+ *   ```
+ *
+ *   Calling these methods invoke an {@link ng.$http} with the specified http method,
+ *   destination and parameters. When the data is returned from the server then the object is an
+ *   instance of the resource class. The actions `save`, `remove` and `delete` are available on it
+ *   as  methods with the `$` prefix. This allows you to easily perform CRUD operations (create,
+ *   read, update, delete) on server-side data like this:
+ *   ```js
+ *   var User = $resource('/user/:userId', {userId:'@id'});
+ *   var user = User.get({userId:123}, function() {
+ *     user.abc = true;
+ *     user.$save();
+ *   });
+ *   ```
+ *
+ *   It is important to realize that invoking a $resource object method immediately returns an
+ *   empty reference (object or array depending on `isArray`). Once the data is returned from the
+ *   server the existing reference is populated with the actual data. This is a useful trick since
+ *   usually the resource is assigned to a model which is then rendered by the view. Having an empty
+ *   object results in no rendering, once the data arrives from the server then the object is
+ *   populated with the data and the view automatically re-renders itself showing the new data. This
+ *   means that in most cases one never has to write a callback function for the action methods.
+ *
+ *   The action methods on the class object or instance object can be invoked with the following
+ *   parameters:
+ *
+ *   - HTTP GET "class" actions: `Resource.action([parameters], [success], [error])`
+ *   - non-GET "class" actions: `Resource.action([parameters], postData, [success], [error])`
+ *   - non-GET instance actions:  `instance.$action([parameters], [success], [error])`
+ *
+ *   Success callback is called with (value, responseHeaders) arguments. Error callback is called
+ *   with (httpResponse) argument.
+ *
+ *   Class actions return empty instance (with additional properties below).
+ *   Instance actions return promise of the action.
+ *
+ *   The Resource instances and collection have these additional properties:
+ *
+ *   - `$promise`: the {@link ng.$q promise} of the original server interaction that created this
+ *     instance or collection.
+ *
+ *     On success, the promise is resolved with the same resource instance or collection object,
+ *     updated with data from server. This makes it easy to use in
+ *     {@link ngRoute.$routeProvider resolve section of $routeProvider.when()} to defer view
+ *     rendering until the resource(s) are loaded.
+ *
+ *     On failure, the promise is resolved with the {@link ng.$http http response} object, without
+ *     the `resource` property.
+ *
+ *   - `$resolved`: `true` after first server interaction is completed (either with success or
+ *      rejection), `false` before that. Knowing if the Resource has been resolved is useful in
+ *      data-binding.
+ *
+ * @example
+ *
+ * # Credit card resource
+ *
+ * ```js
+     // Define CreditCard class
+     var CreditCard = $resource('/user/:userId/card/:cardId',
+      {userId:123, cardId:'@id'}, {
+       charge: {method:'POST', params:{charge:true}}
+      });
+
+     // We can retrieve a collection from the server
+     var cards = CreditCard.query(function() {
+       // GET: /user/123/card
+       // server returns: [ {id:456, number:'1234', name:'Smith'} ];
+
+       var card = cards[0];
+       // each item is an instance of CreditCard
+       expect(card instanceof CreditCard).toEqual(true);
+       card.name = "J. Smith";
+       // non GET methods are mapped onto the instances
+       card.$save();
+       // POST: /user/123/card/456 {id:456, number:'1234', name:'J. Smith'}
+       // server returns: {id:456, number:'1234', name: 'J. Smith'};
+
+       // our custom method is mapped as well.
+       card.$charge({amount:9.99});
+       // POST: /user/123/card/456?amount=9.99&charge=true {id:456, number:'1234', name:'J. Smith'}
+     });
+
+     // we can create an instance as well
+     var newCard = new CreditCard({number:'0123'});
+     newCard.name = "Mike Smith";
+     newCard.$save();
+     // POST: /user/123/card {number:'0123', name:'Mike Smith'}
+     // server returns: {id:789, number:'0123', name: 'Mike Smith'};
+     expect(newCard.id).toEqual(789);
+ * ```
+ *
+ * The object returned from this function execution is a resource "class" which has "static" method
+ * for each action in the definition.
+ *
+ * Calling these methods invoke `$http` on the `url` template with the given `method`, `params` and
+ * `headers`.
+ * When the data is returned from the server then the object is an instance of the resource type and
+ * all of the non-GET methods are available with `$` prefix. This allows you to easily support CRUD
+ * operations (create, read, update, delete) on server-side data.
+
+   ```js
+     var User = $resource('/user/:userId', {userId:'@id'});
+     User.get({userId:123}, function(user) {
+       user.abc = true;
+       user.$save();
+     });
+   ```
+ *
+ * It's worth noting that the success callback for `get`, `query` and other methods gets passed
+ * in the response that came from the server as well as $http header getter function, so one
+ * could rewrite the above example and get access to http headers as:
+ *
+   ```js
+     var User = $resource('/user/:userId', {userId:'@id'});
+     User.get({userId:123}, function(u, getResponseHeaders){
+       u.abc = true;
+       u.$save(function(u, putResponseHeaders) {
+         //u => saved user object
+         //putResponseHeaders => $http header getter
+       });
+     });
+   ```
+ *
+ * You can also access the raw `$http` promise via the `$promise` property on the object returned
+ *
+   ```
+     var User = $resource('/user/:userId', {userId:'@id'});
+     User.get({userId:123})
+         .$promise.then(function(user) {
+           $scope.user = user;
+         });
+   ```
+
+ * # Creating a custom 'PUT' request
+ * In this example we create a custom method on our resource to make a PUT request
+ * ```js
+ *		var app = angular.module('app', ['ngResource', 'ngRoute']);
+ *
+ *		// Some APIs expect a PUT request in the format URL/object/ID
+ *		// Here we are creating an 'update' method
+ *		app.factory('Notes', ['$resource', function($resource) {
+ *    return $resource('/notes/:id', null,
+ *        {
+ *            'update': { method:'PUT' }
+ *        });
+ *		}]);
+ *
+ *		// In our controller we get the ID from the URL using ngRoute and $routeParams
+ *		// We pass in $routeParams and our Notes factory along with $scope
+ *		app.controller('NotesCtrl', ['$scope', '$routeParams', 'Notes',
+                                      function($scope, $routeParams, Notes) {
+ *    // First get a note object from the factory
+ *    var note = Notes.get({ id:$routeParams.id });
+ *    $id = note.id;
+ *
+ *    // Now call update passing in the ID first then the object you are updating
+ *    Notes.update({ id:$id }, note);
+ *
+ *    // This will PUT /notes/ID with the note object in the request payload
+ *		}]);
+ * ```
+ */
+angular.module('ngResource', ['ng']).
+  factory('$resource', ['$http', '$q', function($http, $q) {
+
+    var DEFAULT_ACTIONS = {
+      'get':    {method:'GET'},
+      'save':   {method:'POST'},
+      'query':  {method:'GET', isArray:true},
+      'remove': {method:'DELETE'},
+      'delete': {method:'DELETE'}
+    };
+    var noop = angular.noop,
+        forEach = angular.forEach,
+        extend = angular.extend,
+        copy = angular.copy,
+        isFunction = angular.isFunction;
+
+    /**
+     * We need our custom method because encodeURIComponent is too aggressive and doesn't follow
+     * http://www.ietf.org/rfc/rfc3986.txt with regards to the character set (pchar) allowed in path
+     * segments:
+     *    segment       = *pchar
+     *    pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
+     *    pct-encoded   = "%" HEXDIG HEXDIG
+     *    unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
+     *    sub-delims    = "!" / "$" / "&" / "'" / "(" / ")"
+     *                     / "*" / "+" / "," / ";" / "="
+     */
+    function encodeUriSegment(val) {
+      return encodeUriQuery(val, true).
+        replace(/%26/gi, '&').
+        replace(/%3D/gi, '=').
+        replace(/%2B/gi, '+');
+    }
+
+
+    /**
+     * This method is intended for encoding *key* or *value* parts of query component. We need a
+     * custom method because encodeURIComponent is too aggressive and encodes stuff that doesn't
+     * have to be encoded per http://tools.ietf.org/html/rfc3986:
+     *    query       = *( pchar / "/" / "?" )
+     *    pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
+     *    unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
+     *    pct-encoded   = "%" HEXDIG HEXDIG
+     *    sub-delims    = "!" / "$" / "&" / "'" / "(" / ")"
+     *                     / "*" / "+" / "," / ";" / "="
+     */
+    function encodeUriQuery(val, pctEncodeSpaces) {
+      return encodeURIComponent(val).
+        replace(/%40/gi, '@').
+        replace(/%3A/gi, ':').
+        replace(/%24/g, '$').
+        replace(/%2C/gi, ',').
+        replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));
+    }
+
+    function Route(template, defaults) {
+      this.template = template;
+      this.defaults = defaults || {};
+      this.urlParams = {};
+    }
+
+    Route.prototype = {
+      setUrlParams: function(config, params, actionUrl) {
+        var self = this,
+            url = actionUrl || self.template,
+            val,
+            encodedVal;
+
+        var urlParams = self.urlParams = {};
+        forEach(url.split(/\W/), function(param){
+          if (param === 'hasOwnProperty') {
+            throw $resourceMinErr('badname', "hasOwnProperty is not a valid parameter name.");
+          }
+          if (!(new RegExp("^\\d+$").test(param)) && param &&
+               (new RegExp("(^|[^\\\\]):" + param + "(\\W|$)").test(url))) {
+            urlParams[param] = true;
+          }
+        });
+        url = url.replace(/\\:/g, ':');
+
+        params = params || {};
+        forEach(self.urlParams, function(_, urlParam){
+          val = params.hasOwnProperty(urlParam) ? params[urlParam] : self.defaults[urlParam];
+          if (angular.isDefined(val) && val !== null) {
+            encodedVal = encodeUriSegment(val);
+            url = url.replace(new RegExp(":" + urlParam + "(\\W|$)", "g"), function(match, p1) {
+              return encodedVal + p1;
+            });
+          } else {
+            url = url.replace(new RegExp("(\/?):" + urlParam + "(\\W|$)", "g"), function(match,
+                leadingSlashes, tail) {
+              if (tail.charAt(0) == '/') {
+                return tail;
+              } else {
+                return leadingSlashes + tail;
+              }
+            });
+          }
+        });
+
+        // strip trailing slashes and set the url
+        url = url.replace(/\/+$/, '') || '/';
+        // then replace collapse `/.` if found in the last URL path segment before the query
+        // E.g. `http://url.com/id./format?q=x` becomes `http://url.com/id.format?q=x`
+        url = url.replace(/\/\.(?=\w+($|\?))/, '.');
+        // replace escaped `/\.` with `/.`
+        config.url = url.replace(/\/\\\./, '/.');
+
+
+        // set params - delegate param encoding to $http
+        forEach(params, function(value, key){
+          if (!self.urlParams[key]) {
+            config.params = config.params || {};
+            config.params[key] = value;
+          }
+        });
+      }
+    };
+
+
+    function resourceFactory(url, paramDefaults, actions) {
+      var route = new Route(url);
+
+      actions = extend({}, DEFAULT_ACTIONS, actions);
+
+      function extractParams(data, actionParams){
+        var ids = {};
+        actionParams = extend({}, paramDefaults, actionParams);
+        forEach(actionParams, function(value, key){
+          if (isFunction(value)) { value = value(); }
+          ids[key] = value && value.charAt && value.charAt(0) == '@' ?
+            lookupDottedPath(data, value.substr(1)) : value;
+        });
+        return ids;
+      }
+
+      function defaultResponseInterceptor(response) {
+        return response.resource;
+      }
+
+      function Resource(value){
+        shallowClearAndCopy(value || {}, this);
+      }
+
+      forEach(actions, function(action, name) {
+        var hasBody = /^(POST|PUT|PATCH)$/i.test(action.method);
+
+        Resource[name] = function(a1, a2, a3, a4) {
+          var params = {}, data, success, error;
+
+          /* jshint -W086 */ /* (purposefully fall through case statements) */
+          switch(arguments.length) {
+          case 4:
+            error = a4;
+            success = a3;
+            //fallthrough
+          case 3:
+          case 2:
+            if (isFunction(a2)) {
+              if (isFunction(a1)) {
+                success = a1;
+                error = a2;
+                break;
+              }
+
+              success = a2;
+              error = a3;
+              //fallthrough
+            } else {
+              params = a1;
+              data = a2;
+              success = a3;
+              break;
+            }
+          case 1:
+            if (isFunction(a1)) success = a1;
+            else if (hasBody) data = a1;
+            else params = a1;
+            break;
+          case 0: break;
+          default:
+            throw $resourceMinErr('badargs',
+              "Expected up to 4 arguments [params, data, success, error], got {0} arguments",
+              arguments.length);
+          }
+          /* jshint +W086 */ /* (purposefully fall through case statements) */
+
+          var isInstanceCall = this instanceof Resource;
+          var value = isInstanceCall ? data : (action.isArray ? [] : new Resource(data));
+          var httpConfig = {};
+          var responseInterceptor = action.interceptor && action.interceptor.response ||
+                                    defaultResponseInterceptor;
+          var responseErrorInterceptor = action.interceptor && action.interceptor.responseError ||
+                                    undefined;
+
+          forEach(action, function(value, key) {
+            if (key != 'params' && key != 'isArray' && key != 'interceptor') {
+              httpConfig[key] = copy(value);
+            }
+          });
+
+          if (hasBody) httpConfig.data = data;
+          route.setUrlParams(httpConfig,
+                             extend({}, extractParams(data, action.params || {}), params),
+                             action.url);
+
+          var promise = $http(httpConfig).then(function(response) {
+            var data = response.data,
+                promise = value.$promise;
+
+            if (data) {
+              // Need to convert action.isArray to boolean in case it is undefined
+              // jshint -W018
+              if (angular.isArray(data) !== (!!action.isArray)) {
+                throw $resourceMinErr('badcfg', 'Error in resource configuration. Expected ' +
+                  'response to contain an {0} but got an {1}',
+                  action.isArray?'array':'object', angular.isArray(data)?'array':'object');
+              }
+              // jshint +W018
+              if (action.isArray) {
+                value.length = 0;
+                forEach(data, function(item) {
+                  value.push(new Resource(item));
+                });
+              } else {
+                shallowClearAndCopy(data, value);
+                value.$promise = promise;
+              }
+            }
+
+            value.$resolved = true;
+
+            response.resource = value;
+
+            return response;
+          }, function(response) {
+            value.$resolved = true;
+
+            (error||noop)(response);
+
+            return $q.reject(response);
+          });
+
+          promise = promise.then(
+              function(response) {
+                var value = responseInterceptor(response);
+                (success||noop)(value, response.headers);
+                return value;
+              },
+              responseErrorInterceptor);
+
+          if (!isInstanceCall) {
+            // we are creating instance / collection
+            // - set the initial promise
+            // - return the instance / collection
+            value.$promise = promise;
+            value.$resolved = false;
+
+            return value;
+          }
+
+          // instance call
+          return promise;
+        };
+
+
+        Resource.prototype['$' + name] = function(params, success, error) {
+          if (isFunction(params)) {
+            error = success; success = params; params = {};
+          }
+          var result = Resource[name].call(this, params, this, success, error);
+          return result.$promise || result;
+        };
+      });
+
+      Resource.bind = function(additionalParamDefaults){
+        return resourceFactory(url, extend({}, paramDefaults, additionalParamDefaults), actions);
+      };
+
+      return Resource;
+    }
+
+    return resourceFactory;
+  }]);
+
+
+})(window, window.angular);
diff --git a/src/dist/assets/scripts/angular-resource.min.js b/src/dist/assets/scripts/angular-resource.min.js
new file mode 100644
index 0000000..5c7c854
--- /dev/null
+++ b/src/dist/assets/scripts/angular-resource.min.js
@@ -0,0 +1,13 @@
+/*
+ AngularJS v1.2.15
+ (c) 2010-2014 Google, Inc. http://angularjs.org
+ License: MIT
+*/
+(function(H,a,A){'use strict';function D(p,g){g=g||{};a.forEach(g,function(a,c){delete g[c]});for(var c in p)!p.hasOwnProperty(c)||"$"===c.charAt(0)&&"$"===c.charAt(1)||(g[c]=p[c]);return g}var v=a.$$minErr("$resource"),C=/^(\.[a-zA-Z_$][0-9a-zA-Z_$]*)+$/;a.module("ngResource",["ng"]).factory("$resource",["$http","$q",function(p,g){function c(a,c){this.template=a;this.defaults=c||{};this.urlParams={}}function t(n,w,l){function r(h,d){var e={};d=x({},w,d);s(d,function(b,d){u(b)&&(b=b());var k;if(b&&
+b.charAt&&"@"==b.charAt(0)){k=h;var a=b.substr(1);if(null==a||""===a||"hasOwnProperty"===a||!C.test("."+a))throw v("badmember",a);for(var a=a.split("."),f=0,c=a.length;f<c&&k!==A;f++){var g=a[f];k=null!==k?k[g]:A}}else k=b;e[d]=k});return e}function e(a){return a.resource}function f(a){D(a||{},this)}var F=new c(n);l=x({},B,l);s(l,function(h,d){var c=/^(POST|PUT|PATCH)$/i.test(h.method);f[d]=function(b,d,k,w){var q={},n,l,y;switch(arguments.length){case 4:y=w,l=k;case 3:case 2:if(u(d)){if(u(b)){l=
+b;y=d;break}l=d;y=k}else{q=b;n=d;l=k;break}case 1:u(b)?l=b:c?n=b:q=b;break;case 0:break;default:throw v("badargs",arguments.length);}var t=this instanceof f,m=t?n:h.isArray?[]:new f(n),z={},B=h.interceptor&&h.interceptor.response||e,C=h.interceptor&&h.interceptor.responseError||A;s(h,function(a,b){"params"!=b&&("isArray"!=b&&"interceptor"!=b)&&(z[b]=G(a))});c&&(z.data=n);F.setUrlParams(z,x({},r(n,h.params||{}),q),h.url);q=p(z).then(function(b){var d=b.data,k=m.$promise;if(d){if(a.isArray(d)!==!!h.isArray)throw v("badcfg",
+h.isArray?"array":"object",a.isArray(d)?"array":"object");h.isArray?(m.length=0,s(d,function(b){m.push(new f(b))})):(D(d,m),m.$promise=k)}m.$resolved=!0;b.resource=m;return b},function(b){m.$resolved=!0;(y||E)(b);return g.reject(b)});q=q.then(function(b){var a=B(b);(l||E)(a,b.headers);return a},C);return t?q:(m.$promise=q,m.$resolved=!1,m)};f.prototype["$"+d]=function(b,a,k){u(b)&&(k=a,a=b,b={});b=f[d].call(this,b,this,a,k);return b.$promise||b}});f.bind=function(a){return t(n,x({},w,a),l)};return f}
+var B={get:{method:"GET"},save:{method:"POST"},query:{method:"GET",isArray:!0},remove:{method:"DELETE"},"delete":{method:"DELETE"}},E=a.noop,s=a.forEach,x=a.extend,G=a.copy,u=a.isFunction;c.prototype={setUrlParams:function(c,g,l){var r=this,e=l||r.template,f,p,h=r.urlParams={};s(e.split(/\W/),function(a){if("hasOwnProperty"===a)throw v("badname");!/^\d+$/.test(a)&&(a&&RegExp("(^|[^\\\\]):"+a+"(\\W|$)").test(e))&&(h[a]=!0)});e=e.replace(/\\:/g,":");g=g||{};s(r.urlParams,function(d,c){f=g.hasOwnProperty(c)?
+g[c]:r.defaults[c];a.isDefined(f)&&null!==f?(p=encodeURIComponent(f).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"%20").replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+"),e=e.replace(RegExp(":"+c+"(\\W|$)","g"),function(a,c){return p+c})):e=e.replace(RegExp("(/?):"+c+"(\\W|$)","g"),function(a,c,d){return"/"==d.charAt(0)?d:c+d})});e=e.replace(/\/+$/,"")||"/";e=e.replace(/\/\.(?=\w+($|\?))/,".");c.url=e.replace(/\/\\\./,"/.");s(g,function(a,
+e){r.urlParams[e]||(c.params=c.params||{},c.params[e]=a)})}};return t}])})(window,window.angular);
+//# sourceMappingURL=angular-resource.min.js.map
diff --git a/src/dist/assets/scripts/angular-resource.min.js.map b/src/dist/assets/scripts/angular-resource.min.js.map
new file mode 100644
index 0000000..1766ea9
--- /dev/null
+++ b/src/dist/assets/scripts/angular-resource.min.js.map
@@ -0,0 +1,8 @@
+{
+"version":3,
+"file":"angular-resource.min.js",
+"lineCount":12,
+"mappings":"A;;;;;aAKC,SAAQ,CAACA,CAAD,CAASC,CAAT,CAAkBC,CAAlB,CAA6B,CA6BtCC,QAASA,EAAmB,CAACC,CAAD,CAAMC,CAAN,CAAW,CACrCA,CAAA,CAAMA,CAAN,EAAa,EAEbJ,EAAAK,QAAA,CAAgBD,CAAhB,CAAqB,QAAQ,CAACE,CAAD,CAAQC,CAAR,CAAY,CACvC,OAAOH,CAAA,CAAIG,CAAJ,CADgC,CAAzC,CAIA,KAAKA,IAAIA,CAAT,GAAgBJ,EAAhB,CACM,CAAAA,CAAAK,eAAA,CAAmBD,CAAnB,CAAJ,EAAmD,GAAnD,GAAiCA,CAAAE,OAAA,CAAW,CAAX,CAAjC,EAA4E,GAA5E,GAA0DF,CAAAE,OAAA,CAAW,CAAX,CAA1D,GACEL,CAAA,CAAIG,CAAJ,CADF,CACaJ,CAAA,CAAII,CAAJ,CADb,CAKF,OAAOH,EAb8B,CA3BvC,IAAIM,EAAkBV,CAAAW,SAAA,CAAiB,WAAjB,CAAtB,CAKIC,EAAoB,iCAoTxBZ,EAAAa,OAAA,CAAe,YAAf,CAA6B,CAAC,IAAD,CAA7B,CAAAC,QAAA,CACU,WADV,CACuB,CAAC,OAAD,CAAU,IAAV,CAAgB,QAAQ,CAACC,CAAD,CAAQC,CAAR,CAAY,CAsDvDC,QAASA,EAAK,CAACC,CAAD,CAAWC,CAAX,CAAqB,CACjC,IAAAD,SAAA,CAAgBA,CAChB,KAAAC,SAAA,CAAgBA,CAAhB,EAA4B,EAC5B,KAAAC,UAAA,CAAiB,EAHgB,CAiEnCC,QAASA,EAAe,CAACC,CAAD,CAAMC,CAAN,CAAqBC,CAArB,CAA8B,CAKpDC,QAASA,EAAa,CAACC,CAAD,CAAOC,CAAP,CAAoB,CACxC,IAAIC,EAAM,EACVD,EAAA,CAAeE,CAAA,CAAO,EAAP,CAAWN,CAAX,CAA0BI,CAA1B,CACftB,EAAA,CAAQsB,CAAR,CAAsB,QAAQ,CAACrB,CAAD,CAAQC,CAAR,CAAY,CACpCuB,CAAA,CAAWxB,CAAX,CAAJ,GAAyBA,CAAzB,CAAiCA,CAAA,EAAjC,CACW,KAAA,CAAA,IAAAA,CAAA;AAASA,CAAAG,OAAT,EAA4C,GAA5C,EAAyBH,CAAAG,OAAA,CAAa,CAAb,CAAzB,CAAA,CACT,CAAA,CAAA,CAAA,KAAA,EAAA,CAAA,OAAA,CAAA,CAAA,CA/aV,IALgB,IAKhB,EAAuBsB,CAAvB,EALiC,EAKjC,GAAuBA,CAAvB,EALgD,gBAKhD,GAAuBA,CAAvB,EAJI,CAAAnB,CAAAoB,KAAA,CAAuB,GAAvB,CAImBD,CAJnB,CAIJ,CACE,KAAMrB,EAAA,CAAgB,WAAhB,CAAsEqB,CAAtE,CAAN,CAGF,IADIE,IAAAA,EAAOF,CAAAG,MAAA,CAAW,GAAX,CAAPD,CACKE,EAAI,CADTF,CACYG,EAAKH,CAAAI,OAArB,CAAkCF,CAAlC,CAAsCC,CAAtC,EAA4CE,CAA5C,GAAoDrC,CAApD,CAA+DkC,CAAA,EAA/D,CAAoE,CAClE,IAAI5B,EAAM0B,CAAA,CAAKE,CAAL,CACVG,EAAA,CAAe,IAAT,GAACA,CAAD,CAAiBA,CAAA,CAAI/B,CAAJ,CAAjB,CAA4BN,CAFgC,CA0ajD,CAAA,IACiCK,EAAAA,CAAAA,CAD5CsB,EAAA,CAAIrB,CAAJ,CAAA,CAAW,CAF6B,CAA1C,CAKA,OAAOqB,EARiC,CAW1CW,QAASA,EAA0B,CAACC,CAAD,CAAW,CAC5C,MAAOA,EAAAC,SADqC,CAI9CC,QAASA,EAAQ,CAACpC,CAAD,CAAO,CACtBJ,CAAA,CAAoBI,CAApB,EAA6B,EAA7B,CAAiC,IAAjC,CADsB,CAnBxB,IAAIqC,EAAQ,IAAI1B,CAAJ,CAAUK,CAAV,CAEZE,EAAA,CAAUK,CAAA,CAAO,EAAP,CAAWe,CAAX,CAA4BpB,CAA5B,CAqBVnB,EAAA,CAAQmB,CAAR,CAAiB,QAAQ,CAACqB,CAAD,CAASC,CAAT,CAAe,CACtC,IAAIC,EAAU,qBAAAf,KAAA,CAA2Ba,CAAAG,OAA3B,CAEdN,EAAA,CAASI,CAAT,CAAA,CAAiB,QAAQ,CAACG,CAAD,CAAKC,CAAL,CAASC,CAAT,CAAaC,CAAb,CAAiB,CAAA,IACpCC,EAAS,EAD2B,CACvB3B,CADuB,CACjB4B,CADiB,CACRC,CAGhC,QAAOC,SAAAnB,OAAP,EACA,KAAK,CAAL,CACEkB,CACA,CADQH,CACR,CAAAE,CAAA,CAAUH,CAEZ,MAAK,CAAL,CACA,KAAK,CAAL,CACE,GAAIrB,CAAA,CAAWoB,CAAX,CAAJ,CAAoB,CAClB,GAAIpB,CAAA,CAAWmB,CAAX,CAAJ,CAAoB,CAClBK,CAAA;AAAUL,CACVM,EAAA,CAAQL,CACR,MAHkB,CAMpBI,CAAA,CAAUJ,CACVK,EAAA,CAAQJ,CARU,CAApB,IAUO,CACLE,CAAA,CAASJ,CACTvB,EAAA,CAAOwB,CACPI,EAAA,CAAUH,CACV,MAJK,CAMT,KAAK,CAAL,CACMrB,CAAA,CAAWmB,CAAX,CAAJ,CAAoBK,CAApB,CAA8BL,CAA9B,CACSF,CAAJ,CAAarB,CAAb,CAAoBuB,CAApB,CACAI,CADA,CACSJ,CACd,MACF,MAAK,CAAL,CAAQ,KACR,SACE,KAAMvC,EAAA,CAAgB,SAAhB,CAEJ8C,SAAAnB,OAFI,CAAN,CA9BF,CAoCA,IAAIoB,EAAiB,IAAjBA,WAAiCf,EAArC,CACIpC,EAAQmD,CAAA,CAAiB/B,CAAjB,CAAyBmB,CAAAa,QAAA,CAAiB,EAAjB,CAAsB,IAAIhB,CAAJ,CAAahB,CAAb,CAD3D,CAEIiC,EAAa,EAFjB,CAGIC,EAAsBf,CAAAgB,YAAtBD,EAA4Cf,CAAAgB,YAAArB,SAA5CoB,EACsBrB,CAJ1B,CAKIuB,EAA2BjB,CAAAgB,YAA3BC,EAAiDjB,CAAAgB,YAAAE,cAAjDD,EACsB7D,CAE1BI,EAAA,CAAQwC,CAAR,CAAgB,QAAQ,CAACvC,CAAD,CAAQC,CAAR,CAAa,CACxB,QAAX,EAAIA,CAAJ,GAA8B,SAA9B,EAAuBA,CAAvB,EAAkD,aAAlD,EAA2CA,CAA3C,IACEoD,CAAA,CAAWpD,CAAX,CADF,CACoByD,CAAA,CAAK1D,CAAL,CADpB,CADmC,CAArC,CAMIyC,EAAJ,GAAaY,CAAAjC,KAAb,CAA+BA,CAA/B,CACAiB,EAAAsB,aAAA,CAAmBN,CAAnB,CACmB9B,CAAA,CAAO,EAAP,CAAWJ,CAAA,CAAcC,CAAd,CAAoBmB,CAAAQ,OAApB,EAAqC,EAArC,CAAX,CAAqDA,CAArD,CADnB,CAEmBR,CAAAvB,IAFnB,CAII4C,EAAAA,CAAUnD,CAAA,CAAM4C,CAAN,CAAAQ,KAAA,CAAuB,QAAQ,CAAC3B,CAAD,CAAW,CAAA,IAClDd,EAAOc,CAAAd,KAD2C,CAElDwC,EAAU5D,CAAA8D,SAEd,IAAI1C,CAAJ,CAAU,CAGR,GAAI1B,CAAA0D,QAAA,CAAgBhC,CAAhB,CAAJ,GAA+B,CAAC,CAACmB,CAAAa,QAAjC,CACE,KAAMhD,EAAA,CAAgB,QAAhB;AAEJmC,CAAAa,QAAA,CAAe,OAAf,CAAuB,QAFnB,CAE6B1D,CAAA0D,QAAA,CAAgBhC,CAAhB,CAAA,CAAsB,OAAtB,CAA8B,QAF3D,CAAN,CAKEmB,CAAAa,QAAJ,EACEpD,CAAA+B,OACA,CADe,CACf,CAAAhC,CAAA,CAAQqB,CAAR,CAAc,QAAQ,CAAC2C,CAAD,CAAO,CAC3B/D,CAAAgE,KAAA,CAAW,IAAI5B,CAAJ,CAAa2B,CAAb,CAAX,CAD2B,CAA7B,CAFF,GAMEnE,CAAA,CAAoBwB,CAApB,CAA0BpB,CAA1B,CACA,CAAAA,CAAA8D,SAAA,CAAiBF,CAPnB,CATQ,CAoBV5D,CAAAiE,UAAA,CAAkB,CAAA,CAElB/B,EAAAC,SAAA,CAAoBnC,CAEpB,OAAOkC,EA5B+C,CAA1C,CA6BX,QAAQ,CAACA,CAAD,CAAW,CACpBlC,CAAAiE,UAAA,CAAkB,CAAA,CAEjB,EAAAhB,CAAA,EAAOiB,CAAP,EAAahC,CAAb,CAED,OAAOxB,EAAAyD,OAAA,CAAUjC,CAAV,CALa,CA7BR,CAqCd0B,EAAA,CAAUA,CAAAC,KAAA,CACN,QAAQ,CAAC3B,CAAD,CAAW,CACjB,IAAIlC,EAAQsD,CAAA,CAAoBpB,CAApB,CACX,EAAAc,CAAA,EAASkB,CAAT,EAAelE,CAAf,CAAsBkC,CAAAkC,QAAtB,CACD,OAAOpE,EAHU,CADb,CAMNwD,CANM,CAQV,OAAKL,EAAL,CAWOS,CAXP,EAIE5D,CAAA8D,SAGO9D,CAHU4D,CAGV5D,CAFPA,CAAAiE,UAEOjE,CAFW,CAAA,CAEXA,CAAAA,CAPT,CAxGwC,CAuH1CoC,EAAAiC,UAAA,CAAmB,GAAnB,CAAyB7B,CAAzB,CAAA,CAAiC,QAAQ,CAACO,CAAD,CAASC,CAAT,CAAkBC,CAAlB,CAAyB,CAC5DzB,CAAA,CAAWuB,CAAX,CAAJ,GACEE,CAAmC,CAA3BD,CAA2B,CAAlBA,CAAkB,CAARD,CAAQ,CAAAA,CAAA,CAAS,EAD9C,CAGIuB,EAAAA,CAASlC,CAAA,CAASI,CAAT,CAAA+B,KAAA,CAAoB,IAApB,CAA0BxB,CAA1B,CAAkC,IAAlC,CAAwCC,CAAxC,CAAiDC,CAAjD,CACb,OAAOqB,EAAAR,SAAP,EAA0BQ,CALsC,CA1H5B,CAAxC,CAmIAlC,EAAAoC,KAAA,CAAgBC,QAAQ,CAACC,CAAD,CAAyB,CAC/C,MAAO3D,EAAA,CAAgBC,CAAhB,CAAqBO,CAAA,CAAO,EAAP,CAAWN,CAAX,CAA0ByD,CAA1B,CAArB,CAAyExD,CAAzE,CADwC,CAIjD,OAAOkB,EA/J6C,CAvHC;AAEvD,IAAIE,EAAkB,KACV,QAAQ,KAAR,CADU,MAEV,QAAQ,MAAR,CAFU,OAGV,QAAQ,KAAR,SAAuB,CAAA,CAAvB,CAHU,QAIV,QAAQ,QAAR,CAJU,CAKpB,QALoB,CAKV,QAAQ,QAAR,CALU,CAAtB,CAOI4B,EAAOxE,CAAAwE,KAPX,CAQInE,EAAUL,CAAAK,QARd,CASIwB,EAAS7B,CAAA6B,OATb,CAUImC,EAAOhE,CAAAgE,KAVX,CAWIlC,EAAa9B,CAAA8B,WA+CjBb,EAAA0D,UAAA,CAAkB,cACFV,QAAQ,CAACgB,CAAD,CAAS5B,CAAT,CAAiB6B,CAAjB,CAA4B,CAAA,IAC5CC,EAAO,IADqC,CAE5C7D,EAAM4D,CAAN5D,EAAmB6D,CAAAjE,SAFyB,CAG5CkE,CAH4C,CAI5CC,CAJ4C,CAM5CjE,EAAY+D,CAAA/D,UAAZA,CAA6B,EACjCf,EAAA,CAAQiB,CAAAY,MAAA,CAAU,IAAV,CAAR,CAAyB,QAAQ,CAACoD,CAAD,CAAO,CACtC,GAAc,gBAAd,GAAIA,CAAJ,CACE,KAAM5E,EAAA,CAAgB,SAAhB,CAAN,CAEI,CAAA,OAAAsB,KAAA,CAA0BsD,CAA1B,CAAN,GAA2CA,CAA3C,EACUC,MAAJ,CAAW,cAAX,CAA4BD,CAA5B,CAAoC,SAApC,CAAAtD,KAAA,CAAoDV,CAApD,CADN,IAEEF,CAAA,CAAUkE,CAAV,CAFF,CAEqB,CAAA,CAFrB,CAJsC,CAAxC,CASAhE,EAAA,CAAMA,CAAAkE,QAAA,CAAY,MAAZ,CAAoB,GAApB,CAENnC,EAAA,CAASA,CAAT,EAAmB,EACnBhD,EAAA,CAAQ8E,CAAA/D,UAAR,CAAwB,QAAQ,CAACqE,CAAD,CAAIC,CAAJ,CAAa,CAC3CN,CAAA,CAAM/B,CAAA7C,eAAA,CAAsBkF,CAAtB,CAAA;AAAkCrC,CAAA,CAAOqC,CAAP,CAAlC,CAAqDP,CAAAhE,SAAA,CAAcuE,CAAd,CACvD1F,EAAA2F,UAAA,CAAkBP,CAAlB,CAAJ,EAAsC,IAAtC,GAA8BA,CAA9B,EACEC,CACA,CAtCCO,kBAAA,CAqC6BR,CArC7B,CAAAI,QAAA,CACG,OADH,CACY,GADZ,CAAAA,QAAA,CAEG,OAFH,CAEY,GAFZ,CAAAA,QAAA,CAGG,MAHH,CAGW,GAHX,CAAAA,QAAA,CAIG,OAJH,CAIY,GAJZ,CAAAA,QAAA,CAKG,MALH,CAK8B,KAL9B,CAnBAA,QAAA,CACG,OADH,CACY,GADZ,CAAAA,QAAA,CAEG,OAFH,CAEY,GAFZ,CAAAA,QAAA,CAGG,OAHH,CAGY,GAHZ,CAyDD,CAAAlE,CAAA,CAAMA,CAAAkE,QAAA,CAAgBD,MAAJ,CAAW,GAAX,CAAiBG,CAAjB,CAA4B,SAA5B,CAAuC,GAAvC,CAAZ,CAAyD,QAAQ,CAACG,CAAD,CAAQC,CAAR,CAAY,CACjF,MAAOT,EAAP,CAAoBS,CAD6D,CAA7E,CAFR,EAMExE,CANF,CAMQA,CAAAkE,QAAA,CAAgBD,MAAJ,CAAW,OAAX,CAAsBG,CAAtB,CAAiC,SAAjC,CAA4C,GAA5C,CAAZ,CAA8D,QAAQ,CAACG,CAAD,CACxEE,CADwE,CACxDC,CADwD,CAClD,CACxB,MAAsB,GAAtB,EAAIA,CAAAvF,OAAA,CAAY,CAAZ,CAAJ,CACSuF,CADT,CAGSD,CAHT,CAG0BC,CAJF,CADpB,CARmC,CAA7C,CAoBA1E,EAAA,CAAMA,CAAAkE,QAAA,CAAY,MAAZ,CAAoB,EAApB,CAAN,EAAiC,GAGjClE,EAAA,CAAMA,CAAAkE,QAAA,CAAY,mBAAZ,CAAiC,GAAjC,CAENP,EAAA3D,IAAA,CAAaA,CAAAkE,QAAA,CAAY,QAAZ,CAAsB,IAAtB,CAIbnF,EAAA,CAAQgD,CAAR,CAAgB,QAAQ,CAAC/C,CAAD;AAAQC,CAAR,CAAY,CAC7B4E,CAAA/D,UAAA,CAAeb,CAAf,CAAL,GACE0E,CAAA5B,OACA,CADgB4B,CAAA5B,OAChB,EADiC,EACjC,CAAA4B,CAAA5B,OAAA,CAAc9C,CAAd,CAAA,CAAqBD,CAFvB,CADkC,CAApC,CAhDgD,CADlC,CA6NlB,OAAOe,EAzRgD,CAApC,CADvB,CA3TsC,CAArC,CAAA,CAylBEtB,MAzlBF,CAylBUA,MAAAC,QAzlBV;",
+"sources":["angular-resource.js"],
+"names":["window","angular","undefined","shallowClearAndCopy","src","dst","forEach","value","key","hasOwnProperty","charAt","$resourceMinErr","$$minErr","MEMBER_NAME_REGEX","module","factory","$http","$q","Route","template","defaults","urlParams","resourceFactory","url","paramDefaults","actions","extractParams","data","actionParams","ids","extend","isFunction","path","test","keys","split","i","ii","length","obj","defaultResponseInterceptor","response","resource","Resource","route","DEFAULT_ACTIONS","action","name","hasBody","method","a1","a2","a3","a4","params","success","error","arguments","isInstanceCall","isArray","httpConfig","responseInterceptor","interceptor","responseErrorInterceptor","responseError","copy","setUrlParams","promise","then","$promise","item","push","$resolved","noop","reject","headers","prototype","result","call","bind","Resource.bind","additionalParamDefaults","config","actionUrl","self","val","encodedVal","param","RegExp","replace","_","urlParam","isDefined","encodeURIComponent","match","p1","leadingSlashes","tail"]
+}
diff --git a/src/dist/assets/scripts/angular-route.min.js b/src/dist/assets/scripts/angular-route.min.js
new file mode 100644
index 0000000..c831a02
--- /dev/null
+++ b/src/dist/assets/scripts/angular-route.min.js
@@ -0,0 +1,14 @@
+/*
+ AngularJS v1.2.15
+ (c) 2010-2014 Google, Inc. http://angularjs.org
+ License: MIT
+*/
+(function(n,e,A){'use strict';function x(s,g,k){return{restrict:"ECA",terminal:!0,priority:400,transclude:"element",link:function(a,c,b,f,w){function y(){p&&(p.remove(),p=null);h&&(h.$destroy(),h=null);l&&(k.leave(l,function(){p=null}),p=l,l=null)}function v(){var b=s.current&&s.current.locals;if(e.isDefined(b&&b.$template)){var b=a.$new(),d=s.current;l=w(b,function(d){k.enter(d,null,l||c,function(){!e.isDefined(t)||t&&!a.$eval(t)||g()});y()});h=d.scope=b;h.$emit("$viewContentLoaded");h.$eval(u)}else y()}
+var h,l,p,t=b.autoscroll,u=b.onload||"";a.$on("$routeChangeSuccess",v);v()}}}function z(e,g,k){return{restrict:"ECA",priority:-400,link:function(a,c){var b=k.current,f=b.locals;c.html(f.$template);var w=e(c.contents());b.controller&&(f.$scope=a,f=g(b.controller,f),b.controllerAs&&(a[b.controllerAs]=f),c.data("$ngControllerController",f),c.children().data("$ngControllerController",f));w(a)}}}n=e.module("ngRoute",["ng"]).provider("$route",function(){function s(a,c){return e.extend(new (e.extend(function(){},
+{prototype:a})),c)}function g(a,e){var b=e.caseInsensitiveMatch,f={originalPath:a,regexp:a},k=f.keys=[];a=a.replace(/([().])/g,"\\$1").replace(/(\/)?:(\w+)([\?\*])?/g,function(a,e,b,c){a="?"===c?c:null;c="*"===c?c:null;k.push({name:b,optional:!!a});e=e||"";return""+(a?"":e)+"(?:"+(a?e:"")+(c&&"(.+?)"||"([^/]+)")+(a||"")+")"+(a||"")}).replace(/([\/$\*])/g,"\\$1");f.regexp=RegExp("^"+a+"$",b?"i":"");return f}var k={};this.when=function(a,c){k[a]=e.extend({reloadOnSearch:!0},c,a&&g(a,c));if(a){var b=
+"/"==a[a.length-1]?a.substr(0,a.length-1):a+"/";k[b]=e.extend({redirectTo:a},g(b,c))}return this};this.otherwise=function(a){this.when(null,a);return this};this.$get=["$rootScope","$location","$routeParams","$q","$injector","$http","$templateCache","$sce",function(a,c,b,f,g,n,v,h){function l(){var d=p(),m=r.current;if(d&&m&&d.$$route===m.$$route&&e.equals(d.pathParams,m.pathParams)&&!d.reloadOnSearch&&!u)m.params=d.params,e.copy(m.params,b),a.$broadcast("$routeUpdate",m);else if(d||m)u=!1,a.$broadcast("$routeChangeStart",
+d,m),(r.current=d)&&d.redirectTo&&(e.isString(d.redirectTo)?c.path(t(d.redirectTo,d.params)).search(d.params).replace():c.url(d.redirectTo(d.pathParams,c.path(),c.search())).replace()),f.when(d).then(function(){if(d){var a=e.extend({},d.resolve),c,b;e.forEach(a,function(d,c){a[c]=e.isString(d)?g.get(d):g.invoke(d)});e.isDefined(c=d.template)?e.isFunction(c)&&(c=c(d.params)):e.isDefined(b=d.templateUrl)&&(e.isFunction(b)&&(b=b(d.params)),b=h.getTrustedResourceUrl(b),e.isDefined(b)&&(d.loadedTemplateUrl=
+b,c=n.get(b,{cache:v}).then(function(a){return a.data})));e.isDefined(c)&&(a.$template=c);return f.all(a)}}).then(function(c){d==r.current&&(d&&(d.locals=c,e.copy(d.params,b)),a.$broadcast("$routeChangeSuccess",d,m))},function(c){d==r.current&&a.$broadcast("$routeChangeError",d,m,c)})}function p(){var a,b;e.forEach(k,function(f,k){var q;if(q=!b){var g=c.path();q=f.keys;var l={};if(f.regexp)if(g=f.regexp.exec(g)){for(var h=1,p=g.length;h<p;++h){var n=q[h-1],r="string"==typeof g[h]?decodeURIComponent(g[h]):
+g[h];n&&r&&(l[n.name]=r)}q=l}else q=null;else q=null;q=a=q}q&&(b=s(f,{params:e.extend({},c.search(),a),pathParams:a}),b.$$route=f)});return b||k[null]&&s(k[null],{params:{},pathParams:{}})}function t(a,c){var b=[];e.forEach((a||"").split(":"),function(a,d){if(0===d)b.push(a);else{var e=a.match(/(\w+)(.*)/),f=e[1];b.push(c[f]);b.push(e[2]||"");delete c[f]}});return b.join("")}var u=!1,r={routes:k,reload:function(){u=!0;a.$evalAsync(l)}};a.$on("$locationChangeSuccess",l);return r}]});n.provider("$routeParams",
+function(){this.$get=function(){return{}}});n.directive("ngView",x);n.directive("ngView",z);x.$inject=["$route","$anchorScroll","$animate"];z.$inject=["$compile","$controller","$route"]})(window,window.angular);
+//# sourceMappingURL=angular-route.min.js.map
diff --git a/src/dist/assets/scripts/angular-route.min.js.map b/src/dist/assets/scripts/angular-route.min.js.map
new file mode 100644
index 0000000..3510eaf
--- /dev/null
+++ b/src/dist/assets/scripts/angular-route.min.js.map
@@ -0,0 +1,8 @@
+{
+"version":3,
+"file":"angular-route.min.js",
+"lineCount":13,
+"mappings":"A;;;;;aAKC,SAAQ,CAACA,CAAD,CAASC,CAAT,CAAkBC,CAAlB,CAA6B,CAizBtCC,QAASA,EAAa,CAAIC,CAAJ,CAAcC,CAAd,CAA+BC,CAA/B,CAAyC,CAC7D,MAAO,UACK,KADL,UAEK,CAAA,CAFL,UAGK,GAHL,YAIO,SAJP,MAKCC,QAAQ,CAACC,CAAD,CAAQC,CAAR,CAAkBC,CAAlB,CAAwBC,CAAxB,CAA8BC,CAA9B,CAA2C,CAUrDC,QAASA,EAAe,EAAG,CACtBC,CAAH,GACEA,CAAAC,OAAA,EACA,CAAAD,CAAA,CAAkB,IAFpB,CAIGE,EAAH,GACEA,CAAAC,SAAA,EACA,CAAAD,CAAA,CAAe,IAFjB,CAIGE,EAAH,GACEZ,CAAAa,MAAA,CAAeD,CAAf,CAA+B,QAAQ,EAAG,CACxCJ,CAAA,CAAkB,IADsB,CAA1C,CAIA,CADAA,CACA,CADkBI,CAClB,CAAAA,CAAA,CAAiB,IALnB,CATyB,CAkB3BE,QAASA,EAAM,EAAG,CAAA,IACZC,EAASjB,CAAAkB,QAATD,EAA2BjB,CAAAkB,QAAAD,OAG/B,IAAIpB,CAAAsB,UAAA,CAFWF,CAEX,EAFqBA,CAAAG,UAErB,CAAJ,CAAiC,CAC3BC,IAAAA,EAAWjB,CAAAkB,KAAA,EAAXD,CACAH,EAAUlB,CAAAkB,QAkBdJ,EAAA,CAVYN,CAAAe,CAAYF,CAAZE,CAAsB,QAAQ,CAACA,CAAD,CAAQ,CAChDrB,CAAAsB,MAAA,CAAeD,CAAf,CAAsB,IAAtB,CAA4BT,CAA5B,EAA8CT,CAA9C,CAAwDoB,QAAuB,EAAG,CAC5E,CAAA5B,CAAAsB,UAAA,CAAkBO,CAAlB,CAAJ,EACOA,CADP,EACwB,CAAAtB,CAAAuB,MAAA,CAAYD,CAAZ,CADxB,EAEEzB,CAAA,EAH8E,CAAlF,CAMAQ,EAAA,EAPgD,CAAtCc,CAWZX,EAAA,CAAeM,CAAAd,MAAf,CAA+BiB,CAC/BT,EAAAgB,MAAA,CAAmB,oBAAnB,CACAhB,EAAAe,MAAA,CAAmBE,CAAnB,CAvB+B,CAAjC,IAyBEpB,EAAA,EA7Bc,CA5BmC;AAAA,IACjDG,CADiD,CAEjDE,CAFiD,CAGjDJ,CAHiD,CAIjDgB,EAAgBpB,CAAAwB,WAJiC,CAKjDD,EAAYvB,CAAAyB,OAAZF,EAA2B,EAE/BzB,EAAA4B,IAAA,CAAU,qBAAV,CAAiChB,CAAjC,CACAA,EAAA,EARqD,CALpD,CADsD,CA4E/DiB,QAASA,EAAwB,CAACC,CAAD,CAAWC,CAAX,CAAwBnC,CAAxB,CAAgC,CAC/D,MAAO,UACK,KADL,UAEM,IAFN,MAGCG,QAAQ,CAACC,CAAD,CAAQC,CAAR,CAAkB,CAAA,IAC1Ba,EAAUlB,CAAAkB,QADgB,CAE1BD,EAASC,CAAAD,OAEbZ,EAAA+B,KAAA,CAAcnB,CAAAG,UAAd,CAEA,KAAIjB,EAAO+B,CAAA,CAAS7B,CAAAgC,SAAA,EAAT,CAEPnB,EAAAoB,WAAJ,GACErB,CAAAsB,OAMA,CANgBnC,CAMhB,CALIkC,CAKJ,CALiBH,CAAA,CAAYjB,CAAAoB,WAAZ,CAAgCrB,CAAhC,CAKjB,CAJIC,CAAAsB,aAIJ,GAHEpC,CAAA,CAAMc,CAAAsB,aAAN,CAGF,CAHgCF,CAGhC,EADAjC,CAAAoC,KAAA,CAAc,yBAAd,CAAyCH,CAAzC,CACA,CAAAjC,CAAAqC,SAAA,EAAAD,KAAA,CAAyB,yBAAzB,CAAoDH,CAApD,CAPF,CAUAnC,EAAA,CAAKC,CAAL,CAlB8B,CAH3B,CADwD,CA32B7DuC,CAAAA,CAAgB9C,CAAA+C,OAAA,CAAe,SAAf,CAA0B,CAAC,IAAD,CAA1B,CAAAC,SAAA,CACa,QADb,CAkBpBC,QAAuB,EAAE,CACvBC,QAASA,EAAO,CAACC,CAAD,CAASC,CAAT,CAAgB,CAC9B,MAAOpD,EAAAqD,OAAA,CAAe,KAAKrD,CAAAqD,OAAA,CAAe,QAAQ,EAAG,EAA1B;AAA8B,WAAWF,CAAX,CAA9B,CAAL,CAAf,CAA0EC,CAA1E,CADuB,CA0IhCE,QAASA,EAAU,CAACC,CAAD,CAAOC,CAAP,CAAa,CAAA,IAC1BC,EAAcD,CAAAE,qBADY,CAE1BC,EAAM,cACUJ,CADV,QAEIA,CAFJ,CAFoB,CAM1BK,EAAOD,CAAAC,KAAPA,CAAkB,EAEtBL,EAAA,CAAOA,CAAAM,QAAA,CACI,UADJ,CACgB,MADhB,CAAAA,QAAA,CAEI,uBAFJ,CAE6B,QAAQ,CAACC,CAAD,CAAIC,CAAJ,CAAWC,CAAX,CAAgBC,CAAhB,CAAuB,CAC3DC,CAAAA,CAAsB,GAAX,GAAAD,CAAA,CAAiBA,CAAjB,CAA0B,IACrCE,EAAAA,CAAkB,GAAX,GAAAF,CAAA,CAAiBA,CAAjB,CAA0B,IACrCL,EAAAQ,KAAA,CAAU,MAAQJ,CAAR,UAAuB,CAAC,CAACE,CAAzB,CAAV,CACAH,EAAA,CAAQA,CAAR,EAAiB,EACjB,OAAO,EAAP,EACKG,CAAA,CAAW,EAAX,CAAgBH,CADrB,EAEI,KAFJ,EAGKG,CAAA,CAAWH,CAAX,CAAmB,EAHxB,GAIKI,CAJL,EAIa,OAJb,EAIwB,SAJxB,GAKKD,CALL,EAKiB,EALjB,EAMI,GANJ,EAOKA,CAPL,EAOiB,EAPjB,CAL+D,CAF5D,CAAAL,QAAA,CAgBI,YAhBJ,CAgBkB,MAhBlB,CAkBPF,EAAAU,OAAA,CAAiBC,MAAJ,CAAW,GAAX,CAAiBf,CAAjB,CAAwB,GAAxB,CAA6BE,CAAA,CAAc,GAAd,CAAoB,EAAjD,CACb,OAAOE,EA3BuB,CAtIhC,IAAIY,EAAS,EAqGb,KAAAC,KAAA,CAAYC,QAAQ,CAAClB,CAAD,CAAOmB,CAAP,CAAc,CAChCH,CAAA,CAAOhB,CAAP,CAAA,CAAevD,CAAAqD,OAAA,CACb,gBAAiB,CAAA,CAAjB,CADa,CAEbqB,CAFa,CAGbnB,CAHa,EAGLD,CAAA,CAAWC,CAAX,CAAiBmB,CAAjB,CAHK,CAOf,IAAInB,CAAJ,CAAU,CACR,IAAIoB;AAAuC,GACxB,EADCpB,CAAA,CAAKA,CAAAqB,OAAL,CAAiB,CAAjB,CACD,CAAXrB,CAAAsB,OAAA,CAAY,CAAZ,CAAetB,CAAAqB,OAAf,CAA2B,CAA3B,CAAW,CACXrB,CADW,CACL,GAEdgB,EAAA,CAAOI,CAAP,CAAA,CAAuB3E,CAAAqD,OAAA,CACrB,YAAaE,CAAb,CADqB,CAErBD,CAAA,CAAWqB,CAAX,CAAyBD,CAAzB,CAFqB,CALf,CAWV,MAAO,KAnByB,CA0ElC,KAAAI,UAAA,CAAiBC,QAAQ,CAACC,CAAD,CAAS,CAChC,IAAAR,KAAA,CAAU,IAAV,CAAgBQ,CAAhB,CACA,OAAO,KAFyB,CAMlC,KAAAC,KAAA,CAAY,CAAC,YAAD,CACC,WADD,CAEC,cAFD,CAGC,IAHD,CAIC,WAJD,CAKC,OALD,CAMC,gBAND,CAOC,MAPD,CAQR,QAAQ,CAACC,CAAD,CAAaC,CAAb,CAAwBC,CAAxB,CAAsCC,CAAtC,CAA0CC,CAA1C,CAAqDC,CAArD,CAA4DC,CAA5D,CAA4EC,CAA5E,CAAkF,CA2P5FC,QAASA,EAAW,EAAG,CAAA,IACjBC,EAAOC,CAAA,EADU,CAEjBC,EAAO1F,CAAAkB,QAEX,IAAIsE,CAAJ,EAAYE,CAAZ,EAAoBF,CAAAG,QAApB,GAAqCD,CAAAC,QAArC,EACO9F,CAAA+F,OAAA,CAAeJ,CAAAK,WAAf,CAAgCH,CAAAG,WAAhC,CADP,EAEO,CAACL,CAAAM,eAFR,EAE+B,CAACC,CAFhC,CAGEL,CAAAb,OAEA,CAFcW,CAAAX,OAEd,CADAhF,CAAAmG,KAAA,CAAaN,CAAAb,OAAb,CAA0BI,CAA1B,CACA,CAAAF,CAAAkB,WAAA,CAAsB,cAAtB,CAAsCP,CAAtC,CALF,KAMO,IAAIF,CAAJ,EAAYE,CAAZ,CACLK,CAeA,CAfc,CAAA,CAed,CAdAhB,CAAAkB,WAAA,CAAsB,mBAAtB;AAA2CT,CAA3C,CAAiDE,CAAjD,CAcA,EAbA1F,CAAAkB,QAaA,CAbiBsE,CAajB,GAXMA,CAAAU,WAWN,GAVQrG,CAAAsG,SAAA,CAAiBX,CAAAU,WAAjB,CAAJ,CACElB,CAAA5B,KAAA,CAAegD,CAAA,CAAYZ,CAAAU,WAAZ,CAA6BV,CAAAX,OAA7B,CAAf,CAAAwB,OAAA,CAAiEb,CAAAX,OAAjE,CAAAnB,QAAA,EADF,CAIEsB,CAAAsB,IAAA,CAAcd,CAAAU,WAAA,CAAgBV,CAAAK,WAAhB,CAAiCb,CAAA5B,KAAA,EAAjC,CAAmD4B,CAAAqB,OAAA,EAAnD,CAAd,CAAA3C,QAAA,EAMN,EAAAwB,CAAAb,KAAA,CAAQmB,CAAR,CAAAe,KAAA,CACO,QAAQ,EAAG,CACd,GAAIf,CAAJ,CAAU,CAAA,IACJvE,EAASpB,CAAAqD,OAAA,CAAe,EAAf,CAAmBsC,CAAAgB,QAAnB,CADL,CAEJC,CAFI,CAEMC,CAEd7G,EAAA8G,QAAA,CAAgB1F,CAAhB,CAAwB,QAAQ,CAAC2F,CAAD,CAAQ/C,CAAR,CAAa,CAC3C5C,CAAA,CAAO4C,CAAP,CAAA,CAAchE,CAAAsG,SAAA,CAAiBS,CAAjB,CAAA,CACVzB,CAAA0B,IAAA,CAAcD,CAAd,CADU,CACazB,CAAA2B,OAAA,CAAiBF,CAAjB,CAFgB,CAA7C,CAKI/G,EAAAsB,UAAA,CAAkBsF,CAAlB,CAA6BjB,CAAAiB,SAA7B,CAAJ,CACM5G,CAAAkH,WAAA,CAAmBN,CAAnB,CADN,GAEIA,CAFJ,CAEeA,CAAA,CAASjB,CAAAX,OAAT,CAFf,EAIWhF,CAAAsB,UAAA,CAAkBuF,CAAlB,CAAgClB,CAAAkB,YAAhC,CAJX,GAKM7G,CAAAkH,WAAA,CAAmBL,CAAnB,CAIJ,GAHEA,CAGF,CAHgBA,CAAA,CAAYlB,CAAAX,OAAZ,CAGhB,EADA6B,CACA,CADcpB,CAAA0B,sBAAA,CAA2BN,CAA3B,CACd,CAAI7G,CAAAsB,UAAA,CAAkBuF,CAAlB,CAAJ,GACElB,CAAAyB,kBACA;AADyBP,CACzB,CAAAD,CAAA,CAAWrB,CAAAyB,IAAA,CAAUH,CAAV,CAAuB,OAAQrB,CAAR,CAAvB,CAAAkB,KAAA,CACF,QAAQ,CAACW,CAAD,CAAW,CAAE,MAAOA,EAAAzE,KAAT,CADjB,CAFb,CATF,CAeI5C,EAAAsB,UAAA,CAAkBsF,CAAlB,CAAJ,GACExF,CAAA,UADF,CACwBwF,CADxB,CAGA,OAAOvB,EAAAiC,IAAA,CAAOlG,CAAP,CA3BC,CADI,CADlB,CAAAsF,KAAA,CAiCO,QAAQ,CAACtF,CAAD,CAAS,CAChBuE,CAAJ,EAAYxF,CAAAkB,QAAZ,GACMsE,CAIJ,GAHEA,CAAAvE,OACA,CADcA,CACd,CAAApB,CAAAmG,KAAA,CAAaR,CAAAX,OAAb,CAA0BI,CAA1B,CAEF,EAAAF,CAAAkB,WAAA,CAAsB,qBAAtB,CAA6CT,CAA7C,CAAmDE,CAAnD,CALF,CADoB,CAjCxB,CAyCK,QAAQ,CAAC0B,CAAD,CAAQ,CACb5B,CAAJ,EAAYxF,CAAAkB,QAAZ,EACE6D,CAAAkB,WAAA,CAAsB,mBAAtB,CAA2CT,CAA3C,CAAiDE,CAAjD,CAAuD0B,CAAvD,CAFe,CAzCrB,CA1BmB,CA+EvB3B,QAASA,EAAU,EAAG,CAAA,IAEhBZ,CAFgB,CAERwC,CACZxH,EAAA8G,QAAA,CAAgBvC,CAAhB,CAAwB,QAAQ,CAACG,CAAD,CAAQnB,CAAR,CAAc,CACxC,IAAA,CAAA,IAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAW,IAAA,EAAA,CAAA,KAAA,EAzGbK,EAAAA,CAyGac,CAzGNd,KAAX,KACIoB,EAAS,EAEb,IAsGiBN,CAtGZL,OAAL,CAGA,GADIoD,CACJ,CAmGiB/C,CApGTL,OAAAqD,KAAA,CAAkBC,CAAlB,CACR,CAAA,CAEA,IATqC,IAS5BC,EAAI,CATwB,CASrBC,EAAMJ,CAAA7C,OAAtB,CAAgCgD,CAAhC,CAAoCC,CAApC,CAAyC,EAAED,CAA3C,CAA8C,CAC5C,IAAI5D,EAAMJ,CAAA,CAAKgE,CAAL,CAAS,CAAT,CAAV,CAEIE,EAAM,QACA,EADY,MAAOL,EAAA,CAAEG,CAAF,CACnB,CAAFG,kBAAA,CAAmBN,CAAA,CAAEG,CAAF,CAAnB,CAAE;AACFH,CAAA,CAAEG,CAAF,CAEJ5D,EAAJ,EAAW8D,CAAX,GACE9C,CAAA,CAAOhB,CAAAgE,KAAP,CADF,CACqBF,CADrB,CAP4C,CAW9C,CAAA,CAAO9C,CAbP,CAAA,IAAQ,EAAA,CAAO,IAHf,KAAmB,EAAA,CAAO,IAsGT,EAAA,CAAA,CAAA,CAAA,CAAX,CAAA,CAAJ,GACEwC,CAGA,CAHQtE,CAAA,CAAQwB,CAAR,CAAe,QACb1E,CAAAqD,OAAA,CAAe,EAAf,CAAmB8B,CAAAqB,OAAA,EAAnB,CAAuCxB,CAAvC,CADa,YAETA,CAFS,CAAf,CAGR,CAAAwC,CAAA1B,QAAA,CAAgBpB,CAJlB,CAD4C,CAA9C,CASA,OAAO8C,EAAP,EAAgBjD,CAAA,CAAO,IAAP,CAAhB,EAAgCrB,CAAA,CAAQqB,CAAA,CAAO,IAAP,CAAR,CAAsB,QAAS,EAAT,YAAwB,EAAxB,CAAtB,CAZZ,CAkBtBgC,QAASA,EAAW,CAAC0B,CAAD,CAASjD,CAAT,CAAiB,CACnC,IAAIkD,EAAS,EACblI,EAAA8G,QAAA,CAAiBqB,CAAAF,CAAAE,EAAQ,EAARA,OAAA,CAAkB,GAAlB,CAAjB,CAAyC,QAAQ,CAACC,CAAD,CAAUR,CAAV,CAAa,CAC5D,GAAU,CAAV,GAAIA,CAAJ,CACEM,CAAA9D,KAAA,CAAYgE,CAAZ,CADF,KAEO,CACL,IAAIC,EAAeD,CAAAZ,MAAA,CAAc,WAAd,CAAnB,CACIxD,EAAMqE,CAAA,CAAa,CAAb,CACVH,EAAA9D,KAAA,CAAYY,CAAA,CAAOhB,CAAP,CAAZ,CACAkE,EAAA9D,KAAA,CAAYiE,CAAA,CAAa,CAAb,CAAZ,EAA+B,EAA/B,CACA,QAAOrD,CAAA,CAAOhB,CAAP,CALF,CAHqD,CAA9D,CAWA,OAAOkE,EAAAI,KAAA,CAAY,EAAZ,CAb4B,CA5VuD,IA8LxFpC,EAAc,CAAA,CA9L0E,CA+LxF/F,EAAS,QACCoE,CADD,QAcCgE,QAAQ,EAAG,CACjBrC,CAAA,CAAc,CAAA,CACdhB,EAAAsD,WAAA,CAAsB9C,CAAtB,CAFiB,CAdZ,CAoBbR,EAAA/C,IAAA,CAAe,wBAAf,CAAyCuD,CAAzC,CAEA,OAAOvF,EArNqF,CARlF,CA1LW,CAlBL,CAkkBpB2C,EAAAE,SAAA,CAAuB,cAAvB;AAoCAyF,QAA6B,EAAG,CAC9B,IAAAxD,KAAA,CAAYyD,QAAQ,EAAG,CAAE,MAAO,EAAT,CADO,CApChC,CAwCA5F,EAAA6F,UAAA,CAAwB,QAAxB,CAAkCzI,CAAlC,CACA4C,EAAA6F,UAAA,CAAwB,QAAxB,CAAkCvG,CAAlC,CAmLAlC,EAAA0I,QAAA,CAAwB,CAAC,QAAD,CAAW,eAAX,CAA4B,UAA5B,CA4ExBxG,EAAAwG,QAAA,CAAmC,CAAC,UAAD,CAAa,aAAb,CAA4B,QAA5B,CA53BG,CAArC,CAAA,CAy5BE7I,MAz5BF,CAy5BUA,MAAAC,QAz5BV;",
+"sources":["angular-route.js"],
+"names":["window","angular","undefined","ngViewFactory","$route","$anchorScroll","$animate","link","scope","$element","attr","ctrl","$transclude","cleanupLastView","previousElement","remove","currentScope","$destroy","currentElement","leave","update","locals","current","isDefined","$template","newScope","$new","clone","enter","onNgViewEnter","autoScrollExp","$eval","$emit","onloadExp","autoscroll","onload","$on","ngViewFillContentFactory","$compile","$controller","html","contents","controller","$scope","controllerAs","data","children","ngRouteModule","module","provider","$RouteProvider","inherit","parent","extra","extend","pathRegExp","path","opts","insensitive","caseInsensitiveMatch","ret","keys","replace","_","slash","key","option","optional","star","push","regexp","RegExp","routes","when","this.when","route","redirectPath","length","substr","otherwise","this.otherwise","params","$get","$rootScope","$location","$routeParams","$q","$injector","$http","$templateCache","$sce","updateRoute","next","parseRoute","last","$$route","equals","pathParams","reloadOnSearch","forceReload","copy","$broadcast","redirectTo","isString","interpolate","search","url","then","resolve","template","templateUrl","forEach","value","get","invoke","isFunction","getTrustedResourceUrl","loadedTemplateUrl","response","all","error","match","m","exec","on","i","len","val","decodeURIComponent","name","string","result","split","segment","segmentMatch","join","reload","$evalAsync","$RouteParamsProvider","this.$get","directive","$inject"]
+}
diff --git a/src/dist/assets/scripts/angular.min.js b/src/dist/assets/scripts/angular.min.js
new file mode 100644
index 0000000..1e819cb
--- /dev/null
+++ b/src/dist/assets/scripts/angular.min.js
@@ -0,0 +1,207 @@
+/*
+ AngularJS v1.2.15
+ (c) 2010-2014 Google, Inc. http://angularjs.org
+ License: MIT
+*/
+(function(Q,T,s){'use strict';function z(b){return function(){var a=arguments[0],c,a="["+(b?b+":":"")+a+"] http://errors.angularjs.org/1.2.15/"+(b?b+"/":"")+a;for(c=1;c<arguments.length;c++)a=a+(1==c?"?":"&")+"p"+(c-1)+"="+encodeURIComponent("function"==typeof arguments[c]?arguments[c].toString().replace(/ \{[\s\S]*$/,""):"undefined"==typeof arguments[c]?"undefined":"string"!=typeof arguments[c]?JSON.stringify(arguments[c]):arguments[c]);return Error(a)}}function $a(b){if(null==b||Aa(b))return!1;
+var a=b.length;return 1===b.nodeType&&a?!0:x(b)||M(b)||0===a||"number"===typeof a&&0<a&&a-1 in b}function r(b,a,c){var d;if(b)if(D(b))for(d in b)"prototype"==d||("length"==d||"name"==d||b.hasOwnProperty&&!b.hasOwnProperty(d))||a.call(c,b[d],d);else if(b.forEach&&b.forEach!==r)b.forEach(a,c);else if($a(b))for(d=0;d<b.length;d++)a.call(c,b[d],d);else for(d in b)b.hasOwnProperty(d)&&a.call(c,b[d],d);return b}function Ob(b){var a=[],c;for(c in b)b.hasOwnProperty(c)&&a.push(c);return a.sort()}function Qc(b,
+a,c){for(var d=Ob(b),e=0;e<d.length;e++)a.call(c,b[d[e]],d[e]);return d}function Pb(b){return function(a,c){b(c,a)}}function ab(){for(var b=ia.length,a;b;){b--;a=ia[b].charCodeAt(0);if(57==a)return ia[b]="A",ia.join("");if(90==a)ia[b]="0";else return ia[b]=String.fromCharCode(a+1),ia.join("")}ia.unshift("0");return ia.join("")}function Qb(b,a){a?b.$$hashKey=a:delete b.$$hashKey}function v(b){var a=b.$$hashKey;r(arguments,function(a){a!==b&&r(a,function(a,c){b[c]=a})});Qb(b,a);return b}function R(b){return parseInt(b,
+10)}function Rb(b,a){return v(new (v(function(){},{prototype:b})),a)}function B(){}function Ba(b){return b}function Y(b){return function(){return b}}function E(b){return"undefined"===typeof b}function u(b){return"undefined"!==typeof b}function W(b){return null!=b&&"object"===typeof b}function x(b){return"string"===typeof b}function ub(b){return"number"===typeof b}function Ma(b){return"[object Date]"===ta.call(b)}function M(b){return"[object Array]"===ta.call(b)}function D(b){return"function"===typeof b}
+function bb(b){return"[object RegExp]"===ta.call(b)}function Aa(b){return b&&b.document&&b.location&&b.alert&&b.setInterval}function Rc(b){return!(!b||!(b.nodeName||b.prop&&b.attr&&b.find))}function Sc(b,a,c){var d=[];r(b,function(b,f,g){d.push(a.call(c,b,f,g))});return d}function cb(b,a){if(b.indexOf)return b.indexOf(a);for(var c=0;c<b.length;c++)if(a===b[c])return c;return-1}function Na(b,a){var c=cb(b,a);0<=c&&b.splice(c,1);return a}function $(b,a){if(Aa(b)||b&&b.$evalAsync&&b.$watch)throw Oa("cpws");
+if(a){if(b===a)throw Oa("cpi");if(M(b))for(var c=a.length=0;c<b.length;c++)a.push($(b[c]));else{c=a.$$hashKey;r(a,function(b,c){delete a[c]});for(var d in b)a[d]=$(b[d]);Qb(a,c)}}else(a=b)&&(M(b)?a=$(b,[]):Ma(b)?a=new Date(b.getTime()):bb(b)?a=RegExp(b.source):W(b)&&(a=$(b,{})));return a}function Sb(b,a){a=a||{};for(var c in b)!b.hasOwnProperty(c)||"$"===c.charAt(0)&&"$"===c.charAt(1)||(a[c]=b[c]);return a}function ua(b,a){if(b===a)return!0;if(null===b||null===a)return!1;if(b!==b&&a!==a)return!0;
+var c=typeof b,d;if(c==typeof a&&"object"==c)if(M(b)){if(!M(a))return!1;if((c=b.length)==a.length){for(d=0;d<c;d++)if(!ua(b[d],a[d]))return!1;return!0}}else{if(Ma(b))return Ma(a)&&b.getTime()==a.getTime();if(bb(b)&&bb(a))return b.toString()==a.toString();if(b&&b.$evalAsync&&b.$watch||a&&a.$evalAsync&&a.$watch||Aa(b)||Aa(a)||M(a))return!1;c={};for(d in b)if("$"!==d.charAt(0)&&!D(b[d])){if(!ua(b[d],a[d]))return!1;c[d]=!0}for(d in a)if(!c.hasOwnProperty(d)&&"$"!==d.charAt(0)&&a[d]!==s&&!D(a[d]))return!1;
+return!0}return!1}function Tb(){return T.securityPolicy&&T.securityPolicy.isActive||T.querySelector&&!(!T.querySelector("[ng-csp]")&&!T.querySelector("[data-ng-csp]"))}function db(b,a){var c=2<arguments.length?va.call(arguments,2):[];return!D(a)||a instanceof RegExp?a:c.length?function(){return arguments.length?a.apply(b,c.concat(va.call(arguments,0))):a.apply(b,c)}:function(){return arguments.length?a.apply(b,arguments):a.call(b)}}function Tc(b,a){var c=a;"string"===typeof b&&"$"===b.charAt(0)?c=
+s:Aa(a)?c="$WINDOW":a&&T===a?c="$DOCUMENT":a&&(a.$evalAsync&&a.$watch)&&(c="$SCOPE");return c}function oa(b,a){return"undefined"===typeof b?s:JSON.stringify(b,Tc,a?"  ":null)}function Ub(b){return x(b)?JSON.parse(b):b}function Pa(b){"function"===typeof b?b=!0:b&&0!==b.length?(b=O(""+b),b=!("f"==b||"0"==b||"false"==b||"no"==b||"n"==b||"[]"==b)):b=!1;return b}function fa(b){b=w(b).clone();try{b.empty()}catch(a){}var c=w("<div>").append(b).html();try{return 3===b[0].nodeType?O(c):c.match(/^(<[^>]+>)/)[1].replace(/^<([\w\-]+)/,
+function(a,b){return"<"+O(b)})}catch(d){return O(c)}}function Vb(b){try{return decodeURIComponent(b)}catch(a){}}function Wb(b){var a={},c,d;r((b||"").split("&"),function(b){b&&(c=b.split("="),d=Vb(c[0]),u(d)&&(b=u(c[1])?Vb(c[1]):!0,a[d]?M(a[d])?a[d].push(b):a[d]=[a[d],b]:a[d]=b))});return a}function Xb(b){var a=[];r(b,function(b,d){M(b)?r(b,function(b){a.push(wa(d,!0)+(!0===b?"":"="+wa(b,!0)))}):a.push(wa(d,!0)+(!0===b?"":"="+wa(b,!0)))});return a.length?a.join("&"):""}function vb(b){return wa(b,
+!0).replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+")}function wa(b,a){return encodeURIComponent(b).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,a?"%20":"+")}function Uc(b,a){function c(a){a&&d.push(a)}var d=[b],e,f,g=["ng:app","ng-app","x-ng-app","data-ng-app"],h=/\sng[:\-]app(:\s*([\w\d_]+);?)?\s/;r(g,function(a){g[a]=!0;c(T.getElementById(a));a=a.replace(":","\\:");b.querySelectorAll&&(r(b.querySelectorAll("."+a),c),r(b.querySelectorAll("."+
+a+"\\:"),c),r(b.querySelectorAll("["+a+"]"),c))});r(d,function(a){if(!e){var b=h.exec(" "+a.className+" ");b?(e=a,f=(b[2]||"").replace(/\s+/g,",")):r(a.attributes,function(b){!e&&g[b.name]&&(e=a,f=b.value)})}});e&&a(e,f?[f]:[])}function Yb(b,a){var c=function(){b=w(b);if(b.injector()){var c=b[0]===T?"document":fa(b);throw Oa("btstrpd",c);}a=a||[];a.unshift(["$provide",function(a){a.value("$rootElement",b)}]);a.unshift("ng");c=Zb(a);c.invoke(["$rootScope","$rootElement","$compile","$injector","$animate",
+function(a,b,c,d,e){a.$apply(function(){b.data("$injector",d);c(b)(a)})}]);return c},d=/^NG_DEFER_BOOTSTRAP!/;if(Q&&!d.test(Q.name))return c();Q.name=Q.name.replace(d,"");Ca.resumeBootstrap=function(b){r(b,function(b){a.push(b)});c()}}function eb(b,a){a=a||"_";return b.replace(Vc,function(b,d){return(d?a:"")+b.toLowerCase()})}function wb(b,a,c){if(!b)throw Oa("areq",a||"?",c||"required");return b}function Qa(b,a,c){c&&M(b)&&(b=b[b.length-1]);wb(D(b),a,"not a function, got "+(b&&"object"==typeof b?
+b.constructor.name||"Object":typeof b));return b}function xa(b,a){if("hasOwnProperty"===b)throw Oa("badname",a);}function $b(b,a,c){if(!a)return b;a=a.split(".");for(var d,e=b,f=a.length,g=0;g<f;g++)d=a[g],b&&(b=(e=b)[d]);return!c&&D(b)?db(e,b):b}function xb(b){var a=b[0];b=b[b.length-1];if(a===b)return w(a);var c=[a];do{a=a.nextSibling;if(!a)break;c.push(a)}while(a!==b);return w(c)}function Wc(b){var a=z("$injector"),c=z("ng");b=b.angular||(b.angular={});b.$$minErr=b.$$minErr||z;return b.module||
+(b.module=function(){var b={};return function(e,f,g){if("hasOwnProperty"===e)throw c("badname","module");f&&b.hasOwnProperty(e)&&(b[e]=null);return b[e]||(b[e]=function(){function b(a,d,e){return function(){c[e||"push"]([a,d,arguments]);return n}}if(!f)throw a("nomod",e);var c=[],d=[],l=b("$injector","invoke"),n={_invokeQueue:c,_runBlocks:d,requires:f,name:e,provider:b("$provide","provider"),factory:b("$provide","factory"),service:b("$provide","service"),value:b("$provide","value"),constant:b("$provide",
+"constant","unshift"),animation:b("$animateProvider","register"),filter:b("$filterProvider","register"),controller:b("$controllerProvider","register"),directive:b("$compileProvider","directive"),config:l,run:function(a){d.push(a);return this}};g&&l(g);return n}())}}())}function Xc(b){v(b,{bootstrap:Yb,copy:$,extend:v,equals:ua,element:w,forEach:r,injector:Zb,noop:B,bind:db,toJson:oa,fromJson:Ub,identity:Ba,isUndefined:E,isDefined:u,isString:x,isFunction:D,isObject:W,isNumber:ub,isElement:Rc,isArray:M,
+version:Yc,isDate:Ma,lowercase:O,uppercase:Da,callbacks:{counter:0},$$minErr:z,$$csp:Tb});Ra=Wc(Q);try{Ra("ngLocale")}catch(a){Ra("ngLocale",[]).provider("$locale",Zc)}Ra("ng",["ngLocale"],["$provide",function(a){a.provider({$$sanitizeUri:$c});a.provider("$compile",ac).directive({a:ad,input:bc,textarea:bc,form:bd,script:cd,select:dd,style:ed,option:fd,ngBind:gd,ngBindHtml:hd,ngBindTemplate:id,ngClass:jd,ngClassEven:kd,ngClassOdd:ld,ngCloak:md,ngController:nd,ngForm:od,ngHide:pd,ngIf:qd,ngInclude:rd,
+ngInit:sd,ngNonBindable:td,ngPluralize:ud,ngRepeat:vd,ngShow:wd,ngStyle:xd,ngSwitch:yd,ngSwitchWhen:zd,ngSwitchDefault:Ad,ngOptions:Bd,ngTransclude:Cd,ngModel:Dd,ngList:Ed,ngChange:Fd,required:cc,ngRequired:cc,ngValue:Gd}).directive({ngInclude:Hd}).directive(yb).directive(dc);a.provider({$anchorScroll:Id,$animate:Jd,$browser:Kd,$cacheFactory:Ld,$controller:Md,$document:Nd,$exceptionHandler:Od,$filter:ec,$interpolate:Pd,$interval:Qd,$http:Rd,$httpBackend:Sd,$location:Td,$log:Ud,$parse:Vd,$rootScope:Wd,
+$q:Xd,$sce:Yd,$sceDelegate:Zd,$sniffer:$d,$templateCache:ae,$timeout:be,$window:ce,$$rAF:de,$$asyncCallback:ee})}])}function Sa(b){return b.replace(fe,function(a,b,d,e){return e?d.toUpperCase():d}).replace(ge,"Moz$1")}function zb(b,a,c,d){function e(b){var e=c&&b?[this.filter(b)]:[this],m=a,k,l,n,q,p,t;if(!d||null!=b)for(;e.length;)for(k=e.shift(),l=0,n=k.length;l<n;l++)for(q=w(k[l]),m?q.triggerHandler("$destroy"):m=!m,p=0,q=(t=q.children()).length;p<q;p++)e.push(Ea(t[p]));return f.apply(this,arguments)}
+var f=Ea.fn[b],f=f.$original||f;e.$original=f;Ea.fn[b]=e}function L(b){if(b instanceof L)return b;x(b)&&(b=aa(b));if(!(this instanceof L)){if(x(b)&&"<"!=b.charAt(0))throw Ab("nosel");return new L(b)}if(x(b)){var a=T.createElement("div");a.innerHTML="<div>&#160;</div>"+b;a.removeChild(a.firstChild);Bb(this,a.childNodes);w(T.createDocumentFragment()).append(this)}else Bb(this,b)}function Cb(b){return b.cloneNode(!0)}function Fa(b){fc(b);var a=0;for(b=b.childNodes||[];a<b.length;a++)Fa(b[a])}function gc(b,
+a,c,d){if(u(d))throw Ab("offargs");var e=ja(b,"events");ja(b,"handle")&&(E(a)?r(e,function(a,c){Db(b,c,a);delete e[c]}):r(a.split(" "),function(a){E(c)?(Db(b,a,e[a]),delete e[a]):Na(e[a]||[],c)}))}function fc(b,a){var c=b[fb],d=Ta[c];d&&(a?delete Ta[c].data[a]:(d.handle&&(d.events.$destroy&&d.handle({},"$destroy"),gc(b)),delete Ta[c],b[fb]=s))}function ja(b,a,c){var d=b[fb],d=Ta[d||-1];if(u(c))d||(b[fb]=d=++he,d=Ta[d]={}),d[a]=c;else return d&&d[a]}function hc(b,a,c){var d=ja(b,"data"),e=u(c),f=!e&&
+u(a),g=f&&!W(a);d||g||ja(b,"data",d={});if(e)d[a]=c;else if(f){if(g)return d&&d[a];v(d,a)}else return d}function Eb(b,a){return b.getAttribute?-1<(" "+(b.getAttribute("class")||"")+" ").replace(/[\n\t]/g," ").indexOf(" "+a+" "):!1}function gb(b,a){a&&b.setAttribute&&r(a.split(" "),function(a){b.setAttribute("class",aa((" "+(b.getAttribute("class")||"")+" ").replace(/[\n\t]/g," ").replace(" "+aa(a)+" "," ")))})}function hb(b,a){if(a&&b.setAttribute){var c=(" "+(b.getAttribute("class")||"")+" ").replace(/[\n\t]/g,
+" ");r(a.split(" "),function(a){a=aa(a);-1===c.indexOf(" "+a+" ")&&(c+=a+" ")});b.setAttribute("class",aa(c))}}function Bb(b,a){if(a){a=a.nodeName||!u(a.length)||Aa(a)?[a]:a;for(var c=0;c<a.length;c++)b.push(a[c])}}function ic(b,a){return ib(b,"$"+(a||"ngController")+"Controller")}function ib(b,a,c){b=w(b);9==b[0].nodeType&&(b=b.find("html"));for(a=M(a)?a:[a];b.length;){for(var d=b[0],e=0,f=a.length;e<f;e++)if((c=b.data(a[e]))!==s)return c;b=w(d.parentNode||11===d.nodeType&&d.host)}}function jc(b){for(var a=
+0,c=b.childNodes;a<c.length;a++)Fa(c[a]);for(;b.firstChild;)b.removeChild(b.firstChild)}function kc(b,a){var c=jb[a.toLowerCase()];return c&&lc[b.nodeName]&&c}function ie(b,a){var c=function(c,e){c.preventDefault||(c.preventDefault=function(){c.returnValue=!1});c.stopPropagation||(c.stopPropagation=function(){c.cancelBubble=!0});c.target||(c.target=c.srcElement||T);if(E(c.defaultPrevented)){var f=c.preventDefault;c.preventDefault=function(){c.defaultPrevented=!0;f.call(c)};c.defaultPrevented=!1}c.isDefaultPrevented=
+function(){return c.defaultPrevented||!1===c.returnValue};var g=Sb(a[e||c.type]||[]);r(g,function(a){a.call(b,c)});8>=P?(c.preventDefault=null,c.stopPropagation=null,c.isDefaultPrevented=null):(delete c.preventDefault,delete c.stopPropagation,delete c.isDefaultPrevented)};c.elem=b;return c}function Ga(b){var a=typeof b,c;"object"==a&&null!==b?"function"==typeof(c=b.$$hashKey)?c=b.$$hashKey():c===s&&(c=b.$$hashKey=ab()):c=b;return a+":"+c}function Ua(b){r(b,this.put,this)}function mc(b){var a,c;"function"==
+typeof b?(a=b.$inject)||(a=[],b.length&&(c=b.toString().replace(je,""),c=c.match(ke),r(c[1].split(le),function(b){b.replace(me,function(b,c,d){a.push(d)})})),b.$inject=a):M(b)?(c=b.length-1,Qa(b[c],"fn"),a=b.slice(0,c)):Qa(b,"fn",!0);return a}function Zb(b){function a(a){return function(b,c){if(W(b))r(b,Pb(a));else return a(b,c)}}function c(a,b){xa(a,"service");if(D(b)||M(b))b=n.instantiate(b);if(!b.$get)throw Va("pget",a);return l[a+h]=b}function d(a,b){return c(a,{$get:b})}function e(a){var b=[],
+c,d,f,h;r(a,function(a){if(!k.get(a)){k.put(a,!0);try{if(x(a))for(c=Ra(a),b=b.concat(e(c.requires)).concat(c._runBlocks),d=c._invokeQueue,f=0,h=d.length;f<h;f++){var g=d[f],m=n.get(g[0]);m[g[1]].apply(m,g[2])}else D(a)?b.push(n.invoke(a)):M(a)?b.push(n.invoke(a)):Qa(a,"module")}catch(l){throw M(a)&&(a=a[a.length-1]),l.message&&(l.stack&&-1==l.stack.indexOf(l.message))&&(l=l.m…
82a586e

@shin-szk-engineering shin-szk-engineering referenced this pull request in shin-szk-engineering/mensagg Oct 15, 2014

@shin-szk-engineering shin-szk-engineering [from now] 2014/10/15 18:39:43
diff --git a/public/assets/_groundwork_settings-6584930913c75ff69ba506e1cfbae2c9.css b/public/assets/_groundwork_settings-6584930913c75ff69ba506e1cfbae2c9.css
new file mode 100644
index 0000000..e69de29
diff --git a/public/assets/_groundwork_settings-6584930913c75ff69ba506e1cfbae2c9.css.gz b/public/assets/_groundwork_settings-6584930913c75ff69ba506e1cfbae2c9.css.gz
new file mode 100644
index 0000000..40a03b9
Binary files /dev/null and b/public/assets/_groundwork_settings-6584930913c75ff69ba506e1cfbae2c9.css.gz differ
diff --git a/public/assets/application-396c4fa85cbed39ca65e3842d803c17e.css b/public/assets/application-396c4fa85cbed39ca65e3842d803c17e.css
new file mode 100644
index 0000000..e2d188a
--- /dev/null
+++ b/public/assets/application-396c4fa85cbed39ca65e3842d803c17e.css
@@ -0,0 +1,33069 @@
+/* line 21, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_reset.scss */
+*, *:after, *:before {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+
+/* line 60, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_reset.scss */
+html, body {
+  -webkit-text-size-adjust: none;
+}
+
+/* line 64, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_reset.scss */
+html, body, div, span, header, footer, aside, nav, menu, main, section, article, details, h1, h2, h3, h4, h5, h6, p, ol, ul, li, dl, dt, dd, em, small, big, strong, b, u, i, sub, sup, del, strike, q, blockquote, cite, time, address, code, pre, a, img, center, hr, form, fieldset, legend, label, input, textarea, button, table, caption, tbody, thead, tfoot, tr, th, td, iframe, object, canvas, audio, video, embed {
+  margin: 0;
+  padding: 0;
+  border: 0;
+  font: inherit;
+  vertical-align: baseline;
+}
+
+/* line 72, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_reset.scss */
+header, footer, aside, menu, nav, section, article, details {
+  display: block;
+}
+
+/* line 76, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_reset.scss */
+table {
+  border-collapse: collapse;
+  border-spacing: 0;
+}
+
+/* line 95, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_reset.scss */
+script {
+  display: none !important;
+}
+
+/* line 14, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_global.scss */
+html, body {
+  width: 100% !important;
+  min-height: 100%;
+  background: white;
+}
+
+/* line 21, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_global.scss */
+html {
+  width: 100%;
+  height: 100%;
+}
+
+/* line 26, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_global.scss */
+hr {
+  border: 0;
+  border-bottom: 1px solid #dddddd;
+  margin: 10px auto;
+  clear: both;
+}
+
+/* line 33, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_global.scss */
+img, a img {
+  max-width: 100%;
+  border: none;
+}
+
+/* line 147, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.clear, .clearfix, ul.button-group:after,
+ol.button-group:after, .nav ul, .tabs > div, [role~="tabpanel"] {
+  clear: both;
+}
+/* line 148, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.clear:after, .clearfix:after, ul.button-group:after,
+ol.button-group:after, .nav ul:after, .tabs > div:after, [role~="tabpanel"]:after {
+  content: " ";
+  display: block;
+  height: 0;
+  font-size: 0;
+  clear: both;
+  visibility: hidden;
+}
+
+/* line 151, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.padded, .box, .tabs > div, [role~="tabpanel"] {
+  padding: 10px;
+}
+
+/* line 152, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.half-padded {
+  padding: 5px;
+}
+
+/* line 153, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.double-padded {
+  padding: 20px;
+}
+
+/* line 154, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.triple-padded {
+  padding: 30px;
+}
+
+/* line 156, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.pad-top {
+  padding-top: 10px;
+}
+
+/* line 157, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.half-pad-top {
+  padding-top: 5px;
+}
+
+/* line 158, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.double-pad-top {
+  padding-top: 20px;
+}
+
+/* line 159, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.triple-pad-top {
+  padding-top: 30px;
+}
+
+/* line 161, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.pad-right {
+  padding-right: 10px;
+}
+
+/* line 162, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.half-pad-right {
+  padding-right: 5px;
+}
+
+/* line 163, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.double-pad-right {
+  padding-right: 20px;
+}
+
+/* line 164, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.triple-pad-right {
+  padding-right: 30px;
+}
+
+/* line 166, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.pad-bottom {
+  padding-bottom: 10px;
+}
+
+/* line 167, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.half-pad-bottom {
+  padding-bottom: 5px;
+}
+
+/* line 168, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.double-pad-bottom {
+  padding-bottom: 20px;
+}
+
+/* line 169, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.triple-pad-bottom {
+  padding-bottom: 30px;
+}
+
+/* line 171, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.pad-left {
+  padding-left: 10px;
+}
+
+/* line 172, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.half-pad-left {
+  padding-left: 5px;
+}
+
+/* line 173, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.double-pad-left {
+  padding-left: 20px;
+}
+
+/* line 174, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.triple-pad-left {
+  padding-left: 30px;
+}
+
+/* line 176, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.gapped {
+  margin: 10px;
+}
+
+/* line 177, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.half-gapped {
+  margin: 5px;
+}
+
+/* line 178, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.double-gapped {
+  margin: 20px;
+}
+
+/* line 179, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.triple-gapped {
+  margin: 30px;
+}
+
+/* line 181, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.gap-top {
+  margin-top: 10px;
+}
+
+/* line 182, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.half-gap-top {
+  margin-top: 5px;
+}
+
+/* line 183, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.double-gap-top {
+  margin-top: 20px;
+}
+
+/* line 184, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.triple-gap-top {
+  margin-top: 30px;
+}
+
+/* line 186, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.gap-right {
+  margin-right: 10px;
+}
+
+/* line 187, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.half-gap-right {
+  margin-right: 5px;
+}
+
+/* line 188, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.double-gap-right {
+  margin-right: 20px;
+}
+
+/* line 189, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.triple-gap-right {
+  margin-right: 30px;
+}
+
+/* line 191, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.gap-bottom {
+  margin-bottom: 10px;
+}
+
+/* line 192, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.half-gap-bottom {
+  margin-bottom: 5px;
+}
+
+/* line 193, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.double-gap-bottom {
+  margin-bottom: 20px;
+}
+
+/* line 194, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.triple-gap-bottom {
+  margin-bottom: 30px;
+}
+
+/* line 196, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.gap-left, .dropdown > a:after, .dropdown > button:after, .dropdown .button:after {
+  margin-left: 10px;
+}
+
+/* line 197, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.half-gap-left {
+  margin-left: 5px;
+}
+
+/* line 198, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.double-gap-left {
+  margin-left: 20px;
+}
+
+/* line 199, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.triple-gap-left {
+  margin-left: 30px;
+}
+
+/* line 201, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.offset {
+  margin: -10px;
+}
+
+/* line 202, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.half-offset {
+  margin: -5px;
+}
+
+/* line 203, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.double-offset {
+  margin: -20px;
+}
+
+/* line 204, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.triple-offset {
+  margin: -30px;
+}
+
+/* line 206, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.offset-top {
+  margin-top: -10px;
+}
+
+/* line 207, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.half-offset-top {
+  margin-top: -5px;
+}
+
+/* line 208, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.double-offset-top {
+  margin-top: -20px;
+}
+
+/* line 209, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.triple-offset-top {
+  margin-top: -30px;
+}
+
+/* line 211, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.offset-right {
+  margin-right: -10px;
+}
+
+/* line 212, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.half-offset-right {
+  margin-right: -5px;
+}
+
+/* line 213, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.double-offset-right {
+  margin-right: -20px;
+}
+
+/* line 214, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.triple-offset-right {
+  margin-right: -30px;
+}
+
+/* line 216, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.offset-bottom {
+  margin-bottom: -10px;
+}
+
+/* line 217, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.half-offset-bottom {
+  margin-bottom: -5px;
+}
+
+/* line 218, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.double-offset-bottom {
+  margin-bottom: -20px;
+}
+
+/* line 219, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.triple-offset-bottom {
+  margin-bottom: -30px;
+}
+
+/* line 221, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.offset-left {
+  margin-left: -10px;
+}
+
+/* line 222, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.half-offset-left {
+  margin-left: -5px;
+}
+
+/* line 223, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.double-offset-left {
+  margin-left: -20px;
+}
+
+/* line 224, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.triple-offset-left {
+  margin-left: -30px;
+}
+
+/* line 226, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.stick, .fixed {
+  position: fixed;
+}
+
+/* line 227, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.stick.top, .fixed.top {
+  position: fixed;
+  top: 0;
+}
+
+/* line 228, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.stick.right, .fixed.right {
+  position: fixed;
+  right: 0;
+}
+
+/* line 229, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.stick.bottom, .fixed.bottom {
+  position: fixed;
+  bottom: 0;
+}
+
+/* line 230, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.stick.left, .fixed.left {
+  position: fixed;
+  left: 0;
+}
+
+/* line 231, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.stick.middle, .fixed.middle {
+  position: fixed;
+  top: 50%;
+}
+
+/* line 232, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.stick.center, .fixed.center {
+  position: fixed;
+  left: 50%;
+}
+
+/* line 234, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.absolute, .tabs:not(.accordion).vertical > ul {
+  position: absolute;
+}
+
+/* line 235, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.absolute.top, .tabs:not(.accordion).vertical > ul {
+  position: absolute;
+  top: 0;
+}
+
+/* line 236, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.absolute.right {
+  position: absolute;
+  right: 0;
+}
+
+/* line 237, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.absolute.bottom, .tabs:not(.accordion).vertical > ul {
+  position: absolute;
+  bottom: 0;
+}
+
+/* line 238, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.absolute.left, .tabs:not(.accordion).vertical > ul {
+  position: absolute;
+  left: 0;
+}
+
+/* line 239, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.absolute.middle {
+  position: absolute;
+  top: 50%;
+}
+
+/* line 240, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.absolute.center {
+  position: absolute;
+  left: 50%;
+}
+
+/* line 242, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.relative, sup, sub, blockquote, .box, .message, [role~="alert"], [role~="status"], .nav, [role~="navigation"], .nav li, .tabs:not(.accordion) {
+  position: relative;
+}
+
+/* line 243, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.static {
+  position: static;
+}
+
+/* line 245, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.inline {
+  display: inline;
+}
+
+/* line 246, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.inline-block, a:before, a:after, code, button,
+input[type=submit],
+input[type=button],
+input[type=reset], .button,
+a.button,
+a.button:visited, [role~="button"], .dropdown, .dropdown > a:after, .dropdown > button:after, .dropdown .button:after, input[type="checkbox"], input[type="radio"], .nav a, .nav a:visited, .nav button, .tabs > ul li, [role~="tab"] {
+  display: inline-block;
+  width: auto;
+}
+
+/* line 247, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.block, button.block,
+input[type=submit].block,
+input[type=button].block,
+input[type=reset].block, .button.block,
+a.button.block,
+a.button.block:visited, ul.button-group li a.block, ul.button-group li button.block,
+ol.button-group li a.block,
+ol.button-group li button.block, [role~="button"].block, .dropdown ul li, .dropdown ul li a, .dropdown ul li button, ul.button-group:after,
+ol.button-group:after, ul.button-group li,
+ol.button-group li, ul.button-group li a,
+ol.button-group li a, ul.button-group li button,
+ol.button-group li button, .dropdown.on ul, .dropdown.active ul, .dropdown[aria-selected="true"] ul, .dropdown[aria-pressed="true"] ul, .nav li, .tabs.vertical > ul li, .tabs.accordion > ul li {
+  display: block;
+}
+
+/* line 248, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.hidden {
+  display: none !important;
+}
+
+/* line 250, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.small, sup, sub, small {
+  font-size: 0.8em;
+}
+
+/* line 251, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.medium {
+  font-size: 1em;
+}
+
+/* line 252, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+big, .large {
+  font-size: 1.5em;
+}
+
+/* line 254, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+em, q {
+  font-style: italic;
+}
+
+/* line 255, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+b, q, blockquote, strong, .nav a, .nav a:visited, .nav button {
+  font-weight: 900;
+}
+
+/* line 257, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+html, body, .unstyled, ul.checklist, ul.list, ol.list, ul.unstyled, ol.unstyled, ul.button-group,
+ol.button-group, .nav ul, .tabs > ul, [role~="tablist"], .zero, input[type="checkbox"], input[type="radio"] {
+  margin: 0;
+  padding: 0;
+}
+
+/* line 259, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.pull-right, .nav button.hamburger, .nav li[role="menu"] > a:after, .nav li[role="menu"] > button:after {
+  float: right;
+}
+
+/* line 260, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.pull-left, .nav li {
+  float: left;
+}
+
+/* line 261, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.pull-none, .nav.vertical li {
+  float: none;
+}
+
+/* line 263, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.bordered {
+  border: 1px solid #dddddd;
+}
+
+/* line 264, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.border-top {
+  border-top: 1px solid #dddddd;
+}
+
+/* line 265, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.border-right {
+  border-right: 1px solid #dddddd;
+}
+
+/* line 266, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.border-bottom {
+  border-bottom: 1px solid #dddddd;
+}
+
+/* line 267, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.border-left {
+  border-left: 1px solid #dddddd;
+}
+
+/* line 269, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.align-top {
+  display: table-cell;
+  vertical-align: top;
+}
+
+/* line 270, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.align-right {
+  text-align: right;
+}
+
+/* line 271, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.align-bottom {
+  display: table-cell;
+  vertical-align: bottom;
+}
+
+/* line 272, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.align-left, .nav li ul a, .nav li ul button {
+  text-align: left;
+}
+
+/* line 273, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.align-center, .nav a, .nav a:visited, .nav button {
+  text-align: center;
+}
+
+/* line 274, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.justify {
+  text-align: justify;
+}
+
+/* line 275, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.unstyled, ul.checklist, ul.list, ol.list, ul.unstyled, ol.unstyled, ul.button-group,
+ol.button-group, .nav ul, .tabs > ul, [role~="tablist"] {
+  list-style: none;
+}
+
+/* line 277, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.truncate, .js .responsive:not(table) {
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+}
+
+/* line 279, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.center {
+  display: block;
+  margin: 0 auto;
+}
+
+/* line 281, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.square {
+  -o-border-radius: 0;
+  border-radius: 0;
+}
+
+/* line 282, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.round {
+  -o-border-radius: 9999em;
+  border-radius: 9999em;
+}
+
+/* line 284, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.rotate-90 {
+  display: inline-block;
+  width: auto;
+  -webkit-transform: rotate(90deg);
+  -ms-transform: rotate(90deg);
+  transform: rotate(90deg);
+}
+
+/* line 285, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.rotate-90-ctr {
+  display: inline-block;
+  width: auto;
+  -webkit-transform: rotate(-90deg);
+  -ms-transform: rotate(-90deg);
+  transform: rotate(-90deg);
+}
+
+/* line 286, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.rotate-180 {
+  display: inline-block;
+  width: auto;
+  -webkit-transform: rotate(180deg);
+  -ms-transform: rotate(180deg);
+  transform: rotate(180deg);
+}
+
+/* line 287, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.rotate-180-ctr {
+  display: inline-block;
+  width: auto;
+  -webkit-transform: rotate(-180deg);
+  -ms-transform: rotate(-180deg);
+  transform: rotate(-180deg);
+}
+
+/* line 288, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.rotate-270 {
+  display: inline-block;
+  width: auto;
+  -webkit-transform: rotate(270deg);
+  -ms-transform: rotate(270deg);
+  transform: rotate(270deg);
+}
+
+/* line 289, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.rotate-270-ctr {
+  display: inline-block;
+  width: auto;
+  -webkit-transform: rotate(-270deg);
+  -ms-transform: rotate(-270deg);
+  transform: rotate(-270deg);
+}
+
+/* line 290, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.rotate-360 {
+  display: inline-block;
+  width: auto;
+  -webkit-transform: rotate(360deg);
+  -ms-transform: rotate(360deg);
+  transform: rotate(360deg);
+}
+
+/* line 291, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.rotate-360-ctr {
+  display: inline-block;
+  width: auto;
+  -webkit-transform: rotate(-360deg);
+  -ms-transform: rotate(-360deg);
+  transform: rotate(-360deg);
+}
+
+/* line 364, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.transition {
+  -webkit-transition: all 1s;
+  transition: all 1s;
+}
+
+/* line 367, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.no-transition {
+  -webkit-transition: none !important;
+          transition: none !important;
+}
+
+/* line 24, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.container {
+  max-width: 1200px;
+  margin: 0 auto;
+}
+
+/* line 33, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.row {
+  clear: both;
+  width: 100%;
+}
+/* line 48, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_helpers.scss */
+.row:after {
+  content: " ";
+  display: block;
+  height: 0;
+  font-size: 0;
+  clear: both;
+  visibility: hidden;
+}
+
+/* line 44, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.column, .whole,
+.wholes, .whole.one,
+.wholes.one, .half,
+.halves, .half.one,
+.halves.one, .half.two,
+.halves.two, .third,
+.thirds, .third.one,
+.thirds.one, .third.two,
+.thirds.two, .third.three,
+.thirds.three, .fourth,
+.fourths, .fourth.one,
+.fourths.one, .fourth.two,
+.fourths.two, .fourth.three,
+.fourths.three, .fourth.four,
+.fourths.four, .fifth,
+.fifths, .fifth.one,
+.fifths.one, .fifth.two,
+.fifths.two, .fifth.three,
+.fifths.three, .fifth.four,
+.fifths.four, .fifth.five,
+.fifths.five, .sixth,
+.sixths, .sixth.one,
+.sixths.one, .sixth.two,
+.sixths.two, .sixth.three,
+.sixths.three, .sixth.four,
+.sixths.four, .sixth.five,
+.sixths.five, .sixth.six,
+.sixths.six, .seventh,
+.sevenths, .seventh.one,
+.sevenths.one, .seventh.two,
+.sevenths.two, .seventh.three,
+.sevenths.three, .seventh.four,
+.sevenths.four, .seventh.five,
+.sevenths.five, .seventh.six,
+.sevenths.six, .seventh.seven,
+.sevenths.seven, .eighth,
+.eighths, .eighth.one,
+.eighths.one, .eighth.two,
+.eighths.two, .eighth.three,
+.eighths.three, .eighth.four,
+.eighths.four, .eighth.five,
+.eighths.five, .eighth.six,
+.eighths.six, .eighth.seven,
+.eighths.seven, .eighth.eight,
+.eighths.eight, .ninth,
+.ninths, .ninth.one,
+.ninths.one, .ninth.two,
+.ninths.two, .ninth.three,
+.ninths.three, .ninth.four,
+.ninths.four, .ninth.five,
+.ninths.five, .ninth.six,
+.ninths.six, .ninth.seven,
+.ninths.seven, .ninth.eight,
+.ninths.eight, .ninth.nine,
+.ninths.nine, .tenth,
+.tenths, .tenth.one,
+.tenths.one, .tenth.two,
+.tenths.two, .tenth.three,
+.tenths.three, .tenth.four,
+.tenths.four, .tenth.five,
+.tenths.five, .tenth.six,
+.tenths.six, .tenth.seven,
+.tenths.seven, .tenth.eight,
+.tenths.eight, .tenth.nine,
+.tenths.nine, .tenth.ten,
+.tenths.ten, .eleventh,
+.elevenths, .eleventh.one,
+.elevenths.one, .eleventh.two,
+.elevenths.two, .eleventh.three,
+.elevenths.three, .eleventh.four,
+.elevenths.four, .eleventh.five,
+.elevenths.five, .eleventh.six,
+.elevenths.six, .eleventh.seven,
+.elevenths.seven, .eleventh.eight,
+.elevenths.eight, .eleventh.nine,
+.elevenths.nine, .eleventh.ten,
+.elevenths.ten, .eleventh.eleven,
+.elevenths.eleven, .twelfth,
+.twelfths, .twelfth.one,
+.twelfths.one, .twelfth.two,
+.twelfths.two, .twelfth.three,
+.twelfths.three, .twelfth.four,
+.twelfths.four, .twelfth.five,
+.twelfths.five, .twelfth.six,
+.twelfths.six, .twelfth.seven,
+.twelfths.seven, .twelfth.eight,
+.twelfths.eight, .twelfth.nine,
+.twelfths.nine, .twelfth.ten,
+.twelfths.ten, .twelfth.eleven,
+.twelfths.eleven, .twelfth.twelve,
+.twelfths.twelve {
+  float: left;
+  position: relative;
+  min-height: 1px;
+}
+
+/* line 48, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.centered {
+  float: none !important;
+  margin-left: auto !important;
+  margin-right: auto !important;
+}
+
+/* line 66, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.whole,
+.wholes {
+  width: 100%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.whole.one,
+.wholes.one {
+  width: 100%;
+}
+
+/* line 66, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.half,
+.halves {
+  width: 50%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.half.one,
+.halves.one {
+  width: 50%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.half.two,
+.halves.two {
+  width: 100%;
+}
+/* line 76, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.half.right-one,
+.halves.right-one {
+  left: 50%;
+}
+/* line 79, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.half.left-one,
+.halves.left-one {
+  right: 50%;
+}
+/* line 82, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.half.skip-one,
+.halves.skip-one {
+  margin-left: 50%;
+}
+
+/* line 66, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.third,
+.thirds {
+  width: 33.33333%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.third.one,
+.thirds.one {
+  width: 33.33333%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.third.two,
+.thirds.two {
+  width: 66.66667%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.third.three,
+.thirds.three {
+  width: 100%;
+}
+/* line 76, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.third.right-one,
+.thirds.right-one {
+  left: 33.33333%;
+}
+/* line 79, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.third.left-one,
+.thirds.left-one {
+  right: 33.33333%;
+}
+/* line 82, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.third.skip-one,
+.thirds.skip-one {
+  margin-left: 33.33333%;
+}
+/* line 76, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.third.right-two,
+.thirds.right-two {
+  left: 66.66667%;
+}
+/* line 79, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.third.left-two,
+.thirds.left-two {
+  right: 66.66667%;
+}
+/* line 82, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.third.skip-two,
+.thirds.skip-two {
+  margin-left: 66.66667%;
+}
+
+/* line 66, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.fourth,
+.fourths {
+  width: 25%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.fourth.one,
+.fourths.one {
+  width: 25%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.fourth.two,
+.fourths.two {
+  width: 50%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.fourth.three,
+.fourths.three {
+  width: 75%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.fourth.four,
+.fourths.four {
+  width: 100%;
+}
+/* line 76, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.fourth.right-one,
+.fourths.right-one {
+  left: 25%;
+}
+/* line 79, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.fourth.left-one,
+.fourths.left-one {
+  right: 25%;
+}
+/* line 82, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.fourth.skip-one,
+.fourths.skip-one {
+  margin-left: 25%;
+}
+/* line 76, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.fourth.right-two,
+.fourths.right-two {
+  left: 50%;
+}
+/* line 79, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.fourth.left-two,
+.fourths.left-two {
+  right: 50%;
+}
+/* line 82, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.fourth.skip-two,
+.fourths.skip-two {
+  margin-left: 50%;
+}
+/* line 76, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.fourth.right-three,
+.fourths.right-three {
+  left: 75%;
+}
+/* line 79, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.fourth.left-three,
+.fourths.left-three {
+  right: 75%;
+}
+/* line 82, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.fourth.skip-three,
+.fourths.skip-three {
+  margin-left: 75%;
+}
+
+/* line 66, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.fifth,
+.fifths {
+  width: 20%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.fifth.one,
+.fifths.one {
+  width: 20%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.fifth.two,
+.fifths.two {
+  width: 40%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.fifth.three,
+.fifths.three {
+  width: 60%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.fifth.four,
+.fifths.four {
+  width: 80%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.fifth.five,
+.fifths.five {
+  width: 100%;
+}
+/* line 76, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.fifth.right-one,
+.fifths.right-one {
+  left: 20%;
+}
+/* line 79, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.fifth.left-one,
+.fifths.left-one {
+  right: 20%;
+}
+/* line 82, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.fifth.skip-one,
+.fifths.skip-one {
+  margin-left: 20%;
+}
+/* line 76, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.fifth.right-two,
+.fifths.right-two {
+  left: 40%;
+}
+/* line 79, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.fifth.left-two,
+.fifths.left-two {
+  right: 40%;
+}
+/* line 82, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.fifth.skip-two,
+.fifths.skip-two {
+  margin-left: 40%;
+}
+/* line 76, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.fifth.right-three,
+.fifths.right-three {
+  left: 60%;
+}
+/* line 79, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.fifth.left-three,
+.fifths.left-three {
+  right: 60%;
+}
+/* line 82, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.fifth.skip-three,
+.fifths.skip-three {
+  margin-left: 60%;
+}
+/* line 76, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.fifth.right-four,
+.fifths.right-four {
+  left: 80%;
+}
+/* line 79, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.fifth.left-four,
+.fifths.left-four {
+  right: 80%;
+}
+/* line 82, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.fifth.skip-four,
+.fifths.skip-four {
+  margin-left: 80%;
+}
+
+/* line 66, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.sixth,
+.sixths {
+  width: 16.66667%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.sixth.one,
+.sixths.one {
+  width: 16.66667%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.sixth.two,
+.sixths.two {
+  width: 33.33333%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.sixth.three,
+.sixths.three {
+  width: 50%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.sixth.four,
+.sixths.four {
+  width: 66.66667%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.sixth.five,
+.sixths.five {
+  width: 83.33333%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.sixth.six,
+.sixths.six {
+  width: 100%;
+}
+/* line 76, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.sixth.right-one,
+.sixths.right-one {
+  left: 16.66667%;
+}
+/* line 79, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.sixth.left-one,
+.sixths.left-one {
+  right: 16.66667%;
+}
+/* line 82, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.sixth.skip-one,
+.sixths.skip-one {
+  margin-left: 16.66667%;
+}
+/* line 76, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.sixth.right-two,
+.sixths.right-two {
+  left: 33.33333%;
+}
+/* line 79, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.sixth.left-two,
+.sixths.left-two {
+  right: 33.33333%;
+}
+/* line 82, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.sixth.skip-two,
+.sixths.skip-two {
+  margin-left: 33.33333%;
+}
+/* line 76, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.sixth.right-three,
+.sixths.right-three {
+  left: 50%;
+}
+/* line 79, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.sixth.left-three,
+.sixths.left-three {
+  right: 50%;
+}
+/* line 82, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.sixth.skip-three,
+.sixths.skip-three {
+  margin-left: 50%;
+}
+/* line 76, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.sixth.right-four,
+.sixths.right-four {
+  left: 66.66667%;
+}
+/* line 79, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.sixth.left-four,
+.sixths.left-four {
+  right: 66.66667%;
+}
+/* line 82, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.sixth.skip-four,
+.sixths.skip-four {
+  margin-left: 66.66667%;
+}
+/* line 76, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.sixth.right-five,
+.sixths.right-five {
+  left: 83.33333%;
+}
+/* line 79, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.sixth.left-five,
+.sixths.left-five {
+  right: 83.33333%;
+}
+/* line 82, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.sixth.skip-five,
+.sixths.skip-five {
+  margin-left: 83.33333%;
+}
+
+/* line 66, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.seventh,
+.sevenths {
+  width: 14.28571%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.seventh.one,
+.sevenths.one {
+  width: 14.28571%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.seventh.two,
+.sevenths.two {
+  width: 28.57143%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.seventh.three,
+.sevenths.three {
+  width: 42.85714%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.seventh.four,
+.sevenths.four {
+  width: 57.14286%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.seventh.five,
+.sevenths.five {
+  width: 71.42857%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.seventh.six,
+.sevenths.six {
+  width: 85.71429%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.seventh.seven,
+.sevenths.seven {
+  width: 100%;
+}
+/* line 76, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.seventh.right-one,
+.sevenths.right-one {
+  left: 14.28571%;
+}
+/* line 79, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.seventh.left-one,
+.sevenths.left-one {
+  right: 14.28571%;
+}
+/* line 82, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.seventh.skip-one,
+.sevenths.skip-one {
+  margin-left: 14.28571%;
+}
+/* line 76, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.seventh.right-two,
+.sevenths.right-two {
+  left: 28.57143%;
+}
+/* line 79, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.seventh.left-two,
+.sevenths.left-two {
+  right: 28.57143%;
+}
+/* line 82, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.seventh.skip-two,
+.sevenths.skip-two {
+  margin-left: 28.57143%;
+}
+/* line 76, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.seventh.right-three,
+.sevenths.right-three {
+  left: 42.85714%;
+}
+/* line 79, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.seventh.left-three,
+.sevenths.left-three {
+  right: 42.85714%;
+}
+/* line 82, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.seventh.skip-three,
+.sevenths.skip-three {
+  margin-left: 42.85714%;
+}
+/* line 76, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.seventh.right-four,
+.sevenths.right-four {
+  left: 57.14286%;
+}
+/* line 79, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.seventh.left-four,
+.sevenths.left-four {
+  right: 57.14286%;
+}
+/* line 82, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.seventh.skip-four,
+.sevenths.skip-four {
+  margin-left: 57.14286%;
+}
+/* line 76, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.seventh.right-five,
+.sevenths.right-five {
+  left: 71.42857%;
+}
+/* line 79, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.seventh.left-five,
+.sevenths.left-five {
+  right: 71.42857%;
+}
+/* line 82, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.seventh.skip-five,
+.sevenths.skip-five {
+  margin-left: 71.42857%;
+}
+/* line 76, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.seventh.right-six,
+.sevenths.right-six {
+  left: 85.71429%;
+}
+/* line 79, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.seventh.left-six,
+.sevenths.left-six {
+  right: 85.71429%;
+}
+/* line 82, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.seventh.skip-six,
+.sevenths.skip-six {
+  margin-left: 85.71429%;
+}
+
+/* line 66, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.eighth,
+.eighths {
+  width: 12.5%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.eighth.one,
+.eighths.one {
+  width: 12.5%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.eighth.two,
+.eighths.two {
+  width: 25%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.eighth.three,
+.eighths.three {
+  width: 37.5%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.eighth.four,
+.eighths.four {
+  width: 50%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.eighth.five,
+.eighths.five {
+  width: 62.5%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.eighth.six,
+.eighths.six {
+  width: 75%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.eighth.seven,
+.eighths.seven {
+  width: 87.5%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.eighth.eight,
+.eighths.eight {
+  width: 100%;
+}
+/* line 76, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.eighth.right-one,
+.eighths.right-one {
+  left: 12.5%;
+}
+/* line 79, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.eighth.left-one,
+.eighths.left-one {
+  right: 12.5%;
+}
+/* line 82, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.eighth.skip-one,
+.eighths.skip-one {
+  margin-left: 12.5%;
+}
+/* line 76, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.eighth.right-two,
+.eighths.right-two {
+  left: 25%;
+}
+/* line 79, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.eighth.left-two,
+.eighths.left-two {
+  right: 25%;
+}
+/* line 82, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.eighth.skip-two,
+.eighths.skip-two {
+  margin-left: 25%;
+}
+/* line 76, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.eighth.right-three,
+.eighths.right-three {
+  left: 37.5%;
+}
+/* line 79, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.eighth.left-three,
+.eighths.left-three {
+  right: 37.5%;
+}
+/* line 82, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.eighth.skip-three,
+.eighths.skip-three {
+  margin-left: 37.5%;
+}
+/* line 76, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.eighth.right-four,
+.eighths.right-four {
+  left: 50%;
+}
+/* line 79, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.eighth.left-four,
+.eighths.left-four {
+  right: 50%;
+}
+/* line 82, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.eighth.skip-four,
+.eighths.skip-four {
+  margin-left: 50%;
+}
+/* line 76, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.eighth.right-five,
+.eighths.right-five {
+  left: 62.5%;
+}
+/* line 79, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.eighth.left-five,
+.eighths.left-five {
+  right: 62.5%;
+}
+/* line 82, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.eighth.skip-five,
+.eighths.skip-five {
+  margin-left: 62.5%;
+}
+/* line 76, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.eighth.right-six,
+.eighths.right-six {
+  left: 75%;
+}
+/* line 79, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.eighth.left-six,
+.eighths.left-six {
+  right: 75%;
+}
+/* line 82, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.eighth.skip-six,
+.eighths.skip-six {
+  margin-left: 75%;
+}
+/* line 76, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.eighth.right-seven,
+.eighths.right-seven {
+  left: 87.5%;
+}
+/* line 79, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.eighth.left-seven,
+.eighths.left-seven {
+  right: 87.5%;
+}
+/* line 82, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.eighth.skip-seven,
+.eighths.skip-seven {
+  margin-left: 87.5%;
+}
+
+/* line 66, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.ninth,
+.ninths {
+  width: 11.11111%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.ninth.one,
+.ninths.one {
+  width: 11.11111%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.ninth.two,
+.ninths.two {
+  width: 22.22222%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.ninth.three,
+.ninths.three {
+  width: 33.33333%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.ninth.four,
+.ninths.four {
+  width: 44.44444%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.ninth.five,
+.ninths.five {
+  width: 55.55556%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.ninth.six,
+.ninths.six {
+  width: 66.66667%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.ninth.seven,
+.ninths.seven {
+  width: 77.77778%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.ninth.eight,
+.ninths.eight {
+  width: 88.88889%;
+}
+/* line 70, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.ninth.nine,
+.ninths.nine {
+  width: 100%;
+}
+/* line 76, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.ninth.right-one,
+.ninths.right-one {
+  left: 11.11111%;
+}
+/* line 79, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.ninth.left-one,
+.ninths.left-one {
+  right: 11.11111%;
+}
+/* line 82, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.ninth.skip-one,
+.ninths.skip-one {
+  margin-left: 11.11111%;
+}
+/* line 76, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.ninth.right-two,
+.ninths.right-two {
+  left: 22.22222%;
+}
+/* line 79, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.ninth.left-two,
+.ninths.left-two {
+  right: 22.22222%;
+}
+/* line 82, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.ninth.skip-two,
+.ninths.skip-two {
+  margin-left: 22.22222%;
+}
+/* line 76, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.ninth.right-three,
+.ninths.right-three {
+  left: 33.33333%;
+}
+/* line 79, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.ninth.left-three,
+.ninths.left-three {
+  right: 33.33333%;
+}
+/* line 82, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.ninth.skip-three,
+.ninths.skip-three {
+  margin-left: 33.33333%;
+}
+/* line 76, /Users/suzuki/Workspace/mensagg/vendor/bundle/ruby/2.0.0/gems/groundworkcss-2.3.5/app/assets/stylesheets/groundworkcss/base/_grid.scss */
+.ninth.right-four,
+.ninths.right-four {
+  left: 44.44444%;
+}
+/* line 79,…
79a6fc3

szepeviktor referenced this pull request in jquery-validation/jquery-validation Nov 13, 2014

Closed

AMD needs returning a value #1181

@Swingline0 Swingline0 referenced this pull request in jl455/woocommerce-cardconnect Apr 6, 2015

@Swingline0 Swingline0 First Commit!
Basic scaffold, includes basic frontend JS for CC tokenization and backend UI

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..93f1361
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+node_modules
+npm-debug.log
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..f620d0c
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,339 @@
+   GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/cardconnect-payment-gateway.php b/cardconnect-payment-gateway.php
new file mode 100644
index 0000000..380eacd
--- /dev/null
+++ b/cardconnect-payment-gateway.php
@@ -0,0 +1,302 @@
+<?php
+/*
+Plugin Name: CardConnect Payment Gateway
+Plugin URI: http://sofcorp.com/
+Description: Accept credit card payments in your WooCommerce store!
+Version: 0.0.0 Alpha
+Author: SOF Inc <eran@sofcorp.com>
+Author URI: http://sofcorp.com
+
+	Copyright: © 2015 SOF Inc <eran@sofcorp.com>.
+	License: GNU General Public License v2
+	License URI: http://www.gnu.org/licenses/gpl-2.0.html
+*/
+
+if(!defined('ABSPATH')){
+	exit; // Exit if accessed directly
+}
+
+add_action('plugins_loaded', 'CardConnectPaymentGateway_init', 0);
+function CardConnectPaymentGateway_init(){
+
+	if(class_exists('CardConnectPaymentGateway') || !class_exists('WC_Payment_Gateway')){
+		return;
+	}
+
+	/**
+	 * Gateway class
+	 */
+	class CardConnectPaymentGateway extends WC_Payment_Gateway {
+
+		const CC_TEST_URL = 'fts.cardconnect.com:6443';
+		const CC_LIVE_URL = '???';
+
+		/**
+		 * Constructor for the gateway.
+		 */
+		public function __construct(){
+			$this->id = 'card_connect';
+			$this->icon = apply_filters('woocommerce_CardConnectPaymentGateway_icon', '');
+			$this->has_fields = true;
+			$this->method_title = __('CardConnect Payment Gateway', 'cardconnect-payment-gateway');
+			$this->method_description = __('Payment gateway for CardConnect Payment Processing', 'cardconnect-payment-gateway');
+			$this->supports = array(
+				'default_credit_card_form',
+				'refunds',
+				'products',
+				// 'subscriptions',
+				// 'subscription_cancellation',
+				// 'subscription_reactivation',
+				// 'subscription_suspension',
+				// 'subscription_amount_changes',
+				// 'subscription_payment_method_change',
+				// 'subscription_date_changes'
+			);
+			$this->view_transaction_url = '#';
+
+			// Load the form fields
+			$this->init_form_fields();
+
+			// Load the settings.
+			$this->init_settings();
+
+			// Load user options
+			$this->load_options();
+
+			// Instantiate SDK for CardConnect
+			$this->init_cc_sdk();
+
+			// Actions
+			add_action('wp_enqueue_scripts', array( $this, 'register_scripts'));
+			add_action('woocommerce_update_options_payment_gateways_' . $this->id, array($this, 'process_admin_options'));
+			add_action('woocommerce_thankyou_CardConnectPaymentGateway', array($this, 'thankyou_page'));
+		}
+
+		/**
+		 * Load SDK for communicating with CardConnect servers
+		 *
+		 * @return void
+		 */
+		protected function init_cc_sdk(){
+
+			// @TODO: Load CC SDK stuff here
+
+		}
+
+		/**
+		 * Load user options into class
+		 *
+		 * @return void
+		 */
+		protected function load_options(){
+
+			$this->enabled = $this->get_option('enabled');
+
+			$this->title = $this->get_option('title');
+			$this->description = $this->get_option('description');
+			$this->mode = $this->get_option('mode', 'capture');
+
+			$this->sandbox = $this->get_option('sandbox');
+
+			$env_key = $this->sandbox == 'no' ? 'production' : 'sandbox';
+			$this->api_credentials = array(
+				'mid' => $this->get_option("{$env_key}_mid"),
+				'user' => $this->get_option("{$env_key}_user"),
+				'pass' => $this->get_option("{$env_key}_mid"),
+			);
+
+		}
+
+		/**
+		 * Create form fields for the payment gateway
+		 *
+		 * @return void
+		 */
+		public function init_form_fields(){
+			$this->form_fields = array(
+				'enabled' => array(
+					'title' => __('Enable/Disable', 'woocommerce'),
+					'label' => __('Enable CardConnect Payments', 'woocommerce'),
+					'type' => 'checkbox',
+					'description' => '',
+					'default' => 'no'
+				),
+				'title' => array(
+					'title' => __('Title', 'woocommerce'),
+					'type' => 'text',
+					'description' => __('This controls the title which the user sees during checkout.', 'woocommerce'),
+					'default' => __('Credit card', 'woocommerce'),
+					'desc_tip' => true
+				),
+				'description' => array(
+					'title' => __('Description', 'woocommerce'),
+					'type' => 'text',
+					'description' => __('This controls the description which the user sees during checkout.', 'woocommerce'),
+					'default' => 'Payment secured by CardConnect.',
+					'desc_tip' => true
+				),
+				'mode' => array(
+					'title' => __('Payment Mode', 'woocommerce'),
+					'label' => __('Capture payment or only authorize it.', 'woocommerce'),
+					'type' => 'select',
+					'description' => __('Select <strong>Authorize Only</strong> if you prefer to manually approve each transaction in the CardConnect dashboard.', 'woocommerce'),
+					'default' => 'capture',
+					'options' => array(
+						'capture' => __('Capture Payment', 'woocommerce'),
+						'auth_only' => __('Authorize Only', 'woocommerce')
+					)
+				),
+				'sandbox' => array(
+					'title' => __('Sandbox', 'woocommerce'),
+					'label' => __('Enable Sandbox Mode', 'woocommerce'),
+					'type' => 'checkbox',
+					'description' => __('Place the payment gateway in sandbox mode using the sandbox authentication fields below (real payments will not be taken).', 'woocommerce'),
+					'default' => 'yes',
+					'desc_tip' => true
+				),
+				'sandbox_mid' => array(
+					'title' => __('Sandbox Merchant ID (MID)', 'woocommerce'),
+					'type' => 'text',
+					'description' => __('Platform identifier required to be included in API calls from your ERP application to the CardConnect demo system.  Once your interface is live, you will be assigned a unique id from the processor.  During development and testing, you can use this test merchant id.', 'woocommerce'),
+					'default' => '496160873888',
+					'desc_tip' => true
+				),
+				'sandbox_user' => array(
+					'title' => __('Sandbox Username', 'woocommerce'),
+					'type' => 'text',
+					'description' => __('This is the default information, you may use this or an alternative if provided by CardConnect', 'woocommerce'),
+					'default' => 'testing',
+					'desc_tip' => true
+				),
+				'sandbox_password' => array(
+					'title' => __('Sandbox Password', 'woocommerce'),
+					'type' => 'text',
+					'description' => __('This is the default information, you may use this or an alternative if provided by CardConnect', 'woocommerce'),
+					'default' => 'testing123',
+					'desc_tip' => true
+				),
+				'production_mid' => array(
+					'title' => __('Merchant ID (MID)', 'woocommerce'),
+					'type' => 'text',
+					'description' => __('Your unique MID from CardConnect.', 'woocommerce'),
+					'default' => '',
+					'desc_tip' => true
+				),
+				'production_user' => array(
+					'title' => __('Username', 'woocommerce'),
+					'type' => 'text',
+					'description' => __('Enter the credentials obtained from CardConnect', 'woocommerce'),
+					'default' => '',
+					'desc_tip' => true
+				),
+				'production_password' => array(
+					'title' => __('Password', 'woocommerce'),
+					'type' => 'text',
+					'description' => __('Enter the credentials obtained from CardConnect', 'woocommerce'),
+					'default' => '',
+					'desc_tip' => true
+				),
+			);
+		}
+
+		/**
+		 * Process the order payment status
+		 *
+		 * @param int $order_id
+		 *
+		 * @return array
+		 */
+		public function process_payment($order_id){
+			global $woocommerce;
+			$order = new WC_Order($order_id);
+
+			$token = isset( $_POST['card_connect_token'] ) ? wc_clean( $_POST['card_connect_token'] ) : false;
+
+			if(!$token){
+				wc_add_notice(__('Payment error:', 'woothemes') . 'Please make sure your card details have been entered correctly and that your browser supports JavaScript.', 'error');
+				return;
+			}
+
+			 // Payment Failed!
+			 $order->update_status('failed', __('Payment Failed', 'cardconnect-payment-gateway'));
+			 wc_add_notice( __('Payment error:', 'woothemes') . 'Card Error', 'error' );
+			 return;
+
+			$order->payment_complete();
+
+			// Reduce stock levels
+			$order->reduce_order_stock();
+
+			// Remove cart
+			$woocommerce->cart->empty_cart();
+
+			// Return thankyou redirect
+			return array(
+				'result' => 'success',
+				'redirect' => $this->get_return_url($order)
+			);
+		}
+
+		/**
+		 * Output for the order received page.
+		 *
+		 * @return void
+		 */
+		public function thankyou(){
+			if($description = $this->get_description()){
+				echo wpautop(wptexturize(wp_kses_post($description)));
+			}
+
+			echo '<h2>' . __('Our Details', 'cardconnect-payment-gateway') . '</h2>';
+
+			echo '<ul class="order_details CardConnectPaymentGateway_details">';
+
+			$fields = apply_filters('woocommerce_CardConnectPaymentGateway_fields', array(
+				'example_field' => __('Example field', 'cardconnect-payment-gateway')
+			));
+
+			foreach($fields as $key => $value){
+				if(!empty($this->$key)){
+					echo '<li class="' . esc_attr($key) . '">' . esc_attr($value) . ': <strong>' . wptexturize($this->$key) . '</strong></li>';
+				}
+			}
+
+			echo '</ul>';
+		}
+
+		/**
+		 * Output for the order received page.
+		 *
+		 * @return void
+		 */
+		public function payment_fields(){
+			wp_enqueue_script('woocommerce-cardconnect');
+			$this->credit_card_form(array(
+				'fields_have_names' => false
+			));
+		}
+
+		/**
+		 * Register Frontend Assets
+		 **/
+		public function register_scripts(){
+			wp_register_script(
+				'woocommerce-cardconnect',
+				plugins_url('javascript/dist/woocommerce-cc-gateway.js', __FILE__),
+				array('jquery'), '1.0', true
+			);
+		}
+
+	}
+
+	/**
+	 * Add the Gateway to WooCommerce
+	 **/
+	add_filter('woocommerce_payment_gateways', 'woocommerce_add_gateway_CardConnectPaymentGateway');
+	function woocommerce_add_gateway_CardConnectPaymentGateway($methods){
+		$methods[] = 'CardConnectPaymentGateway';
+
+		return $methods;
+	}
+
+}
diff --git a/gulpfile.js b/gulpfile.js
new file mode 100644
index 0000000..58348aa
--- /dev/null
+++ b/gulpfile.js
@@ -0,0 +1,54 @@
+var gulp = require('gulp');
+var browserify = require('browserify');
+var source = require('vinyl-source-stream');
+var watchify = require('watchify');
+
+gulp.task('browserify', function(){
+  browserifyShare();
+});
+
+gulp.task('browserifyTests', browserifyTests);
+
+function browserifyShare(){
+  // you need to pass these three config option to browserify
+  var b = browserify({
+    cache: {},
+    packageCache: {},
+    fullPaths: true
+  });
+  b = watchify(b);
+  b.on('update', function(){
+    bundleShare(b);
+  });
+
+  b.add('./javascript/src/woocommerce-cc-gateway.js');
+  bundleShare(b);
+}
+
+function bundleShare(b){
+  b.bundle()
+    .pipe(source('woocommerce-cc-gateway.js'))
+    .pipe(gulp.dest('./javascript/dist'));
+}
+
+function browserifyTests(){
+  // you need to pass these three config option to browserify
+  var b = browserify({
+    cache: {},
+    packageCache: {},
+    fullPaths: true
+  });
+  b = watchify(b);
+  b.on('update', function(){
+    bundleTests(b);
+  });
+
+  b.add('./javascript/spec/woocommerce-card-connect.spec.js');
+  bundleTests(b);
+}
+
+function bundleTests(b){
+  b.bundle()
+    .pipe(source('woocommerce-card-connect.spec.js'))
+    .pipe(gulp.dest('./javascript/spec/bundle'));
+}
diff --git a/index.php b/index.php
new file mode 100644
index 0000000..24dc103
--- /dev/null
+++ b/index.php
@@ -0,0 +1 @@
+<?php //Silence is golden
diff --git a/javascript/dist/woocommerce-cc-gateway.js b/javascript/dist/woocommerce-cc-gateway.js
new file mode 100644
index 0000000..a15e11c
--- /dev/null
+++ b/javascript/dist/woocommerce-cc-gateway.js
@@ -0,0 +1,72 @@
+(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({"./javascript/src/woocommerce-cc-gateway.js":[function(require,module,exports){
+var woocommerce_card_connect_1 = require("./woocommerce-card-connect");
+jQuery(function ($) {
+    var cc = new woocommerce_card_connect_1.default($);
+    var $form = $('form.checkout');
+    function formSubmit(ev) {
+        ev.preventDefault();
+        ev.stopPropagation();
+        if (0 === $('input.card-connect-token').size()) {
+            var creditCard = $form.find('.wc-credit-card-form-card-number').val();
+            if (!creditCard) {
+                alert('Please enter a credit card number');
+                return false;
+            }
+            cc.getToken(creditCard, function (token, error) {
+                if (error)
+                    alert(error);
+                $('<input />')
+                    .attr('name', 'card_connect_token')
+                    .attr('type', 'hidden')
+                    .addClass('card-connect-token')
+                    .val(token)
+                    .appendTo($form);
+                $form.submit();
+            });
+            return false;
+        }
+        return true;
+    }
+    $form.on('checkout_place_order_card_connect', formSubmit);
+    $('body').on('checkout_error', function () { return $('.card-connect-token').remove(); });
+    $('form.checkout').on('change', '.wc-credit-card-form-card-number', function () {
+        $('.card-connect-token').remove();
+    });
+});
+
+},{"./woocommerce-card-connect":"/Users/eran/Repositories/VVV/www/cardconnect/htdocs/wp-content/plugins/cardconnect-payment-gateway/javascript/src/woocommerce-card-connect.js"}],"/Users/eran/Repositories/VVV/www/cardconnect/htdocs/wp-content/plugins/cardconnect-payment-gateway/javascript/src/woocommerce-card-connect.js":[function(require,module,exports){
+var WoocommereCardConnect = (function () {
+    function WoocommereCardConnect(jQuery) {
+        var _this = this;
+        this.baseUrl = 'https://fts.prinpay.com/cardsecure/cs?action=CE&type=json';
+        this.getToken = function (number, callback) {
+            if (!_this.validateCard(number))
+                return callback(null, 'Invalid Credit Card Number');
+            _this.$.get(_this.baseUrl + "&data=" + _this.cardNumber)
+                .done(function (data) { return _this.processRequest(data, callback); })
+                .fail(function (data) { return _this.failedRequest(data, callback); });
+        };
+        this.validateCard = function (number) {
+            _this.cardNumber = number;
+            return _this.cardNumber.length > 0;
+        };
+        this.processRequest = function (data, callback) {
+            var processToken = function (response) {
+                var action = response.action, data = response.data;
+                if (action === 'CE')
+                    callback(data, null);
+                else
+                    callback(null, data);
+            };
+            eval(data);
+        };
+        this.failedRequest = function (data, callback) {
+            return callback(null, 'Failed to connect to server');
+        };
+        this.$ = jQuery;
+    }
+    return WoocommereCardConnect;
+})();
+exports.default = WoocommereCardConnect;
+
+},{}]},{},["./javascript/src/woocommerce-cc-gateway.js"]);
diff --git a/javascript/spec/bundle/woocommerce-card-connect.spec.js b/javascript/spec/bundle/woocommerce-card-connect.spec.js
new file mode 100644
index 0000000..474089c
--- /dev/null
+++ b/javascript/spec/bundle/woocommerce-card-connect.spec.js
@@ -0,0 +1,16036 @@
+(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({"./javascript/spec/woocommerce-card-connect.spec.js":[function(require,module,exports){
+var woocommerce_card_connect_1 = require("../src/woocommerce-card-connect");
+var chai = require("chai");
+var expect = chai.expect;
+var $ = require('jquery');
+var cc = new woocommerce_card_connect_1.default($);
+describe('CardConnect Token Generator', function () {
+    it("should generate token with valid credit card number", function (done) {
+        cc.getToken('4242424242424242', function (token, error) {
+            expect(error).to.be.null;
+            expect(token).to.be.a('string');
+            expect(token).to.equal('9428873934894242');
+            done();
+        });
+    });
+    it("should generate error with non-numerical entry", function (done) {
+        cc.getToken('frisbee', function (token, error) {
+            expect(token).to.be.null;
+            expect(error).to.equal('0008::Data not decimal digits');
+            done();
+        });
+    });
+    it("should generate error with oversized entry", function (done) {
+        cc.getToken('42424242424242424242424242424242', function (token, error) {
+            expect(token).to.be.null;
+            expect(error).to.equal('0013::Data too long');
+            done();
+        });
+    });
+    it("should generate error when no entry made", function (done) {
+        cc.getToken('', function (token, error) {
+            expect(token).to.be.null;
+            expect(error).to.equal('Invalid Credit Card Number');
+            done();
+        });
+    });
+});
+
+},{"../src/woocommerce-card-connect":"/Users/eran/Repositories/VVV/www/cardconnect/htdocs/wp-content/plugins/cardconnect-payment-gateway/javascript/src/woocommerce-card-connect.js","chai":"/Users/eran/Repositories/VVV/www/cardconnect/htdocs/wp-content/plugins/cardconnect-payment-gateway/node_modules/chai/index.js","jquery":"/Users/eran/Repositories/VVV/www/cardconnect/htdocs/wp-content/plugins/cardconnect-payment-gateway/node_modules/jquery/dist/jquery.js"}],"/Users/eran/Repositories/VVV/www/cardconnect/htdocs/wp-content/plugins/cardconnect-payment-gateway/javascript/src/woocommerce-card-connect.js":[function(require,module,exports){
+var WoocommereCardConnect = (function () {
+    function WoocommereCardConnect(jQuery) {
+        var _this = this;
+        this.baseUrl = 'https://fts.prinpay.com/cardsecure/cs?action=CE&type=json';
+        this.getToken = function (number, callback) {
+            if (!_this.validateCard(number))
+                return callback(null, 'Invalid Credit Card Number');
+            _this.$.get(_this.baseUrl + "&data=" + _this.cardNumber)
+                .done(function (data) { return _this.processRequest(data, callback); })
+                .fail(function (data) { return _this.failedRequest(data, callback); });
+        };
+        this.validateCard = function (number) {
+            _this.cardNumber = number;
+            return _this.cardNumber.length > 0;
+        };
+        this.processRequest = function (data, callback) {
+            var processToken = function (response) {
+                var action = response.action, data = response.data;
+                if (action === 'CE')
+                    callback(data, null);
+                else
+                    callback(null, data);
+            };
+            eval(data);
+        };
+        this.failedRequest = function (data, callback) {
+            return callback(null, 'Failed to connect to server');
+        };
+        this.$ = jQuery;
+    }
+    return WoocommereCardConnect;
+})();
+exports.default = WoocommereCardConnect;
+
+},{}],"/Users/eran/Repositories/VVV/www/cardconnect/htdocs/wp-content/plugins/cardconnect-payment-gateway/node_modules/browserify/node_modules/buffer/index.js":[function(require,module,exports){
+/*!
+ * The buffer module from node.js, for the browser.
+ *
+ * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
+ * @license  MIT
+ */
+
+var base64 = require('base64-js')
+var ieee754 = require('ieee754')
+var isArray = require('is-array')
+
+exports.Buffer = Buffer
+exports.SlowBuffer = SlowBuffer
+exports.INSPECT_MAX_BYTES = 50
+Buffer.poolSize = 8192 // not used by this implementation
+
+var kMaxLength = 0x3fffffff
+var rootParent = {}
+
+/**
+ * If `Buffer.TYPED_ARRAY_SUPPORT`:
+ *   === true    Use Uint8Array implementation (fastest)
+ *   === false   Use Object implementation (most compatible, even IE6)
+ *
+ * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
+ * Opera 11.6+, iOS 4.2+.
+ *
+ * Note:
+ *
+ * - Implementation must support adding new properties to `Uint8Array` instances.
+ *   Firefox 4-29 lacked support, fixed in Firefox 30+.
+ *   See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.
+ *
+ *  - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.
+ *
+ *  - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of
+ *    incorrect length in some situations.
+ *
+ * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they will
+ * get the Object implementation, which is slower but will work correctly.
+ */
+Buffer.TYPED_ARRAY_SUPPORT = (function () {
+  try {
+    var buf = new ArrayBuffer(0)
+    var arr = new Uint8Array(buf)
+    arr.foo = function () { return 42 }
+    return arr.foo() === 42 && // typed array instances can be augmented
+        typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`
+        new Uint8Array(1).subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`
+  } catch (e) {
+    return false
+  }
+})()
+
+/**
+ * Class: Buffer
+ * =============
+ *
+ * The Buffer constructor returns instances of `Uint8Array` that are augmented
+ * with function properties for all the node `Buffer` API functions. We use
+ * `Uint8Array` so that square bracket notation works as expected -- it returns
+ * a single octet.
+ *
+ * By augmenting the instances, we can avoid modifying the `Uint8Array`
+ * prototype.
+ */
+function Buffer (subject, encoding) {
+  var self = this
+  if (!(self instanceof Buffer)) return new Buffer(subject, encoding)
+
+  var type = typeof subject
+  var length
+
+  if (type === 'number') {
+    length = +subject
+  } else if (type === 'string') {
+    length = Buffer.byteLength(subject, encoding)
+  } else if (type === 'object' && subject !== null) {
+    // assume object is array-like
+    if (subject.type === 'Buffer' && isArray(subject.data)) subject = subject.data
+    length = +subject.length
+  } else {
+    throw new TypeError('must start with number, buffer, array or string')
+  }
+
+  if (length > kMaxLength) {
+    throw new RangeError('Attempt to allocate Buffer larger than maximum size: 0x' +
+      kMaxLength.toString(16) + ' bytes')
+  }
+
+  if (length < 0) length = 0
+  else length >>>= 0 // coerce to uint32
+
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    // Preferred: Return an augmented `Uint8Array` instance for best performance
+    self = Buffer._augment(new Uint8Array(length)) // eslint-disable-line consistent-this
+  } else {
+    // Fallback: Return THIS instance of Buffer (created by `new`)
+    self.length = length
+    self._isBuffer = true
+  }
+
+  var i
+  if (Buffer.TYPED_ARRAY_SUPPORT && typeof subject.byteLength === 'number') {
+    // Speed optimization -- use set if we're copying from a typed array
+    self._set(subject)
+  } else if (isArrayish(subject)) {
+    // Treat array-ish objects as a byte array
+    if (Buffer.isBuffer(subject)) {
+      for (i = 0; i < length; i++) {
+        self[i] = subject.readUInt8(i)
+      }
+    } else {
+      for (i = 0; i < length; i++) {
+        self[i] = ((subject[i] % 256) + 256) % 256
+      }
+    }
+  } else if (type === 'string') {
+    self.write(subject, 0, encoding)
+  } else if (type === 'number' && !Buffer.TYPED_ARRAY_SUPPORT) {
+    for (i = 0; i < length; i++) {
+      self[i] = 0
+    }
+  }
+
+  if (length > 0 && length <= Buffer.poolSize) self.parent = rootParent
+
+  return self
+}
+
+function SlowBuffer (subject, encoding) {
+  if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding)
+
+  var buf = new Buffer(subject, encoding)
+  delete buf.parent
+  return buf
+}
+
+Buffer.isBuffer = function isBuffer (b) {
+  return !!(b != null && b._isBuffer)
+}
+
+Buffer.compare = function compare (a, b) {
+  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
+    throw new TypeError('Arguments must be Buffers')
+  }
+
+  if (a === b) return 0
+
+  var x = a.length
+  var y = b.length
+  for (var i = 0, len = Math.min(x, y); i < len && a[i] === b[i]; i++) {}
+  if (i !== len) {
+    x = a[i]
+    y = b[i]
+  }
+  if (x < y) return -1
+  if (y < x) return 1
+  return 0
+}
+
+Buffer.isEncoding = function isEncoding (encoding) {
+  switch (String(encoding).toLowerCase()) {
+    case 'hex':
+    case 'utf8':
+    case 'utf-8':
+    case 'ascii':
+    case 'binary':
+    case 'base64':
+    case 'raw':
+    case 'ucs2':
+    case 'ucs-2':
+    case 'utf16le':
+    case 'utf-16le':
+      return true
+    default:
+      return false
+  }
+}
+
+Buffer.concat = function concat (list, totalLength) {
+  if (!isArray(list)) throw new TypeError('list argument must be an Array of Buffers.')
+
+  if (list.length === 0) {
+    return new Buffer(0)
+  } else if (list.length === 1) {
+    return list[0]
+  }
+
+  var i
+  if (totalLength === undefined) {
+    totalLength = 0
+    for (i = 0; i < list.length; i++) {
+      totalLength += list[i].length
+    }
+  }
+
+  var buf = new Buffer(totalLength)
+  var pos = 0
+  for (i = 0; i < list.length; i++) {
+    var item = list[i]
+    item.copy(buf, pos)
+    pos += item.length
+  }
+  return buf
+}
+
+Buffer.byteLength = function byteLength (str, encoding) {
+  var ret
+  str = str + ''
+  switch (encoding || 'utf8') {
+    case 'ascii':
+    case 'binary':
+    case 'raw':
+      ret = str.length
+      break
+    case 'ucs2':
+    case 'ucs-2':
+    case 'utf16le':
+    case 'utf-16le':
+      ret = str.length * 2
+      break
+    case 'hex':
+      ret = str.length >>> 1
+      break
+    case 'utf8':
+    case 'utf-8':
+      ret = utf8ToBytes(str).length
+      break
+    case 'base64':
+      ret = base64ToBytes(str).length
+      break
+    default:
+      ret = str.length
+  }
+  return ret
+}
+
+// pre-set for values that may exist in the future
+Buffer.prototype.length = undefined
+Buffer.prototype.parent = undefined
+
+// toString(encoding, start=0, end=buffer.length)
+Buffer.prototype.toString = function toString (encoding, start, end) {
+  var loweredCase = false
+
+  start = start >>> 0
+  end = end === undefined || end === Infinity ? this.length : end >>> 0
+
+  if (!encoding) encoding = 'utf8'
+  if (start < 0) start = 0
+  if (end > this.length) end = this.length
+  if (end <= start) return ''
+
+  while (true) {
+    switch (encoding) {
+      case 'hex':
+        return hexSlice(this, start, end)
+
+      case 'utf8':
+      case 'utf-8':
+        return utf8Slice(this, start, end)
+
+      case 'ascii':
+        return asciiSlice(this, start, end)
+
+      case 'binary':
+        return binarySlice(this, start, end)
+
+      case 'base64':
+        return base64Slice(this, start, end)
+
+      case 'ucs2':
+      case 'ucs-2':
+      case 'utf16le':
+      case 'utf-16le':
+        return utf16leSlice(this, start, end)
+
+      default:
+        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
+        encoding = (encoding + '').toLowerCase()
+        loweredCase = true
+    }
+  }
+}
+
+Buffer.prototype.equals = function equals (b) {
+  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
+  if (this === b) return true
+  return Buffer.compare(this, b) === 0
+}
+
+Buffer.prototype.inspect = function inspect () {
+  var str = ''
+  var max = exports.INSPECT_MAX_BYTES
+  if (this.length > 0) {
+    str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')
+    if (this.length > max) str += ' ... '
+  }
+  return '<Buffer ' + str + '>'
+}
+
+Buffer.prototype.compare = function compare (b) {
+  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
+  if (this === b) return 0
+  return Buffer.compare(this, b)
+}
+
+Buffer.prototype.indexOf = function indexOf (val, byteOffset) {
+  if (byteOffset > 0x7fffffff) byteOffset = 0x7fffffff
+  else if (byteOffset < -0x80000000) byteOffset = -0x80000000
+  byteOffset >>= 0
+
+  if (this.length === 0) return -1
+  if (byteOffset >= this.length) return -1
+
+  // Negative offsets start from the end of the buffer
+  if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0)
+
+  if (typeof val === 'string') {
+    if (val.length === 0) return -1 // special case: looking for empty string always fails
+    return String.prototype.indexOf.call(this, val, byteOffset)
+  }
+  if (Buffer.isBuffer(val)) {
+    return arrayIndexOf(this, val, byteOffset)
+  }
+  if (typeof val === 'number') {
+    if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') {
+      return Uint8Array.prototype.indexOf.call(this, val, byteOffset)
+    }
+    return arrayIndexOf(this, [ val ], byteOffset)
+  }
+
+  function arrayIndexOf (arr, val, byteOffset) {
+    var foundIndex = -1
+    for (var i = 0; byteOffset + i < arr.length; i++) {
+      if (arr[byteOffset + i] === val[foundIndex === -1 ? 0 : i - foundIndex]) {
+        if (foundIndex === -1) foundIndex = i
+        if (i - foundIndex + 1 === val.length) return byteOffset + foundIndex
+      } else {
+        foundIndex = -1
+      }
+    }
+    return -1
+  }
+
+  throw new TypeError('val must be string, number or Buffer')
+}
+
+// `get` will be removed in Node 0.13+
+Buffer.prototype.get = function get (offset) {
+  console.log('.get() is deprecated. Access using array indexes instead.')
+  return this.readUInt8(offset)
+}
+
+// `set` will be removed in Node 0.13+
+Buffer.prototype.set = function set (v, offset) {
+  console.log('.set() is deprecated. Access using array indexes instead.')
+  return this.writeUInt8(v, offset)
+}
+
+function hexWrite (buf, string, offset, length) {
+  offset = Number(offset) || 0
+  var remaining = buf.length - offset
+  if (!length) {
+    length = remaining
+  } else {
+    length = Number(length)
+    if (length > remaining) {
+      length = remaining
+    }
+  }
+
+  // must be an even number of digits
+  var strLen = string.length
+  if (strLen % 2 !== 0) throw new Error('Invalid hex string')
+
+  if (length > strLen / 2) {
+    length = strLen / 2
+  }
+  for (var i = 0; i < length; i++) {
+    var parsed = parseInt(string.substr(i * 2, 2), 16)
+    if (isNaN(parsed)) throw new Error('Invalid hex string')
+    buf[offset + i] = parsed
+  }
+  return i
+}
+
+function utf8Write (buf, string, offset, length) {
+  var charsWritten = blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
+  return charsWritten
+}
+
+function asciiWrite (buf, string, offset, length) {
+  var charsWritten = blitBuffer(asciiToBytes(string), buf, offset, length)
+  return charsWritten
+}
+
+function binaryWrite (buf, string, offset, length) {
+  return asciiWrite(buf, string, offset, length)
+}
+
+function base64Write (buf, string, offset, length) {
+  var charsWritten = blitBuffer(base64ToBytes(string), buf, offset, length)
+  return charsWritten
+}
+
+function utf16leWrite (buf, string, offset, length) {
+  var charsWritten = blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
+  return charsWritten
+}
+
+Buffer.prototype.write = function write (string, offset, length, encoding) {
+  // Support both (string, offset, length, encoding)
+  // and the legacy (string, encoding, offset, length)
+  if (isFinite(offset)) {
+    if (!isFinite(length)) {
+      encoding = length
+      length = undefined
+    }
+  } else {  // legacy
+    var swap = encoding
+    encoding = offset
+    offset = length
+    length = swap
+  }
+
+  offset = Number(offset) || 0
+
+  if (length < 0 || offset < 0 || offset > this.length) {
+    throw new RangeError('attempt to write outside buffer bounds')
+  }
+
+  var remaining = this.length - offset
+  if (!length) {
+    length = remaining
+  } else {
+    length = Number(length)
+    if (length > remaining) {
+      length = remaining
+    }
+  }
+  encoding = String(encoding || 'utf8').toLowerCase()
+
+  var ret
+  switch (encoding) {
+    case 'hex':
+      ret = hexWrite(this, string, offset, length)
+      break
+    case 'utf8':
+    case 'utf-8':
+      ret = utf8Write(this, string, offset, length)
+      break
+    case 'ascii':
+      ret = asciiWrite(this, string, offset, length)
+      break
+    case 'binary':
+      ret = binaryWrite(this, string, offset, length)
+      break
+    case 'base64':
+      ret = base64Write(this, string, offset, length)
+      break
+    case 'ucs2':
+    case 'ucs-2':
+    case 'utf16le':
+    case 'utf-16le':
+      ret = utf16leWrite(this, string, offset, length)
+      break
+    default:
+      throw new TypeError('Unknown encoding: ' + encoding)
+  }
+  return ret
+}
+
+Buffer.prototype.toJSON = function toJSON () {
+  return {
+    type: 'Buffer',
+    data: Array.prototype.slice.call(this._arr || this, 0)
+  }
+}
+
+function base64Slice (buf, start, end) {
+  if (start === 0 && end === buf.length) {
+    return base64.fromByteArray(buf)
+  } else {
+    return base64.fromByteArray(buf.slice(start, end))
+  }
+}
+
+function utf8Slice (buf, start, end) {
+  var res = ''
+  var tmp = ''
+  end = Math.min(buf.length, end)
+
+  for (var i = start; i < end; i++) {
+    if (buf[i] <= 0x7F) {
+      res += decodeUtf8Char(tmp) + String.fromCharCode(buf[i])
+      tmp = ''
+    } else {
+      tmp += '%' + buf[i].toString(16)
+    }
+  }
+
+  return res + decodeUtf8Char(tmp)
+}
+
+function asciiSlice (buf, start, end) {
+  var ret = ''
+  end = Math.min(buf.length, end)
+
+  for (var i = start; i < end; i++) {
+    ret += String.fromCharCode(buf[i] & 0x7F)
+  }
+  return ret
+}
+
+function binarySlice (buf, start, end) {
+  var ret = ''
+  end = Math.min(buf.length, end)
+
+  for (var i = start; i < end; i++) {
+    ret += String.fromCharCode(buf[i])
+  }
+  return ret
+}
+
+function hexSlice (buf, start, end) {
+  var len = buf.length
+
+  if (!start || start < 0) start = 0
+  if (!end || end < 0 || end > len) end = len
+
+  var out = ''
+  for (var i = start; i < end; i++) {
+    out += toHex(buf[i])
+  }
+  return out
+}
+
+function utf16leSlice (buf, start, end) {
+  var bytes = buf.slice(start, end)
+  var res = ''
+  for (var i = 0; i < bytes.length; i += 2) {
+    res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)
+  }
+  return res
+}
+
+Buffer.prototype.slice = function slice (start, end) {
+  var len = this.length
+  start = ~~start
+  end = end === undefined ? len : ~~end
+
+  if (start < 0) {
+    start += len
+    if (start < 0) start = 0
+  } else if (start > len) {
+    start = len
+  }
+
+  if (end < 0) {
+    end += len
+    if (end < 0) end = 0
+  } else if (end > len) {
+    end = len
+  }
+
+  if (end < start) end = start
+
+  var newBuf
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    newBuf = Buffer._augment(this.subarray(start, end))
+  } else {
+    var sliceLen = end - start
+    newBuf = new Buffer(sliceLen, undefined)
+    for (var i = 0; i < sliceLen; i++) {
+      newBuf[i] = this[i + start]
+    }
+  }
+
+  if (newBuf.length) newBuf.parent = this.parent || this
+
+  return newBuf
+}
+
+/*
+ * Need to make sure that buffer isn't trying to write out of bounds.
+ */
+function checkOffset (offset, ext, length) {
+  if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
+  if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
+}
+
+Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
+  offset = offset >>> 0
+  byteLength = byteLength >>> 0
+  if (!noAssert) checkOffset(offset, byteLength, this.length)
+
+  var val = this[offset]
+  var mul = 1
+  var i = 0
+  while (++i < byteLength && (mul *= 0x100)) {
+    val += this[offset + i] * mul
+  }
+
+  return val
+}
+
+Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
+  offset = offset >>> 0
+  byteLength = byteLength >>> 0
+  if (!noAssert) {
+    checkOffset(offset, byteLength, this.length)
+  }
+
+  var val = this[offset + --byteLength]
+  var mul = 1
+  while (byteLength > 0 && (mul *= 0x100)) {
+    val += this[offset + --byteLength] * mul
+  }
+
+  return val
+}
+
+Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 1, this.length)
+  return this[offset]
+}
+
+Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 2, this.length)
+  return this[offset] | (this[offset + 1] << 8)
+}
+
+Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 2, this.length)
+  return (this[offset] << 8) | this[offset + 1]
+}
+
+Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 4, this.length)
+
+  return ((this[offset]) |
+      (this[offset + 1] << 8) |
+      (this[offset + 2] << 16)) +
+      (this[offset + 3] * 0x1000000)
+}
+
+Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 4, this.length)
+
+  return (this[offset] * 0x1000000) +
+    ((this[offset + 1] << 16) |
+    (this[offset + 2] << 8) |
+    this[offset + 3])
+}
+
+Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
+  offset = offset >>> 0
+  byteLength = byteLength >>> 0
+  if (!noAssert) checkOffset(offset, byteLength, this.length)
+
+  var val = this[offset]
+  var mul = 1
+  var i = 0
+  while (++i < byteLength && (mul *= 0x100)) {
+    val += this[offset + i] * mul
+  }
+  mul *= 0x80
+
+  if (val >= mul) val -= Math.pow(2, 8 * byteLength)
+
+  return val
+}
+
+Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
+  offset = offset >>> 0
+  byteLength = byteLength >>> 0
+  if (!noAssert) checkOffset(offset, byteLength, this.length)
+
+  var i = byteLength
+  var mul = 1
+  var val = this[offset + --i]
+  while (i > 0 && (mul *= 0x100)) {
+    val += this[offset + --i] * mul
+  }
+  mul *= 0x80
+
+  if (val >= mul) val -= Math.pow(2, 8 * byteLength)
+
+  return val
+}
+
+Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 1, this.length)
+  if (!(this[offset] & 0x80)) return (this[offset])
+  return ((0xff - this[offset] + 1) * -1)
+}
+
+Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 2, this.length)
+  var val = this[offset] | (this[offset + 1] << 8)
+  return (val & 0x8000) ? val | 0xFFFF0000 : val
+}
+
+Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 2, this.length)
+  var val = this[offset + 1] | (this[offset] << 8)
+  return (val & 0x8000) ? val | 0xFFFF0000 : val
+}
+
+Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 4, this.length)
+
+  return (this[offset]) |
+    (this[offset + 1] << 8) |
+    (this[offset + 2] << 16) |
+    (this[offset + 3] << 24)
+}
+
+Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 4, this.length)
+
+  return (this[offset] << 24) |
+    (this[offset + 1] << 16) |
+    (this[offset + 2] << 8) |
+    (this[offset + 3])
+}
+
+Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 4, this.length)
+  return ieee754.read(this, offset, true, 23, 4)
+}
+
+Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 4, this.length)
+  return ieee754.read(this, offset, false, 23, 4)
+}
+
+Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 8, this.length)
+  return ieee754.read(this, offset, true, 52, 8)
+}
+
+Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 8, this.length)
+  return ieee754.read(this, offset, false, 52, 8)
+}
+
+function checkInt (buf, value, offset, ext, max, min) {
+  if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance')
+  if (value > max || value < min) throw new RangeError('value is out of bounds')
+  if (offset + ext > buf.length) throw new RangeError('index out of range')
+}
+
+Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  byteLength = byteLength >>> 0
+  if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)
+
+  var mul = 1
+  var i = 0
+  this[offset] = value & 0xFF
+  while (++i < byteLength && (mul *= 0x100)) {
+    this[offset + i] = (value / mul) >>> 0 & 0xFF
+  }
+
+  return offset + byteLength
+}
+
+Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  byteLength = byteLength >>> 0
+  if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)
+
+  var i = byteLength - 1
+  var mul = 1
+  this[offset + i] = value & 0xFF
+  while (--i >= 0 && (mul *= 0x100)) {
+    this[offset + i] = (value / mul) >>> 0 & 0xFF
+  }
+
+  return offset + byteLength
+}
+
+Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
+  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
+  this[offset] = value
+  return offset + 1
+}
+
+function objectWriteUInt16 (buf, value, offset, littleEndian) {
+  if (value < 0) value = 0xffff + value + 1
+  for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) {
+    buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>
+      (littleEndian ? i : 1 - i) * 8
+  }
+}
+
+Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = value
+    this[offset + 1] = (value >>> 8)
+  } else {
+    objectWriteUInt16(this, value, offset, true)
+  }
+  return offset + 2
+}
+
+Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = (value >>> 8)
+    this[offset + 1] = value
+  } else {
+    objectWriteUInt16(this, value, offset, false)
+  }
+  return offset + 2
+}
+
+function objectWriteUInt32 (buf, value, offset, littleEndian) {
+  if (value < 0) value = 0xffffffff + value + 1
+  for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) {
+    buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff
+  }
+}
+
+Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset + 3] = (value >>> 24)
+    this[offset + 2] = (value >>> 16)
+    this[offset + 1] = (value >>> 8)
+    this[offset] = value
+  } else {
+    objectWriteUInt32(this, value, offset, true)
+  }
+  return offset + 4
+}
+
+Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = (value >>> 24)
+    this[offset + 1] = (value >>> 16)
+    this[offset + 2] = (value >>> 8)
+    this[offset + 3] = value
+  } else {
+    objectWriteUInt32(this, value, offset, false)
+  }
+  return offset + 4
+}
+
+Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  if (!noAssert) {
+    checkInt(
+      this, value, offset, byteLength,
+      Math.pow(2, 8 * byteLength - 1) - 1,
+      -Math.pow(2, 8 * byteLength - 1)
+    )
+  }
+
+  var i = 0
+  var mul = 1
+  var sub = value < 0 ? 1 : 0
+  this[offset] = value & 0xFF
+  while (++i < byteLength && (mul *= 0x100)) {
+    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
+  }
+
+  return offset + byteLength
+}
+
+Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  if (!noAssert) {
+    checkInt(
+      this, value, offset, byteLength,
+      Math.pow(2, 8 * byteLength - 1) - 1,
+      -Math.pow(2, 8 * byteLength - 1)
+    )
+  }
+
+  var i = byteLength - 1
+  var mul = 1
+  var sub = value < 0 ? 1 : 0
+  this[offset + i] = value & 0xFF
+  while (--i >= 0 && (mul *= 0x100)) {
+    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
+  }
+
+  return offset + byteLength
+}
+
+Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
+  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
+  if (value < 0) value = 0xff + value + 1
+  this[offset] = value
+  return offset + 1
+}
+
+Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = value
+    this[offset + 1] = (value >>> 8)
+  } else {
+    objectWriteUInt16(this, value, offset, true)
+  }
+  return offset + 2
+}
+
+Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = (value >>> 8)
+    this[offset + 1] = value
+  } else {
+    objectWriteUInt16(this, value, offset, false)
+  }
+  return offset + 2
+}
+
+Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = value
…
bcc5c47

@benja83 benja83 referenced this pull request in benja83/toyotakataboard-relational May 24, 2015

@benja83 benja83 initial commit, create kata and condition model
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..6a502e9
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,16 @@
+# See https://help.github.com/articles/ignoring-files for more about ignoring files.
+#
+# If you find yourself ignoring temporary files generated by your text editor
+# or operating system, you probably want to add a global ignore instead:
+#   git config --global core.excludesfile '~/.gitignore_global'
+
+# Ignore bundler config.
+/.bundle
+
+# Ignore the default SQLite database.
+/db/*.sqlite3
+/db/*.sqlite3-journal
+
+# Ignore all logfiles and tempfiles.
+/log/*.log
+/tmp
diff --git a/.rspec b/.rspec
new file mode 100644
index 0000000..83e16f8
--- /dev/null
+++ b/.rspec
@@ -0,0 +1,2 @@
+--color
+--require spec_helper
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 0000000..1176802
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,43 @@
+source 'https://rubygems.org'
+
+
+# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
+gem 'rails', '4.1.0'
+# Use postgresql as the database for Active Record
+gem 'pg'
+# Use SCSS for stylesheets
+gem 'sass-rails', '~> 4.0.3'
+# Use Uglifier as compressor for JavaScript assets
+gem 'uglifier', '>= 1.3.0'
+# Use CoffeeScript for .js.coffee assets and views
+# gem 'coffee-rails', '~> 4.0.0'
+# See https://github.com/sstephenson/execjs#readme for more supported runtimes
+# gem 'therubyracer',  platforms: :ruby
+
+# Use jquery as the JavaScript library
+gem 'jquery-rails'
+# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
+gem 'turbolinks'
+# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
+gem 'jbuilder', '~> 2.0'
+# bundle exec rake doc:rails generates the API under doc/api.
+gem 'sdoc', '~> 0.4.0',          group: :doc
+
+# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
+gem 'spring',        group: :development
+
+# Use ActiveModel has_secure_password
+# gem 'bcrypt', '~> 3.1.7'
+
+# Use unicorn as the app server
+# gem 'unicorn'
+
+# Use Capistrano for deployment
+# gem 'capistrano-rails', group: :development
+
+# Use debugger
+# gem 'debugger', group: [:development, :test]
+
+group :development, :test do
+  gem 'rspec-rails', '~> 3.0'
+end
\ No newline at end of file
diff --git a/Gemfile.lock b/Gemfile.lock
new file mode 100644
index 0000000..9d708c6
--- /dev/null
+++ b/Gemfile.lock
@@ -0,0 +1,143 @@
+GEM
+  remote: https://rubygems.org/
+  specs:
+    actionmailer (4.1.0)
+      actionpack (= 4.1.0)
+      actionview (= 4.1.0)
+      mail (~> 2.5.4)
+    actionpack (4.1.0)
+      actionview (= 4.1.0)
+      activesupport (= 4.1.0)
+      rack (~> 1.5.2)
+      rack-test (~> 0.6.2)
+    actionview (4.1.0)
+      activesupport (= 4.1.0)
+      builder (~> 3.1)
+      erubis (~> 2.7.0)
+    activemodel (4.1.0)
+      activesupport (= 4.1.0)
+      builder (~> 3.1)
+    activerecord (4.1.0)
+      activemodel (= 4.1.0)
+      activesupport (= 4.1.0)
+      arel (~> 5.0.0)
+    activesupport (4.1.0)
+      i18n (~> 0.6, >= 0.6.9)
+      json (~> 1.7, >= 1.7.7)
+      minitest (~> 5.1)
+      thread_safe (~> 0.1)
+      tzinfo (~> 1.1)
+    arel (5.0.1.20140414130214)
+    builder (3.2.2)
+    coffee-rails (4.1.0)
+      coffee-script (>= 2.2.0)
+      railties (>= 4.0.0, < 5.0)
+    coffee-script (2.4.1)
+      coffee-script-source
+      execjs
+    coffee-script-source (1.9.1.1)
+    diff-lcs (1.2.5)
+    erubis (2.7.0)
+    execjs (2.5.2)
+    hike (1.2.3)
+    i18n (0.7.0)
+    jbuilder (2.2.16)
+      activesupport (>= 3.0.0, < 5)
+      multi_json (~> 1.2)
+    jquery-rails (3.1.2)
+      railties (>= 3.0, < 5.0)
+      thor (>= 0.14, < 2.0)
+    json (1.8.2)
+    mail (2.5.4)
+      mime-types (~> 1.16)
+      treetop (~> 1.4.8)
+    mime-types (1.25.1)
+    minitest (5.6.1)
+    multi_json (1.11.0)
+    pg (0.18.2)
+    polyglot (0.3.5)
+    rack (1.5.3)
+    rack-test (0.6.3)
+      rack (>= 1.0)
+    rails (4.1.0)
+      actionmailer (= 4.1.0)
+      actionpack (= 4.1.0)
+      actionview (= 4.1.0)
+      activemodel (= 4.1.0)
+      activerecord (= 4.1.0)
+      activesupport (= 4.1.0)
+      bundler (>= 1.3.0, < 2.0)
+      railties (= 4.1.0)
+      sprockets-rails (~> 2.0)
+    railties (4.1.0)
+      actionpack (= 4.1.0)
+      activesupport (= 4.1.0)
+      rake (>= 0.8.7)
+      thor (>= 0.18.1, < 2.0)
+    rake (10.4.2)
+    rdoc (4.2.0)
+      json (~> 1.4)
+    rspec-core (3.2.3)
+      rspec-support (~> 3.2.0)
+    rspec-expectations (3.2.1)
+      diff-lcs (>= 1.2.0, < 2.0)
+      rspec-support (~> 3.2.0)
+    rspec-mocks (3.2.1)
+      diff-lcs (>= 1.2.0, < 2.0)
+      rspec-support (~> 3.2.0)
+    rspec-rails (3.2.1)
+      actionpack (>= 3.0, < 4.3)
+      activesupport (>= 3.0, < 4.3)
+      railties (>= 3.0, < 4.3)
+      rspec-core (~> 3.2.0)
+      rspec-expectations (~> 3.2.0)
+      rspec-mocks (~> 3.2.0)
+      rspec-support (~> 3.2.0)
+    rspec-support (3.2.2)
+    sass (3.2.19)
+    sass-rails (4.0.5)
+      railties (>= 4.0.0, < 5.0)
+      sass (~> 3.2.2)
+      sprockets (~> 2.8, < 3.0)
+      sprockets-rails (~> 2.0)
+    sdoc (0.4.1)
+      json (~> 1.7, >= 1.7.7)
+      rdoc (~> 4.0)
+    spring (1.3.6)
+    sprockets (2.12.3)
+      hike (~> 1.2)
+      multi_json (~> 1.0)
+      rack (~> 1.0)
+      tilt (~> 1.1, != 1.3.0)
+    sprockets-rails (2.3.1)
+      actionpack (>= 3.0)
+      activesupport (>= 3.0)
+      sprockets (>= 2.8, < 4.0)
+    thor (0.19.1)
+    thread_safe (0.3.5)
+    tilt (1.4.1)
+    treetop (1.4.15)
+      polyglot
+      polyglot (>= 0.3.1)
+    turbolinks (2.5.3)
+      coffee-rails
+    tzinfo (1.2.2)
+      thread_safe (~> 0.1)
+    uglifier (2.7.1)
+      execjs (>= 0.3.0)
+      json (>= 1.8.0)
+
+PLATFORMS
+  ruby
+
+DEPENDENCIES
+  jbuilder (~> 2.0)
+  jquery-rails
+  pg
+  rails (= 4.1.0)
+  rspec-rails (~> 3.0)
+  sass-rails (~> 4.0.3)
+  sdoc (~> 0.4.0)
+  spring
+  turbolinks
+  uglifier (>= 1.3.0)
diff --git a/README.rdoc b/README.rdoc
new file mode 100644
index 0000000..dd4e97e
--- /dev/null
+++ b/README.rdoc
@@ -0,0 +1,28 @@
+== README
+
+This README would normally document whatever steps are necessary to get the
+application up and running.
+
+Things you may want to cover:
+
+* Ruby version
+
+* System dependencies
+
+* Configuration
+
+* Database creation
+
+* Database initialization
+
+* How to run the test suite
+
+* Services (job queues, cache servers, search engines, etc.)
+
+* Deployment instructions
+
+* ...
+
+
+Please feel free to use a different markup language if you do not plan to run
+<tt>rake doc:app</tt>.
diff --git a/Rakefile b/Rakefile
new file mode 100644
index 0000000..ba6b733
--- /dev/null
+++ b/Rakefile
@@ -0,0 +1,6 @@
+# Add your own tasks in files placed in lib/tasks ending in .rake,
+# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
+
+require File.expand_path('../config/application', __FILE__)
+
+Rails.application.load_tasks
diff --git a/app/assets/images/.keep b/app/assets/images/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
new file mode 100644
index 0000000..d6925fa
--- /dev/null
+++ b/app/assets/javascripts/application.js
@@ -0,0 +1,16 @@
+// This is a manifest file that'll be compiled into application.js, which will include all the files
+// listed below.
+//
+// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
+// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
+//
+// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
+// compiled file.
+//
+// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
+// about supported directives.
+//
+//= require jquery
+//= require jquery_ujs
+//= require turbolinks
+//= require_tree .
diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css
new file mode 100644
index 0000000..a443db3
--- /dev/null
+++ b/app/assets/stylesheets/application.css
@@ -0,0 +1,15 @@
+/*
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
+ * listed below.
+ *
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
+ *
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
+ * compiled file so the styles you add here take precedence over styles defined in any styles
+ * defined in the other CSS/SCSS files in this directory. It is generally better to create a new
+ * file per style scope.
+ *
+ *= require_tree .
+ *= require_self
+ */
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
new file mode 100644
index 0000000..d83690e
--- /dev/null
+++ b/app/controllers/application_controller.rb
@@ -0,0 +1,5 @@
+class ApplicationController < ActionController::Base
+  # Prevent CSRF attacks by raising an exception.
+  # For APIs, you may want to use :null_session instead.
+  protect_from_forgery with: :exception
+end
diff --git a/app/controllers/concerns/.keep b/app/controllers/concerns/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
new file mode 100644
index 0000000..de6be79
--- /dev/null
+++ b/app/helpers/application_helper.rb
@@ -0,0 +1,2 @@
+module ApplicationHelper
+end
diff --git a/app/mailers/.keep b/app/mailers/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/app/models/.keep b/app/models/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/app/models/concerns/.keep b/app/models/concerns/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/app/models/condition.rb b/app/models/condition.rb
new file mode 100644
index 0000000..e288628
--- /dev/null
+++ b/app/models/condition.rb
@@ -0,0 +1,3 @@
+class Condition < ActiveRecord::Base
+  belongs_to :kata
+end
diff --git a/app/models/kata.rb b/app/models/kata.rb
new file mode 100644
index 0000000..9fe377a
--- /dev/null
+++ b/app/models/kata.rb
@@ -0,0 +1,3 @@
+class Kata < ActiveRecord::Base
+  has_many :conditions
+end
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
new file mode 100644
index 0000000..c8c3a37
--- /dev/null
+++ b/app/views/layouts/application.html.erb
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>Toyotakataboard</title>
+  <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track' => true %>
+  <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
+  <%= csrf_meta_tags %>
+</head>
+<body>
+
+<%= yield %>
+
+</body>
+</html>
diff --git a/bin/bundle b/bin/bundle
new file mode 100755
index 0000000..66e9889
--- /dev/null
+++ b/bin/bundle
@@ -0,0 +1,3 @@
+#!/usr/bin/env ruby
+ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
+load Gem.bin_path('bundler', 'bundle')
diff --git a/bin/rails b/bin/rails
new file mode 100755
index 0000000..728cd85
--- /dev/null
+++ b/bin/rails
@@ -0,0 +1,4 @@
+#!/usr/bin/env ruby
+APP_PATH = File.expand_path('../../config/application',  __FILE__)
+require_relative '../config/boot'
+require 'rails/commands'
diff --git a/bin/rake b/bin/rake
new file mode 100755
index 0000000..1724048
--- /dev/null
+++ b/bin/rake
@@ -0,0 +1,4 @@
+#!/usr/bin/env ruby
+require_relative '../config/boot'
+require 'rake'
+Rake.application.run
diff --git a/config.ru b/config.ru
new file mode 100644
index 0000000..5bc2a61
--- /dev/null
+++ b/config.ru
@@ -0,0 +1,4 @@
+# This file is used by Rack-based servers to start the application.
+
+require ::File.expand_path('../config/environment',  __FILE__)
+run Rails.application
diff --git a/config/application.rb b/config/application.rb
new file mode 100644
index 0000000..784b718
--- /dev/null
+++ b/config/application.rb
@@ -0,0 +1,30 @@
+require File.expand_path('../boot', __FILE__)
+
+# Pick the frameworks you want:
+require "active_model/railtie"
+require "active_record/railtie"
+require "action_controller/railtie"
+require "action_mailer/railtie"
+require "action_view/railtie"
+require "sprockets/railtie"
+# require "rails/test_unit/railtie"
+
+# Require the gems listed in Gemfile, including any gems
+# you've limited to :test, :development, or :production.
+Bundler.require(*Rails.groups)
+
+module Toyotakataboard
+  class Application < Rails::Application
+    # Settings in config/environments/* take precedence over those specified here.
+    # Application configuration should go into files in config/initializers
+    # -- all .rb files in that directory are automatically loaded.
+
+    # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
+    # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
+    # config.time_zone = 'Central Time (US & Canada)'
+
+    # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
+    # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
+    # config.i18n.default_locale = :de
+  end
+end
diff --git a/config/boot.rb b/config/boot.rb
new file mode 100644
index 0000000..5e5f0c1
--- /dev/null
+++ b/config/boot.rb
@@ -0,0 +1,4 @@
+# Set up gems listed in the Gemfile.
+ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
+
+require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
diff --git a/config/database.yml b/config/database.yml
new file mode 100644
index 0000000..0ac6612
--- /dev/null
+++ b/config/database.yml
@@ -0,0 +1,85 @@
+# PostgreSQL. Versions 8.2 and up are supported.
+#
+# Install the pg driver:
+#   gem install pg
+# On OS X with Homebrew:
+#   gem install pg -- --with-pg-config=/usr/local/bin/pg_config
+# On OS X with MacPorts:
+#   gem install pg -- --with-pg-config=/opt/local/lib/postgresql84/bin/pg_config
+# On Windows:
+#   gem install pg
+#       Choose the win32 build.
+#       Install PostgreSQL and put its /bin directory on your path.
+#
+# Configure Using Gemfile
+# gem 'pg'
+#
+default: &default
+  adapter: postgresql
+  encoding: unicode
+  # For details on connection pooling, see rails configuration guide
+  # http://guides.rubyonrails.org/configuring.html#database-pooling
+  pool: 5
+
+development:
+  <<: *default
+  database: toyotakataboard_development
+
+  # The specified database role being used to connect to postgres.
+  # To create additional roles in postgres see `$ createuser --help`.
+  # When left blank, postgres will use the default role. This is
+  # the same name as the operating system user that initialized the database.
+  #username: toyotakataboard
+
+  # The password associated with the postgres role (username).
+  #password:
+
+  # Connect on a TCP socket. Omitted by default since the client uses a
+  # domain socket that doesn't need configuration. Windows does not have
+  # domain sockets, so uncomment these lines.
+  #host: localhost
+
+  # The TCP port the server listens on. Defaults to 5432.
+  # If your server runs on a different port number, change accordingly.
+  #port: 5432
+
+  # Schema search path. The server defaults to $user,public
+  #schema_search_path: myapp,sharedapp,public
+
+  # Minimum log levels, in increasing order:
+  #   debug5, debug4, debug3, debug2, debug1,
+  #   log, notice, warning, error, fatal, and panic
+  # Defaults to warning.
+  #min_messages: notice
+
+# Warning: The database defined as "test" will be erased and
+# re-generated from your development database when you run "rake".
+# Do not set this db to the same as development or production.
+test:
+  <<: *default
+  database: toyotakataboard_test
+
+# As with config/secrets.yml, you never want to store sensitive information,
+# like your database password, in your source code. If your source code is
+# ever seen by anyone, they now have access to your database.
+#
+# Instead, provide the password as a unix environment variable when you boot
+# the app. Read http://guides.rubyonrails.org/configuring.html#configuring-a-database
+# for a full rundown on how to provide these environment variables in a
+# production deployment.
+#
+# On Heroku and other platform providers, you may have a full connection URL
+# available as an environment variable. For example:
+#
+#   DATABASE_URL="postgres://myuser:mypass@localhost/somedatabase"
+#
+# You can use this database configuration with:
+#
+#   production:
+#     url: <%= ENV['DATABASE_URL'] %>
+#
+production:
+  <<: *default
+  database: toyotakataboard_production
+  username: toyotakataboard
+  password: <%= ENV['TOYOTAKATABOARD_DATABASE_PASSWORD'] %>
diff --git a/config/environment.rb b/config/environment.rb
new file mode 100644
index 0000000..ee8d90d
--- /dev/null
+++ b/config/environment.rb
@@ -0,0 +1,5 @@
+# Load the Rails application.
+require File.expand_path('../application', __FILE__)
+
+# Initialize the Rails application.
+Rails.application.initialize!
diff --git a/config/environments/development.rb b/config/environments/development.rb
new file mode 100644
index 0000000..ddf0e90
--- /dev/null
+++ b/config/environments/development.rb
@@ -0,0 +1,37 @@
+Rails.application.configure do
+  # Settings specified here will take precedence over those in config/application.rb.
+
+  # In the development environment your application's code is reloaded on
+  # every request. This slows down response time but is perfect for development
+  # since you don't have to restart the web server when you make code changes.
+  config.cache_classes = false
+
+  # Do not eager load code on boot.
+  config.eager_load = false
+
+  # Show full error reports and disable caching.
+  config.consider_all_requests_local       = true
+  config.action_controller.perform_caching = false
+
+  # Don't care if the mailer can't send.
+  config.action_mailer.raise_delivery_errors = false
+
+  # Print deprecation notices to the Rails logger.
+  config.active_support.deprecation = :log
+
+  # Raise an error on page load if there are pending migrations.
+  config.active_record.migration_error = :page_load
+
+  # Debug mode disables concatenation and preprocessing of assets.
+  # This option may cause significant delays in view rendering with a large
+  # number of complex assets.
+  config.assets.debug = true
+
+  # Adds additional error checking when serving assets at runtime.
+  # Checks for improperly declared sprockets dependencies.
+  # Raises helpful error messages.
+  config.assets.raise_runtime_errors = true
+
+  # Raises error for missing translations
+  # config.action_view.raise_on_missing_translations = true
+end
diff --git a/config/environments/production.rb b/config/environments/production.rb
new file mode 100644
index 0000000..47d3553
--- /dev/null
+++ b/config/environments/production.rb
@@ -0,0 +1,83 @@
+Rails.application.configure do
+  # Settings specified here will take precedence over those in config/application.rb.
+
+  # Code is not reloaded between requests.
+  config.cache_classes = true
+
+  # Eager load code on boot. This eager loads most of Rails and
+  # your application in memory, allowing both threaded web servers
+  # and those relying on copy on write to perform better.
+  # Rake tasks automatically ignore this option for performance.
+  config.eager_load = true
+
+  # Full error reports are disabled and caching is turned on.
+  config.consider_all_requests_local       = false
+  config.action_controller.perform_caching = true
+
+  # Enable Rack::Cache to put a simple HTTP cache in front of your application
+  # Add `rack-cache` to your Gemfile before enabling this.
+  # For large-scale production use, consider using a caching reverse proxy like nginx, varnish or squid.
+  # config.action_dispatch.rack_cache = true
+
+  # Disable Rails's static asset server (Apache or nginx will already do this).
+  config.serve_static_assets = false
+
+  # Compress JavaScripts and CSS.
+  config.assets.js_compressor = :uglifier
+  # config.assets.css_compressor = :sass
+
+  # Do not fallback to assets pipeline if a precompiled asset is missed.
+  config.assets.compile = false
+
+  # Generate digests for assets URLs.
+  config.assets.digest = true
+
+  # Version of your assets, change this if you want to expire all your assets.
+  config.assets.version = '1.0'
+
+  # Specifies the header that your server uses for sending files.
+  # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
+  # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
+
+  # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
+  # config.force_ssl = true
+
+  # Set to :debug to see everything in the log.
+  config.log_level = :info
+
+  # Prepend all log lines with the following tags.
+  # config.log_tags = [ :subdomain, :uuid ]
+
+  # Use a different logger for distributed setups.
+  # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)
+
+  # Use a different cache store in production.
+  # config.cache_store = :mem_cache_store
+
+  # Enable serving of images, stylesheets, and JavaScripts from an asset server.
+  # config.action_controller.asset_host = "http://assets.example.com"
+
+  # Precompile additional assets.
+  # application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
+  # config.assets.precompile += %w( search.js )
+
+  # Ignore bad email addresses and do not raise email delivery errors.
+  # Set this to true and configure the email server for immediate delivery to raise delivery errors.
+  # config.action_mailer.raise_delivery_errors = false
+
+  # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
+  # the I18n.default_locale when a translation cannot be found).
+  config.i18n.fallbacks = true
+
+  # Send deprecation notices to registered listeners.
+  config.active_support.deprecation = :notify
+
+  # Disable automatic flushing of the log to improve performance.
+  # config.autoflush_log = false
+
+  # Use default logging formatter so that PID and timestamp are not suppressed.
+  config.log_formatter = ::Logger::Formatter.new
+
+  # Do not dump schema after migrations.
+  config.active_record.dump_schema_after_migration = false
+end
diff --git a/config/environments/test.rb b/config/environments/test.rb
new file mode 100644
index 0000000..053f5b6
--- /dev/null
+++ b/config/environments/test.rb
@@ -0,0 +1,39 @@
+Rails.application.configure do
+  # Settings specified here will take precedence over those in config/application.rb.
+
+  # The test environment is used exclusively to run your application's
+  # test suite. You never need to work with it otherwise. Remember that
+  # your test database is "scratch space" for the test suite and is wiped
+  # and recreated between test runs. Don't rely on the data there!
+  config.cache_classes = true
+
+  # Do not eager load code on boot. This avoids loading your whole application
+  # just for the purpose of running a single test. If you are using a tool that
+  # preloads Rails for running tests, you may have to set it to true.
+  config.eager_load = false
+
+  # Configure static asset server for tests with Cache-Control for performance.
+  config.serve_static_assets  = true
+  config.static_cache_control = 'public, max-age=3600'
+
+  # Show full error reports and disable caching.
+  config.consider_all_requests_local       = true
+  config.action_controller.perform_caching = false
+
+  # Raise exceptions instead of rendering exception templates.
+  config.action_dispatch.show_exceptions = false
+
+  # Disable request forgery protection in test environment.
+  config.action_controller.allow_forgery_protection = false
+
+  # Tell Action Mailer not to deliver emails to the real world.
+  # The :test delivery method accumulates sent emails in the
+  # ActionMailer::Base.deliveries array.
+  config.action_mailer.delivery_method = :test
+
+  # Print deprecation notices to the stderr.
+  config.active_support.deprecation = :stderr
+
+  # Raises error for missing translations
+  # config.action_view.raise_on_missing_translations = true
+end
diff --git a/config/initializers/backtrace_silencers.rb b/config/initializers/backtrace_silencers.rb
new file mode 100644
index 0000000..59385cd
--- /dev/null
+++ b/config/initializers/backtrace_silencers.rb
@@ -0,0 +1,7 @@
+# Be sure to restart your server when you modify this file.
+
+# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
+# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
+
+# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
+# Rails.backtrace_cleaner.remove_silencers!
diff --git a/config/initializers/cookies_serializer.rb b/config/initializers/cookies_serializer.rb
new file mode 100644
index 0000000..7a06a89
--- /dev/null
+++ b/config/initializers/cookies_serializer.rb
@@ -0,0 +1,3 @@
+# Be sure to restart your server when you modify this file.
+
+Rails.application.config.action_dispatch.cookies_serializer = :json
\ No newline at end of file
diff --git a/config/initializers/filter_parameter_logging.rb b/config/initializers/filter_parameter_logging.rb
new file mode 100644
index 0000000..4a994e1
--- /dev/null
+++ b/config/initializers/filter_parameter_logging.rb
@@ -0,0 +1,4 @@
+# Be sure to restart your server when you modify this file.
+
+# Configure sensitive parameters which will be filtered from the log file.
+Rails.application.config.filter_parameters += [:password]
diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb
new file mode 100644
index 0000000..ac033bf
--- /dev/null
+++ b/config/initializers/inflections.rb
@@ -0,0 +1,16 @@
+# Be sure to restart your server when you modify this file.
+
+# Add new inflection rules using the following format. Inflections
+# are locale specific, and you may define rules for as many different
+# locales as you wish. All of these examples are active by default:
+# ActiveSupport::Inflector.inflections(:en) do |inflect|
+#   inflect.plural /^(ox)$/i, '\1en'
+#   inflect.singular /^(ox)en/i, '\1'
+#   inflect.irregular 'person', 'people'
+#   inflect.uncountable %w( fish sheep )
+# end
+
+# These inflection rules are supported but not enabled by default:
+# ActiveSupport::Inflector.inflections(:en) do |inflect|
+#   inflect.acronym 'RESTful'
+# end
diff --git a/config/initializers/mime_types.rb b/config/initializers/mime_types.rb
new file mode 100644
index 0000000..dc18996
--- /dev/null
+++ b/config/initializers/mime_types.rb
@@ -0,0 +1,4 @@
+# Be sure to restart your server when you modify this file.
+
+# Add new mime types for use in respond_to blocks:
+# Mime::Type.register "text/richtext", :rtf
diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb
new file mode 100644
index 0000000..f73ba88
--- /dev/null
+++ b/config/initializers/session_store.rb
@@ -0,0 +1,3 @@
+# Be sure to restart your server when you modify this file.
+
+Rails.application.config.session_store :cookie_store, key: '_toyotakataboard_session'
diff --git a/config/initializers/wrap_parameters.rb b/config/initializers/wrap_parameters.rb
new file mode 100644
index 0000000..33725e9
--- /dev/null
+++ b/config/initializers/wrap_parameters.rb
@@ -0,0 +1,14 @@
+# Be sure to restart your server when you modify this file.
+
+# This file contains settings for ActionController::ParamsWrapper which
+# is enabled by default.
+
+# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
+ActiveSupport.on_load(:action_controller) do
+  wrap_parameters format: [:json] if respond_to?(:wrap_parameters)
+end
+
+# To enable root element in JSON for ActiveRecord objects.
+# ActiveSupport.on_load(:active_record) do
+#  self.include_root_in_json = true
+# end
diff --git a/config/locales/en.yml b/config/locales/en.yml
new file mode 100644
index 0000000..0653957
--- /dev/null
+++ b/config/locales/en.yml
@@ -0,0 +1,23 @@
+# Files in the config/locales directory are used for internationalization
+# and are automatically loaded by Rails. If you want to use locales other
+# than English, add the necessary files in this directory.
+#
+# To use the locales, use `I18n.t`:
+#
+#     I18n.t 'hello'
+#
+# In views, this is aliased to just `t`:
+#
+#     <%= t('hello') %>
+#
+# To use a different locale, set it with `I18n.locale`:
+#
+#     I18n.locale = :es
+#
+# This would use the information in config/locales/es.yml.
+#
+# To learn more, please read the Rails Internationalization guide
+# available at http://guides.rubyonrails.org/i18n.html.
+
+en:
+  hello: "Hello world"
diff --git a/config/routes.rb b/config/routes.rb
new file mode 100644
index 0000000..3f66539
--- /dev/null
+++ b/config/routes.rb
@@ -0,0 +1,56 @@
+Rails.application.routes.draw do
+  # The priority is based upon order of creation: first created -> highest priority.
+  # See how all your routes lay out with "rake routes".
+
+  # You can have the root of your site routed with "root"
+  # root 'welcome#index'
+
+  # Example of regular route:
+  #   get 'products/:id' => 'catalog#view'
+
+  # Example of named route that can be invoked with purchase_url(id: product.id)
+  #   get 'products/:id/purchase' => 'catalog#purchase', as: :purchase
+
+  # Example resource route (maps HTTP verbs to controller actions automatically):
+  #   resources :products
+
+  # Example resource route with options:
+  #   resources :products do
+  #     member do
+  #       get 'short'
+  #       post 'toggle'
+  #     end
+  #
+  #     collection do
+  #       get 'sold'
+  #     end
+  #   end
+
+  # Example resource route with sub-resources:
+  #   resources :products do
+  #     resources :comments, :sales
+  #     resource :seller
+  #   end
+
+  # Example resource route with more complex sub-resources:
+  #   resources :products do
+  #     resources :comments
+  #     resources :sales do
+  #       get 'recent', on: :collection
+  #     end
+  #   end
+
+  # Example resource route with concerns:
+  #   concern :toggleable do
+  #     post 'toggle'
+  #   end
+  #   resources :posts, concerns: :toggleable
+  #   resources :photos, concerns: :toggleable
+
+  # Example resource route within a namespace:
+  #   namespace :admin do
+  #     # Directs /admin/products/* to Admin::ProductsController
+  #     # (app/controllers/admin/products_controller.rb)
+  #     resources :products
+  #   end
+end
diff --git a/config/secrets.yml b/config/secrets.yml
new file mode 100644
index 0000000..3581cc2
--- /dev/null
+++ b/config/secrets.yml
@@ -0,0 +1,22 @@
+# Be sure to restart your server when you modify this file.
+
+# Your secret key is used for verifying the integrity of signed cookies.
+# If you change this key, all old signed cookies will become invalid!
+
+# Make sure the secret is at least 30 characters and all random,
+# no regular words or you'll be exposed to dictionary attacks.
+# You can use `rake secret` to generate a secure secret key.
+
+# Make sure the secrets in this file are kept private
+# if you're sharing your code publicly.
+
+development:
+  secret_key_base: 302b3fcb0aa199aec43023bdb6908f5c00c3451fcabb825b33052c910958805752462436ba6725e921d4528068481d1888ddf3a58816b95a2d3cdd4623be22bc
+
+test:
+  secret_key_base: eed3713fdcb5cd2767385f7a9450f13eadd5ca88f125ec5b8fa81198dfa3bae7d0a6c7696c2ea866b982aa9c602e58af09f363de178e569fdb869cfe9f7f4d52
+
+# Do not keep production secrets in the repository,
+# instead read values from the environment.
+production:
+  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
diff --git a/db/migrate/20150524190249_create_kata.rb b/db/migrate/20150524190249_create_kata.rb
new file mode 100644
index 0000000..3da4eb7
--- /dev/null
+++ b/db/migrate/20150524190249_create_kata.rb
@@ -0,0 +1,13 @@
+class CreateKata < ActiveRecord::Migration
+  def change
+    create_table :kata do |t|
+      t.string :name
+      t.string :vision
+      t.string :team
+      t.date :init_date
+      t.date :end_date
+      t.string :responsible
+      t.timestamps
+    end
+  end
+end
diff --git a/db/migrate/20150524192645_create_conditions.rb b/db/migrate/20150524192645_create_conditions.rb
new file mode 100644
index 0000000..d8725f3
--- /dev/null
+++ b/db/migrate/20150524192645_create_conditions.rb
@@ -0,0 +1,10 @@
+class CreateConditions < ActiveRecord::Migration
+  def change
+    create_table :conditions do |t|
+      t.string :title
+      t.string :type
+      t.timestamps
+    end
+    add_reference :conditions, :kata, index: true
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
new file mode 100644
index 0000000..b092856
--- /dev/null
+++ b/db/schema.rb
@@ -0,0 +1,30 @@
+# encoding: UTF-8
+# This file is auto-generated from the current state of the database. Instead
+# of editing this file, please use the migrations feature of Active Record to
+# incrementally modify your database, and then regenerate this schema definition.
+#
+# Note that this schema.rb definition is the authoritative source for your
+# database schema. If you need to create the application database on another
+# system, you should be using db:schema:load, not running all the migrations
+# from scratch. The latter is a flawed and unsustainable approach (the more migrations
+# you'll amass, the slower it'll run and the greater likelihood for issues).
+#
+# It's strongly recommended that you check this file into your version control system.
+
+ActiveRecord::Schema.define(version: 20150524190249) do
+
+  # These are extensions that must be enabled in order to support this database
+  enable_extension "plpgsql"
+
+  create_table "kata", force: true do |t|
+    t.string   "name"
+    t.string   "vision"
+    t.string   "team"
+    t.date     "init_date"
+    t.date     "end_date"
+    t.string   "responsible"
+    t.datetime "created_at"
+    t.datetime "updated_at"
+  end
+
+end
diff --git a/db/seeds.rb b/db/seeds.rb
new file mode 100644
index 0000000..4edb1e8
--- /dev/null
+++ b/db/seeds.rb
@@ -0,0 +1,7 @@
+# This file should contain all the record creation needed to seed the database with its default values.
+# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
+#
+# Examples:
+#
+#   cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }])
+#   Mayor.create(name: 'Emanuel', city: cities.first)
diff --git a/lib/assets/.keep b/lib/assets/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/lib/tasks/.keep b/lib/tasks/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/log/.keep b/log/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/public/404.html b/public/404.html
new file mode 100644
index 0000000..b612547
--- /dev/null
+++ b/public/404.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>The page you were looking for doesn't exist (404)</title>
+  <meta name="viewport" content="width=device-width,initial-scale=1">
+  <style>
+  body {
+    background-color: #EFEFEF;
+    color: #2E2F30;
+    text-align: center;
+    font-family: arial, sans-serif;
+    margin: 0;
+  }
+
+  div.dialog {
+    width: 95%;
+    max-width: 33em;
+    margin: 4em auto 0;
+  }
+
+  div.dialog > div {
+    border: 1px solid #CCC;
+    border-right-color: #999;
+    border-left-color: #999;
+    border-bottom-color: #BBB;
+    border-top: #B00100 solid 4px;
+    border-top-left-radius: 9px;
+    border-top-right-radius: 9px;
+    background-color: white;
+    padding: 7px 12% 0;
+    box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
+  }
+
+  h1 {
+    font-size: 100%;
+    color: #730E15;
+    line-height: 1.5em;
+  }
+
+  div.dialog > p {
+    margin: 0 0 1em;
+    padding: 1em;
+    background-color: #F7F7F7;
+    border: 1px solid #CCC;
+    border-right-color: #999;
+    border-left-color: #999;
+    border-bottom-color: #999;
+    border-bottom-left-radius: 4px;
+    border-bottom-right-radius: 4px;
+    border-top-color: #DADADA;
+    color: #666;
+    box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
+  }
+  </style>
+</head>
+
+<body>
+  <!-- This file lives in public/404.html -->
+  <div class="dialog">
+    <div>
+      <h1>The page you were looking for doesn't exist.</h1>
+      <p>You may have mistyped the address or the page may have moved.</p>
+    </div>
+    <p>If you are the application owner check the logs for more information.</p>
+  </div>
+</body>
+</html>
diff --git a/public/422.html b/public/422.html
new file mode 100644
index 0000000..a21f82b
--- /dev/null
+++ b/public/422.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>The change you wanted was rejected (422)</title>
+  <meta name="viewport" content="width=device-width,initial-scale=1">
+  <style>
+  body {
+    background-color: #EFEFEF;
+    color: #2E2F30;
+    text-align: center;
+    font-family: arial, sans-serif;
+    margin: 0;
+  }
+
+  div.dialog {
+    width: 95%;
+    max-width: 33em;
+    margin: 4em auto 0;
+  }
+
+  div.dialog > div {
+    border: 1px solid #CCC;
+    border-right-color: #999;
+    border-left-color: #999;
+    border-bottom-color: #BBB;
+    border-top: #B00100 solid 4px;
+    border-top-left-radius: 9px;
+    border-top-right-radius: 9px;
+    background-color: white;
+    padding: 7px 12% 0;
+    box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
+  }
+
+  h1 {
+    font-size: 100%;
+    color: #730E15;
+    line-height: 1.5em;
+  }
+
+  div.dialog > p {
+    margin: 0 0 1em;
+    padding: 1em;
+    background-color: #F7F7F7;
+    border: 1px solid #CCC;
+    border-right-color: #999;
+    border-left-color: #999;
+    border-bottom-color: #999;
+    border-bottom-left-radius: 4px;
+    border-bottom-right-radius: 4px;
+    border-top-color: #DADADA;
+    color: #666;
+    box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
+  }
+  </style>
+</head>
+
+<body>
+  <!-- This file lives in public/422.html -->
+  <div class="dialog">
+    <div>
+      <h1>The change you wanted was rejected.</h1>
+      <p>Maybe you tried to change something you didn't have access to.</p>
+    </div>
+    <p>If you are the application owner check the logs for more information.</p>
+  </div>
+</body>
+</html>
diff --git a/public/500.html b/public/500.html
new file mode 100644
index 0000000..061abc5
--- /dev/null
+++ b/public/500.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>We're sorry, but something went wrong (500)</title>
+  <meta name="viewport" content="width=device-width,initial-scale=1">
+  <style>
+  body {
+    background-color: #EFEFEF;
+    color: #2E2F30;
+    text-align: center;
+    font-family: arial, sans-serif;
+    margin: 0;
+  }
+
+  div.dialog {
+    width: 95%;
+    max-width: 33em;
+    margin: 4em auto 0;
+  }
+
+  div.dialog > div {
+    border: 1px solid #CCC;
+    border-right-color: #999;
+    border-left-color: #999;
+    border-bottom-color: #BBB;
+    border-top: #B00100 solid 4px;
+    border-top-left-radius: 9px;
+    border-top-right-radius: 9px;
+    background-color: white;
+    padding: 7px 12% 0;
+    box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
+  }
+
+  h1 {
+    font-size: 100%;
+    color: #730E15;
+    line-height: 1.5em;
+  }
+
+  div.dialog > p {
+    margin: 0 0 1em;
+    padding: 1em;
+    background-color: #F7F7F7;
+    border: 1px solid #CCC;
+    border-right-color: #999;
+    border-left-color: #999;
+    border-bottom-color: #999;
+    border-bottom-left-radius: 4px;
+    border-bottom-right-radius: 4px;
+    border-top-color: #DADADA;
+    color: #666;
+    box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
+  }
+  </style>
+</head>
+
+<body>
+  <!-- This file lives in public/500.html -->
+  <div class="dialog">
+    <div>
+      <h1>We're sorry, but something went wrong.</h1>
+    </div>
+    <p>If you are the application owner check the logs for more information.</p>
+  </div>
+</body>
+</html>
diff --git a/public/favicon.ico b/public/favicon.ico
new file mode 100644
index 0000000..e69de29
diff --git a/public/robots.txt b/public/robots.txt
new file mode 100644
index 0000000..3c9c7c0
--- /dev/null
+++ b/public/robots.txt
@@ -0,0 +1,5 @@
+# See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file
+#
+# To ban all spiders from the entire site uncomment the next two lines:
+# User-agent: *
+# Disallow: /
diff --git a/spec/models/condition_spec.rb b/spec/models/condition_spec.rb
new file mode 100644
index 0000000..bcf85ec
--- /dev/null
+++ b/spec/models/condition_spec.rb
@@ -0,0 +1,5 @@
+require 'rails_helper'
+
+RSpec.describe Condition, type: :model do
+  pending "add some examples to (or delete) #{__FILE__}"
+end
diff --git a/spec/models/kata_spec.rb b/spec/models/kata_spec.rb
new file mode 100644
index 0000000..e75ae04
--- /dev/null
+++ b/spec/models/kata_spec.rb
@@ -0,0 +1,5 @@
+require 'rails_helper'
+
+RSpec.describe Kata, type: :model do
+  pending "add some examples to (or delete) #{__FILE__}"
+end
diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb
new file mode 100644
index 0000000..c278035
--- /dev/null
+++ b/spec/rails_helper.rb
@@ -0,0 +1,50 @@
+# This file is copied to spec/ when you run 'rails generate rspec:install'
+ENV['RAILS_ENV'] ||= 'test'
+require 'spec_helper'
+require File.expand_path('../../config/environment', __FILE__)
+require 'rspec/rails'
+# Add additional requires below this line. Rails is not loaded until this point!
+
+# Requires supporting ruby files with custom matchers and macros, etc, in
+# spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
+# run as spec files by default. This means that files in spec/support that end
+# in _spec.rb will both be required and run as specs, causing the specs to be
+# run twice. It is recommended that you do not name files matching this glob to
+# end with _spec.rb. You can configure this pattern with the --pattern
+# option on the command line or in ~/.rspec, .rspec or `.rspec-local`.
+#
+# The following line is provided for convenience purposes. It has the downside
+# of increasing the boot-up time by auto-requiring all files in the support
+# directory. Alternatively, in the individual `*_spec.rb` files, manually
+# require only the support files necessary.
+#
+# Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
+
+# Checks for pending migrations before tests are run.
+# If you are not using ActiveRecord, you can remove this line.
+ActiveRecord::Migration.maintain_test_schema!
+
+RSpec.configure do |config|
+  # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
+  config.fixture_path = "#{::Rails.root}/spec/fixtures"
+
+  # If you're not using ActiveRecord, or you'd prefer not to run each of your
+  # examples within a transaction, remove the following line or assign false
+  # instead of true.
+  config.use_transactional_fixtures = true
+
+  # RSpec Rails can automatically mix in different behaviours to your tests
+  # based on their file location, for example enabling you to call `get` and
+  # `post` in specs under `spec/controllers`.
+  #
+  # You can disable this behaviour by removing the line below, and instead
+  # explicitly tag your specs with their type, e.g.:
+  #
+  #     RSpec.describe UsersController, :type => :controller do
+  #       # ...
+  #     end
+  #
+  # The different available types are documented in the features, such as in
+  # https://relishapp.com/rspec/rspec-rails/docs
+  config.infer_spec_type_from_file_location!
+end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
new file mode 100644
index 0000000..38a4f9a
--- /dev/null
+++ b/spec/spec_helper.rb
@@ -0,0 +1,87 @@
+# This file was generated by the `rails generate rspec:install` command. Conventionally, all
+# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
+# The generated `.rspec` file contains `--require spec_helper` which will cause
+# this file to always be loaded, without a need to explicitly require it in any
+# files.
+#
+# Given that it is always loaded, you are encouraged to keep this file as
+# light-weight as possible. Requiring heavyweight dependencies from this file
+# will add to the boot time of your test suite on EVERY test run, even for an
+# individual file that may not need all of that loaded. Instead, consider making
+# a separate helper file that requires the additional dependencies and performs
+# the additional setup, and require it from the spec files that actually need
+# it.
+#
+# The `.rspec` file also contains a few flags that are not defaults but that
+# users commonly want.
+#
+# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
+RSpec.configure do |config|
+  # rspec-expectations config goes here. You can use an alternate
+  # assertion/expectation library such as wrong or the stdlib/minitest
+  # assertions if you prefer.
+  config.expect_with :rspec do |expectations|
+    # This option will default to `true` in RSpec 4. It makes the `description`
+    # and `failure_message` of custom matchers include text for helper methods
+    # defined using `chain`, e.g.:
+    #     be_bigger_than(2).and_smaller_than(4).description
+    #     # => "be bigger than 2 and smaller than 4"
+    # ...rather than:
+    #     # => "be bigger than 2"
+    expectations.include_chain_clauses_in_custom_matcher_descriptions = true
+  end
+
+  # rspec-mocks config goes here. You can use an alternate test double
+  # library (such as bogus or mocha) by changing the `mock_with` option here.
+  config.mock_with :rspec do |mocks|
+    # Prevents you from mocking or stubbing a method that does not exist on
+    # a real object. This is generally recommended, and will default to
+    # `true` in RSpec 4.
+    mocks.verify_partial_doubles = true
+  end
+
+# The settings below are suggested to provide a good initial experience
+# with RSpec, but feel free to customize to your heart's content.
+=begin
+  # These two settings work together to allow you to limit a spec run
+  # to individual examples or groups you care about by tagging them with
+  # `:focus` metadata. When nothing is tagged with `:focus`, all examples
+  # get run.
+  config.filter_run :focus
+  config.run_all_when_everything_filtered = true
+
+  # Limits the available syntax to the non-monkey patched syntax that is
+  # recommended. For more details, see:
+  #   - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
+  #   - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
+  #   - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
+  config.disable_monkey_patching!
+
+  # Many RSpec users commonly either run the entire suite or an individual
+  # file, and it's useful to allow more verbose output when running an
+  # individual spec file.
+  if config.files_to_run.one?
+    # Use the documentation formatter for detailed output,
+    # unless a formatter has already been configured
+    # (e.g. via a command-line flag).
+    config.default_formatter = 'doc'
+  end
+
+  # Print the 10 slowest examples and example groups at the
+  # end of the spec run, to help surface which specs are running
+  # particularly slow.
+  config.profile_examples = 10
+
+  # Run specs in random order to surface order dependencies. If you find an
+  # order dependency and want to debug it, you can fix the order by providing
+  # the seed, which is printed after each run.
+  #     --seed 1234
+  config.order = :random
+
+  # Seed global randomization in this process using the `--seed` CLI option.
+  # Setting this allows you to use `--seed` to deterministically reproduce
+  # test failures related to randomization by passing the same `--seed` value
+  # as the one that triggered the failure.
+  Kernel.srand config.seed
+=end
+end
diff --git a/vendor/assets/javascripts/.keep b/vendor/assets/javascripts/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/vendor/assets/stylesheets/.keep b/vendor/assets/stylesheets/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/vendor/bundle/ruby/2.1.0/bin/erubis b/vendor/bundle/ruby/2.1.0/bin/erubis
new file mode 100755
index 0000000..301dd30
--- /dev/null
+++ b/vendor/bundle/ruby/2.1.0/bin/erubis
@@ -0,0 +1,23 @@
+#!/usr/bin/env ruby
+#
+# This file was generated by RubyGems.
+#
+# The application 'erubis' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
+
+require 'rubygems'
+
+version = ">= 0"
+
+if ARGV.first
+  str = ARGV.first
+  str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
+  if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
+    version = $1
+    ARGV.shift
+  end
+end
+
+gem 'erubis', version
+load Gem.bin_path('erubis', 'erubis', version)
diff --git a/vendor/bundle/ruby/2.1.0/bin/htmldiff b/vendor/bundle/ruby/2.1.0/bin/htmldiff
new file mode 100755
index 0000000..6829c46
--- /dev/null
+++ b/vendor/bundle/ruby/2.1.0/bin/htmldiff
@@ -0,0 +1,25 @@
+#!/bin/sh
+'exec' "ruby" '-x' "$0" "$@"
+#!/Users/benjamintarenne/.rvm/rubies/ruby-2.1.1/bin/ruby
+#
+# This file was generated by RubyGems.
+#
+# The application 'diff-lcs' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
+
+require 'rubygems'
+
+version = ">= 0"
+
+if ARGV.first
+  str = ARGV.first
+  str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
+  if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
+    version = $1
+    ARGV.shift
+  end
+end
+
+gem 'diff-lcs', version
+load Gem.bin_path('diff-lcs', 'htmldiff', version)
diff --git a/vendor/bundle/ruby/2.1.0/bin/ldiff b/vendor/bundle/ruby/2.1.0/bin/ldiff
new file mode 100755
index 0000000..5d8588a
--- /dev/null
+++ b/vendor/bundle/ruby/2.1.0/bin/ldiff
@@ -0,0 +1,25 @@
+#!/bin/sh
+'exec' "ruby" '-x' "$0" "$@"
+#!/Users/benjamintarenne/.rvm/rubies/ruby-2.1.1/bin/ruby
+#
+# This file was generated by RubyGems.
+#
+# The application 'diff-lcs' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
+
+require 'rubygems'
+
+version = ">= 0"
+
+if ARGV.first
+  str = ARGV.first
+  str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
+  if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
+    version = $1
+    ARGV.shift
+  end
+end
+
+gem 'diff-lcs', version
+load Gem.bin_path('diff-lcs', 'ldiff', version)
diff --git a/vendor/bundle/ruby/2.1.0/bin/rackup b/vendor/bundle/ruby/2.1.0/bin/rackup
new file mode 100755
index 0000000..416d30a
--- /dev/null
+++ b/vendor/bundle/ruby/2.1.0/bin/rackup
@@ -0,0 +1,23 @@
+#!/usr/bin/env ruby
+#
+# This file was generated by RubyGems.
+#
+# The application 'rack' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
+
+require 'rubygems'
+
+version = ">= 0"
+
+if ARGV.first
+  str = ARGV.first
+  str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
+  if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
+    version = $1
+    ARGV.shift
+  end
+end
+
+gem 'rack', version
+load Gem.bin_path('rack', 'rackup', version)
diff --git a/vendor/bundle/ruby/2.1.0/bin/rails b/vendor/bundle/ruby/2.1.0/bin/rails
new file mode 100755
index 0000000..b2a661f
--- /dev/null
+++ b/vendor/bundle/ruby/2.1.0/bin/rails
@@ -0,0 +1,23 @@
+#!/usr/bin/env ruby
+#
+# This file was generated by RubyGems.
+#
+# The application 'railties' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
+
+require 'rubygems'
+
+version = ">= 0"
+
+if ARGV.first
+  str = ARGV.first
+  str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
+  if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
+    version = $1
+    ARGV.shift
+  end
+end
+
+gem 'railties', version
+load Gem.bin_path('railties', 'rails', version)
diff --git a/vendor/bundle/ruby/2.1.0/bin/rake b/vendor/bundle/ruby/2.1.0/bin/rake
new file mode 100755
index 0000000..97d1fcc
--- /dev/null
+++ b/vendor/bundle/ruby/2.1.0/bin/rake
@@ -0,0 +1,23 @@
+#!/usr/bin/env ruby
+#
+# This file was generated by RubyGems.
+#
+# The application 'rake' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
+
+require 'rubygems'
+
+version = ">= 0"
+
+if ARGV.first
+  str = ARGV.first
+  str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
+  if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
+    version = $1
+    ARGV.shift
+  end
+end
+
+gem 'rake', version
+load Gem.bin_path('rake', 'rake', version)
diff --git a/vendor/bundle/ruby/2.1.0/bin/rdoc b/vendor/bundle/ruby/2.1.0/bin/rdoc
new file mode 100755
index 0000000..0d3d314
--- /dev/null
+++ b/vendor/bundle/ruby/2.1.0/bin/rdoc
@@ -0,0 +1,23 @@
+#!/usr/bin/env ruby
+#
+# This file was generated by RubyGems.
+#
+# The application 'rdoc' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
+
+require 'rubygems'
+
+version = ">= 0"
+
+if ARGV.first
+  str = ARGV.first
+  str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
+  if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
+    version = $1
+    ARGV.shift
+  end
+end
+
+gem 'rdoc', version
+load Gem.bin_path('rdoc', 'rdoc', version)
diff --git a/vendor/bundle/ruby/2.1.0/bin/ri b/vendor/bundle/ruby/2.1.0/bin/ri
new file mode 100755
index 0000000..cf45350
--- /dev/null
+++ b/vendor/bundle/ruby/2.1.0/bin/ri
@@ -0,0 +1,23 @@
+#!/usr/bin/env ruby
+#
+# This file was generated by RubyGems.
+#
+# The application 'rdoc' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
+
+require 'rubygems'
+
+version = ">= 0"
+
+if ARGV.first
+  str = ARGV.first
+  str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
+  if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
+    version = $1
+    ARGV.shift
+  end
+end
+
+gem 'rdoc', version
+load Gem.bin_path('rdoc', 'ri', version)
diff --git a/vendor/bundle/ruby/2.1.0/bin/rspec b/vendor/bundle/ruby/2.1.0/bin/rspec
new file mode 100755
index 0000000..1df29e9
--- /dev/null
+++ b/vendor/bundle/ruby/2.1.0/bin/rspec
@@ -0,0 +1,23 @@
+#!/usr/bin/env ruby
+#
+# This file was generated by RubyGems.
+#
+# The application 'rspec-core' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
+
+require 'rubygems'
+
+version = ">= 0"
+
+if ARGV.first
+  str = ARGV.first
+  str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
+  if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
+    version = $1
+    ARGV.shift
+  end
+end
+
+gem 'rspec-core', version
+load Gem.bin_path('rspec-core', 'rspec', version)
diff --git a/vendor/bundle/ruby/2.1.0/bin/sass b/vendor/bundle/ruby/2.1.0/bin/sass
new file mode 100755
index 0000000..2ade46c
--- /dev/null
+++ b/vendor/bundle/ruby/2.1.0/bin/sass
@@ -0,0 +1,23 @@
+#!/usr/bin/env ruby
+#
+# This file was generated by RubyGems.
+#
+# The application 'sass' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
+
+require 'rubygems'
+
+version = ">= 0"
+
+if ARGV.first
+  str = ARGV.first
+  str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
+  if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
+    version = $1
+    ARGV.shift
+  end
+end
+
+gem 'sass', version
+load Gem.bin_path('sass', 'sass', version)
diff --git a/vendor/bundle/ruby/2.1.0/bin/sass-convert b/vendor/bundle/ruby/2.1.0/bin/sass-convert
new file mode 100755
index 0000000..2c1393c
--- /dev/null
+++ b/vendor/bundle/ruby/2.1.0/bin/sass-convert
@@ -0,0 +1,23 @@
+#!/usr/bin/env ruby
+#
+# This file was generated by RubyGems.
+#
+# The application 'sass' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
+
+require 'rubygems'
+
+version = ">= 0"
+
+if ARGV.first
+  str = ARGV.first
+  str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
+  if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
+    version = $1
+    ARGV.shift
+  end
+end
+
+gem 'sass', version
+load Gem.bin_path('sass', 'sass-convert', version)
diff --git a/vendor/bundle/ruby/2.1.0/bin/scss b/vendor/bundle/ruby/2.1.0/bin/scss
new file mode 100755
index 0000000..6be603a
--- /dev/null
+++ b/vendor/bundle/ruby/2.1.0/bin/scss
@@ -0,0 +1,23 @@
+#!/usr/bin/env ruby
+#
+# This file was generated by RubyGems.
+#
+# The application 'sass' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
+
+require 'rubygems'
+
+version = ">= 0"
+
+if ARGV.first
+  str = ARGV.first
+  str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
+  if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
+    version = $1
+    ARGV.shift
+  end
+end
+
+gem 'sass', version
+load Gem.bin_path('sass', 'scss', version)
diff --git a/vendor/bundle/ruby/2.1.0/bin/sdoc b/vendor/bundle/ruby/2.1.0/bin/sdoc
new file mode 100755
index 0000000..b28fa10
--- /dev/null
+++ b/vendor/bundle/ruby/2.1.0/bin/sdoc
@@ -0,0 +1,25 @@
+#!/bin/sh
+'exec' "ruby" '-x' "$0" "$@"
+#!/Users/benjamintarenne/.rvm/rubies/ruby-2.1.1/bin/ruby
+#
+# This file was generated by RubyGems.
+#
+# The application 'sdoc' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
+
+require 'rubygems'
+
+version = ">= 0"
+
+if ARGV.first
+  str = ARGV.first
+  str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
+  if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
+    version = $1
+    ARGV.shift
+  end
+end
+
+gem 'sdoc', version
+load Gem.bin_path('sdoc', 'sdoc', version)
diff --git a/vendor/bundle/ruby/2.1.0/bin/sdoc-merge b/vendor/bundle/ruby/2.1.0/bin/sdoc-merge
new file mode 100755
index 0000000..a836cc7
--- /dev/null
+++ b/vendor/bundle/ruby/2.1.0/bin/sdoc-merge
@@ -0,0 +1,25 @@
+#!/bin/sh
+'exec' "ruby" '-x' "$0" "$@"
+#!/Users/benjamintarenne/.rvm/rubies/ruby-2.1.1/bin/ruby
+#
+# This file was generated by RubyGems.
+#
+# The application 'sdoc' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
+
+require 'rubygems'
+
+version = ">= 0"
+
+if ARGV.first
+  str = ARGV.first
+  str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
+  if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
+    version = $1
+    ARGV.shift
+  end
+end
+
+gem 'sdoc', version
+load Gem.bin_path('sdoc', 'sdoc-merge', version)
diff --git a/vendor/bundle/ruby/2.1.0/bin/spring b/vendor/bundle/ruby/2.1.0/bin/spring
new file mode 100755
index 0000000..49623b8
--- /dev/null
+++ b/vendor/bundle/ruby/2.1.0/bin/spring
@@ -0,0 +1,23 @@
+#!/usr/bin/env ruby
+#
+# This file was generated by RubyGems.
+#
+# The application 'spring' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
+
+require 'rubygems'
+
+version = ">= 0"
+
+if ARGV.first
+  str = ARGV.first
+  str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
+  if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
+    version = $1
+    ARGV.shift
+  end
+end
+
+gem 'spring', version
+load Gem.bin_path('spring', 'spring', version)
diff --git a/vendor/bundle/ruby/2.1.0/bin/sprockets b/vendor/bundle/ruby/2.1.0/bin/sprockets
new file mode 100755
index 0000000..bb01742
--- /dev/null
+++ b/vendor/bundle/ruby/2.1.0/bin/sprockets
@@ -0,0 +1,23 @@
+#!/usr/bin/env ruby
+#
+# This file was generated by RubyGems.
+#
+# The application 'sprockets' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
+
+require 'rubygems'
+
+version = ">= 0"
+
+if ARGV.first
+  str = ARGV.first
+  str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
+  if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
+    version = $1
+    ARGV.shift
+  end
+end
+
+gem 'sprockets', version
+load Gem.bin_path('sprockets', 'sprockets', version)
diff --git a/vendor/bundle/ruby/2.1.0/bin/thor b/vendor/bundle/ruby/2.1.0/bin/thor
new file mode 100755
index 0000000..2533f7b
--- /dev/null
+++ b/vendor/bundle/ruby/2.1.0/bin/thor
@@ -0,0 +1,23 @@
+#!/usr/bin/env ruby
+#
+# This file was generated by RubyGems.
+#
+# The application 'thor' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
+
+require 'rubygems'
+
+version = ">= 0"
+
+if ARGV.first
+  str = ARGV.first
+  str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
+  if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
+    version = $1
+    ARGV.shift
+  end
+end
+
+gem 'thor', version
+load Gem.bin_path('thor', 'thor', version)
diff --git a/vendor/bundle/ruby/2.1.0/bin/tilt b/vendor/bundle/ruby/2.1.0/bin/tilt
new file mode 100755
index 0000000..cba5196
--- /dev/null
+++ b/vendor/bundle/ruby/2.1.0/bin/tilt
@@ -0,0 +1,23 @@
+#!/usr/bin/env ruby
+#
+# This file was generated by RubyGems.
+#
+# The application 'tilt' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
+
+require 'rubygems'
+
+version = ">= 0"
+
+if ARGV.first
+  str = ARGV.first
+  str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
+  if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
+    version = $1
+    ARGV.shift
+  end
+end
+
+gem 'tilt', version
+load Gem.bin_path('tilt', 'tilt', version)
diff --git a/vendor/bundle/ruby/2.1.0/bin/tt b/vendor/bundle/ruby/2.1.0/bin/tt
new file mode 100755
index 0000000..34efa1b
--- /dev/null
+++ b/vendor/bundle/ruby/2.1.0/bin/tt
@@ -0,0 +1,23 @@
+#!/usr/bin/env ruby
+#
+# This file was generated by RubyGems.
+#
+# The application 'treetop' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
+
+require 'rubygems'
+
+version = ">= 0"
+
+if ARGV.first
+  str = ARGV.first
+  str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
+  if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
+    version = $1
+    ARGV.shift
+  end
+end
+
+gem 'treetop', version
+load Gem.bin_path('treetop', 'tt', version)
diff --git a/vendor/bundle/ruby/2.1.0/cache/actionmailer-4.1.0.gem b/vendor/bundle/ruby/2.1.0/cache/actionmailer-4.1.0.gem
new file mode 100644
index 0000000..9e518e7
Binary files /dev/null and b/vendor/bundle/ruby/2.1.0/cache/actionmailer-4.1.0.gem differ
diff --git a/vendor/bundle/ruby/2.1.0/cache/actionpack-4.1.0.gem b/vendor/bundle/ruby/2.1.0/cache/actionpack-4.1.0.gem
new file mode 100644
index 0000000..1e70691
Binary files /dev/null and b/vendor/bundle/ruby/2.1.0/cache/actionpack-4.1.0.gem differ
diff --git a/vendor/bundle/ruby/2.1.0/cache/actionview-4.1.0.gem b/vendor/bundle/ruby/2.1.0/cache/actionview-4.1.0.gem
new file mode 100644
index 0000000..af9fb87
Binary files /dev/null and b/vendor/bundle/ruby/2.1.0/cache/actionview-4.1.0.gem differ
diff --git a/vendor/bundle/ruby/2.1.0/cache/activemodel-4.1.0.gem b/vendor/bundle/ruby/2.1.0/cache/activemodel-4.1.0.gem
new file mode 100644
index 0000000..3f961d6
Binary files /dev/null and b/vendor/bundle/ruby/2.1.0/cache/activemodel-4.1.0.gem differ
diff --git a/vendor/bundle/ruby/2.1.0/cache/activerecord-4.1.0.gem b/vendor/bundle/ruby/2.1.0/cache/activerecord-4.1.0.gem
new file mode 100644
index 0000000..c624bbb
Binary files /dev/null and b/vendor/bundle/ruby/2.1.0/cache/activerecord-4.1.0.gem differ
diff --git a/vendor/bundle/ruby/2.1.0/cache/activesupport-4.1.0.gem b/vendor/bundle/ruby/2.1.0/cache/activesupport-4.1.0.gem
new file mode 100644
index 0000000..c9b221c
Binary files /dev/null and b/vendor/bundle/ruby/2.1.0/cache/activesupport-4.1.0.gem differ
diff --git a/vendor/bundle/ruby/2.1.0/cache/arel-5.0.1.20140414130214.gem b/vendor/bundle/ruby/2.1.0/cache/arel-5.0.1.20140414130214.gem
new file mode 100644
index 0000000..5200b6f
Binary files /dev/null and b/vendor/bundle/ruby/2.1.0/cache/arel-5.0.1.20140414130214.gem differ
diff --git a/vendor/bundle/ruby/2.1.0/cache/builder-3.2.2.gem b/vendor/bundle/ruby/2.1.0/cache/builder-3.2.2.gem
new file mode 100644
index 0000000..b59ef92
Binary files /dev/null and b/vendor/bundle/ruby/2.1.0/cache/builder-3.2.2.gem differ
diff --git a/vendor/bundle/ruby/2.1.0/cache/coffee-rails-4.1.0.gem b/vendor/bundle/ruby/2.1.0/cache/coffee-rails-4.1.0.gem
new file mode 100644
index 0000000..7477588
Binary files /dev/null and b/vendor/bundle/ruby/2.1.0/cache/coffee-rails-4.1.0.gem differ
diff --git a/vendor/bundle/ruby/2.1.0/cache/coffee-script-2.4.1.gem b/vendor/bundle/ruby/2.1.0/cache/coffee-script-2.4.1.gem
new file mode 100644
index 0000000..7e4066d
Binary files /dev/null and b/vendor/bundle/ruby/2.1.0/cache/coffee-script-2.4.1.gem differ
diff --git a/vendor/bundle/ruby/2.1.0/cache/coffee-script-source-1.9.1.1.gem b/vendor/bundle/ruby/2.1.0/cache/coffee-script-source-1.9.1.1.gem
new file mode 100644
index 0000000..5c27695
Binary files /dev/null and b/vendor/bundle/ruby/2.1.0/cache/coffee-script-source-1.9.1.1.gem differ
diff --git a/vendor/bundle/ruby/2.1.0/cache/diff-lcs-1.2.5.gem b/vendor/bundle/ruby/2.1.0/cache/diff-lcs-1.2.5.gem
new file mode 100644
index 0000000..e4436cc
Binary files /dev/null and b/vendor/bundle/ruby/2.1.0/cache/diff-lcs-1.2.5.gem diffe…
a53f3de

mislav referenced this pull request in madrobby/zepto Jul 13, 2016

Merged

Enable AMD-compatible module output #1200

@n6g7 n6g7 added a commit to n6g7/chapter that referenced this pull request Aug 6, 2016

@n6g7 n6g7 Chapter v0.0.9.
diff --git a/bundle.js b/bundle.js
index 8082ea3..e2686ae 100644
--- a/bundle.js
+++ b/bundle.js
@@ -76,23 +76,23 @@

 	var _Library2 = _interopRequireDefault(_Library);

-	var _NewBook = __webpack_require__(451);
+	var _NewBook = __webpack_require__(442);

 	var _NewBook2 = _interopRequireDefault(_NewBook);

-	var _EditBook = __webpack_require__(457);
+	var _EditBook = __webpack_require__(459);

 	var _EditBook2 = _interopRequireDefault(_EditBook);

-	var _ImportExport = __webpack_require__(459);
+	var _ImportExport = __webpack_require__(461);

 	var _ImportExport2 = _interopRequireDefault(_ImportExport);

-	var _reducer = __webpack_require__(467);
+	var _reducer = __webpack_require__(469);

 	var _reducer2 = _interopRequireDefault(_reducer);

-	__webpack_require__(468);
+	__webpack_require__(470);

 	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

@@ -32571,10 +32571,10 @@
 	  value: true
 	});
 	exports.INITIAL_STATE = undefined;
-	exports.setState = setState;
 	exports.addBook = addBook;
 	exports.updateBook = updateBook;
 	exports.removeBook = removeBook;
+	exports.importState = importState;

 	var _immutable = __webpack_require__(254);

@@ -32590,10 +32590,6 @@
 	  }
 	});

-	function setState(state, newState) {
-	  return state.merge(newState);
-	}
-
 	function addBook(state, book) {
 	  if (!book.has('uuid')) {
 	    book = book.set('uuid', _uuid2.default.v4());
@@ -32633,6 +32629,24 @@
 	  });
 	}

+	function importState(state, imported) {
+	  var importedState = (0, _immutable.fromJS)(imported);
+
+	  if (importedState.has('books')) {
+	    importedState = (0, _immutable.Map)({
+	      library: importedState
+	    });
+	  }
+
+	  return importedState.updateIn(['library', 'books'], function (books) {
+	    return books.map(function (book) {
+	      return book.merge({
+	        uuid: _uuid2.default.v4()
+	      });
+	    });
+	  });
+	}
+
 /***/ },
 /* 256 */
 /***/ function(module, exports, __webpack_require__) {
@@ -33071,7 +33085,7 @@

 	module.exports = {
 		"name": "chapter",
-		"version": "0.0.8",
+		"version": "0.0.9",
 		"description": "Digital library for physical books",
 		"main": "index.js",
 		"scripts": {
@@ -33097,6 +33111,7 @@
 			"react-dnd": "^2.1.4",
 			"react-dnd-html5-backend": "^2.1.2",
 			"react-dom": "^15.1.0",
+			"react-input-mask": "^0.7.0",
 			"react-redux": "^4.4.5",
 			"react-router": "^2.4.1",
 			"redux": "^3.5.2",
@@ -33109,6 +33124,7 @@
 			"babel-loader": "^6.2.4",
 			"babel-preset-es2015": "^6.6.0",
 			"babel-preset-react": "^6.5.0",
+			"babel-preset-stage-1": "^6.5.0",
 			"chai": "^3.5.0",
 			"chai-immutable": "astorije/chai-immutable",
 			"css-loader": "^0.23.1",
@@ -33127,6 +33143,7 @@
 		"babel": {
 			"presets": [
 				"es2015",
+				"stage-1",
 				"react"
 			]
 		},
@@ -33145,6 +33162,7 @@
 			},
 			"parserOptions": {
 				"ecmaFeatures": {
+					"experimentalObjectRestSpread": true,
 					"jsx": true
 				},
 				"ecmaVersion": 6,
@@ -33165,17 +33183,10 @@
 	Object.defineProperty(exports, "__esModule", {
 	  value: true
 	});
-	exports.setState = setState;
 	exports.addBook = addBook;
 	exports.updateBook = updateBook;
 	exports.removeBook = removeBook;
-	function setState(state) {
-	  return {
-	    type: 'SET_STATE',
-	    state: state
-	  };
-	}
-
+	exports.importState = importState;
 	function addBook(book) {
 	  return {
 	    type: 'ADD_BOOK',
@@ -33197,6 +33208,13 @@
 	  };
 	}

+	function importState(importedState) {
+	  return {
+	    type: 'IMPORT_STATE',
+	    importedState: importedState
+	  };
+	}
+
 /***/ },
 /* 266 */
 /***/ function(module, exports, __webpack_require__) {
@@ -33265,15 +33283,15 @@

 	var _Button2 = _interopRequireDefault(_Button);

-	var _Header = __webpack_require__(446);
+	var _Header = __webpack_require__(437);

 	var _Header2 = _interopRequireDefault(_Header);

-	var _bookStates = __webpack_require__(448);
+	var _bookStates = __webpack_require__(439);

 	var _bookStates2 = _interopRequireDefault(_bookStates);

-	__webpack_require__(449);
+	__webpack_require__(440);

 	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

@@ -40857,7 +40875,7 @@

 	var _BookList2 = _interopRequireDefault(_BookList);

-	var _dragDropTypes = __webpack_require__(445);
+	var _dragDropTypes = __webpack_require__(436);

 	var _dragDropTypes2 = _interopRequireDefault(_dragDropTypes);

@@ -41342,7 +41360,7 @@
 	      this.props.books.map(function (book) {
 	        return _react2.default.createElement(
 	          'li',
-	          { key: book.get('ISBN'), onClick: function onClick() {
+	          { key: book.get('uuid'), onClick: function onClick() {
 	              return _this.goTo(book);
 	            } },
 	          _react2.default.createElement(_DraggableCover2.default, { book: book })
@@ -41378,7 +41396,7 @@

 	var _Cover2 = _interopRequireDefault(_Cover);

-	var _dragDropTypes = __webpack_require__(445);
+	var _dragDropTypes = __webpack_require__(436);

 	var _dragDropTypes2 = _interopRequireDefault(_dragDropTypes);

@@ -41439,17 +41457,11 @@

 	var _immutable = __webpack_require__(254);

-	var _get = __webpack_require__(429);
-
-	var _get2 = _interopRequireDefault(_get);
-
-	var _Loader = __webpack_require__(435);
+	var _Loader = __webpack_require__(429);

 	var _Loader2 = _interopRequireDefault(_Loader);

-	var _apis = __webpack_require__(440);
-
-	__webpack_require__(443);
+	__webpack_require__(434);

 	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

@@ -41457,37 +41469,24 @@
 	  displayName: 'Cover',
 	  mixins: [_reactAddonsPureRenderMixin2.default],
 	  propTypes: {
-	    book: _react2.default.PropTypes.instanceOf(_immutable.Map)
-	  },
-	  fetchBookData: function fetchBookData(book) {
-	    var _this = this;
-
-	    (0, _apis.getBookData)(book).then(function (data) {
-	      _this.setState({ loaded: true, data: data });
-
-	      var imageUrl = (0, _get2.default)(_this.state.data, 'imageLinks.thumbnail');
-	      if (imageUrl) {
-	        (0, _apis.getMainColour)(imageUrl).then(function (colour) {
-	          return _this.setState({ colour: colour });
-	        });
-	      }
-	    });
+	    book: _react2.default.PropTypes.instanceOf(_immutable.Map).isRequired,
+	    loading: _react2.default.PropTypes.bool
 	  },
 	  getImage: function getImage() {
-	    if (!this.state || !this.state.loaded) return _react2.default.createElement(_Loader2.default, null);
+	    var _props = this.props;
+	    var book = _props.book;
+	    var loading = _props.loading;

-	    var url = (0, _get2.default)(this.state.data, 'imageLinks.thumbnail', '');
-	    return _react2.default.createElement('img', { src: url, alt: this.props.book.get('title') });
-	  },
-	  componentDidMount: function componentDidMount() {
-	    this.fetchBookData(this.props.book);
-	  },
-	  componentWillReceiveProps: function componentWillReceiveProps(props) {
-	    this.fetchBookData(props.book);
+	    var url = book.getIn(['extra', 'coverUrl']);
+
+	    return loading ? _react2.default.createElement(_Loader2.default, null) : _react2.default.createElement('img', { src: url, alt: book.get('title') });
 	  },
 	  render: function render() {
-	    var book = this.props.book;
-	    var colour = (0, _get2.default)(this.state, 'colour');
+	    var _props2 = this.props;
+	    var book = _props2.book;
+	    var loading = _props2.loading;
+
+	    var colour = !loading ? book.getIn(['extra', 'coverColour']) : null;

 	    return _react2.default.createElement(
 	      'div',
@@ -41518,190 +41517,6 @@
 /* 429 */
 /***/ function(module, exports, __webpack_require__) {

-	var baseGet = __webpack_require__(430);
-
-	/**
-	 * Gets the value at `path` of `object`. If the resolved value is
-	 * `undefined`, the `defaultValue` is used in its place.
-	 *
-	 * @static
-	 * @memberOf _
-	 * @since 3.7.0
-	 * @category Object
-	 * @param {Object} object The object to query.
-	 * @param {Array|string} path The path of the property to get.
-	 * @param {*} [defaultValue] The value returned for `undefined` resolved values.
-	 * @returns {*} Returns the resolved value.
-	 * @example
-	 *
-	 * var object = { 'a': [{ 'b': { 'c': 3 } }] };
-	 *
-	 * _.get(object, 'a[0].b.c');
-	 * // => 3
-	 *
-	 * _.get(object, ['a', '0', 'b', 'c']);
-	 * // => 3
-	 *
-	 * _.get(object, 'a.b.c', 'default');
-	 * // => 'default'
-	 */
-	function get(object, path, defaultValue) {
-	  var result = object == null ? undefined : baseGet(object, path);
-	  return result === undefined ? defaultValue : result;
-	}
-
-	module.exports = get;
-
-
-/***/ },
-/* 430 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var castPath = __webpack_require__(431),
-	    isKey = __webpack_require__(433),
-	    toKey = __webpack_require__(434);
-
-	/**
-	 * The base implementation of `_.get` without support for default values.
-	 *
-	 * @private
-	 * @param {Object} object The object to query.
-	 * @param {Array|string} path The path of the property to get.
-	 * @returns {*} Returns the resolved value.
-	 */
-	function baseGet(object, path) {
-	  path = isKey(path, object) ? [path] : castPath(path);
-
-	  var index = 0,
-	      length = path.length;
-
-	  while (object != null && index < length) {
-	    object = object[toKey(path[index++])];
-	  }
-	  return (index && index == length) ? object : undefined;
-	}
-
-	module.exports = baseGet;
-
-
-/***/ },
-/* 431 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var isArray = __webpack_require__(276),
-	    stringToPath = __webpack_require__(432);
-
-	/**
-	 * Casts `value` to a path array if it's not one.
-	 *
-	 * @private
-	 * @param {*} value The value to inspect.
-	 * @returns {Array} Returns the cast property path array.
-	 */
-	function castPath(value) {
-	  return isArray(value) ? value : stringToPath(value);
-	}
-
-	module.exports = castPath;
-
-
-/***/ },
-/* 432 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var memoize = __webpack_require__(408),
-	    toString = __webpack_require__(416);
-
-	/** Used to match property names within property paths. */
-	var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(\.|\[\])(?:\4|$))/g;
-
-	/** Used to match backslashes in property paths. */
-	var reEscapeChar = /\\(\\)?/g;
-
-	/**
-	 * Converts `string` to a property path array.
-	 *
-	 * @private
-	 * @param {string} string The string to convert.
-	 * @returns {Array} Returns the property path array.
-	 */
-	var stringToPath = memoize(function(string) {
-	  var result = [];
-	  toString(string).replace(rePropName, function(match, number, quote, string) {
-	    result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
-	  });
-	  return result;
-	});
-
-	module.exports = stringToPath;
-
-
-/***/ },
-/* 433 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var isArray = __webpack_require__(276),
-	    isSymbol = __webpack_require__(335);
-
-	/** Used to match property names within property paths. */
-	var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
-	    reIsPlainProp = /^\w*$/;
-
-	/**
-	 * Checks if `value` is a property name and not a property path.
-	 *
-	 * @private
-	 * @param {*} value The value to check.
-	 * @param {Object} [object] The object to query keys on.
-	 * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
-	 */
-	function isKey(value, object) {
-	  if (isArray(value)) {
-	    return false;
-	  }
-	  var type = typeof value;
-	  if (type == 'number' || type == 'symbol' || type == 'boolean' ||
-	      value == null || isSymbol(value)) {
-	    return true;
-	  }
-	  return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
-	    (object != null && value in Object(object));
-	}
-
-	module.exports = isKey;
-
-
-/***/ },
-/* 434 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var isSymbol = __webpack_require__(335);
-
-	/** Used as references for various `Number` constants. */
-	var INFINITY = 1 / 0;
-
-	/**
-	 * Converts `value` to a string key if it's not a string or symbol.
-	 *
-	 * @private
-	 * @param {*} value The value to inspect.
-	 * @returns {string|symbol} Returns the key.
-	 */
-	function toKey(value) {
-	  if (typeof value == 'string' || isSymbol(value)) {
-	    return value;
-	  }
-	  var result = (value + '');
-	  return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
-	}
-
-	module.exports = toKey;
-
-
-/***/ },
-/* 435 */
-/***/ function(module, exports, __webpack_require__) {
-
 	'use strict';

 	Object.defineProperty(exports, "__esModule", {
@@ -41716,7 +41531,7 @@

 	var _reactAddonsPureRenderMixin2 = _interopRequireDefault(_reactAddonsPureRenderMixin);

-	__webpack_require__(436);
+	__webpack_require__(430);

 	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

@@ -41733,16 +41548,16 @@
 	});

 /***/ },
-/* 436 */
+/* 430 */
 /***/ function(module, exports, __webpack_require__) {

 	// style-loader: Adds some css to the DOM by adding a <style> tag

 	// load the styles
-	var content = __webpack_require__(437);
+	var content = __webpack_require__(431);
 	if(typeof content === 'string') content = [[module.id, content, '']];
 	// add the styles to the DOM
-	var update = __webpack_require__(439)(content, {});
+	var update = __webpack_require__(433)(content, {});
 	if(content.locals) module.exports = content.locals;
 	// Hot Module Replacement
 	if(false) {
@@ -41759,10 +41574,10 @@
 	}

 /***/ },
-/* 437 */
+/* 431 */
 /***/ function(module, exports, __webpack_require__) {

-	exports = module.exports = __webpack_require__(438)();
+	exports = module.exports = __webpack_require__(432)();
 	// imports

@@ -41773,7 +41588,7 @@

 /***/ },
-/* 438 */
+/* 432 */
 /***/ function(module, exports) {

 	/*
@@ -41829,7 +41644,7 @@

 /***/ },
-/* 439 */
+/* 433 */
 /***/ function(module, exports, __webpack_require__) {

 	/*
@@ -42081,189 +41896,895 @@

 /***/ },
-/* 440 */
+/* 434 */
 /***/ function(module, exports, __webpack_require__) {

-	'use strict';
+	// style-loader: Adds some css to the DOM by adding a <style> tag

-	Object.defineProperty(exports, "__esModule", {
-	  value: true
-	});
-	exports.getBookData = getBookData;
-	exports.getMainColour = getMainColour;
+	// load the styles
+	var content = __webpack_require__(435);
+	if(typeof content === 'string') content = [[module.id, content, '']];
+	// add the styles to the DOM
+	var update = __webpack_require__(433)(content, {});
+	if(content.locals) module.exports = content.locals;
+	// Hot Module Replacement
+	if(false) {
+		// When the styles change, update the <style> tags
+		if(!content.locals) {
+			module.hot.accept("!!./../../../node_modules/css-loader/index.js!./../../../node_modules/stylus-loader/index.js!./cover.styl", function() {
+				var newContent = require("!!./../../../node_modules/css-loader/index.js!./../../../node_modules/stylus-loader/index.js!./cover.styl");
+				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
+				update(newContent);
+			});
+		}
+		// When the module is disposed, remove the <style> tags
+		module.hot.dispose(function() { update(); });
+	}

-	var _jquery = __webpack_require__(441);
+/***/ },
+/* 435 */
+/***/ function(module, exports, __webpack_require__) {

-	var _jquery2 = _interopRequireDefault(_jquery);
+	exports = module.exports = __webpack_require__(432)();
+	// imports

-	var _keys = __webpack_require__(442);

-	var _keys2 = _interopRequireDefault(_keys);
+	// module
+	exports.push([module.id, ".cover {\n  background: rgba(0,0,0,0.1);\n  height: 280px;\n  position: relative;\n  width: 180px;\n}\n.cover img {\n  display: block;\n  height: 200px;\n  left: 20px;\n  object-fit: contain;\n  position: absolute;\n  top: 20px;\n  width: 140px;\n}\n.cover .description {\n  background: linear-gradient(to top, #35495d 0%, #35495d 40%, transparent 100%);\n  bottom: 0;\n  display: flex;\n  flex-flow: column nowrap;\n  height: 160px;\n  justify-content: flex-end;\n  padding: 0 10px 10px;\n  position: absolute;\n  width: 100%;\n}\n.cover .description h3 {\n  font-size: 1.6rem;\n  margin-bottom: 5px;\n}\n.cover .description p {\n  font-size: 1rem;\n  margin: 0;\n  opacity: 0.7;\n}\n", ""]);

-	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+	// exports

-	var GOOGLE_API = 'https://www.googleapis.com/books/v1/volumes';
-	var TINT_API = '//tint.gnab.fr';

-	function getBookData(book) {
-	  var isbn = book.get('ISBN');
+/***/ },
+/* 436 */
+/***/ function(module, exports) {

-	  // An ISBN is either 10 or 13 chars long
-	  if (!isbn || isbn.length != 10 && isbn.length != 13) return Promise.resolve(null);
+	'use strict';

-	  return new Promise(function (resolve, reject) {
-	    _jquery2.default.ajax({
-	      url: GOOGLE_API,
-	      data: {
-	        q: 'isbn:' + isbn,
-	        key: _keys2.default.google
-	      },
-	      success: function success(data) {
-	        resolve(data.totalItems === 0 ? null : data.items[0].volumeInfo);
-	      },
-	      error: function error(err) {
-	        return reject(err);
-	      }
-	    });
-	  });
-	}
+	Object.defineProperty(exports, "__esModule", {
+	  value: true
+	});
+	var ItemTypes = {
+	  BOOK: 'book'
+	};

-	function getMainColour(imageUrl) {
-	  return new Promise(function (resolve, reject) {
-	    _jquery2.default.ajax({
-	      url: TINT_API + '/' + imageUrl,
-	      success: function success(data) {
-	        return resolve(data.colour);
-	      },
-	      error: reject
-	    });
-	  });
-	}
+	exports.default = ItemTypes;

 /***/ },
-/* 441 */
+/* 437 */
 /***/ function(module, exports, __webpack_require__) {

-	var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
-	 * jQuery JavaScript Library v3.0.0
-	 * https://jquery.com/
-	 *
-	 * Includes Sizzle.js
-	 * https://sizzlejs.com/
-	 *
-	 * Copyright jQuery Foundation and other contributors
-	 * Released under the MIT license
-	 * https://jquery.org/license
-	 *
-	 * Date: 2016-06-09T18:02Z
-	 */
-	( function( global, factory ) {
+	'use strict';

-		"use strict";
+	Object.defineProperty(exports, "__esModule", {
+	  value: true
+	});

-		if ( typeof module === "object" && typeof module.exports === "object" ) {
+	var _react = __webpack_require__(1);

-			// For CommonJS and CommonJS-like environments where a proper `window`
-			// is present, execute the factory and get jQuery.
-			// For environments that do not have a `window` with a `document`
-			// (such as Node.js), expose a factory as module.exports.
-			// This accentuates the need for the creation of a real `window`.
-			// e.g. var jQuery = require("jquery")(window);
-			// See ticket #14549 for more info.
-			module.exports = global.document ?
-				factory( global, true ) :
-				function( w ) {
-					if ( !w.document ) {
-						throw new Error( "jQuery requires a window with a document" );
-					}
-					return factory( w );
-				};
-		} else {
-			factory( global );
-		}
+	var _react2 = _interopRequireDefault(_react);

-	// Pass this if window is not defined yet
-	}( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
+	var _reactAddonsPureRenderMixin = __webpack_require__(261);

-	// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
-	// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
-	// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
-	// enough that all such attempts are guarded in a try block.
-	"use strict";
+	var _reactAddonsPureRenderMixin2 = _interopRequireDefault(_reactAddonsPureRenderMixin);

-	var arr = [];
+	var _ActionBar = __webpack_require__(438);

-	var document = window.document;
+	var _ActionBar2 = _interopRequireDefault(_ActionBar);

-	var getProto = Object.getPrototypeOf;
+	var _Button = __webpack_require__(425);

-	var slice = arr.slice;
+	var _Button2 = _interopRequireDefault(_Button);

-	var concat = arr.concat;
+	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

-	var push = arr.push;
+	var DEFAULT_TITLE = 'Chapter';

-	var indexOf = arr.indexOf;
+	exports.default = _react2.default.createClass({
+	  displayName: 'Header',
+	  mixins: [_reactAddonsPureRenderMixin2.default],
+	  propTypes: {
+	    title: _react2.default.PropTypes.string,
+	    backButton: _react2.default.PropTypes.bool,
+	    children: _react2.default.PropTypes.oneOfType([_react2.default.PropTypes.element, _react2.default.PropTypes.arrayOf(_react2.default.PropTypes.element)])
+	  },
+	  contextTypes: {
+	    router: _react2.default.PropTypes.object
+	  },
+	  goBack: function goBack() {
+	    this.context.router.goBack();
+	  },
+	  render: function render() {
+	    var title = this.props.title || DEFAULT_TITLE;
+	    var addPreTitle = title !== DEFAULT_TITLE;

-	var class2type = {};
+	    return _react2.default.createElement(
+	      'header',
+	      null,
+	      this.props.backButton && _react2.default.createElement(_Button2.default, { click: this.goBack, label: '<', className: 'back' }),
+	      addPreTitle && _react2.default.createElement(
+	        'p',
+	        null,
+	        DEFAULT_TITLE
+	      ),
+	      _react2.default.createElement(
+	        'h1',
+	        null,
+	        title
+	      ),
+	      _react2.default.createElement(
+	        _ActionBar2.default,
+	        null,
+	        this.props.children
+	      )
+	    );
+	  }
+	});

-	var toString = class2type.toString;
+/***/ },
+/* 438 */
+/***/ function(module, exports, __webpack_require__) {

-	var hasOwn = class2type.hasOwnProperty;
+	'use strict';

-	var fnToString = hasOwn.toString;
+	Object.defineProperty(exports, "__esModule", {
+	  value: true
+	});

-	var ObjectFunctionString = fnToString.call( Object );
+	var _react = __webpack_require__(1);

-	var support = {};
+	var _react2 = _interopRequireDefault(_react);

+	var _reactAddonsPureRenderMixin = __webpack_require__(261);

+	var _reactAddonsPureRenderMixin2 = _interopRequireDefault(_reactAddonsPureRenderMixin);

-		function DOMEval( code, doc ) {
-			doc = doc || document;
+	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

-			var script = doc.createElement( "script" );
+	exports.default = _react2.default.createClass({
+	  displayName: 'ActionBar',
+	  mixins: [_reactAddonsPureRenderMixin2.default],
+	  propTypes: {
+	    children: _react2.default.PropTypes.oneOfType([_react2.default.PropTypes.element, _react2.default.PropTypes.arrayOf(_react2.default.PropTypes.element)])
+	  },
+	  render: function render() {
+	    return _react2.default.createElement(
+	      'nav',
+	      null,
+	      this.props.children
+	    );
+	  }
+	});

-			script.text = code;
-			doc.head.appendChild( script ).parentNode.removeChild( script );
-		}
+/***/ },
+/* 439 */
+/***/ function(module, exports) {

+	'use strict';

-	var
-		version = "3.0.0",
+	Object.defineProperty(exports, "__esModule", {
+	  value: true
+	});
+	exports.default = {
+	  stock: 'stock',
+	  reading: 'reading',
+	  read: 'read'
+	};

-		// Define a local copy of jQuery
-		jQuery = function( selector, context ) {
+/***/ },
+/* 440 */
+/***/ function(module, exports, __webpack_require__) {

-			// The jQuery object is actually just the init constructor 'enhanced'
-			// Need init if jQuery is called (just allow error to be thrown if not included)
-			return new jQuery.fn.init( selector, context );
-		},
+	// style-loader: Adds some css to the DOM by adding a <style> tag

-		// Support: Android <=4.0 only
-		// Make sure we trim BOM and NBSP
-		rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
+	// load the styles
+	var content = __webpack_require__(441);
+	if(typeof content === 'string') content = [[module.id, content, '']];
+	// add the styles to the DOM
+	var update = __webpack_require__(433)(content, {});
+	if(content.locals) module.exports = content.locals;
+	// Hot Module Replacement
+	if(false) {
+		// When the styles change, update the <style> tags
+		if(!content.locals) {
+			module.hot.accept("!!./../../../node_modules/css-loader/index.js!./../../../node_modules/stylus-loader/index.js!./library.styl", function() {
+				var newContent = require("!!./../../../node_modules/css-loader/index.js!./../../../node_modules/stylus-loader/index.js!./library.styl");
+				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
+				update(newContent);
+			});
+		}
+		// When the module is disposed, remove the <style> tags
+		module.hot.dispose(function() { update(); });
+	}

-		// Matches dashed string for camelizing
-		rmsPrefix = /^-ms-/,
-		rdashAlpha = /-([a-z])/g,
+/***/ },
+/* 441 */
+/***/ function(module, exports, __webpack_require__) {

-		// Used by jQuery.camelCase as callback to replace()
-		fcamelCase = function( all, letter ) {
-			return letter.toUpperCase();
-		};
+	exports = module.exports = __webpack_require__(432)();
+	// imports

-	jQuery.fn = jQuery.prototype = {

-		// The current version of jQuery being used
-		jquery: version,
+	// module
+	exports.push([module.id, ".collections {\n  display: flex;\n  flex-flow: row wrap;\n  justify-content: space-between;\n}\n.collections section {\n  height: 320px;\n  max-width: 100%;\n  overflow-y: auto;\n}\n.collections section ul {\n  display: flex;\n  flex-flow: row nowrap;\n  justify-content: flex-start;\n  list-style: none;\n  margin: 0;\n  padding: 0;\n}\n.collections section ul li {\n  margin-right: 20px;\n}\n.collections section ul li:last-child {\n  margin: 0;\n}\n.collections section .announce {\n  color: rgba(255,255,255,0.9);\n  font-size: 1.8rem;\n  left: 50%;\n  margin: 0;\n  position: absolute;\n  top: 50%;\n  transform: translate(-50%, -50%);\n}\n.collections section .announce .button {\n  box-shadow: 0 1px 2px rgba(0,0,0,0.5);\n  height: 30px;\n  line-height: 30px;\n  margin: 0 5px;\n}\n.collections section.stock {\n  background: #ecf0f1;\n  padding: 20px 60px 20px 80px;\n  position: relative;\n  flex-basis: 100%;\n}\n.collections section.stock h2,\n.collections section.stock::before {\n  background: #bdc3c7;\n  bottom: 0;\n  color: transparent;\n  content: '';\n  font-size: 1.8rem;\n  height: 20px;\n  line-height: 20px;\n  position: absolute;\n  right: 100%;\n  text-align: center;\n  top: 0;\n  transition: 0.5s;\n  transform: rotate(-90deg);\n  transform-origin: top right;\n  width: 320px;\n}\n.collections section.stock:hover h2,\n.collections section.stock.hover h2 {\n  color: rgba(255,255,255,0.8);\n  height: 40px;\n  line-height: 40px;\n}\n.collections section.stock .announce {\n  color: rgba(0,0,0,0.6);\n}\n.collections section.reading {\n  background: #f0c330;\n  padding: 20px 60px 20px 80px;\n  position: relative;\n  flex-basis: auto;\n  transition: 0.5s;\n}\n.collections section.reading h2,\n.collections section.reading::before {\n  background: #f19b2c;\n  bottom: 0;\n  color: transparent;\n  content: '';\n  font-size: 1.8rem;\n  height: 20px;\n  line-height: 20px;\n  position: absolute;\n  right: 100%;\n  text-align: center;\n  top: 0;\n  transition: 0.5s;\n  transform: rotate(-90deg);\n  transform-origin: top right;\n  width: 320px;\n}\n.collections section.reading:hover h2,\n.collections section.reading.hover h2 {\n  color: rgba(255,255,255,0.8);\n  height: 40px;\n  line-height: 40px;\n}\n.collections section.reading.hide {\n  min-width: 0;\n  padding: 0;\n}\n.collections section.reading.hover {\n  min-width: 320px;\n}\n.collections section.read {\n  background: #2fd1af;\n  padding: 20px 60px 20px 80px;\n  position: relative;\n  flex-basis: 50%;\n  flex-grow: 1;\n}\n.collections section.read h2,\n.collections section.read::before {\n  background: #239f85;\n  bottom: 0;\n  color: transparent;\n  content: '';\n  font-size: 1.8rem;\n  height: 20px;\n  line-height: 20px;\n  position: absolute;\n  right: 100%;\n  text-align: center;\n  top: 0;\n  transition: 0.5s;\n  transform: rotate(-90deg);\n  transform-origin: top right;\n  width: 320px;\n}\n.collections section.read:hover h2,\n.collections section.read.hover h2 {\n  color: rgba(255,255,255,0.8);\n  height: 40px;\n  line-height: 40px;\n}\n", ""]);

-		constructor: jQuery,
+	// exports

-		// The default length of a jQuery object is 0
-		length: 0,

-		toArray: function() {
+/***/ },
+/* 442 */
+/***/ function(module, exports, __webpack_require__) {
+
+	'use strict';
+
+	Object.defineProperty(exports, "__esModule", {
+	  value: true
+	});
+
+	var _reactRedux = __webpack_require__(181);
+
+	var _NewBook = __webpack_require__(443);
+
+	var _NewBook2 = _interopRequireDefault(_NewBook);
+
+	var _actionCreators = __webpack_require__(265);
+
+	var actionCreators = _interopRequireWildcard(_actionCreators);
+
+	function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
+
+	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+	var mapStateToProps = function mapStateToProps() {
+	  return {};
+	};
+
+	var NewBookContainer = (0, _reactRedux.connect)(mapStateToProps, actionCreators)(_NewBook2.default);
+
+	exports.default = NewBookContainer;
+
+/***/ },
+/* 443 */
+/***/ function(module, exports, __webpack_require__) {
+
+	'use strict';
+
+	Object.defineProperty(exports, "__esModule", {
+	  value: true
+	});
+
+	var _react = __webpack_require__(1);
+
+	var _react2 = _interopRequireDefault(_react);
+
+	var _reactAddonsPureRenderMixin = __webpack_require__(261);
+
+	var _reactAddonsPureRenderMixin2 = _interopRequireDefault(_reactAddonsPureRenderMixin);
+
+	var _BookForm = __webpack_require__(444);
+
+	var _BookForm2 = _interopRequireDefault(_BookForm);
+
+	var _Button = __webpack_require__(425);
+
+	var _Button2 = _interopRequireDefault(_Button);
+
+	var _Header = __webpack_require__(437);
+
+	var _Header2 = _interopRequireDefault(_Header);
+
+	var _book = __webpack_require__(456);
+
+	__webpack_require__(457);
+
+	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+	exports.default = _react2.default.createClass({
+	  displayName: 'NewBook',
+	  mixins: [_reactAddonsPureRenderMixin2.default],
+	  propTypes: {
+	    addBook: _react2.default.PropTypes.func
+	  },
+	  contextTypes: {
+	    router: _react2.default.PropTypes.object
+	  },
+	  update: function update(book) {
+	    this.setState({ book: book });
+	  },
+	  save: function save(book) {
+	    this.props.addBook(book);
+	    this.context.router.push('/');
+	  },
+	  render: function render() {
+	    var _this = this;
+
+	    return _react2.default.createElement(
+	      'div',
+	      null,
+	      _react2.default.createElement(
+	        _Header2.default,
+	        { title: 'Add a book', backButton: true },
+	        _react2.default.createElement(_Button2.default, { click: function click() {
+	            return _this.save(_this.state.book);
+	          }, label: 'Save book' })
+	      ),
+	      _react2.default.createElement(
+	        'section',
+	        { className: 'form' },
+	        _react2.default.createElement(_BookForm2.default, {
+	          book: _book.newBook,
+	          onSubmit: this.save,
+	          onChange: this.update
+	        })
+	      )
+	    );
+	  }
+	});
+
+/***/ },
+/* 444 */
+/***/ function(module, exports, __webpack_require__) {
+
+	'use strict';
+
+	Object.defineProperty(exports, "__esModule", {
+	  value: true
+	});
+
+	var _react = __webpack_require__(1);
+
+	var _react2 = _interopRequireDefault(_react);
+
+	var _reactAddonsPureRenderMixin = __webpack_require__(261);
+
+	var _reactAddonsPureRenderMixin2 = _interopRequireDefault(_reactAddonsPureRenderMixin);
+
+	var _immutable = __webpack_require__(254);
+
+	var _get = __webpack_require__(445);
+
+	var _get2 = _interopRequireDefault(_get);
+
+	var _Cover = __webpack_require__(428);
+
+	var _Cover2 = _interopRequireDefault(_Cover);
+
+	var _bookStates = __webpack_require__(439);
+
+	var _bookStates2 = _interopRequireDefault(_bookStates);
+
+	var _apis = __webpack_require__(451);
+
+	var _ISBNInput = __webpack_require__(454);
+
+	var _ISBNInput2 = _interopRequireDefault(_ISBNInput);
+
+	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+	function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
+
+	exports.default = _react2.default.createClass({
+	  displayName: 'BookForm',
+	  mixins: [_reactAddonsPureRenderMixin2.default],
+	  propTypes: {
+	    onChange: _react2.default.PropTypes.func,
+	    book: _react2.default.PropTypes.instanceOf(_immutable.Map)
+	  },
+	  getInitialState: function getInitialState() {
+	    return {
+	      loading: false
+	    };
+	  },
+	  fetchBookData: function fetchBookData(book) {
+	    var _this = this;
+
+	    this.setState({ loading: true });
+
+	    return (0, _apis.getBookData)(book).then(function (data) {
+	      var coverUrl = (0, _get2.default)(data, 'imageLinks.thumbnail');
+
+	      if (coverUrl) {
+	        return (0, _apis.getMainColour)(coverUrl).then(function (colour) {
+	          _this.setState({ loading: false });
+
+	          return book.merge({
+	            extra: {
+	              coverUrl: coverUrl,
+	              coverColour: colour
+	            }
+	          });
+	        });
+	      } else {
+	        _this.setState({ loading: false });
+	        return book.delete('extra');
+	      }
+	    });
+	  },
+	  handleChange: function handleChange(e) {
+	    var book = this.props.book.merge((0, _immutable.Map)(_defineProperty({}, e.target.id, e.target.value)));
+
+	    if (e.target.id === 'ISBN') {
+	      this.fetchBookData(book).then(this.props.onChange);
+	    } else this.props.onChange(book);
+	  },
+	  render: function render() {
+	    var book = this.props.book;
+	    var loading = this.state.loading;
+
+
+	    return _react2.default.createElement(
+	      'div',
+	      { className: 'bookForm' },
+	      _react2.default.createElement(_Cover2.default, { book: book, loading: loading }),
+	      _react2.default.createElement(
+	        'form',
+	        null,
+	        _react2.default.createElement(
+	          'div',
+	          { className: 'item half' },
+	          _react2.default.createElement(
+	            'label',
+	            { htmlFor: 'isbn' },
+	            'ISBN'
+	          ),
+	          _react2.default.createElement(_ISBNInput2.default, {
+	            id: 'ISBN',
+	            value: book.get('ISBN'),
+	            onChange: this.handleChange
+	          })
+	        ),
+	        _react2.default.createElement(
+	          'div',
+	          { className: 'item half' },
+	          _react2.default.createElement(
+	            'label',
+	            { htmlFor: 'state' },
+	            'Status'
+	          ),
+	          _react2.default.createElement(
+	            'select',
+	            {
+	              id: 'state',
+	              value: book.get('state'),
+	              onChange: this.handleChange
+	            },
+	            _react2.default.createElement(
+	              'option',
+	              { value: _bookStates2.default.stock },
+	              'Stock'
+	            ),
+	            _react2.default.createElement(
+	              'option',
+	              { value: _bookStates2.default.reading },
+	              'Reading'
+	            ),
+	            _react2.default.createElement(
+	              'option',
+	              { value: _bookStates2.default.read },
+	              'Read'
+	            )
+	          )
+	        ),
+	        _react2.default.createElement(
+	          'div',
+	          { className: 'item full' },
+	          _react2.default.createElement(
+	            'label',
+	            { htmlFor: 'title' },
+	            'Title'
+	          ),
+	          _react2.default.createElement('input', {
+	            type: 'text',
+	            id: 'title',
+	            value: book.get('title'),
+	            onChange: this.handleChange
+	          })
+	        ),
+	        _react2.default.createElement(
+	          'div',
+	          { className: 'item half' },
+	          _react2.default.createElement(
+	            'label',
+	            { htmlFor: 'startDate' },
+	            'Start date'
+	          ),
+	          _react2.default.createElement('input', {
+	            type: 'date',
+	            id: 'startDate',
+	            value: book.get('startDate'),
+	            placeholder: 'YYYY-MM-DD',
+	            onChange: this.handleChange
+	          })
+	        ),
+	        _react2.default.createElement(
+	          'div',
+	          { className: 'item half' },
+	          _react2.default.createElement(
+	            'label',
+	            { htmlFor: 'endDate' },
+	            'End date'
+	          ),
+	          _react2.default.createElement('input', {
+	            type: 'date',
+	            id: 'endDate',
+	            value: book.get('endDate'),
+	            placeholder: 'YYYY-MM-DD',
+	            onChange: this.handleChange
+	          })
+	        )
+	      )
+	    );
+	  }
+	});
+
+/***/ },
+/* 445 */
+/***/ function(module, exports, __webpack_require__) {
+
+	var baseGet = __webpack_require__(446);
+
+	/**
+	 * Gets the value at `path` of `object`. If the resolved value is
+	 * `undefined`, the `defaultValue` is used in its place.
+	 *
+	 * @static
+	 * @memberOf _
+	 * @since 3.7.0
+	 * @category Object
+	 * @param {Object} object The object to query.
+	 * @param {Array|string} path The path of the property to get.
+	 * @param {*} [defaultValue] The value returned for `undefined` resolved values.
+	 * @returns {*} Returns the resolved value.
+	 * @example
+	 *
+	 * var object = { 'a': [{ 'b': { 'c': 3 } }] };
+	 *
+	 * _.get(object, 'a[0].b.c');
+	 * // => 3
+	 *
+	 * _.get(object, ['a', '0', 'b', 'c']);
+	 * // => 3
+	 *
+	 * _.get(object, 'a.b.c', 'default');
+	 * // => 'default'
+	 */
+	function get(object, path, defaultValue) {
+	  var result = object == null ? undefined : baseGet(object, path);
+	  return result === undefined ? defaultValue : result;
+	}
+
+	module.exports = get;
+
+
+/***/ },
+/* 446 */
+/***/ function(module, exports, __webpack_require__) {
+
+	var castPath = __webpack_require__(447),
+	    isKey = __webpack_require__(449),
+	    toKey = __webpack_require__(450);
+
+	/**
+	 * The base implementation of `_.get` without support for default values.
+	 *
+	 * @private
+	 * @param {Object} object The object to query.
+	 * @param {Array|string} path The path of the property to get.
+	 * @returns {*} Returns the resolved value.
+	 */
+	function baseGet(object, path) {
+	  path = isKey(path, object) ? [path] : castPath(path);
+
+	  var index = 0,
+	      length = path.length;
+
+	  while (object != null && index < length) {
+	    object = object[toKey(path[index++])];
+	  }
+	  return (index && index == length) ? object : undefined;
+	}
+
+	module.exports = baseGet;
+
+
+/***/ },
+/* 447 */
+/***/ function(module, exports, __webpack_require__) {
+
+	var isArray = __webpack_require__(276),
+	    stringToPath = __webpack_require__(448);
+
+	/**
+	 * Casts `value` to a path array if it's not one.
+	 *
+	 * @private
+	 * @param {*} value The value to inspect.
+	 * @returns {Array} Returns the cast property path array.
+	 */
+	function castPath(value) {
+	  return isArray(value) ? value : stringToPath(value);
+	}
+
+	module.exports = castPath;
+
+
+/***/ },
+/* 448 */
+/***/ function(module, exports, __webpack_require__) {
+
+	var memoize = __webpack_require__(408),
+	    toString = __webpack_require__(416);
+
+	/** Used to match property names within property paths. */
+	var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(\.|\[\])(?:\4|$))/g;
+
+	/** Used to match backslashes in property paths. */
+	var reEscapeChar = /\\(\\)?/g;
+
+	/**
+	 * Converts `string` to a property path array.
+	 *
+	 * @private
+	 * @param {string} string The string to convert.
+	 * @returns {Array} Returns the property path array.
+	 */
+	var stringToPath = memoize(function(string) {
+	  var result = [];
+	  toString(string).replace(rePropName, function(match, number, quote, string) {
+	    result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
+	  });
+	  return result;
+	});
+
+	module.exports = stringToPath;
+
+
+/***/ },
+/* 449 */
+/***/ function(module, exports, __webpack_require__) {
+
+	var isArray = __webpack_require__(276),
+	    isSymbol = __webpack_require__(335);
+
+	/** Used to match property names within property paths. */
+	var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
+	    reIsPlainProp = /^\w*$/;
+
+	/**
+	 * Checks if `value` is a property name and not a property path.
+	 *
+	 * @private
+	 * @param {*} value The value to check.
+	 * @param {Object} [object] The object to query keys on.
+	 * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
+	 */
+	function isKey(value, object) {
+	  if (isArray(value)) {
+	    return false;
+	  }
+	  var type = typeof value;
+	  if (type == 'number' || type == 'symbol' || type == 'boolean' ||
+	      value == null || isSymbol(value)) {
+	    return true;
+	  }
+	  return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
+	    (object != null && value in Object(object));
+	}
+
+	module.exports = isKey;
+
+
+/***/ },
+/* 450 */
+/***/ function(module, exports, __webpack_require__) {
+
+	var isSymbol = __webpack_require__(335);
+
+	/** Used as references for various `Number` constants. */
+	var INFINITY = 1 / 0;
+
+	/**
+	 * Converts `value` to a string key if it's not a string or symbol.
+	 *
+	 * @private
+	 * @param {*} value The value to inspect.
+	 * @returns {string|symbol} Returns the key.
+	 */
+	function toKey(value) {
+	  if (typeof value == 'string' || isSymbol(value)) {
+	    return value;
+	  }
+	  var result = (value + '');
+	  return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
+	}
+
+	module.exports = toKey;
+
+
+/***/ },
+/* 451 */
+/***/ function(module, exports, __webpack_require__) {
+
+	'use strict';
+
+	Object.defineProperty(exports, "__esModule", {
+	  value: true
+	});
+	exports.getBookData = getBookData;
+	exports.getMainColour = getMainColour;
+
+	var _jquery = __webpack_require__(452);
+
+	var _jquery2 = _interopRequireDefault(_jquery);
+
+	var _keys = __webpack_require__(453);
+
+	var _keys2 = _interopRequireDefault(_keys);
+
+	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+	var GOOGLE_API = 'https://www.googleapis.com/books/v1/volumes';
+	var TINT_API = '//tint.gnab.fr';
+
+	function getBookData(book) {
+	  var isbn = book.get('ISBN');
+
+	  // An ISBN is either 10 or 13 chars long
+	  if (!isbn || isbn.length != 10 && isbn.length != 13) return Promise.resolve(null);
+
+	  return new Promise(function (resolve, reject) {
+	    _jquery2.default.ajax({
+	      url: GOOGLE_API,
+	      data: {
+	        q: 'isbn:' + isbn,
+	        key: _keys2.default.google
+	      },
+	      success: function success(data) {
+	        resolve(data.totalItems === 0 ? null : data.items[0].volumeInfo);
+	      },
+	      error: function error(err) {
+	        return reject(err);
+	      }
+	    });
+	  });
+	}
+
+	function getMainColour(imageUrl) {
+	  return new Promise(function (resolve, reject) {
+	    _jquery2.default.ajax({
+	      url: TINT_API + '/' + imageUrl,
+	      success: function success(data) {
+	        return resolve(data.colour);
+	      },
+	      error: reject
+	    });
+	  });
+	}
+
+/***/ },
+/* 452 */
+/***/ function(module, exports, __webpack_require__) {
+
+	var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
+	 * jQuery JavaScript Library v3.0.0
+	 * https://jquery.com/
+	 *
+	 * Includes Sizzle.js
+	 * https://sizzlejs.com/
+	 *
+	 * Copyright jQuery Foundation and other contributors
+	 * Released under the MIT license
+	 * https://jquery.org/license
+	 *
+	 * Date: 2016-06-09T18:02Z
+	 */
+	( function( global, factory ) {
+
+		"use strict";
+
+		if ( typeof module === "object" && typeof module.exports === "object" ) {
+
+			// For CommonJS and CommonJS-like environments where a proper `window`
+			// is present, execute the factory and get jQuery.
+			// For environments that do not have a `window` with a `document`
+			// (such as Node.js), expose a factory as module.exports.
+			// This accentuates the need for the creation of a real `window`.
+			// e.g. var jQuery = require("jquery")(window);
+			// See ticket #14549 for more info.
+			module.exports = global.document ?
+				factory( global, true ) :
+				function( w ) {
+					if ( !w.document ) {
+						throw new Error( "jQuery requires a window with a document" );
+					}
+					return factory( w );
+				};
+		} else {
+			factory( global );
+		}
+
+	// Pass this if window is not defined yet
+	}( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
+
+	// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
+	// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
+	// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
+	// enough that all such attempts are guarded in a try block.
+	"use strict";
+
+	var arr = [];
+
+	var document = window.document;
+
+	var getProto = Object.getPrototypeOf;
+
+	var slice = arr.slice;
+
+	var concat = arr.concat;
+
+	var push = arr.push;
+
+	var indexOf = arr.indexOf;
+
+	var class2type = {};
+
+	var toString = class2type.toString;
+
+	var hasOwn = class2type.hasOwnProperty;
+
+	var fnToString = hasOwn.toString;
+
+	var ObjectFunctionString = fnToString.call( Object );
+
+	var support = {};
+
+
+
+		function DOMEval( code, doc ) {
+			doc = doc || document;
+
+			var script = doc.createElement( "script" );
+
+			script.text = code;
+			doc.head.appendChild( script ).parentNode.removeChild( script );
+		}
+
+
+	var
+		version = "3.0.0",
+
+		// Define a local copy of jQuery
+		jQuery = function( selector, context ) {
+
+			// The jQuery object is actually just the init constructor 'enhanced'
+			// Need init if jQuery is called (just allow error to be thrown if not included)
+			return new jQuery.fn.init( selector, context );
+		},
+
+		// Support: Android <=4.0 only
+		// Make sure we trim BOM and NBSP
+		rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
+
+		// Matches dashed string for camelizing
+		rmsPrefix = /^-ms-/,
+		rdashAlpha = /-([a-z])/g,
+
+		// Used by jQuery.camelCase as callback to replace()
+		fcamelCase = function( all, letter ) {
+			return letter.toUpperCase();
+		};
+
+	jQuery.fn = jQuery.prototype = {
+
+		// The current version of jQuery being used
+		jquery: version,
+
+		constructor: jQuery,
+
+		// The default length of a jQuery object is 0
+		length: 0,
+
+		toArray: function() {
 			return slice.call( this );
 		},

@@ -52174,151 +52695,25 @@
 	// Expose jQuery and $ identifiers, even in AMD
 	// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
 	// and CommonJS for browser emulators (#13566)
-	if ( !noGlobal ) {
-		window.jQuery = window.$ = jQuery;
-	}
-
-
-	return jQuery;
-	} ) );
-
-
-/***/ },
-/* 442 */
-/***/ function(module, exports) {
-
-	module.exports = {
-		"google": "AIzaSyCGJLle1uZO6BzHvdYdwY7JEHuHoz8Av-s"
-	};
-
-/***/ },
-/* 443 */
-/***/ function(module, exports, __webpack_require__) {
-
-	// style-loader: Adds some css to the DOM by adding a <style> tag
-
-	// load the styles
-	var content = __webpack_require__(444);
-	if(typeof content === 'string') content = [[module.id, content, '']];
-	// add the styles to the DOM
-	var update = __webpack_require__(439)(content, {});
-	if(content.locals) module.exports = content.locals;
-	// Hot Module Replacement
-	if(false) {
-		// When the styles change, update the <style> tags
-		if(!content.locals) {
-			module.hot.accept("!!./../../../node_modules/css-loader/index.js!./../../../node_modules/stylus-loader/index.js!./cover.styl", function() {
-				var newContent = require("!!./../../../node_modules/css-loader/index.js!./../../../node_modules/stylus-loader/index.js!./cover.styl");
-				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
-				update(newContent);
-			});
-		}
-		// When the module is disposed, remove the <style> tags
-		module.hot.dispose(function() { update(); });
-	}
-
-/***/ },
-/* 444 */
-/***/ function(module, exports, __webpack_require__) {
-
-	exports = module.exports = __webpack_require__(438)();
-	// imports
-
-
-	// module
-	exports.push([module.id, ".cover {\n  background: rgba(0,0,0,0.1);\n  height: 280px;\n  position: relative;\n  width: 180px;\n}\n.cover img {\n  display: block;\n  height: 200px;\n  left: 20px;\n  object-fit: contain;\n  position: absolute;\n  top: 20px;\n  width: 140px;\n}\n.cover .description {\n  background: linear-gradient(to top, #35495d 0%, #35495d 40%, transparent 100%);\n  bottom: 0;\n  display: flex;\n  flex-flow: column nowrap;\n  height: 160px;\n  justify-content: flex-end;\n  padding: 0 10px 10px;\n  position: absolute;\n  width: 100%;\n}\n.cover .description h3 {\n  font-size: 1.6rem;\n  margin-bottom: 5px;\n}\n.cover .description p {\n  font-size: 1rem;\n  margin: 0;\n  opacity: 0.7;\n}\n", ""]);
-
-	// exports
-
-
-/***/ },
-/* 445 */
-/***/ function(module, exports) {
-
-	'use strict';
-
-	Object.defineProperty(exports, "__esModule", {
-	  value: true
-	});
-	var ItemTypes = {
-	  BOOK: 'book'
-	};
-
-	exports.default = ItemTypes;
-
-/***/ },
-/* 446 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	Object.defineProperty(exports, "__esModule", {
-	  value: true
-	});
-
-	var _react = __webpack_require__(1);
-
-	var _react2 = _interopRequireDefault(_react);
-
-	var _reactAddonsPureRenderMixin = __webpack_require__(261);
-
-	var _reactAddonsPureRenderMixin2 = _interopRequireDefault(_reactAddonsPureRenderMixin);
-
-	var _ActionBar = __webpack_require__(447);
-
-	var _ActionBar2 = _interopRequireDefault(_ActionBar);
-
-	var _Button = __webpack_require__(425);
-
-	var _Button2 = _interopRequireDefault(_Button);
-
-	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
-	var DEFAULT_TITLE = 'Chapter';
-
-	exports.default = _react2.default.createClass({
-	  displayName: 'Header',
-	  mixins: [_reactAddonsPureRenderMixin2.default],
-	  propTypes: {
-	    title: _react2.default.PropTypes.string,
-	    backButton: _react2.default.PropTypes.bool,
-	    children: _react2.default.PropTypes.oneOfType([_react2.default.PropTypes.element, _react2.default.PropTypes.arrayOf(_react2.default.PropTypes.element)])
-	  },
-	  contextTypes: {
-	    router: _react2.default.PropTypes.object
-	  },
-	  goBack: function goBack() {
-	    this.context.router.goBack();
-	  },
-	  render: function render() {
-	    var title = this.props.title || DEFAULT_TITLE;
-	    var addPreTitle = title !== DEFAULT_TITLE;
-
-	    return _react2.default.createElement(
-	      'header',
-	      null,
-	      this.props.backButton && _react2.default.createElement(_Button2.default, { click: this.goBack, label: '<', className: 'back' }),
-	      addPreTitle && _react2.default.createElement(
-	        'p',
-	        null,
-	        DEFAULT_TITLE
-	      ),
-	      _react2.default.createElement(
-	        'h1',
-	        null,
-	        title
-	      ),
-	      _react2.default.createElement(
-	        _ActionBar2.default,
-	        null,
-	        this.props.children
-	      )
-	    );
-	  }
-	});
+	if ( !noGlobal ) {
+		window.jQuery = window.$ = jQuery;
+	}
+
+
+	return jQuery;
+	} ) );
+

 /***/ },
-/* 447 */
+/* 453 */
+/***/ function(module, exports) {
+
+	module.exports = {
+		"google": "changeme"
+	};
+
+/***/ },
+/* 454 */
 /***/ function(module, exports, __webpack_require__) {

 	'use strict';
@@ -52327,6 +52722,8 @@
 	  value: true
 	});

+	var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
+
 	var _react = __webpack_require__(1);

 	var _react2 = _interopRequireDefault(_react);
@@ -52335,349 +52732,864 @@

 	var _reactAddonsPureRenderMixin2 = _interopRequireDefault(_reactAddonsPureRenderMixin);

+	var _reactInputMask = __webpack_require__(455);
+
+	var _reactInputMask2 = _interopRequireDefault(_reactInputMask);
+
 	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

+	function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
+
+	var ISBN_REGEX = /^(9(7[89]?)?)?/;
+	var ISBN_10_MASK = '9 999 99999 9';
+	var ISBN_13_MASK = '999 ' + ISBN_10_MASK;
+
 	exports.default = _react2.default.createClass({
-	  displayName: 'ActionBar',
+	  displayName: 'ISBNInput',
 	  mixins: [_reactAddonsPureRenderMixin2.default],
 	  propTypes: {
-	    children: _react2.default.PropTypes.oneOfType([_react2.default.PropTypes.element, _react2.default.PropTypes.arrayOf(_react2.default.PropTypes.element)])
+	    onChange: _react2.default.PropTypes.func
+	  },
+	  getInitialState: function getInitialState() {
+	    return { mask: ISBN_13_MASK };
+	  },
+	  handleChange: function handleChange(e) {
+	    var value = e.target.value.split(' ').join('');
+	    e.target.value = value;
+
+	    this.setState({
+	      mask: ISBN_REGEX.test(value) ? ISBN_13_MASK : ISBN_10_MASK
+	    });
+
+	    this.props.onChange(e);
 	  },
 	  render: function render() {
-	    return _react2.default.createElement(
-	      'nav',
-	      null,
-	      this.props.children
-	    );
-	  }
-	});
+	    var extraProps = _objectWithoutProperties(this.props, []);

-/***/ },
-/* 448 */
-/***/ function(module, exports) {
+	    var mask = this.state.mask;

-	'use strict';

-	Object.defineProperty(exports, "__esModule", {
-	  value: true
+	    return _react2.default.createElement(_reactInputMask2.default, _extends({
+	      mask: mask,
+	      maskChar: null,
+	      placeholder: '000 0 000 00000 0',
+	      onChange: this.handleChange,
+	      type: 'text'
+	    }, extraProps));
+	  }
 	});
-	exports.default = {
-	  stock: 'stock',
-	  reading: 'reading',
-	  read: 'read'
-	};

 /***/ },
-/* 449 */
+/* 455 */
 /***/ function(module, exports, __webpack_require__) {

-	// style-loader: Adds some css to the DOM by adding a <style> tag
+	// https://github.com/sanniassin/react-input-mask

-	// load the styles
-	var content = __webpack_require__(450);
-	if(typeof content === 'string') content = [[module.id, content, '']];
-	// add the styles to the DOM
-	var update = __webpack_require__(439)(content, {});
-	if(content.locals) module.exports = content.locals;
-	// Hot Module Replacement
-	if(false) {
-		// When the styles change, update the <style> tags
-		if(!content.locals) {
-			module.hot.accept("!!./../../../node_modules/css-loader/index.js!./../../../node_modules/stylus-loader/index.js!./library.styl", function() {
-				var newContent = require("!!./../../../node_modules/css-loader/index.js!./../../../node_modules/stylus-loader/index.js!./library.styl");
-				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
-				update(newContent);
-			});
-		}
-		// When the module is disposed, remove the <style> tags
-		module.hot.dispose(function() { update(); });
-	}
+	"use strict";

-/***/ },
-/* 450 */
-/***/ function(module, exports, __webpack_require__) {
+	var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

-	exports = module.exports = __webpack_require__(438)();
-	// imports
+	var React = __webpack_require__(1);

+	var InputElement = React.createClass({
+	    displayName: "InputElement",

-	// module
-	exports.push([module.id, ".collections {\n  display: flex;\n  flex-flow: row wrap;\n  justify-content: space-between;\n}\n.collections section {\n  height: 320px;\n  max-width: 100%;\n  overflow-y: auto;\n}\n.collections section ul {\n  display: flex;\n  flex-flow: row nowrap;\n  justify-content: flex-start;\n  list-style: none;\n  margin: 0;\n  padding: 0;\n}\n.collections section ul li {\n  margin-right: 20px;\n}\n.collections section ul li:last-child {\n  margin: 0;\n}\n.collections section .announce {\n  color: rgba(255,255,255,0.9);\n  font-size: 1.8rem;\n  left: 50%;\n  margin: 0;\n  position: absolute;\n  top: 50%;\n  transform: translate(-50%, -50%);\n}\n.collections section .announce .button {\n  box-shadow: 0 1px 2px rgba(0,0,0,0.5);\n  height: 30px;\n  line-height: 30px;\n  margin: 0 5px;\n}\n.collections section.stock {\n  background: #ecf0f1;\n  padding: 20px 60px 20px 80px;\n  position: relative;\n  flex-basis: 100%;\n}\n.collections section.stock h2,\n.collections section.stock::before {\n  background: #bdc3c7;\n  bottom: 0;\n  color: transparent;\n  content: '';\n  font-size: 1.8rem;\n  height: 20px;\n  line-height: 20px;\n  position: absolute;\n  right: 100%;\n  text-align: center;\n  top: 0;\n  transition: 0.5s;\n  transform: rotate(-90deg);\n  transform-origin: top right;\n  width: 320px;\n}\n.collections section.stock:hover h2,\n.collections section.stock.hover h2 {\n  color: rgba(255,255,255,0.8);\n  height: 40px;\n  line-height: 40px;\n}\n.collections section.stock .announce {\n  color: rgba(0,0,0,0.6);\n}\n.collections section.reading {\n  background: #f0c330;\n  padding: 20px 60px 20px 80px;\n  position: relative;\n  flex-basis: auto;\n  transition: 0.5s;\n}\n.collections section.reading h2,\n.collections section.reading::before {\n  background: #f19b2c;\n  bottom: 0;\n  color: transparent;\n  content: '';\n  font-size: 1.8rem;\n  height: 20px;\n  line-height: 20px;\n  position: absolute;\n  right: 100%;\n  text-align: center;\n  top: 0;\n  transition: 0.5s;\n  transform: rotate(-90deg);\n  transform-origin: top right;\n  width: 320px;\n}\n.collections section.reading:hover h2,\n.collections section.reading.hover h2 {\n  color: rgba(255,255,255,0.8);\n  height: 40px;\n  line-height: 40px;\n}\n.collections section.reading.hide {\n  min-width: 0;\n  padding: 0;\n}\n.collections section.reading.hover {\n  min-width: 320px;\n}\n.collections section.read {\n  background: #2fd1af;\n  padding: 20px 60px 20px 80px;\n  position: relative;\n  flex-basis: 50%;\n  flex-grow: 1;\n}\n.collections section.read h2,\n.collections section.read::before {\n  background: #239f85;\n  bottom: 0;\n  color: transparent;\n  content: '';\n  font-size: 1.8rem;\n  height: 20px;\n  line-height: 20px;\n  position: absolute;\n  right: 100%;\n  text-align: center;\n  top: 0;\n  transition: 0.5s;\n  transform: rotate(-90deg);\n  transform-origin: top right;\n  width: 320px;\n}\n.collections section.read:hover h2,\n.collections section.read.hover h2 {\n  color: rgba(255,255,255,0.8);\n  height: 40px;\n  line-height: 40px;\n}\n", ""]);
+	    defaultCharsRules: {
+	        "9": "[0-9]",
+	        "a": "[A-Za-z]",
+	        "*": "[A-Za-z0-9]"
+	    },
+	    defaultMaskChar: "_",
+	    lastCaretPos: null,
+	    isAndroidBrowser: function () {
+	        var windows = new RegExp("windows", "i");
+	        var firefox = new RegExp("firefox", "i");
+	        var android = new RegExp("android", "i");
+	        var ua = navigator.userAgent;
+	        return !windows.test(ua) && !firefox.test(ua) && android.test(ua);
+	    },
+	    isWindowsPhoneBrowser: function () {
+	        var windows = new RegExp("windows", "i");
+	        var phone = new RegExp("phone", "i");
+	        var ua = navigator.userAgent;
+	        return windows.test(ua) && phone.test(ua);
+	    },
+	    isAndroidFirefox: function () {
+	        var windows = new RegExp("windows", "i");
+	        var firefox = new RegExp("firefox", "i");
+	        var android = new RegExp("android", "i");
+	        var ua = navigator.userAgent;
+	        return !windows.test(ua) && firefox.test(ua) && android.test(ua);
+	    },
+	    isDOMElement: function (element) {
+	        return typeof HTMLElement === "object" ? element instanceof HTMLElement // DOM2
+	        : element.nodeType === 1 && typeof element.nodeName === "string";
+	    },
+	    // getDOMNode is deprecated but we need it to stay compatible with React 0.12
+	    getInputDOMNode: function () {
+	        var input = this.refs.input;

-	// exports
+	        if (!input) {
+	            return null;
+	        }

+	        // React 0.14
+	        if (this.isDOMElement(input)) {
+	            return input;
+	        }

-/***/ },
-/* 451 */
-/***/ function(module, exports, __webpack_require__) {
+	        return input.getDOMNode();
+	    },
+	    enableValueAccessors: function () {
+	        var _this = this;
+
+	        var canUseAccessors = !!(Object.getOwnPropertyDescriptor && Object.getPrototypeOf && Object.defineProperty);
+	        if (canUseAccessors) {
+	            var input = this.getInputDOMNode();
+	            this.valueDescriptor = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(input), 'value');
+	            Object.defineProperty(input, 'value', {
+	                configurable: true,
+	                enumerable: true,
+	                get: function () {
+	                    return _this.value;
+	                },
+	                set: function (val) {
+	                    _this.value = val;
+	                    _this.valueDescriptor.set.call(input, val);
+	                }
+	            });
+	        }
+	    },
+	    disableValueAccessors: function () {
+	        var valueDescriptor = this.valueDescriptor;

-	'use strict';
+	        if (!valueDescriptor) {
+	            return;
+	        }
+	        this.valueDescriptor = null;
+	        var input = this.getInputDOMNode();
+	        Object.defineProperty(input, 'value', valueDescriptor);
+	    },
+	    getInputValue: function () {
+	        var input = this.getInputDOMNode();
+	        var valueDescriptor = this.valueDescriptor;

-	Object.defineProperty(exports, "__esModule", {
-	  value: true
-	});
+	        var value;
+	        if (valueDescriptor) {
+	            value = valueDescriptor.get.call(input);
+	        } else {
+	            value = input.value;
+	        }

-	var _reactRedux = __webpack_require__(181);
+	        return value;
+	    },
+	    getPrefix: function () {
+	        var prefix = "";
+	        var mask = this.mask;

-	var _NewBook = __webpack_require__(452);
+	        for (var i = 0; i < mask.length && this.isPermanentChar(i); ++i) {
+	            prefix += mask[i];
+	        }
+	        return prefix;
+	    },
+	    getFilledLength: function () {
+	        var value = arguments.length <= 0 || arguments[0] === undefined ? this.state.value : arguments[0];

-	var _NewBook2 = _interopRequireDefault(_NewBook);
+	        var i;
+	        var maskChar = this.maskChar;

-	var _actionCreators = __webpack_require__(265);
+	        if (!maskChar) {
+	            return value.length;
+	        }

-	var actionCreators = _interopRequireWildcard(_actionCreators);
+	        for (i = value.length - 1; i >= 0; --i) {
+	            var character = value[i];
+	            if (!this.isPermanentChar(i) && this.isAllowedChar(character, i)) {
+	                break;
+	            }
+	        }

-	function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
+	        return ++i || this.getPrefix().length;
+	    },
+	    getLeftEditablePos: function (pos) {
+	        for (var i = pos; i >= 0; --i) {
+	            if (!this.isPermanentChar(i)) {
+	                return i;
+	            }
+	        }
+	        return null;
+	    },
+	    getRightEditablePos: function (pos) {
+	        var mask = this.mask;

-	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+	        for (var i = pos; i < mask.length; ++i) {
+	            if (!this.isPermanentChar(i)) {
+	                return i;
+	            }
+	        }
+	        return null;
+	    },
+	    isEmpty: function () {
+	        var _this2 = this;

-	var mapStateToProps = function mapStateToProps() {
-	  return {};
-	};
+	        var value = arguments.length <= 0 || arguments[0] === undefined ? this.state.value : arguments[0];

-	var NewBookContainer = (0, _reactRedux.connect)(mapStateToProps, actionCreators)(_NewBook2.default);
+	        return !value.split("").some(function (character, i) {
+	            return !_this2.isPermanentChar(i) && _this2.isAllowedChar(character, i);
+	        });
+	    },
+	    isFilled: function () {
+	        var value = arguments.length <= 0 || arguments[0] === undefined ? this.state.value : arguments[0];

-	exports.default = NewBookContainer;
+	        return this.getFi…
aec3602

@n6g7 n6g7 added a commit to n6g7/chapter that referenced this pull request Aug 6, 2016

@n6g7 n6g7 Chapter v0.0.9.
diff --git a/bundle.js b/bundle.js
index 8082ea3..e2686ae 100644
--- a/bundle.js
+++ b/bundle.js
@@ -76,23 +76,23 @@

 	var _Library2 = _interopRequireDefault(_Library);

-	var _NewBook = __webpack_require__(451);
+	var _NewBook = __webpack_require__(442);

 	var _NewBook2 = _interopRequireDefault(_NewBook);

-	var _EditBook = __webpack_require__(457);
+	var _EditBook = __webpack_require__(459);

 	var _EditBook2 = _interopRequireDefault(_EditBook);

-	var _ImportExport = __webpack_require__(459);
+	var _ImportExport = __webpack_require__(461);

 	var _ImportExport2 = _interopRequireDefault(_ImportExport);

-	var _reducer = __webpack_require__(467);
+	var _reducer = __webpack_require__(469);

 	var _reducer2 = _interopRequireDefault(_reducer);

-	__webpack_require__(468);
+	__webpack_require__(470);

 	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

@@ -32571,10 +32571,10 @@
 	  value: true
 	});
 	exports.INITIAL_STATE = undefined;
-	exports.setState = setState;
 	exports.addBook = addBook;
 	exports.updateBook = updateBook;
 	exports.removeBook = removeBook;
+	exports.importState = importState;

 	var _immutable = __webpack_require__(254);

@@ -32590,10 +32590,6 @@
 	  }
 	});

-	function setState(state, newState) {
-	  return state.merge(newState);
-	}
-
 	function addBook(state, book) {
 	  if (!book.has('uuid')) {
 	    book = book.set('uuid', _uuid2.default.v4());
@@ -32633,6 +32629,24 @@
 	  });
 	}

+	function importState(state, imported) {
+	  var importedState = (0, _immutable.fromJS)(imported);
+
+	  if (importedState.has('books')) {
+	    importedState = (0, _immutable.Map)({
+	      library: importedState
+	    });
+	  }
+
+	  return importedState.updateIn(['library', 'books'], function (books) {
+	    return books.map(function (book) {
+	      return book.merge({
+	        uuid: _uuid2.default.v4()
+	      });
+	    });
+	  });
+	}
+
 /***/ },
 /* 256 */
 /***/ function(module, exports, __webpack_require__) {
@@ -33071,7 +33085,7 @@

 	module.exports = {
 		"name": "chapter",
-		"version": "0.0.8",
+		"version": "0.0.9",
 		"description": "Digital library for physical books",
 		"main": "index.js",
 		"scripts": {
@@ -33097,6 +33111,7 @@
 			"react-dnd": "^2.1.4",
 			"react-dnd-html5-backend": "^2.1.2",
 			"react-dom": "^15.1.0",
+			"react-input-mask": "^0.7.0",
 			"react-redux": "^4.4.5",
 			"react-router": "^2.4.1",
 			"redux": "^3.5.2",
@@ -33109,6 +33124,7 @@
 			"babel-loader": "^6.2.4",
 			"babel-preset-es2015": "^6.6.0",
 			"babel-preset-react": "^6.5.0",
+			"babel-preset-stage-1": "^6.5.0",
 			"chai": "^3.5.0",
 			"chai-immutable": "astorije/chai-immutable",
 			"css-loader": "^0.23.1",
@@ -33127,6 +33143,7 @@
 		"babel": {
 			"presets": [
 				"es2015",
+				"stage-1",
 				"react"
 			]
 		},
@@ -33145,6 +33162,7 @@
 			},
 			"parserOptions": {
 				"ecmaFeatures": {
+					"experimentalObjectRestSpread": true,
 					"jsx": true
 				},
 				"ecmaVersion": 6,
@@ -33165,17 +33183,10 @@
 	Object.defineProperty(exports, "__esModule", {
 	  value: true
 	});
-	exports.setState = setState;
 	exports.addBook = addBook;
 	exports.updateBook = updateBook;
 	exports.removeBook = removeBook;
-	function setState(state) {
-	  return {
-	    type: 'SET_STATE',
-	    state: state
-	  };
-	}
-
+	exports.importState = importState;
 	function addBook(book) {
 	  return {
 	    type: 'ADD_BOOK',
@@ -33197,6 +33208,13 @@
 	  };
 	}

+	function importState(importedState) {
+	  return {
+	    type: 'IMPORT_STATE',
+	    importedState: importedState
+	  };
+	}
+
 /***/ },
 /* 266 */
 /***/ function(module, exports, __webpack_require__) {
@@ -33265,15 +33283,15 @@

 	var _Button2 = _interopRequireDefault(_Button);

-	var _Header = __webpack_require__(446);
+	var _Header = __webpack_require__(437);

 	var _Header2 = _interopRequireDefault(_Header);

-	var _bookStates = __webpack_require__(448);
+	var _bookStates = __webpack_require__(439);

 	var _bookStates2 = _interopRequireDefault(_bookStates);

-	__webpack_require__(449);
+	__webpack_require__(440);

 	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

@@ -40857,7 +40875,7 @@

 	var _BookList2 = _interopRequireDefault(_BookList);

-	var _dragDropTypes = __webpack_require__(445);
+	var _dragDropTypes = __webpack_require__(436);

 	var _dragDropTypes2 = _interopRequireDefault(_dragDropTypes);

@@ -41342,7 +41360,7 @@
 	      this.props.books.map(function (book) {
 	        return _react2.default.createElement(
 	          'li',
-	          { key: book.get('ISBN'), onClick: function onClick() {
+	          { key: book.get('uuid'), onClick: function onClick() {
 	              return _this.goTo(book);
 	            } },
 	          _react2.default.createElement(_DraggableCover2.default, { book: book })
@@ -41378,7 +41396,7 @@

 	var _Cover2 = _interopRequireDefault(_Cover);

-	var _dragDropTypes = __webpack_require__(445);
+	var _dragDropTypes = __webpack_require__(436);

 	var _dragDropTypes2 = _interopRequireDefault(_dragDropTypes);

@@ -41439,17 +41457,11 @@

 	var _immutable = __webpack_require__(254);

-	var _get = __webpack_require__(429);
-
-	var _get2 = _interopRequireDefault(_get);
-
-	var _Loader = __webpack_require__(435);
+	var _Loader = __webpack_require__(429);

 	var _Loader2 = _interopRequireDefault(_Loader);

-	var _apis = __webpack_require__(440);
-
-	__webpack_require__(443);
+	__webpack_require__(434);

 	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

@@ -41457,37 +41469,24 @@
 	  displayName: 'Cover',
 	  mixins: [_reactAddonsPureRenderMixin2.default],
 	  propTypes: {
-	    book: _react2.default.PropTypes.instanceOf(_immutable.Map)
-	  },
-	  fetchBookData: function fetchBookData(book) {
-	    var _this = this;
-
-	    (0, _apis.getBookData)(book).then(function (data) {
-	      _this.setState({ loaded: true, data: data });
-
-	      var imageUrl = (0, _get2.default)(_this.state.data, 'imageLinks.thumbnail');
-	      if (imageUrl) {
-	        (0, _apis.getMainColour)(imageUrl).then(function (colour) {
-	          return _this.setState({ colour: colour });
-	        });
-	      }
-	    });
+	    book: _react2.default.PropTypes.instanceOf(_immutable.Map).isRequired,
+	    loading: _react2.default.PropTypes.bool
 	  },
 	  getImage: function getImage() {
-	    if (!this.state || !this.state.loaded) return _react2.default.createElement(_Loader2.default, null);
+	    var _props = this.props;
+	    var book = _props.book;
+	    var loading = _props.loading;

-	    var url = (0, _get2.default)(this.state.data, 'imageLinks.thumbnail', '');
-	    return _react2.default.createElement('img', { src: url, alt: this.props.book.get('title') });
-	  },
-	  componentDidMount: function componentDidMount() {
-	    this.fetchBookData(this.props.book);
-	  },
-	  componentWillReceiveProps: function componentWillReceiveProps(props) {
-	    this.fetchBookData(props.book);
+	    var url = book.getIn(['extra', 'coverUrl']);
+
+	    return loading ? _react2.default.createElement(_Loader2.default, null) : _react2.default.createElement('img', { src: url, alt: book.get('title') });
 	  },
 	  render: function render() {
-	    var book = this.props.book;
-	    var colour = (0, _get2.default)(this.state, 'colour');
+	    var _props2 = this.props;
+	    var book = _props2.book;
+	    var loading = _props2.loading;
+
+	    var colour = !loading ? book.getIn(['extra', 'coverColour']) : null;

 	    return _react2.default.createElement(
 	      'div',
@@ -41518,190 +41517,6 @@
 /* 429 */
 /***/ function(module, exports, __webpack_require__) {

-	var baseGet = __webpack_require__(430);
-
-	/**
-	 * Gets the value at `path` of `object`. If the resolved value is
-	 * `undefined`, the `defaultValue` is used in its place.
-	 *
-	 * @static
-	 * @memberOf _
-	 * @since 3.7.0
-	 * @category Object
-	 * @param {Object} object The object to query.
-	 * @param {Array|string} path The path of the property to get.
-	 * @param {*} [defaultValue] The value returned for `undefined` resolved values.
-	 * @returns {*} Returns the resolved value.
-	 * @example
-	 *
-	 * var object = { 'a': [{ 'b': { 'c': 3 } }] };
-	 *
-	 * _.get(object, 'a[0].b.c');
-	 * // => 3
-	 *
-	 * _.get(object, ['a', '0', 'b', 'c']);
-	 * // => 3
-	 *
-	 * _.get(object, 'a.b.c', 'default');
-	 * // => 'default'
-	 */
-	function get(object, path, defaultValue) {
-	  var result = object == null ? undefined : baseGet(object, path);
-	  return result === undefined ? defaultValue : result;
-	}
-
-	module.exports = get;
-
-
-/***/ },
-/* 430 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var castPath = __webpack_require__(431),
-	    isKey = __webpack_require__(433),
-	    toKey = __webpack_require__(434);
-
-	/**
-	 * The base implementation of `_.get` without support for default values.
-	 *
-	 * @private
-	 * @param {Object} object The object to query.
-	 * @param {Array|string} path The path of the property to get.
-	 * @returns {*} Returns the resolved value.
-	 */
-	function baseGet(object, path) {
-	  path = isKey(path, object) ? [path] : castPath(path);
-
-	  var index = 0,
-	      length = path.length;
-
-	  while (object != null && index < length) {
-	    object = object[toKey(path[index++])];
-	  }
-	  return (index && index == length) ? object : undefined;
-	}
-
-	module.exports = baseGet;
-
-
-/***/ },
-/* 431 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var isArray = __webpack_require__(276),
-	    stringToPath = __webpack_require__(432);
-
-	/**
-	 * Casts `value` to a path array if it's not one.
-	 *
-	 * @private
-	 * @param {*} value The value to inspect.
-	 * @returns {Array} Returns the cast property path array.
-	 */
-	function castPath(value) {
-	  return isArray(value) ? value : stringToPath(value);
-	}
-
-	module.exports = castPath;
-
-
-/***/ },
-/* 432 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var memoize = __webpack_require__(408),
-	    toString = __webpack_require__(416);
-
-	/** Used to match property names within property paths. */
-	var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(\.|\[\])(?:\4|$))/g;
-
-	/** Used to match backslashes in property paths. */
-	var reEscapeChar = /\\(\\)?/g;
-
-	/**
-	 * Converts `string` to a property path array.
-	 *
-	 * @private
-	 * @param {string} string The string to convert.
-	 * @returns {Array} Returns the property path array.
-	 */
-	var stringToPath = memoize(function(string) {
-	  var result = [];
-	  toString(string).replace(rePropName, function(match, number, quote, string) {
-	    result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
-	  });
-	  return result;
-	});
-
-	module.exports = stringToPath;
-
-
-/***/ },
-/* 433 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var isArray = __webpack_require__(276),
-	    isSymbol = __webpack_require__(335);
-
-	/** Used to match property names within property paths. */
-	var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
-	    reIsPlainProp = /^\w*$/;
-
-	/**
-	 * Checks if `value` is a property name and not a property path.
-	 *
-	 * @private
-	 * @param {*} value The value to check.
-	 * @param {Object} [object] The object to query keys on.
-	 * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
-	 */
-	function isKey(value, object) {
-	  if (isArray(value)) {
-	    return false;
-	  }
-	  var type = typeof value;
-	  if (type == 'number' || type == 'symbol' || type == 'boolean' ||
-	      value == null || isSymbol(value)) {
-	    return true;
-	  }
-	  return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
-	    (object != null && value in Object(object));
-	}
-
-	module.exports = isKey;
-
-
-/***/ },
-/* 434 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var isSymbol = __webpack_require__(335);
-
-	/** Used as references for various `Number` constants. */
-	var INFINITY = 1 / 0;
-
-	/**
-	 * Converts `value` to a string key if it's not a string or symbol.
-	 *
-	 * @private
-	 * @param {*} value The value to inspect.
-	 * @returns {string|symbol} Returns the key.
-	 */
-	function toKey(value) {
-	  if (typeof value == 'string' || isSymbol(value)) {
-	    return value;
-	  }
-	  var result = (value + '');
-	  return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
-	}
-
-	module.exports = toKey;
-
-
-/***/ },
-/* 435 */
-/***/ function(module, exports, __webpack_require__) {
-
 	'use strict';

 	Object.defineProperty(exports, "__esModule", {
@@ -41716,7 +41531,7 @@

 	var _reactAddonsPureRenderMixin2 = _interopRequireDefault(_reactAddonsPureRenderMixin);

-	__webpack_require__(436);
+	__webpack_require__(430);

 	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

@@ -41733,16 +41548,16 @@
 	});

 /***/ },
-/* 436 */
+/* 430 */
 /***/ function(module, exports, __webpack_require__) {

 	// style-loader: Adds some css to the DOM by adding a <style> tag

 	// load the styles
-	var content = __webpack_require__(437);
+	var content = __webpack_require__(431);
 	if(typeof content === 'string') content = [[module.id, content, '']];
 	// add the styles to the DOM
-	var update = __webpack_require__(439)(content, {});
+	var update = __webpack_require__(433)(content, {});
 	if(content.locals) module.exports = content.locals;
 	// Hot Module Replacement
 	if(false) {
@@ -41759,10 +41574,10 @@
 	}

 /***/ },
-/* 437 */
+/* 431 */
 /***/ function(module, exports, __webpack_require__) {

-	exports = module.exports = __webpack_require__(438)();
+	exports = module.exports = __webpack_require__(432)();
 	// imports

@@ -41773,7 +41588,7 @@

 /***/ },
-/* 438 */
+/* 432 */
 /***/ function(module, exports) {

 	/*
@@ -41829,7 +41644,7 @@

 /***/ },
-/* 439 */
+/* 433 */
 /***/ function(module, exports, __webpack_require__) {

 	/*
@@ -42081,189 +41896,895 @@

 /***/ },
-/* 440 */
+/* 434 */
 /***/ function(module, exports, __webpack_require__) {

-	'use strict';
+	// style-loader: Adds some css to the DOM by adding a <style> tag

-	Object.defineProperty(exports, "__esModule", {
-	  value: true
-	});
-	exports.getBookData = getBookData;
-	exports.getMainColour = getMainColour;
+	// load the styles
+	var content = __webpack_require__(435);
+	if(typeof content === 'string') content = [[module.id, content, '']];
+	// add the styles to the DOM
+	var update = __webpack_require__(433)(content, {});
+	if(content.locals) module.exports = content.locals;
+	// Hot Module Replacement
+	if(false) {
+		// When the styles change, update the <style> tags
+		if(!content.locals) {
+			module.hot.accept("!!./../../../node_modules/css-loader/index.js!./../../../node_modules/stylus-loader/index.js!./cover.styl", function() {
+				var newContent = require("!!./../../../node_modules/css-loader/index.js!./../../../node_modules/stylus-loader/index.js!./cover.styl");
+				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
+				update(newContent);
+			});
+		}
+		// When the module is disposed, remove the <style> tags
+		module.hot.dispose(function() { update(); });
+	}

-	var _jquery = __webpack_require__(441);
+/***/ },
+/* 435 */
+/***/ function(module, exports, __webpack_require__) {

-	var _jquery2 = _interopRequireDefault(_jquery);
+	exports = module.exports = __webpack_require__(432)();
+	// imports

-	var _keys = __webpack_require__(442);

-	var _keys2 = _interopRequireDefault(_keys);
+	// module
+	exports.push([module.id, ".cover {\n  background: rgba(0,0,0,0.1);\n  height: 280px;\n  position: relative;\n  width: 180px;\n}\n.cover img {\n  display: block;\n  height: 200px;\n  left: 20px;\n  object-fit: contain;\n  position: absolute;\n  top: 20px;\n  width: 140px;\n}\n.cover .description {\n  background: linear-gradient(to top, #35495d 0%, #35495d 40%, transparent 100%);\n  bottom: 0;\n  display: flex;\n  flex-flow: column nowrap;\n  height: 160px;\n  justify-content: flex-end;\n  padding: 0 10px 10px;\n  position: absolute;\n  width: 100%;\n}\n.cover .description h3 {\n  font-size: 1.6rem;\n  margin-bottom: 5px;\n}\n.cover .description p {\n  font-size: 1rem;\n  margin: 0;\n  opacity: 0.7;\n}\n", ""]);

-	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+	// exports

-	var GOOGLE_API = 'https://www.googleapis.com/books/v1/volumes';
-	var TINT_API = '//tint.gnab.fr';

-	function getBookData(book) {
-	  var isbn = book.get('ISBN');
+/***/ },
+/* 436 */
+/***/ function(module, exports) {

-	  // An ISBN is either 10 or 13 chars long
-	  if (!isbn || isbn.length != 10 && isbn.length != 13) return Promise.resolve(null);
+	'use strict';

-	  return new Promise(function (resolve, reject) {
-	    _jquery2.default.ajax({
-	      url: GOOGLE_API,
-	      data: {
-	        q: 'isbn:' + isbn,
-	        key: _keys2.default.google
-	      },
-	      success: function success(data) {
-	        resolve(data.totalItems === 0 ? null : data.items[0].volumeInfo);
-	      },
-	      error: function error(err) {
-	        return reject(err);
-	      }
-	    });
-	  });
-	}
+	Object.defineProperty(exports, "__esModule", {
+	  value: true
+	});
+	var ItemTypes = {
+	  BOOK: 'book'
+	};

-	function getMainColour(imageUrl) {
-	  return new Promise(function (resolve, reject) {
-	    _jquery2.default.ajax({
-	      url: TINT_API + '/' + imageUrl,
-	      success: function success(data) {
-	        return resolve(data.colour);
-	      },
-	      error: reject
-	    });
-	  });
-	}
+	exports.default = ItemTypes;

 /***/ },
-/* 441 */
+/* 437 */
 /***/ function(module, exports, __webpack_require__) {

-	var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
-	 * jQuery JavaScript Library v3.0.0
-	 * https://jquery.com/
-	 *
-	 * Includes Sizzle.js
-	 * https://sizzlejs.com/
-	 *
-	 * Copyright jQuery Foundation and other contributors
-	 * Released under the MIT license
-	 * https://jquery.org/license
-	 *
-	 * Date: 2016-06-09T18:02Z
-	 */
-	( function( global, factory ) {
+	'use strict';

-		"use strict";
+	Object.defineProperty(exports, "__esModule", {
+	  value: true
+	});

-		if ( typeof module === "object" && typeof module.exports === "object" ) {
+	var _react = __webpack_require__(1);

-			// For CommonJS and CommonJS-like environments where a proper `window`
-			// is present, execute the factory and get jQuery.
-			// For environments that do not have a `window` with a `document`
-			// (such as Node.js), expose a factory as module.exports.
-			// This accentuates the need for the creation of a real `window`.
-			// e.g. var jQuery = require("jquery")(window);
-			// See ticket #14549 for more info.
-			module.exports = global.document ?
-				factory( global, true ) :
-				function( w ) {
-					if ( !w.document ) {
-						throw new Error( "jQuery requires a window with a document" );
-					}
-					return factory( w );
-				};
-		} else {
-			factory( global );
-		}
+	var _react2 = _interopRequireDefault(_react);

-	// Pass this if window is not defined yet
-	}( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
+	var _reactAddonsPureRenderMixin = __webpack_require__(261);

-	// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
-	// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
-	// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
-	// enough that all such attempts are guarded in a try block.
-	"use strict";
+	var _reactAddonsPureRenderMixin2 = _interopRequireDefault(_reactAddonsPureRenderMixin);

-	var arr = [];
+	var _ActionBar = __webpack_require__(438);

-	var document = window.document;
+	var _ActionBar2 = _interopRequireDefault(_ActionBar);

-	var getProto = Object.getPrototypeOf;
+	var _Button = __webpack_require__(425);

-	var slice = arr.slice;
+	var _Button2 = _interopRequireDefault(_Button);

-	var concat = arr.concat;
+	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

-	var push = arr.push;
+	var DEFAULT_TITLE = 'Chapter';

-	var indexOf = arr.indexOf;
+	exports.default = _react2.default.createClass({
+	  displayName: 'Header',
+	  mixins: [_reactAddonsPureRenderMixin2.default],
+	  propTypes: {
+	    title: _react2.default.PropTypes.string,
+	    backButton: _react2.default.PropTypes.bool,
+	    children: _react2.default.PropTypes.oneOfType([_react2.default.PropTypes.element, _react2.default.PropTypes.arrayOf(_react2.default.PropTypes.element)])
+	  },
+	  contextTypes: {
+	    router: _react2.default.PropTypes.object
+	  },
+	  goBack: function goBack() {
+	    this.context.router.goBack();
+	  },
+	  render: function render() {
+	    var title = this.props.title || DEFAULT_TITLE;
+	    var addPreTitle = title !== DEFAULT_TITLE;

-	var class2type = {};
+	    return _react2.default.createElement(
+	      'header',
+	      null,
+	      this.props.backButton && _react2.default.createElement(_Button2.default, { click: this.goBack, label: '<', className: 'back' }),
+	      addPreTitle && _react2.default.createElement(
+	        'p',
+	        null,
+	        DEFAULT_TITLE
+	      ),
+	      _react2.default.createElement(
+	        'h1',
+	        null,
+	        title
+	      ),
+	      _react2.default.createElement(
+	        _ActionBar2.default,
+	        null,
+	        this.props.children
+	      )
+	    );
+	  }
+	});

-	var toString = class2type.toString;
+/***/ },
+/* 438 */
+/***/ function(module, exports, __webpack_require__) {

-	var hasOwn = class2type.hasOwnProperty;
+	'use strict';

-	var fnToString = hasOwn.toString;
+	Object.defineProperty(exports, "__esModule", {
+	  value: true
+	});

-	var ObjectFunctionString = fnToString.call( Object );
+	var _react = __webpack_require__(1);

-	var support = {};
+	var _react2 = _interopRequireDefault(_react);

+	var _reactAddonsPureRenderMixin = __webpack_require__(261);

+	var _reactAddonsPureRenderMixin2 = _interopRequireDefault(_reactAddonsPureRenderMixin);

-		function DOMEval( code, doc ) {
-			doc = doc || document;
+	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

-			var script = doc.createElement( "script" );
+	exports.default = _react2.default.createClass({
+	  displayName: 'ActionBar',
+	  mixins: [_reactAddonsPureRenderMixin2.default],
+	  propTypes: {
+	    children: _react2.default.PropTypes.oneOfType([_react2.default.PropTypes.element, _react2.default.PropTypes.arrayOf(_react2.default.PropTypes.element)])
+	  },
+	  render: function render() {
+	    return _react2.default.createElement(
+	      'nav',
+	      null,
+	      this.props.children
+	    );
+	  }
+	});

-			script.text = code;
-			doc.head.appendChild( script ).parentNode.removeChild( script );
-		}
+/***/ },
+/* 439 */
+/***/ function(module, exports) {

+	'use strict';

-	var
-		version = "3.0.0",
+	Object.defineProperty(exports, "__esModule", {
+	  value: true
+	});
+	exports.default = {
+	  stock: 'stock',
+	  reading: 'reading',
+	  read: 'read'
+	};

-		// Define a local copy of jQuery
-		jQuery = function( selector, context ) {
+/***/ },
+/* 440 */
+/***/ function(module, exports, __webpack_require__) {

-			// The jQuery object is actually just the init constructor 'enhanced'
-			// Need init if jQuery is called (just allow error to be thrown if not included)
-			return new jQuery.fn.init( selector, context );
-		},
+	// style-loader: Adds some css to the DOM by adding a <style> tag

-		// Support: Android <=4.0 only
-		// Make sure we trim BOM and NBSP
-		rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
+	// load the styles
+	var content = __webpack_require__(441);
+	if(typeof content === 'string') content = [[module.id, content, '']];
+	// add the styles to the DOM
+	var update = __webpack_require__(433)(content, {});
+	if(content.locals) module.exports = content.locals;
+	// Hot Module Replacement
+	if(false) {
+		// When the styles change, update the <style> tags
+		if(!content.locals) {
+			module.hot.accept("!!./../../../node_modules/css-loader/index.js!./../../../node_modules/stylus-loader/index.js!./library.styl", function() {
+				var newContent = require("!!./../../../node_modules/css-loader/index.js!./../../../node_modules/stylus-loader/index.js!./library.styl");
+				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
+				update(newContent);
+			});
+		}
+		// When the module is disposed, remove the <style> tags
+		module.hot.dispose(function() { update(); });
+	}

-		// Matches dashed string for camelizing
-		rmsPrefix = /^-ms-/,
-		rdashAlpha = /-([a-z])/g,
+/***/ },
+/* 441 */
+/***/ function(module, exports, __webpack_require__) {

-		// Used by jQuery.camelCase as callback to replace()
-		fcamelCase = function( all, letter ) {
-			return letter.toUpperCase();
-		};
+	exports = module.exports = __webpack_require__(432)();
+	// imports

-	jQuery.fn = jQuery.prototype = {

-		// The current version of jQuery being used
-		jquery: version,
+	// module
+	exports.push([module.id, ".collections {\n  display: flex;\n  flex-flow: row wrap;\n  justify-content: space-between;\n}\n.collections section {\n  height: 320px;\n  max-width: 100%;\n  overflow-y: auto;\n}\n.collections section ul {\n  display: flex;\n  flex-flow: row nowrap;\n  justify-content: flex-start;\n  list-style: none;\n  margin: 0;\n  padding: 0;\n}\n.collections section ul li {\n  margin-right: 20px;\n}\n.collections section ul li:last-child {\n  margin: 0;\n}\n.collections section .announce {\n  color: rgba(255,255,255,0.9);\n  font-size: 1.8rem;\n  left: 50%;\n  margin: 0;\n  position: absolute;\n  top: 50%;\n  transform: translate(-50%, -50%);\n}\n.collections section .announce .button {\n  box-shadow: 0 1px 2px rgba(0,0,0,0.5);\n  height: 30px;\n  line-height: 30px;\n  margin: 0 5px;\n}\n.collections section.stock {\n  background: #ecf0f1;\n  padding: 20px 60px 20px 80px;\n  position: relative;\n  flex-basis: 100%;\n}\n.collections section.stock h2,\n.collections section.stock::before {\n  background: #bdc3c7;\n  bottom: 0;\n  color: transparent;\n  content: '';\n  font-size: 1.8rem;\n  height: 20px;\n  line-height: 20px;\n  position: absolute;\n  right: 100%;\n  text-align: center;\n  top: 0;\n  transition: 0.5s;\n  transform: rotate(-90deg);\n  transform-origin: top right;\n  width: 320px;\n}\n.collections section.stock:hover h2,\n.collections section.stock.hover h2 {\n  color: rgba(255,255,255,0.8);\n  height: 40px;\n  line-height: 40px;\n}\n.collections section.stock .announce {\n  color: rgba(0,0,0,0.6);\n}\n.collections section.reading {\n  background: #f0c330;\n  padding: 20px 60px 20px 80px;\n  position: relative;\n  flex-basis: auto;\n  transition: 0.5s;\n}\n.collections section.reading h2,\n.collections section.reading::before {\n  background: #f19b2c;\n  bottom: 0;\n  color: transparent;\n  content: '';\n  font-size: 1.8rem;\n  height: 20px;\n  line-height: 20px;\n  position: absolute;\n  right: 100%;\n  text-align: center;\n  top: 0;\n  transition: 0.5s;\n  transform: rotate(-90deg);\n  transform-origin: top right;\n  width: 320px;\n}\n.collections section.reading:hover h2,\n.collections section.reading.hover h2 {\n  color: rgba(255,255,255,0.8);\n  height: 40px;\n  line-height: 40px;\n}\n.collections section.reading.hide {\n  min-width: 0;\n  padding: 0;\n}\n.collections section.reading.hover {\n  min-width: 320px;\n}\n.collections section.read {\n  background: #2fd1af;\n  padding: 20px 60px 20px 80px;\n  position: relative;\n  flex-basis: 50%;\n  flex-grow: 1;\n}\n.collections section.read h2,\n.collections section.read::before {\n  background: #239f85;\n  bottom: 0;\n  color: transparent;\n  content: '';\n  font-size: 1.8rem;\n  height: 20px;\n  line-height: 20px;\n  position: absolute;\n  right: 100%;\n  text-align: center;\n  top: 0;\n  transition: 0.5s;\n  transform: rotate(-90deg);\n  transform-origin: top right;\n  width: 320px;\n}\n.collections section.read:hover h2,\n.collections section.read.hover h2 {\n  color: rgba(255,255,255,0.8);\n  height: 40px;\n  line-height: 40px;\n}\n", ""]);

-		constructor: jQuery,
+	// exports

-		// The default length of a jQuery object is 0
-		length: 0,

-		toArray: function() {
+/***/ },
+/* 442 */
+/***/ function(module, exports, __webpack_require__) {
+
+	'use strict';
+
+	Object.defineProperty(exports, "__esModule", {
+	  value: true
+	});
+
+	var _reactRedux = __webpack_require__(181);
+
+	var _NewBook = __webpack_require__(443);
+
+	var _NewBook2 = _interopRequireDefault(_NewBook);
+
+	var _actionCreators = __webpack_require__(265);
+
+	var actionCreators = _interopRequireWildcard(_actionCreators);
+
+	function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
+
+	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+	var mapStateToProps = function mapStateToProps() {
+	  return {};
+	};
+
+	var NewBookContainer = (0, _reactRedux.connect)(mapStateToProps, actionCreators)(_NewBook2.default);
+
+	exports.default = NewBookContainer;
+
+/***/ },
+/* 443 */
+/***/ function(module, exports, __webpack_require__) {
+
+	'use strict';
+
+	Object.defineProperty(exports, "__esModule", {
+	  value: true
+	});
+
+	var _react = __webpack_require__(1);
+
+	var _react2 = _interopRequireDefault(_react);
+
+	var _reactAddonsPureRenderMixin = __webpack_require__(261);
+
+	var _reactAddonsPureRenderMixin2 = _interopRequireDefault(_reactAddonsPureRenderMixin);
+
+	var _BookForm = __webpack_require__(444);
+
+	var _BookForm2 = _interopRequireDefault(_BookForm);
+
+	var _Button = __webpack_require__(425);
+
+	var _Button2 = _interopRequireDefault(_Button);
+
+	var _Header = __webpack_require__(437);
+
+	var _Header2 = _interopRequireDefault(_Header);
+
+	var _book = __webpack_require__(456);
+
+	__webpack_require__(457);
+
+	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+	exports.default = _react2.default.createClass({
+	  displayName: 'NewBook',
+	  mixins: [_reactAddonsPureRenderMixin2.default],
+	  propTypes: {
+	    addBook: _react2.default.PropTypes.func
+	  },
+	  contextTypes: {
+	    router: _react2.default.PropTypes.object
+	  },
+	  update: function update(book) {
+	    this.setState({ book: book });
+	  },
+	  save: function save(book) {
+	    this.props.addBook(book);
+	    this.context.router.push('/');
+	  },
+	  render: function render() {
+	    var _this = this;
+
+	    return _react2.default.createElement(
+	      'div',
+	      null,
+	      _react2.default.createElement(
+	        _Header2.default,
+	        { title: 'Add a book', backButton: true },
+	        _react2.default.createElement(_Button2.default, { click: function click() {
+	            return _this.save(_this.state.book);
+	          }, label: 'Save book' })
+	      ),
+	      _react2.default.createElement(
+	        'section',
+	        { className: 'form' },
+	        _react2.default.createElement(_BookForm2.default, {
+	          book: _book.newBook,
+	          onSubmit: this.save,
+	          onChange: this.update
+	        })
+	      )
+	    );
+	  }
+	});
+
+/***/ },
+/* 444 */
+/***/ function(module, exports, __webpack_require__) {
+
+	'use strict';
+
+	Object.defineProperty(exports, "__esModule", {
+	  value: true
+	});
+
+	var _react = __webpack_require__(1);
+
+	var _react2 = _interopRequireDefault(_react);
+
+	var _reactAddonsPureRenderMixin = __webpack_require__(261);
+
+	var _reactAddonsPureRenderMixin2 = _interopRequireDefault(_reactAddonsPureRenderMixin);
+
+	var _immutable = __webpack_require__(254);
+
+	var _get = __webpack_require__(445);
+
+	var _get2 = _interopRequireDefault(_get);
+
+	var _Cover = __webpack_require__(428);
+
+	var _Cover2 = _interopRequireDefault(_Cover);
+
+	var _bookStates = __webpack_require__(439);
+
+	var _bookStates2 = _interopRequireDefault(_bookStates);
+
+	var _apis = __webpack_require__(451);
+
+	var _ISBNInput = __webpack_require__(454);
+
+	var _ISBNInput2 = _interopRequireDefault(_ISBNInput);
+
+	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+	function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
+
+	exports.default = _react2.default.createClass({
+	  displayName: 'BookForm',
+	  mixins: [_reactAddonsPureRenderMixin2.default],
+	  propTypes: {
+	    onChange: _react2.default.PropTypes.func,
+	    book: _react2.default.PropTypes.instanceOf(_immutable.Map)
+	  },
+	  getInitialState: function getInitialState() {
+	    return {
+	      loading: false
+	    };
+	  },
+	  fetchBookData: function fetchBookData(book) {
+	    var _this = this;
+
+	    this.setState({ loading: true });
+
+	    return (0, _apis.getBookData)(book).then(function (data) {
+	      var coverUrl = (0, _get2.default)(data, 'imageLinks.thumbnail');
+
+	      if (coverUrl) {
+	        return (0, _apis.getMainColour)(coverUrl).then(function (colour) {
+	          _this.setState({ loading: false });
+
+	          return book.merge({
+	            extra: {
+	              coverUrl: coverUrl,
+	              coverColour: colour
+	            }
+	          });
+	        });
+	      } else {
+	        _this.setState({ loading: false });
+	        return book.delete('extra');
+	      }
+	    });
+	  },
+	  handleChange: function handleChange(e) {
+	    var book = this.props.book.merge((0, _immutable.Map)(_defineProperty({}, e.target.id, e.target.value)));
+
+	    if (e.target.id === 'ISBN') {
+	      this.fetchBookData(book).then(this.props.onChange);
+	    } else this.props.onChange(book);
+	  },
+	  render: function render() {
+	    var book = this.props.book;
+	    var loading = this.state.loading;
+
+
+	    return _react2.default.createElement(
+	      'div',
+	      { className: 'bookForm' },
+	      _react2.default.createElement(_Cover2.default, { book: book, loading: loading }),
+	      _react2.default.createElement(
+	        'form',
+	        null,
+	        _react2.default.createElement(
+	          'div',
+	          { className: 'item half' },
+	          _react2.default.createElement(
+	            'label',
+	            { htmlFor: 'isbn' },
+	            'ISBN'
+	          ),
+	          _react2.default.createElement(_ISBNInput2.default, {
+	            id: 'ISBN',
+	            value: book.get('ISBN'),
+	            onChange: this.handleChange
+	          })
+	        ),
+	        _react2.default.createElement(
+	          'div',
+	          { className: 'item half' },
+	          _react2.default.createElement(
+	            'label',
+	            { htmlFor: 'state' },
+	            'Status'
+	          ),
+	          _react2.default.createElement(
+	            'select',
+	            {
+	              id: 'state',
+	              value: book.get('state'),
+	              onChange: this.handleChange
+	            },
+	            _react2.default.createElement(
+	              'option',
+	              { value: _bookStates2.default.stock },
+	              'Stock'
+	            ),
+	            _react2.default.createElement(
+	              'option',
+	              { value: _bookStates2.default.reading },
+	              'Reading'
+	            ),
+	            _react2.default.createElement(
+	              'option',
+	              { value: _bookStates2.default.read },
+	              'Read'
+	            )
+	          )
+	        ),
+	        _react2.default.createElement(
+	          'div',
+	          { className: 'item full' },
+	          _react2.default.createElement(
+	            'label',
+	            { htmlFor: 'title' },
+	            'Title'
+	          ),
+	          _react2.default.createElement('input', {
+	            type: 'text',
+	            id: 'title',
+	            value: book.get('title'),
+	            onChange: this.handleChange
+	          })
+	        ),
+	        _react2.default.createElement(
+	          'div',
+	          { className: 'item half' },
+	          _react2.default.createElement(
+	            'label',
+	            { htmlFor: 'startDate' },
+	            'Start date'
+	          ),
+	          _react2.default.createElement('input', {
+	            type: 'date',
+	            id: 'startDate',
+	            value: book.get('startDate'),
+	            placeholder: 'YYYY-MM-DD',
+	            onChange: this.handleChange
+	          })
+	        ),
+	        _react2.default.createElement(
+	          'div',
+	          { className: 'item half' },
+	          _react2.default.createElement(
+	            'label',
+	            { htmlFor: 'endDate' },
+	            'End date'
+	          ),
+	          _react2.default.createElement('input', {
+	            type: 'date',
+	            id: 'endDate',
+	            value: book.get('endDate'),
+	            placeholder: 'YYYY-MM-DD',
+	            onChange: this.handleChange
+	          })
+	        )
+	      )
+	    );
+	  }
+	});
+
+/***/ },
+/* 445 */
+/***/ function(module, exports, __webpack_require__) {
+
+	var baseGet = __webpack_require__(446);
+
+	/**
+	 * Gets the value at `path` of `object`. If the resolved value is
+	 * `undefined`, the `defaultValue` is used in its place.
+	 *
+	 * @static
+	 * @memberOf _
+	 * @since 3.7.0
+	 * @category Object
+	 * @param {Object} object The object to query.
+	 * @param {Array|string} path The path of the property to get.
+	 * @param {*} [defaultValue] The value returned for `undefined` resolved values.
+	 * @returns {*} Returns the resolved value.
+	 * @example
+	 *
+	 * var object = { 'a': [{ 'b': { 'c': 3 } }] };
+	 *
+	 * _.get(object, 'a[0].b.c');
+	 * // => 3
+	 *
+	 * _.get(object, ['a', '0', 'b', 'c']);
+	 * // => 3
+	 *
+	 * _.get(object, 'a.b.c', 'default');
+	 * // => 'default'
+	 */
+	function get(object, path, defaultValue) {
+	  var result = object == null ? undefined : baseGet(object, path);
+	  return result === undefined ? defaultValue : result;
+	}
+
+	module.exports = get;
+
+
+/***/ },
+/* 446 */
+/***/ function(module, exports, __webpack_require__) {
+
+	var castPath = __webpack_require__(447),
+	    isKey = __webpack_require__(449),
+	    toKey = __webpack_require__(450);
+
+	/**
+	 * The base implementation of `_.get` without support for default values.
+	 *
+	 * @private
+	 * @param {Object} object The object to query.
+	 * @param {Array|string} path The path of the property to get.
+	 * @returns {*} Returns the resolved value.
+	 */
+	function baseGet(object, path) {
+	  path = isKey(path, object) ? [path] : castPath(path);
+
+	  var index = 0,
+	      length = path.length;
+
+	  while (object != null && index < length) {
+	    object = object[toKey(path[index++])];
+	  }
+	  return (index && index == length) ? object : undefined;
+	}
+
+	module.exports = baseGet;
+
+
+/***/ },
+/* 447 */
+/***/ function(module, exports, __webpack_require__) {
+
+	var isArray = __webpack_require__(276),
+	    stringToPath = __webpack_require__(448);
+
+	/**
+	 * Casts `value` to a path array if it's not one.
+	 *
+	 * @private
+	 * @param {*} value The value to inspect.
+	 * @returns {Array} Returns the cast property path array.
+	 */
+	function castPath(value) {
+	  return isArray(value) ? value : stringToPath(value);
+	}
+
+	module.exports = castPath;
+
+
+/***/ },
+/* 448 */
+/***/ function(module, exports, __webpack_require__) {
+
+	var memoize = __webpack_require__(408),
+	    toString = __webpack_require__(416);
+
+	/** Used to match property names within property paths. */
+	var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(\.|\[\])(?:\4|$))/g;
+
+	/** Used to match backslashes in property paths. */
+	var reEscapeChar = /\\(\\)?/g;
+
+	/**
+	 * Converts `string` to a property path array.
+	 *
+	 * @private
+	 * @param {string} string The string to convert.
+	 * @returns {Array} Returns the property path array.
+	 */
+	var stringToPath = memoize(function(string) {
+	  var result = [];
+	  toString(string).replace(rePropName, function(match, number, quote, string) {
+	    result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
+	  });
+	  return result;
+	});
+
+	module.exports = stringToPath;
+
+
+/***/ },
+/* 449 */
+/***/ function(module, exports, __webpack_require__) {
+
+	var isArray = __webpack_require__(276),
+	    isSymbol = __webpack_require__(335);
+
+	/** Used to match property names within property paths. */
+	var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
+	    reIsPlainProp = /^\w*$/;
+
+	/**
+	 * Checks if `value` is a property name and not a property path.
+	 *
+	 * @private
+	 * @param {*} value The value to check.
+	 * @param {Object} [object] The object to query keys on.
+	 * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
+	 */
+	function isKey(value, object) {
+	  if (isArray(value)) {
+	    return false;
+	  }
+	  var type = typeof value;
+	  if (type == 'number' || type == 'symbol' || type == 'boolean' ||
+	      value == null || isSymbol(value)) {
+	    return true;
+	  }
+	  return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
+	    (object != null && value in Object(object));
+	}
+
+	module.exports = isKey;
+
+
+/***/ },
+/* 450 */
+/***/ function(module, exports, __webpack_require__) {
+
+	var isSymbol = __webpack_require__(335);
+
+	/** Used as references for various `Number` constants. */
+	var INFINITY = 1 / 0;
+
+	/**
+	 * Converts `value` to a string key if it's not a string or symbol.
+	 *
+	 * @private
+	 * @param {*} value The value to inspect.
+	 * @returns {string|symbol} Returns the key.
+	 */
+	function toKey(value) {
+	  if (typeof value == 'string' || isSymbol(value)) {
+	    return value;
+	  }
+	  var result = (value + '');
+	  return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
+	}
+
+	module.exports = toKey;
+
+
+/***/ },
+/* 451 */
+/***/ function(module, exports, __webpack_require__) {
+
+	'use strict';
+
+	Object.defineProperty(exports, "__esModule", {
+	  value: true
+	});
+	exports.getBookData = getBookData;
+	exports.getMainColour = getMainColour;
+
+	var _jquery = __webpack_require__(452);
+
+	var _jquery2 = _interopRequireDefault(_jquery);
+
+	var _keys = __webpack_require__(453);
+
+	var _keys2 = _interopRequireDefault(_keys);
+
+	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+	var GOOGLE_API = 'https://www.googleapis.com/books/v1/volumes';
+	var TINT_API = '//tint.gnab.fr';
+
+	function getBookData(book) {
+	  var isbn = book.get('ISBN');
+
+	  // An ISBN is either 10 or 13 chars long
+	  if (!isbn || isbn.length != 10 && isbn.length != 13) return Promise.resolve(null);
+
+	  return new Promise(function (resolve, reject) {
+	    _jquery2.default.ajax({
+	      url: GOOGLE_API,
+	      data: {
+	        q: 'isbn:' + isbn,
+	        key: _keys2.default.google
+	      },
+	      success: function success(data) {
+	        resolve(data.totalItems === 0 ? null : data.items[0].volumeInfo);
+	      },
+	      error: function error(err) {
+	        return reject(err);
+	      }
+	    });
+	  });
+	}
+
+	function getMainColour(imageUrl) {
+	  return new Promise(function (resolve, reject) {
+	    _jquery2.default.ajax({
+	      url: TINT_API + '/' + imageUrl,
+	      success: function success(data) {
+	        return resolve(data.colour);
+	      },
+	      error: reject
+	    });
+	  });
+	}
+
+/***/ },
+/* 452 */
+/***/ function(module, exports, __webpack_require__) {
+
+	var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
+	 * jQuery JavaScript Library v3.0.0
+	 * https://jquery.com/
+	 *
+	 * Includes Sizzle.js
+	 * https://sizzlejs.com/
+	 *
+	 * Copyright jQuery Foundation and other contributors
+	 * Released under the MIT license
+	 * https://jquery.org/license
+	 *
+	 * Date: 2016-06-09T18:02Z
+	 */
+	( function( global, factory ) {
+
+		"use strict";
+
+		if ( typeof module === "object" && typeof module.exports === "object" ) {
+
+			// For CommonJS and CommonJS-like environments where a proper `window`
+			// is present, execute the factory and get jQuery.
+			// For environments that do not have a `window` with a `document`
+			// (such as Node.js), expose a factory as module.exports.
+			// This accentuates the need for the creation of a real `window`.
+			// e.g. var jQuery = require("jquery")(window);
+			// See ticket #14549 for more info.
+			module.exports = global.document ?
+				factory( global, true ) :
+				function( w ) {
+					if ( !w.document ) {
+						throw new Error( "jQuery requires a window with a document" );
+					}
+					return factory( w );
+				};
+		} else {
+			factory( global );
+		}
+
+	// Pass this if window is not defined yet
+	}( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
+
+	// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
+	// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
+	// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
+	// enough that all such attempts are guarded in a try block.
+	"use strict";
+
+	var arr = [];
+
+	var document = window.document;
+
+	var getProto = Object.getPrototypeOf;
+
+	var slice = arr.slice;
+
+	var concat = arr.concat;
+
+	var push = arr.push;
+
+	var indexOf = arr.indexOf;
+
+	var class2type = {};
+
+	var toString = class2type.toString;
+
+	var hasOwn = class2type.hasOwnProperty;
+
+	var fnToString = hasOwn.toString;
+
+	var ObjectFunctionString = fnToString.call( Object );
+
+	var support = {};
+
+
+
+		function DOMEval( code, doc ) {
+			doc = doc || document;
+
+			var script = doc.createElement( "script" );
+
+			script.text = code;
+			doc.head.appendChild( script ).parentNode.removeChild( script );
+		}
+
+
+	var
+		version = "3.0.0",
+
+		// Define a local copy of jQuery
+		jQuery = function( selector, context ) {
+
+			// The jQuery object is actually just the init constructor 'enhanced'
+			// Need init if jQuery is called (just allow error to be thrown if not included)
+			return new jQuery.fn.init( selector, context );
+		},
+
+		// Support: Android <=4.0 only
+		// Make sure we trim BOM and NBSP
+		rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
+
+		// Matches dashed string for camelizing
+		rmsPrefix = /^-ms-/,
+		rdashAlpha = /-([a-z])/g,
+
+		// Used by jQuery.camelCase as callback to replace()
+		fcamelCase = function( all, letter ) {
+			return letter.toUpperCase();
+		};
+
+	jQuery.fn = jQuery.prototype = {
+
+		// The current version of jQuery being used
+		jquery: version,
+
+		constructor: jQuery,
+
+		// The default length of a jQuery object is 0
+		length: 0,
+
+		toArray: function() {
 			return slice.call( this );
 		},

@@ -52174,151 +52695,25 @@
 	// Expose jQuery and $ identifiers, even in AMD
 	// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
 	// and CommonJS for browser emulators (#13566)
-	if ( !noGlobal ) {
-		window.jQuery = window.$ = jQuery;
-	}
-
-
-	return jQuery;
-	} ) );
-
-
-/***/ },
-/* 442 */
-/***/ function(module, exports) {
-
-	module.exports = {
-		"google": "AIzaSyCGJLle1uZO6BzHvdYdwY7JEHuHoz8Av-s"
-	};
-
-/***/ },
-/* 443 */
-/***/ function(module, exports, __webpack_require__) {
-
-	// style-loader: Adds some css to the DOM by adding a <style> tag
-
-	// load the styles
-	var content = __webpack_require__(444);
-	if(typeof content === 'string') content = [[module.id, content, '']];
-	// add the styles to the DOM
-	var update = __webpack_require__(439)(content, {});
-	if(content.locals) module.exports = content.locals;
-	// Hot Module Replacement
-	if(false) {
-		// When the styles change, update the <style> tags
-		if(!content.locals) {
-			module.hot.accept("!!./../../../node_modules/css-loader/index.js!./../../../node_modules/stylus-loader/index.js!./cover.styl", function() {
-				var newContent = require("!!./../../../node_modules/css-loader/index.js!./../../../node_modules/stylus-loader/index.js!./cover.styl");
-				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
-				update(newContent);
-			});
-		}
-		// When the module is disposed, remove the <style> tags
-		module.hot.dispose(function() { update(); });
-	}
-
-/***/ },
-/* 444 */
-/***/ function(module, exports, __webpack_require__) {
-
-	exports = module.exports = __webpack_require__(438)();
-	// imports
-
-
-	// module
-	exports.push([module.id, ".cover {\n  background: rgba(0,0,0,0.1);\n  height: 280px;\n  position: relative;\n  width: 180px;\n}\n.cover img {\n  display: block;\n  height: 200px;\n  left: 20px;\n  object-fit: contain;\n  position: absolute;\n  top: 20px;\n  width: 140px;\n}\n.cover .description {\n  background: linear-gradient(to top, #35495d 0%, #35495d 40%, transparent 100%);\n  bottom: 0;\n  display: flex;\n  flex-flow: column nowrap;\n  height: 160px;\n  justify-content: flex-end;\n  padding: 0 10px 10px;\n  position: absolute;\n  width: 100%;\n}\n.cover .description h3 {\n  font-size: 1.6rem;\n  margin-bottom: 5px;\n}\n.cover .description p {\n  font-size: 1rem;\n  margin: 0;\n  opacity: 0.7;\n}\n", ""]);
-
-	// exports
-
-
-/***/ },
-/* 445 */
-/***/ function(module, exports) {
-
-	'use strict';
-
-	Object.defineProperty(exports, "__esModule", {
-	  value: true
-	});
-	var ItemTypes = {
-	  BOOK: 'book'
-	};
-
-	exports.default = ItemTypes;
-
-/***/ },
-/* 446 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	Object.defineProperty(exports, "__esModule", {
-	  value: true
-	});
-
-	var _react = __webpack_require__(1);
-
-	var _react2 = _interopRequireDefault(_react);
-
-	var _reactAddonsPureRenderMixin = __webpack_require__(261);
-
-	var _reactAddonsPureRenderMixin2 = _interopRequireDefault(_reactAddonsPureRenderMixin);
-
-	var _ActionBar = __webpack_require__(447);
-
-	var _ActionBar2 = _interopRequireDefault(_ActionBar);
-
-	var _Button = __webpack_require__(425);
-
-	var _Button2 = _interopRequireDefault(_Button);
-
-	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
-	var DEFAULT_TITLE = 'Chapter';
-
-	exports.default = _react2.default.createClass({
-	  displayName: 'Header',
-	  mixins: [_reactAddonsPureRenderMixin2.default],
-	  propTypes: {
-	    title: _react2.default.PropTypes.string,
-	    backButton: _react2.default.PropTypes.bool,
-	    children: _react2.default.PropTypes.oneOfType([_react2.default.PropTypes.element, _react2.default.PropTypes.arrayOf(_react2.default.PropTypes.element)])
-	  },
-	  contextTypes: {
-	    router: _react2.default.PropTypes.object
-	  },
-	  goBack: function goBack() {
-	    this.context.router.goBack();
-	  },
-	  render: function render() {
-	    var title = this.props.title || DEFAULT_TITLE;
-	    var addPreTitle = title !== DEFAULT_TITLE;
-
-	    return _react2.default.createElement(
-	      'header',
-	      null,
-	      this.props.backButton && _react2.default.createElement(_Button2.default, { click: this.goBack, label: '<', className: 'back' }),
-	      addPreTitle && _react2.default.createElement(
-	        'p',
-	        null,
-	        DEFAULT_TITLE
-	      ),
-	      _react2.default.createElement(
-	        'h1',
-	        null,
-	        title
-	      ),
-	      _react2.default.createElement(
-	        _ActionBar2.default,
-	        null,
-	        this.props.children
-	      )
-	    );
-	  }
-	});
+	if ( !noGlobal ) {
+		window.jQuery = window.$ = jQuery;
+	}
+
+
+	return jQuery;
+	} ) );
+

 /***/ },
-/* 447 */
+/* 453 */
+/***/ function(module, exports) {
+
+	module.exports = {
+		"google": "changeme"
+	};
+
+/***/ },
+/* 454 */
 /***/ function(module, exports, __webpack_require__) {

 	'use strict';
@@ -52327,6 +52722,8 @@
 	  value: true
 	});

+	var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
+
 	var _react = __webpack_require__(1);

 	var _react2 = _interopRequireDefault(_react);
@@ -52335,349 +52732,864 @@

 	var _reactAddonsPureRenderMixin2 = _interopRequireDefault(_reactAddonsPureRenderMixin);

+	var _reactInputMask = __webpack_require__(455);
+
+	var _reactInputMask2 = _interopRequireDefault(_reactInputMask);
+
 	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

+	function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
+
+	var ISBN_REGEX = /^(9(7[89]?)?)?/;
+	var ISBN_10_MASK = '9 999 99999 9';
+	var ISBN_13_MASK = '999 ' + ISBN_10_MASK;
+
 	exports.default = _react2.default.createClass({
-	  displayName: 'ActionBar',
+	  displayName: 'ISBNInput',
 	  mixins: [_reactAddonsPureRenderMixin2.default],
 	  propTypes: {
-	    children: _react2.default.PropTypes.oneOfType([_react2.default.PropTypes.element, _react2.default.PropTypes.arrayOf(_react2.default.PropTypes.element)])
+	    onChange: _react2.default.PropTypes.func
+	  },
+	  getInitialState: function getInitialState() {
+	    return { mask: ISBN_13_MASK };
+	  },
+	  handleChange: function handleChange(e) {
+	    var value = e.target.value.split(' ').join('');
+	    e.target.value = value;
+
+	    this.setState({
+	      mask: ISBN_REGEX.test(value) ? ISBN_13_MASK : ISBN_10_MASK
+	    });
+
+	    this.props.onChange(e);
 	  },
 	  render: function render() {
-	    return _react2.default.createElement(
-	      'nav',
-	      null,
-	      this.props.children
-	    );
-	  }
-	});
+	    var extraProps = _objectWithoutProperties(this.props, []);

-/***/ },
-/* 448 */
-/***/ function(module, exports) {
+	    var mask = this.state.mask;

-	'use strict';

-	Object.defineProperty(exports, "__esModule", {
-	  value: true
+	    return _react2.default.createElement(_reactInputMask2.default, _extends({
+	      mask: mask,
+	      maskChar: null,
+	      placeholder: '000 0 000 00000 0',
+	      onChange: this.handleChange,
+	      type: 'text'
+	    }, extraProps));
+	  }
 	});
-	exports.default = {
-	  stock: 'stock',
-	  reading: 'reading',
-	  read: 'read'
-	};

 /***/ },
-/* 449 */
+/* 455 */
 /***/ function(module, exports, __webpack_require__) {

-	// style-loader: Adds some css to the DOM by adding a <style> tag
+	// https://github.com/sanniassin/react-input-mask

-	// load the styles
-	var content = __webpack_require__(450);
-	if(typeof content === 'string') content = [[module.id, content, '']];
-	// add the styles to the DOM
-	var update = __webpack_require__(439)(content, {});
-	if(content.locals) module.exports = content.locals;
-	// Hot Module Replacement
-	if(false) {
-		// When the styles change, update the <style> tags
-		if(!content.locals) {
-			module.hot.accept("!!./../../../node_modules/css-loader/index.js!./../../../node_modules/stylus-loader/index.js!./library.styl", function() {
-				var newContent = require("!!./../../../node_modules/css-loader/index.js!./../../../node_modules/stylus-loader/index.js!./library.styl");
-				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
-				update(newContent);
-			});
-		}
-		// When the module is disposed, remove the <style> tags
-		module.hot.dispose(function() { update(); });
-	}
+	"use strict";

-/***/ },
-/* 450 */
-/***/ function(module, exports, __webpack_require__) {
+	var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

-	exports = module.exports = __webpack_require__(438)();
-	// imports
+	var React = __webpack_require__(1);

+	var InputElement = React.createClass({
+	    displayName: "InputElement",

-	// module
-	exports.push([module.id, ".collections {\n  display: flex;\n  flex-flow: row wrap;\n  justify-content: space-between;\n}\n.collections section {\n  height: 320px;\n  max-width: 100%;\n  overflow-y: auto;\n}\n.collections section ul {\n  display: flex;\n  flex-flow: row nowrap;\n  justify-content: flex-start;\n  list-style: none;\n  margin: 0;\n  padding: 0;\n}\n.collections section ul li {\n  margin-right: 20px;\n}\n.collections section ul li:last-child {\n  margin: 0;\n}\n.collections section .announce {\n  color: rgba(255,255,255,0.9);\n  font-size: 1.8rem;\n  left: 50%;\n  margin: 0;\n  position: absolute;\n  top: 50%;\n  transform: translate(-50%, -50%);\n}\n.collections section .announce .button {\n  box-shadow: 0 1px 2px rgba(0,0,0,0.5);\n  height: 30px;\n  line-height: 30px;\n  margin: 0 5px;\n}\n.collections section.stock {\n  background: #ecf0f1;\n  padding: 20px 60px 20px 80px;\n  position: relative;\n  flex-basis: 100%;\n}\n.collections section.stock h2,\n.collections section.stock::before {\n  background: #bdc3c7;\n  bottom: 0;\n  color: transparent;\n  content: '';\n  font-size: 1.8rem;\n  height: 20px;\n  line-height: 20px;\n  position: absolute;\n  right: 100%;\n  text-align: center;\n  top: 0;\n  transition: 0.5s;\n  transform: rotate(-90deg);\n  transform-origin: top right;\n  width: 320px;\n}\n.collections section.stock:hover h2,\n.collections section.stock.hover h2 {\n  color: rgba(255,255,255,0.8);\n  height: 40px;\n  line-height: 40px;\n}\n.collections section.stock .announce {\n  color: rgba(0,0,0,0.6);\n}\n.collections section.reading {\n  background: #f0c330;\n  padding: 20px 60px 20px 80px;\n  position: relative;\n  flex-basis: auto;\n  transition: 0.5s;\n}\n.collections section.reading h2,\n.collections section.reading::before {\n  background: #f19b2c;\n  bottom: 0;\n  color: transparent;\n  content: '';\n  font-size: 1.8rem;\n  height: 20px;\n  line-height: 20px;\n  position: absolute;\n  right: 100%;\n  text-align: center;\n  top: 0;\n  transition: 0.5s;\n  transform: rotate(-90deg);\n  transform-origin: top right;\n  width: 320px;\n}\n.collections section.reading:hover h2,\n.collections section.reading.hover h2 {\n  color: rgba(255,255,255,0.8);\n  height: 40px;\n  line-height: 40px;\n}\n.collections section.reading.hide {\n  min-width: 0;\n  padding: 0;\n}\n.collections section.reading.hover {\n  min-width: 320px;\n}\n.collections section.read {\n  background: #2fd1af;\n  padding: 20px 60px 20px 80px;\n  position: relative;\n  flex-basis: 50%;\n  flex-grow: 1;\n}\n.collections section.read h2,\n.collections section.read::before {\n  background: #239f85;\n  bottom: 0;\n  color: transparent;\n  content: '';\n  font-size: 1.8rem;\n  height: 20px;\n  line-height: 20px;\n  position: absolute;\n  right: 100%;\n  text-align: center;\n  top: 0;\n  transition: 0.5s;\n  transform: rotate(-90deg);\n  transform-origin: top right;\n  width: 320px;\n}\n.collections section.read:hover h2,\n.collections section.read.hover h2 {\n  color: rgba(255,255,255,0.8);\n  height: 40px;\n  line-height: 40px;\n}\n", ""]);
+	    defaultCharsRules: {
+	        "9": "[0-9]",
+	        "a": "[A-Za-z]",
+	        "*": "[A-Za-z0-9]"
+	    },
+	    defaultMaskChar: "_",
+	    lastCaretPos: null,
+	    isAndroidBrowser: function () {
+	        var windows = new RegExp("windows", "i");
+	        var firefox = new RegExp("firefox", "i");
+	        var android = new RegExp("android", "i");
+	        var ua = navigator.userAgent;
+	        return !windows.test(ua) && !firefox.test(ua) && android.test(ua);
+	    },
+	    isWindowsPhoneBrowser: function () {
+	        var windows = new RegExp("windows", "i");
+	        var phone = new RegExp("phone", "i");
+	        var ua = navigator.userAgent;
+	        return windows.test(ua) && phone.test(ua);
+	    },
+	    isAndroidFirefox: function () {
+	        var windows = new RegExp("windows", "i");
+	        var firefox = new RegExp("firefox", "i");
+	        var android = new RegExp("android", "i");
+	        var ua = navigator.userAgent;
+	        return !windows.test(ua) && firefox.test(ua) && android.test(ua);
+	    },
+	    isDOMElement: function (element) {
+	        return typeof HTMLElement === "object" ? element instanceof HTMLElement // DOM2
+	        : element.nodeType === 1 && typeof element.nodeName === "string";
+	    },
+	    // getDOMNode is deprecated but we need it to stay compatible with React 0.12
+	    getInputDOMNode: function () {
+	        var input = this.refs.input;

-	// exports
+	        if (!input) {
+	            return null;
+	        }

+	        // React 0.14
+	        if (this.isDOMElement(input)) {
+	            return input;
+	        }

-/***/ },
-/* 451 */
-/***/ function(module, exports, __webpack_require__) {
+	        return input.getDOMNode();
+	    },
+	    enableValueAccessors: function () {
+	        var _this = this;
+
+	        var canUseAccessors = !!(Object.getOwnPropertyDescriptor && Object.getPrototypeOf && Object.defineProperty);
+	        if (canUseAccessors) {
+	            var input = this.getInputDOMNode();
+	            this.valueDescriptor = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(input), 'value');
+	            Object.defineProperty(input, 'value', {
+	                configurable: true,
+	                enumerable: true,
+	                get: function () {
+	                    return _this.value;
+	                },
+	                set: function (val) {
+	                    _this.value = val;
+	                    _this.valueDescriptor.set.call(input, val);
+	                }
+	            });
+	        }
+	    },
+	    disableValueAccessors: function () {
+	        var valueDescriptor = this.valueDescriptor;

-	'use strict';
+	        if (!valueDescriptor) {
+	            return;
+	        }
+	        this.valueDescriptor = null;
+	        var input = this.getInputDOMNode();
+	        Object.defineProperty(input, 'value', valueDescriptor);
+	    },
+	    getInputValue: function () {
+	        var input = this.getInputDOMNode();
+	        var valueDescriptor = this.valueDescriptor;

-	Object.defineProperty(exports, "__esModule", {
-	  value: true
-	});
+	        var value;
+	        if (valueDescriptor) {
+	            value = valueDescriptor.get.call(input);
+	        } else {
+	            value = input.value;
+	        }

-	var _reactRedux = __webpack_require__(181);
+	        return value;
+	    },
+	    getPrefix: function () {
+	        var prefix = "";
+	        var mask = this.mask;

-	var _NewBook = __webpack_require__(452);
+	        for (var i = 0; i < mask.length && this.isPermanentChar(i); ++i) {
+	            prefix += mask[i];
+	        }
+	        return prefix;
+	    },
+	    getFilledLength: function () {
+	        var value = arguments.length <= 0 || arguments[0] === undefined ? this.state.value : arguments[0];

-	var _NewBook2 = _interopRequireDefault(_NewBook);
+	        var i;
+	        var maskChar = this.maskChar;

-	var _actionCreators = __webpack_require__(265);
+	        if (!maskChar) {
+	            return value.length;
+	        }

-	var actionCreators = _interopRequireWildcard(_actionCreators);
+	        for (i = value.length - 1; i >= 0; --i) {
+	            var character = value[i];
+	            if (!this.isPermanentChar(i) && this.isAllowedChar(character, i)) {
+	                break;
+	            }
+	        }

-	function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
+	        return ++i || this.getPrefix().length;
+	    },
+	    getLeftEditablePos: function (pos) {
+	        for (var i = pos; i >= 0; --i) {
+	            if (!this.isPermanentChar(i)) {
+	                return i;
+	            }
+	        }
+	        return null;
+	    },
+	    getRightEditablePos: function (pos) {
+	        var mask = this.mask;

-	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+	        for (var i = pos; i < mask.length; ++i) {
+	            if (!this.isPermanentChar(i)) {
+	                return i;
+	            }
+	        }
+	        return null;
+	    },
+	    isEmpty: function () {
+	        var _this2 = this;

-	var mapStateToProps = function mapStateToProps() {
-	  return {};
-	};
+	        var value = arguments.length <= 0 || arguments[0] === undefined ? this.state.value : arguments[0];

-	var NewBookContainer = (0, _reactRedux.connect)(mapStateToProps, actionCreators)(_NewBook2.default);
+	        return !value.split("").some(function (character, i) {
+	            return !_this2.isPermanentChar(i) && _this2.isAllowedChar(character, i);
+	        });
+	    },
+	    isFilled: function () {
+	        var value = arguments.length <= 0 || arguments[0] === undefined ? this.state.value : arguments[0];

-	exports.default = NewBookContainer;
+	        return this.getF…
43416ed

@kovzol kovzol pushed a commit to geogebra/geogebra that referenced this pull request Aug 8, 2016

@zbynek zbynek Removed the bit of jQuery that conflicts with require.js jquery/jquer…
…y#557/

git-svn-id: http://dev.geogebra.org/svn/trunk/geogebra@48714 23ce0884-8a58-47d3-bc5c-ddf1cd5b9f9e
a847c33

jdalton referenced this pull request in webpack/webpack Mar 11, 2017

Closed

Lodash is exported to window #4465

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment