diff --git a/.gitignore b/.gitignore
index 1b27a8b0..db172d59 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
-
-*.map
+.idea
+**/.idea
+apidocs/
+layout.js.map
diff --git a/.ruby-gemset b/.ruby-gemset
new file mode 100644
index 00000000..ae6e8360
--- /dev/null
+++ b/.ruby-gemset
@@ -0,0 +1 @@
+dreem
diff --git a/.ruby-version b/.ruby-version
new file mode 100644
index 00000000..b8d757e0
--- /dev/null
+++ b/.ruby-version
@@ -0,0 +1 @@
+ruby-2.0.0-p481
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 00000000..24c03deb
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,9 @@
+source 'https://rubygems.org'
+
+gem 'jsduck'
+
+gem 'rspec'
+gem 'capybara'
+gem 'poltergeist'
+gem 'selenium-webdriver'
+# gem 'capybara-webkit'
diff --git a/Gemfile.lock b/Gemfile.lock
new file mode 100644
index 00000000..b9512c2f
--- /dev/null
+++ b/Gemfile.lock
@@ -0,0 +1,70 @@
+GEM
+ remote: https://rubygems.org/
+ specs:
+ capybara (2.4.3)
+ mime-types (>= 1.16)
+ nokogiri (>= 1.3.3)
+ rack (>= 1.0.0)
+ rack-test (>= 0.5.4)
+ xpath (~> 2.0)
+ childprocess (0.5.5)
+ ffi (~> 1.0, >= 1.0.11)
+ cliver (0.3.2)
+ diff-lcs (1.2.5)
+ dimensions (1.2.0)
+ ffi (1.9.5)
+ jsduck (5.3.4)
+ dimensions (~> 1.2.0)
+ json (~> 1.8.0)
+ parallel (~> 0.7.1)
+ rdiscount (~> 2.1.6)
+ rkelly-remix (~> 0.0.4)
+ json (1.8.1)
+ mime-types (2.3)
+ mini_portile (0.6.0)
+ multi_json (1.10.1)
+ nokogiri (1.6.3.1)
+ mini_portile (= 0.6.0)
+ parallel (0.7.1)
+ poltergeist (1.5.1)
+ capybara (~> 2.1)
+ cliver (~> 0.3.1)
+ multi_json (~> 1.0)
+ websocket-driver (>= 0.2.0)
+ rack (1.5.2)
+ rack-test (0.6.2)
+ rack (>= 1.0)
+ rdiscount (2.1.7.1)
+ rkelly-remix (0.0.6)
+ rspec (3.1.0)
+ rspec-core (~> 3.1.0)
+ rspec-expectations (~> 3.1.0)
+ rspec-mocks (~> 3.1.0)
+ rspec-core (3.1.5)
+ rspec-support (~> 3.1.0)
+ rspec-expectations (3.1.2)
+ diff-lcs (>= 1.2.0, < 2.0)
+ rspec-support (~> 3.1.0)
+ rspec-mocks (3.1.2)
+ rspec-support (~> 3.1.0)
+ rspec-support (3.1.1)
+ rubyzip (1.1.6)
+ selenium-webdriver (2.43.0)
+ childprocess (~> 0.5)
+ multi_json (~> 1.0)
+ rubyzip (~> 1.0)
+ websocket (~> 1.0)
+ websocket (1.2.1)
+ websocket-driver (0.3.4)
+ xpath (2.0.0)
+ nokogiri (~> 1.3)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ capybara
+ jsduck
+ poltergeist
+ rspec
+ selenium-webdriver
diff --git a/LICENSE.md b/LICENSE.md
index 3562e7f6..f279c3c0 100644
--- a/LICENSE.md
+++ b/LICENSE.md
@@ -1,6 +1,6 @@
The MIT License (MIT)
-Copyright (c) 2012 Max Carlson
+Copyright (c) 2014 Teem2 LLC
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index 9e52e0e4..04d3b4f9 100644
--- a/README.md
+++ b/README.md
@@ -1,17 +1,122 @@
-rheses
+dreem
======
+getting started with dreem
+--------------------------
+It is quick and easy to get started writing your dreem application. After cloning the project, you will need to serve the dreem files through a web server to satisfy the browser's same-origin policy. SimpleHTTPServer is a quick and easy option to get started. From within the dreem root directory just run:
+ python -m SimpleHTTPServer
+
+This will turn that directory into a webserver and allow you to run any of the example files on localhost, such as [http://localhost:8000/data.html]()
+
+That's all you need to do to get set up to build a dreem application. There are many sample files in the root directory that you can reference to get familiar with the language. You will also want to build the API documentation to run on your machine as it is currently not hosted anywhere on the web. This is a simple process, and instructions are included below.
+
+You can put your dreem files right in the root dreem directory or a subdirectory to get started. However, if you want to keep your files in source control its helpful to keep them separate from the dreem git repo. You can easily do so by creating a softlink in the dreem directory that points to a separate directory located elsewhere in your machine. For example, if your dreem installation is located at ~/dev/dreem, and you want to keep your dreem application in ~/dev/mydreemapp, then within ~/dev/dreem run:
+
+ ln -s ~/dev/mydreemapp ./mydreemapp
+
+Now you can access your files at http://localhost:8000/mydreemapp/
+
+installing the sublime plugin
+-----------------------------
+
+For Sublime Text, use the preferences -> browse packages menu, back out a folder and browse to 'Installed Packages', then copy /tools/Dreem.sublime-package there.
building
--------
+This is only required when editing the coffeescript core.
+Make sure coffescript is installed
- coffee -j layout.js -mo ./ -cw *.coffee
+ npm install -g coffee-script
+
+And run
+ coffee -mo ./ -cw *.coffee
+
+building the documentation
+--------------------------
-running
---------
+The API docs are built with [https://github.com/senchalabs/jsduck](). Install jsduck as a ruby gem using bundler by running
- python -m SimpleHTTPServer
+ gem install bundler
+ bundle install
+
+If you are using rvm or similar your gems will be installed in a gemset called 'dreem'.
+
+With jsduck installed run:
+
+ ./bin/builddocs
+
+running smoke tests
+--------------------------
+
+The smoke tests docs are run with [http://phantomjs.org/](), so you'll need to install it. Next, run:
+
+ phantomjs ./bin/phantomrunner.js
+
+If you get RESOURCE ERROR messages, try specifying a different timeout argument. The smaller the number, the faster the tests will run:
+
+ phantomjs ./bin/phantomrunner.js 100
+
+running the component tests
+--------------------------
+
+The components are tested with rspec and capybara. You will need to install the required gems to run them. If you haven't already:
+
+ gem install bundler
+ bundle install
-and visit [http://localhost:8000/data.html]()
+Now to run the specs run
+
+ rspec
+
+If you see an error like:
+
+ Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
+
+ ruby extconf.rb
+ Command 'qmake -spec macx-g++ ' not available
+
+ Makefile not found
+
+ Gem files will remain installed in /Users/maxcarlson/.rvm/gems/ruby-2.0.0-p481@dreem/gems/capybara-webkit-1.3.0 for inspection.
+ Results logged to /Users/maxcarlson/.rvm/gems/ruby-2.0.0-p481@dreem/extensions/x86_64-darwin-13/2.0.0-static/capybara-webkit-1.3.0/gem_make.out
+
+ An error occurred while installing capybara-webkit (1.3.0), and Bundler cannot continue.
+ Make sure that `gem install capybara-webkit -v '1.3.0'` succeeds before bundling.
+
+Per [http://stackoverflow.com/questions/11354656/error-error-error-installing-capybara-webkit]() if you are in Ubuntu:
+
+ sudo apt-get install qt4-dev-tools libqt4-dev libqt4-core libqt4-gui
+
+If you are on Mac
+
+ brew install qt
+
+Then run this again:
+
+ bundle install
+
+Windows users: capybara-webkit can only install on a 32-bit version of Windows. See [https://github.com/thoughtbot/capybara-webkit#windows-support]()
+
+
diff --git a/audio.html b/audio.html
new file mode 100644
index 00000000..14976d41
--- /dev/null
+++ b/audio.html
@@ -0,0 +1,115 @@
+
+
+ dr33m
+
+
+
+
+
+
+
+
+
+
+
+
+
+ // Deal with JSON.stringify() issues by converting to a regular array
+ var copy = Array.apply([], fft);
+ bus.send('fft', copy);
+
+
+
+
+
+
+
+
+ minutes = Math.floor(time / 60)
+ seconds = Math.floor(time) - minutes * 60
+ seconds = '0' + seconds if (seconds < 10)
+ return minutes + ':' + seconds
+
+
+
+
+
+
+
+
+
+ if (audio.playing) {
+ audio.setAttribute('paused', ! audio.paused);
+ } else {
+ audio.setAttribute('playing', true);
+ }
+
+
+ if (audio.loaded) {
+ this.setAttribute('class', 'fa fa-play')
+ if (audio.playing && ! audio.paused) {
+ this.setAttribute('class', 'fa fa-pause')
+ } else {
+ this.setAttribute('class', 'fa fa-play')
+ }
+ } else {
+ this.setAttribute('class', 'fa fa-spin fa-spinner')
+ }
+
+
+
+
+
+
+
+ /
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bin/builddocs b/bin/builddocs
new file mode 100755
index 00000000..5ef08cb5
--- /dev/null
+++ b/bin/builddocs
@@ -0,0 +1,5 @@
+git reset ./docs/api/
+rm -rf docs/api/
+coffee -mo ./ -c *.coffee
+node ./bin/finddoccomments.js > ./classdocs.js
+jsduck layout.js classdocs.js --output=./docs/api/ --eg-iframe=jsduck_iframe.html --title="Dreem API documentation" --footer="Copyright (c) 2014 Teem2 LLC"
diff --git a/bin/expected.txt b/bin/expected.txt
new file mode 100644
index 00000000..898e454b
--- /dev/null
+++ b/bin/expected.txt
@@ -0,0 +1,5 @@
+Unrecognized class goodbye
+attribute.value must be defined on inside
+
+
+Invalid type 'text' for attribute 'something', must be one of: number, boolean, string, json, expression
\ No newline at end of file
diff --git a/bin/finddoccomments.js b/bin/finddoccomments.js
new file mode 100644
index 00000000..f84fd6a8
--- /dev/null
+++ b/bin/finddoccomments.js
@@ -0,0 +1,47 @@
+/*
+The MIT License (MIT)
+
+Copyright ( c ) 2014 Teem2 LLC
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+var fs = require('fs');
+
+var basepath = "./classes/"
+
+var regex = /\/\*\*([\S\s]*?)\*\//mg
+
+fs.readdir(basepath,function(err,files){
+ if(err) throw err;
+ files.forEach(function(file){
+ if (file.indexOf('.dre') == -1) return
+ // console.log(basepath + file)
+ var data = fs.readFileSync(basepath + file, {encoding: 'utf-8'});
+ var matches = data.toString().match(regex);
+
+ if (matches) {
+ matches.forEach(function(match){
+ match = match.replace('', '');
+ console.log(match)
+ });
+ }
+ });
+});
\ No newline at end of file
diff --git a/bin/findrequired.js b/bin/findrequired.js
new file mode 100644
index 00000000..d34cfc1b
--- /dev/null
+++ b/bin/findrequired.js
@@ -0,0 +1,55 @@
+/*
+The MIT License (MIT)
+
+Copyright ( c ) 2014 Teem2 LLC
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+var fs = require('fs');
+var jpath = require('json-path');
+
+var basepath = "./docs/api/"
+
+var regex = /{(.*)}/g
+
+fs.readdir(basepath, function(err, files) {
+ if (err) throw err;
+ files.forEach(function(file) {
+ if (file.indexOf('data-') !== 0) return;
+ // console.log(basepath + file)
+ var filecontents = fs.readFileSync(basepath + file, {
+ encoding: 'utf-8'
+ });
+ var matches = filecontents.toString().match(regex);
+ var data = JSON.parse(matches[0]);
+
+ var res = jpath.executeSelectors(data, jpath.parseSelector("/data/search[*]"));
+ var out = {}
+ res.forEach(function(d, i) {
+ if (!d.meta.required)
+ return;
+ classAndName = d.fullName.substring(3).split('.')
+ if (! out[classAndName[0]])
+ out[classAndName[0]] = {};
+ out[classAndName[0]][classAndName[1]] = 1;
+ })
+ console.log(JSON.stringify(out));
+ });
+});
\ No newline at end of file
diff --git a/bin/node_modules/json-path/.npmignore b/bin/node_modules/json-path/.npmignore
new file mode 100644
index 00000000..4fab4df2
--- /dev/null
+++ b/bin/node_modules/json-path/.npmignore
@@ -0,0 +1 @@
+component.json
\ No newline at end of file
diff --git a/bin/node_modules/json-path/.travis.yml b/bin/node_modules/json-path/.travis.yml
new file mode 100644
index 00000000..9c700cee
--- /dev/null
+++ b/bin/node_modules/json-path/.travis.yml
@@ -0,0 +1,12 @@
+language: node_js
+branches:
+ only:
+ - master
+node_js:
+ - "0.10"
+ - "0.9"
+ - "0.8"
+
+notifications:
+ email:
+ - phillip@flitbit.com
\ No newline at end of file
diff --git a/bin/node_modules/json-path/README.md b/bin/node_modules/json-path/README.md
new file mode 100644
index 00000000..15b07335
--- /dev/null
+++ b/bin/node_modules/json-path/README.md
@@ -0,0 +1,207 @@
+json-path (alpha) [](http://travis-ci.org/flitbit/json-path)
+=========
+
+JSON-Path utility (XPath for JSON) for nodejs and modern browsers.
+
+You may be looking for the prior work [found here](http://goessner.net/articles/JsonPath/). This implementation is a new JSON-Path syntax building on [JSON Pointer (RFC 6901)](http://tools.ietf.org/html/rfc6901) in order to ensure that any valid JSON pointer is also valid JSON-Path.
+
+**Warning:** This is a work in progress - I am actively adding selection expressions and have yet to optimize, but as I use it in a few other projects I went ahead and made it available via `npm`. Until I take the **alpha** tag off you should look to the examples and test to understand the selection path syntax.
+
+## Example
+
+[flikr-example-2.js](https://github.com/flitbit/json-path/blob/master/examples/flikr-example-2.js)
+```javascript
+var jpath = require('json-path')
+, http = require('http')
+, util = require('util')
+;
+
+var feed = "http://api.flickr.com/services/feeds/photos_public.gne?tags=beach,pipeline&tagmode=all&format=json&jsoncallback=processResponse"
+;
+
+function processResponse(json) {
+ var res = jpath.resolve(json, "#/items[first(3)]take(/title,/author,media=/media/m)")
+ console.log( util.inspect(res, false, 5) );
+}
+
+http.get(feed, function(res) {
+ console.log("Got response: " + res.statusCode);
+
+ var data = '';
+
+ res.on('data', function (chunk){
+ data += chunk;
+ });
+
+ res.on('end',function(){
+ // result is formatted as jsonp... this is for illustration only.
+ eval(data);
+ })
+}).on('error', function(e) {
+ console.log("Got error: " + e.message);
+});
+```
+
+## Installation
+
+[node.js](http://nodejs.org)
+```bash
+$ npm install json-path
+```
+
+## Basics
+
+JSON-Path takes a specially formatted *path* statement and applies it to an object graph in order to *select* results. The results are returned as an array of data that matches the path.
+
+Most paths start out looking like a JSON Pointer...
+
+```javascript
+// From: http://goessner.net/articles/JsonPath/
+var data = {
+ store: {
+ book: [
+ { category: "reference",
+ author: "Nigel Rees",
+ title: "Sayings of the Century",
+ price: 8.95
+ },
+ { category: "fiction",
+ author: "Evelyn Waugh",
+ title: "Sword of Honour",
+ price: 12.99
+ },
+ { category: "fiction",
+ author: "Herman Melville",
+ title: "Moby Dick",
+ isbn: "0-553-21311-3",
+ price: 8.99
+ },
+ { category: "fiction",
+ author: "J. R. R. Tolkien",
+ title: "The Lord of the Rings",
+ isbn: "0-395-19395-8",
+ price: 22.99
+ }
+ ],
+ bicycle: {
+ color: "red",
+ price: 19.95
+ }
+ }
+};
+```
+
+The pointer `/store/book/0` refers to the first book in the array of books (the one by Nigen Rees).
+
+**Differentiator**
+
+The thing that makes JSON-Path different from JSON-Pointer is that you can do more than reference a single point in a structure. Instead, you are able to `select` many pieces of data out of a structure, such as:
+
+`/store/book[*]/price`
+```javascript
+[8.95, 12.99, 8.99, 22.99]
+```
+
+In the preceding example, the path `/store/book[*]/price` has three distinct statements:
+
+Statement | Meaning
+--- | ---
+`/store/book` | Get the book property from store. This is similar to `data.store.book` in javascript.
+`*` | Select any element (or property).
+`/price` | Select the price property.
+
+Starting with the original data, each statement refines the data, usually by selecting parts. As each statement is processed, it is given the results from the previous statement and may make further selections, until the final selections are returned to the caller. It works something like map-reduce; or if you like, something like list-comprehensions.
+
+**Distinguishing Statements**
+
+Statements are distinguished from one another using the square-brackets `[` and `]`. In many cases, the parser can infer where one statement ends and another begins, such as in the preceding example `/store/book[*]/price`. However, the parser understands the equivelant, fully specified path `[/store/book][*][/price]`.
+
+Paths can have as many distinct statements as you need to select just the right data. Since it extends JSON-Pointer, you must take care when your path contains square-brackets as part of property names such as the following contrived example:
+
+```javascript
+var data = {
+ 'my[': {
+ contrived: {
+ 'example]': { should: "mess with", your: "noodel" } } }
+};
+```
+
+In this data, the property names `my[` and `example]` are valid but would cuase ambiguities for either the parser or the processing of statements. In these cases, you must use the URI fragment identifier representation described in [RFC 6901 Section 6](http://tools.ietf.org/html/rfc6901#section-6). For instance, to access `data['my['].contrived['example]'].your` you would need the path `#/my%5B/contrived/example%5D/your`.
+
+### More Power
+
+JSON-Path becomes more powerful with a few additional types of statements:
+
+Statement | Meaning
+--- | ---
+`..` | Makes an exhaustive descent, executing the next statement against each branch of the object-graph.
+`take(s0,s1,...)` | Takes one or more items from the structure, each specified as a [JSON Pointer](http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-09).
+`@` | Uses the user-supplied function to select or filter data.
+
+Consider the following examples using the same preceding data:
+
+Path | Result
+--- | ---
+`/store[..]/price` | Selects all prices, from books and the bicycle.
+`../isbn` | Selects all ISBN numbers, wherever they are in the structure.
+`/store/book[*]take(/author,/title)` | Selects author and title from each book.
+`/store/book[*][@]` | Selects all books, providing each to the user-supplied selection method.
+
+**User Supplied Selection Methods**
+
+JSON-Path supports the use of user-supplied selections - which will need to fill in until the expression syntax is completed. Mindful of the preceding data, consider the following code:
+
+```javascript
+var jpath = require('json-path')
+, expect = require('expect.js')
+, data = require('./example-data')
+
+var p = jpath.create("#/store/book[*][@]");
+
+var res = p.resolve(data, function(obj, accum) {
+ if (typeof obj.price === 'number' && obj.price < 10)
+ accum.push(obj);
+ return accum;
+});
+
+// Expect the result to have the two books priced under $10...
+expect(res).to.contain(data["store"]["book"][0]);
+expect(res).to.contain(data["store"]["book"][2]);
+expect(res).to.have.length(2);
+
+```
+
+The example above illustrates user-defined selection given to `resolve` used in place of the `@`.
+
+To use more than one user-defined selections, refer to selection functions by name and provide implementations when resolving the path:
+
+```javascript
+var jpath = require('json-path')
+, expect = require('expect.js')
+, data = require('./example-data')
+
+var p = jpath.create("#/store/book[*][@lt10][@format]");
+
+var res = p.resolve(data, {
+
+ lt10: function(obj, accum) {
+ if (typeof obj.price === 'number' && obj.price < 10)
+ accum.push(obj);
+ return accum;
+ },
+
+ format: function(obj, accum) {
+ accum.push(obj.title.concat(
+ ": $", obj.price
+ ));
+ return accum;
+ }
+
+});
+
+// Expect the result to have formatted strings for
+// the twb books priced under $10...
+expect(res).to.contain("Sayings of the Century: $8.95");
+expect(res).to.contain("Moby Dick: $8.99");
+expect(res).to.have.length(2);
+```
diff --git a/bin/node_modules/json-path/examples/example-data.json b/bin/node_modules/json-path/examples/example-data.json
new file mode 100644
index 00000000..f3fcb77c
--- /dev/null
+++ b/bin/node_modules/json-path/examples/example-data.json
@@ -0,0 +1,32 @@
+{
+ "store": {
+ "book": [
+ { "category": "reference",
+ "author": "Nigel Rees",
+ "title": "Sayings of the Century",
+ "price": 8.95
+ },
+ { "category": "fiction",
+ "author": "Evelyn Waugh",
+ "title": "Sword of Honour",
+ "price": 12.99
+ },
+ { "category": "fiction",
+ "author": "Herman Melville",
+ "title": "Moby Dick",
+ "isbn": "0-553-21311-3",
+ "price": 8.99
+ },
+ { "category": "fiction",
+ "author": "J. R. R. Tolkien",
+ "title": "The Lord of the Rings",
+ "isbn": "0-395-19395-8",
+ "price": 22.99
+ }
+ ],
+ "bicycle": {
+ "color": "red",
+ "price": 19.95
+ }
+ }
+}
\ No newline at end of file
diff --git a/bin/node_modules/json-path/examples/flikr-example-2.js b/bin/node_modules/json-path/examples/flikr-example-2.js
new file mode 100644
index 00000000..c386fffa
--- /dev/null
+++ b/bin/node_modules/json-path/examples/flikr-example-2.js
@@ -0,0 +1,29 @@
+var jpath = require('..')
+, http = require('http')
+, util = require('util')
+;
+
+var feed = "http://api.flickr.com/services/feeds/photos_public.gne?tags=beach,pipeline&tagmode=all&format=json&jsoncallback=processResponse"
+;
+
+function processResponse(json) {
+ var res = jpath.resolve(json, "#/items[first(3)]take(/title,/author,media=/media/m)")
+ console.log( util.inspect(res, false, 5) );
+}
+
+http.get(feed, function(res) {
+ console.log("Got response: " + res.statusCode);
+
+ var data = '';
+
+ res.on('data', function (chunk){
+ data += chunk;
+ });
+
+ res.on('end',function(){
+ // result is formatted as jsonp... this is for illustration only.
+ eval(data);
+ })
+}).on('error', function(e) {
+ console.log("Got error: " + e.message);
+});
\ No newline at end of file
diff --git a/bin/node_modules/json-path/examples/flikr-example.js b/bin/node_modules/json-path/examples/flikr-example.js
new file mode 100644
index 00000000..ac39bda6
--- /dev/null
+++ b/bin/node_modules/json-path/examples/flikr-example.js
@@ -0,0 +1,38 @@
+var jpath = require('..')
+, http = require('http')
+, util = require('util')
+;
+
+var feed = "http://api.flickr.com/services/feeds/photos_public.gne?tags=surf,pipeline&tagmode=all&format=json&jsoncallback=processResponse"
+;
+
+function processResponse(json) {
+ var p = jpath.create("#/items[first(3)][@]")
+ var res = p.resolve(json, function(obj, accum) {
+ accum.push({
+ title: obj.title,
+ author: obj.author,
+ media: obj.media.m
+ });
+ return accum;
+ });
+
+ console.log( util.inspect(res, false, 5) );
+}
+
+http.get(feed, function(res) {
+ console.log("Got response: " + res.statusCode);
+
+ var data = '';
+
+ res.on('data', function (chunk){
+ data += chunk;
+ });
+
+ res.on('end',function(){
+ // result is formatted as jsonp... this is for illustration only.
+ eval(data);
+ })
+}).on('error', function(e) {
+ console.log("Got error: " + e.message);
+});
diff --git a/bin/node_modules/json-path/examples/json-path-example.js b/bin/node_modules/json-path/examples/json-path-example.js
new file mode 100644
index 00000000..4c69b190
--- /dev/null
+++ b/bin/node_modules/json-path/examples/json-path-example.js
@@ -0,0 +1,184 @@
+var expect = require('expect.js'),
+util = require('util'),
+jpath = require('..')
+;
+
+// From: http://goessner.net/articles/JsonPath/
+var data = {
+ store: {
+ book: [
+ { category: "reference",
+ author: "Nigel Rees",
+ title: "Sayings of the Century",
+ price: 8.95
+ },
+ { category: "fiction",
+ author: "Evelyn Waugh",
+ title: "Sword of Honour",
+ price: 12.99
+ },
+ { category: "fiction",
+ author: "Herman Melville",
+ title: "Moby Dick",
+ isbn: "0-553-21311-3",
+ price: 8.99
+ },
+ { category: "fiction",
+ author: "J. R. R. Tolkien",
+ title: "The Lord of the Rings",
+ isbn: "0-395-19395-8",
+ price: 22.99
+ }
+ ],
+ bicycle: {
+ color: "red",
+ price: 19.95
+ }
+ }
+};
+
+// jpath preamble is $
+// -- path segments are interpreted the same as JSON Pointer,
+// with selector instructions in square brackets [].
+
+// select the root object:
+var p = jpath.create("#");
+var res = p.resolve(data);
+expect(res).to.contain(data);
+
+
+// select the authors of all books:
+p = jpath.parseSelector("#/store/book[*][#/author]");
+res = jpath.executeSelectors(data, p);
+expect(res).to.contain('Evelyn Waugh');
+expect(res).to.contain('Nigel Rees');
+expect(res).to.contain('Herman Melville');
+expect(res).to.contain('J. R. R. Tolkien');
+
+// select all authors:
+p = jpath.parseSelector("[..#/author]");
+res = jpath.executeSelectors(data, p);
+expect(res).to.contain('Evelyn Waugh');
+expect(res).to.contain('Nigel Rees');
+expect(res).to.contain('Herman Melville');
+expect(res).to.contain('J. R. R. Tolkien');
+
+// select all things in store
+p = jpath.parseSelector("#/store[*]");
+res = jpath.executeSelectors(data, p);
+expect(res).to.contain(data.store.book);
+expect(res).to.contain(data.store.bicycle);
+
+// resolved.should.eql(data);
+
+// select the price of everything in the store
+p = jpath.parseSelector("#/store[..#/price]");
+res = jpath.executeSelectors(data, p);
+expect(res).to.contain(8.95);
+expect(res).to.contain(12.99);
+expect(res).to.contain(8.99);
+expect(res).to.contain(22.99);
+expect(res).to.contain(19.95);
+
+
+// select the third book
+p = jpath.parseSelector("[..#/book/2]");
+res = jpath.executeSelectors(data, p);
+expect(res).to.contain(data.store.book[2]);
+
+p = jpath.parseSelector("[..#/book[2]]");
+res = jpath.executeSelectors(data, p);
+expect(res).to.contain(data.store.book[2]);
+
+// select the last book
+p = jpath.parseSelector("[..#/book[last]]");
+res = jpath.executeSelectors(data, p);
+expect(res).to.contain(data.store.book[3]);
+
+// select the first two books
+p = jpath.parseSelector("[..#/book[0,1]]");
+res = jpath.executeSelectors(data, p);
+expect(res).to.contain(data.store.book[0]);
+expect(res).to.contain(data.store.book[1]);
+
+// select books without an isbn
+p = jpath.parseSelector("[..#/book[*][#/isbn]]");
+res = jpath.executeSelectors(data, p);
+
+// select author and title from any book
+p = jpath.parseSelector("..#/book[*][take(/author,/title)]");
+res = jpath.executeSelectors(data, p);
+expect(res[0]).to.eql({
+ author: "Nigel Rees",
+ title: "Sayings of the Century"
+});
+expect(res[1]).to.eql({
+ author: "Evelyn Waugh",
+ title: "Sword of Honour"
+});
+expect(res[2]).to.eql({
+ author: "Herman Melville",
+ title: "Moby Dick"
+});
+expect(res[3]).to.eql({
+ author: "J. R. R. Tolkien",
+ title: "The Lord of the Rings"
+});
+
+// select title and price as cost from any book
+p = jpath.parseSelector("..#/book[*][take(/title,cost=/price)]");
+res = jpath.executeSelectors(data, p);
+expect(res[0]).to.eql({
+ title: "Sayings of the Century",
+ cost: 8.95
+});
+expect(res[1]).to.eql({
+ title: "Sword of Honour",
+ cost: 12.99
+});
+expect(res[2]).to.eql({
+ title: "Moby Dick",
+ cost: 8.99
+});
+expect(res[3]).to.eql({
+ title: "The Lord of the Rings",
+ cost: 22.99
+});
+
+// select books priced more than 10 via a selector fn
+// p = jpath.parseSelector("[..#/book[*][!{#/price < 10 || !exists(#/author)}][@myfn]]");
+p = jpath.parseSelector("[..#/book[*][@myfn]]");
+res = jpath.executeSelectors(data, p, {
+ myfn: function(obj, accum, sel) {
+ if (obj.price && obj.price < 10)
+ accum.push(obj);
+ return accum;
+ }
+});
+expect(res).to.contain(data.store.book[0]);
+expect(res).to.contain(data.store.book[2]);
+
+p = jpath.create("[..#/book[*][@myfn][#/category]]");
+res = p.resolve(data, {
+ myfn: function(obj, accum, sel) {
+ if (obj.price && obj.price < 10)
+ accum.push(obj);
+ return accum;
+ }
+});
+expect(res).to.contain(data.store.book[0].category);
+expect(res).to.contain(data.store.book[2].category);
+
+p = jpath.resolve(data, '/store/book[first(2)]');
+
+p = jpath.create("#/store/book[*][@]");
+var res = p.resolve(data, function(obj, accum, sel) {
+ if (obj.price && obj.price < 10)
+ accum.push(obj);
+ return accum;
+});
+expect(res).to.contain(data["store"]["book"][0]);
+expect(res).to.contain(data["store"]["book"][2]);
+expect(res).to.have.length(2);
+
+// p = jpath.parseSelector("[..#/book[*][{#/price >= 10}]]");
diff --git a/bin/node_modules/json-path/examples/readme-snippet-0.js b/bin/node_modules/json-path/examples/readme-snippet-0.js
new file mode 100644
index 00000000..2dc0b1ad
--- /dev/null
+++ b/bin/node_modules/json-path/examples/readme-snippet-0.js
@@ -0,0 +1,16 @@
+var jpath = require('..')
+, expect = require('expect.js')
+, data = require('./example-data')
+
+var p = jpath.create("#/store/book[*][@]");
+
+var res = p.resolve(data, function(obj, accum) {
+ if (typeof obj.price === 'number' && obj.price < 10)
+ accum.push(obj);
+ return accum;
+});
+
+// Expect the result to have the two books priced under $10...
+expect(res).to.contain(data["store"]["book"][0]);
+expect(res).to.contain(data["store"]["book"][2]);
+expect(res).to.have.length(2);
diff --git a/bin/node_modules/json-path/examples/readme-snippet-1.js b/bin/node_modules/json-path/examples/readme-snippet-1.js
new file mode 100644
index 00000000..db3089ab
--- /dev/null
+++ b/bin/node_modules/json-path/examples/readme-snippet-1.js
@@ -0,0 +1,28 @@
+var jpath = require('..')
+, expect = require('expect.js')
+, data = require('./example-data')
+
+var p = jpath.create("#/store/book[*][@lt10][@format]");
+
+var res = p.resolve(data, {
+
+ lt10: function(obj, accum) {
+ if (typeof obj.price === 'number' && obj.price < 10)
+ accum.push(obj);
+ return accum;
+ },
+
+ format: function(obj, accum) {
+ accum.push(obj.title.concat(
+ ": $", obj.price
+ ));
+ return accum;
+ }
+
+});
+
+// Expect the result to have formatted strings for
+// the twb books priced under $10...
+expect(res).to.contain("Sayings of the Century: $8.95");
+expect(res).to.contain("Moby Dick: $8.99");
+expect(res).to.have.length(2);
diff --git a/bin/node_modules/json-path/examples/various-json-pointers.js b/bin/node_modules/json-path/examples/various-json-pointers.js
new file mode 100644
index 00000000..23e3da1a
--- /dev/null
+++ b/bin/node_modules/json-path/examples/various-json-pointers.js
@@ -0,0 +1,118 @@
+var expect = require('expect.js'),
+jpath = require('..')
+;
+
+var obj = {
+ a: 1,
+ b: {
+ c: 2
+ },
+ d: {
+ e: [{a:3}, {b:4}, {c:5}]
+ }
+};
+
+// JSON Pointers (as strings)
+
+var n = -1
+, ub = 1000
+, start = process.hrtime();
+
+
+while(++n < ub) {
+
+ expect(jpath.resolve(obj, "/a")).to.contain(1);
+ expect(jpath.resolve(obj, "/b/c")).to.contain(2);
+ expect(jpath.resolve(obj, "/d/e/0/a")).to.contain(3);
+ expect(jpath.resolve(obj, "/d/e/1/b")).to.contain(4);
+ expect(jpath.resolve(obj, "/d/e/2/c")).to.contain(5);
+
+ expect(jpath.resolve(obj, "")).to.contain(obj);
+}
+
+// JSON Pointers (as URI fragments)
+ub = ub * 2;
+n--;
+while(++n < ub) {
+
+ expect(jpath.resolve(obj, "#/a")).to.contain(1);
+ expect(jpath.resolve(obj, "#/b/c")).to.contain(2);
+ expect(jpath.resolve(obj, "#/d/e/0/a")).to.contain(3);
+ expect(jpath.resolve(obj, "#/d/e/1/b")).to.contain(4);
+ expect(jpath.resolve(obj, "#/d/e/2/c")).to.contain(5);
+
+ expect(jpath.resolve(obj, "#")).to.contain(obj);
+}
+
+var complexKeys = {
+ "a/b": {
+ c: 1
+ },
+ d: {
+ "e/f": 2
+ },
+ "~1": 3,
+ "01": 4
+}
+
+expect(jpath.resolve(complexKeys, "/a~1b/c")).to.contain(1);
+expect(jpath.resolve(complexKeys, "/d/e~1f")).to.contain(2);
+expect(jpath.resolve(complexKeys, "/~01")).to.contain(3);
+expect(jpath.resolve(complexKeys, "/01")).to.contain(4);
+expect(jpath.resolve(complexKeys, "/a/b/c")).to.be.empty();
+expect(jpath.resolve(complexKeys, "/~1")).to.be.empty();
+
+// draft-ietf-appsawg-json-pointer-08 has special array rules
+var ary = [ "zero", "one", "two" ];
+expect(jpath.resolve(ary, "/01")).to.be.empty();
+
+// Examples from the draft:
+var example = {
+ "foo": ["bar", "baz"],
+ "": 0,
+ "a/b": 1,
+ "c%d": 2,
+ "e^f": 3,
+ "g|h": 4,
+ "i\\j": 5,
+ "k\"l": 6,
+ " ": 7,
+ "m~n": 8
+};
+
+var p = jpath.create('#/foo');
+expect(p.resolve(example)).to.contain(example["foo"]);
+
+expect(jpath.resolve(example, "")).to.contain(example);
+var ans = jpath.resolve(example, "/foo");
+expect(ans.length).to.be(1);
+expect(ans[0][0]).to.contain("bar");
+expect(ans[0][1]).to.contain("baz");
+expect(jpath.resolve(example, "/foo/0")).to.contain("bar");
+expect(jpath.resolve(example, "/")).to.contain(0);
+expect(jpath.resolve(example, "/a~1b")).to.contain(1);
+expect(jpath.resolve(example, "/c%d")).to.contain(2);
+expect(jpath.resolve(example, "/e^f")).to.contain(3);
+expect(jpath.resolve(example, "/g|h")).to.contain(4);
+expect(jpath.resolve(example, "/i\\j")).to.contain(5);
+expect(jpath.resolve(example, "/k\"l")).to.contain(6);
+expect(jpath.resolve(example, "/ ")).to.contain(7);
+expect(jpath.resolve(example, "/m~0n")).to.contain(8);
+
+expect(jpath.resolve(example, "#")).to.contain(example);
+var ans = jpath.resolve(example, "#/foo");
+expect(ans.length).to.be(1);
+expect(ans[0][0]).to.contain("bar");
+expect(ans[0][1]).to.contain("baz");
+expect(jpath.resolve(example, "#/foo/0")).to.contain("bar");
+expect(jpath.resolve(example, "#/")).to.contain(0);
+expect(jpath.resolve(example, "#/a~1b")).to.contain(1);
+expect(jpath.resolve(example, "#/c%25d")).to.contain(2);
+expect(jpath.resolve(example, "#/e%5Ef")).to.contain(3);
+expect(jpath.resolve(example, "#/g%7Ch")).to.contain(4);
+expect(jpath.resolve(example, "#/i%5Cj")).to.contain(5);
+expect(jpath.resolve(example, "#/k%22l")).to.contain(6);
+expect(jpath.resolve(example, "#/%20")).to.contain(7);
+expect(jpath.resolve(example, "#/m~0n")).to.contain(8);
+
+console.log("All tests pass.");
\ No newline at end of file
diff --git a/bin/node_modules/json-path/index.js b/bin/node_modules/json-path/index.js
new file mode 100644
index 00000000..748e4490
--- /dev/null
+++ b/bin/node_modules/json-path/index.js
@@ -0,0 +1,631 @@
+/*jshint laxcomma: true*/
+/*global global, window, JsonPointer*/
+
+(function (ptr) {
+ 'use strict';
+
+ var $scope
+ , conflict
+ , conflictResolution = []
+ ;
+ if (typeof global === 'object' && global) {
+ $scope = global;
+ conflict = global.JsonPath;
+ } else if (typeof window !== 'undefined') {
+ $scope = window;
+ conflict = window.JsonPath;
+ } else {
+ $scope = {};
+ }
+ if (conflict) {
+ conflictResolution.push(
+ function () {
+ if ($scope.JsonPath === JsonPath) {
+ $scope.JsonPath = conflict;
+ conflict = null;
+ }
+ });
+ }
+
+ if (ptr) {
+ conflictResolution.push(
+ function (conflictPtr) {
+ if (conflictPtr) { ptr = conflictPtr; }
+ });
+ } else if (!ptr) {
+ if (typeof $scope.JsonPointer !== 'undefined') {
+ ptr = $scope.JsonPointer;
+ conflictResolution.push(
+ function (conflictPtr) {
+ if (conflictPtr) { ptr = conflictPtr; }
+ });
+ } else if (typeof require === 'function') {
+ ptr = require('json-ptr');
+ } else {
+ throw new Error('Missing JsonPointer (https://github.com/flitbit/json-ptr).');
+ }
+ }
+
+ function dbc(requirements, description) {
+ requirements = (Array.isArray(requirements)) ? requirements : [requirements];
+ var i, disposition;
+ for (i = 0; i < requirements.length; i++) {
+ var req = requirements[i];
+ disposition = (typeof req === 'function') ? req() : (req);
+ if (!disposition) {
+ description = description || 'Failed contract requirement:'.concat(req);
+ throw new Error((typeof description === 'function') ? description() : description);
+ }
+ }
+ }
+
+ function seekAny(source, cursor, chars) {
+ chars = (Array.isArray(chars)) ? chars : [chars];
+ var i = cursor
+ , j
+ , len = source.length
+ , clen = chars.length;
+ while (++i < len) {
+ j = -1;
+ while (++j < clen) {
+ if (source[i] === chars[j]) {
+ return i;
+ }
+ }
+ }
+ return -1;
+ }
+
+ function expectSequence(source, cursor, end, sequence) {
+ var c = cursor - 1
+ , i = -1
+ , seqlen = sequence.length
+ ;
+ if (end - cursor < seqlen) {
+ throw new Error("Expected `"
+ .concat(sequence, "` beginning at character ", cursor, "."));
+ }
+ while (++c < end && ++i < seqlen) {
+ if (source[c] !== sequence[i]) {
+ throw new Error("Unexpected character at position "
+ .concat(c, " expected `", sequence, "` beginning at position ", cursor, "."));
+ }
+ }
+ }
+
+ function expectMatchingClose(source, cursor, closeCh) {
+ var openCh = source[cursor]
+ , i = cursor
+ , len = source.length
+ , stack = []
+ ;
+ stack.push(cursor);
+ while (++i < len) {
+ if (source[i] === openCh) {stack.push(cursor);
+ } else if (source[i] === closeCh) {
+ stack.pop();
+ if (stack.length === 0) {
+ break;
+ }
+ }
+ }
+ if (stack.length) {
+ throw new Error(
+ 'Expected `'.concat(source[0], '` to have a matching `', closeCh, '`.')
+ );
+ }
+ return i;
+ }
+
+ function fromJsonPointer(source, state) {
+ var cursor = state.cursor
+ , selectors = state.result
+ , len = source.length
+ , end = seekAny(source, cursor, [']', '[']);
+ if (end < cursor) {
+ end = len;
+ }
+ var p = ptr.create(source.substring(cursor, end));
+ selectors.push(function (obj, accum) {
+ accum = accum || [];
+ var it = p.get(obj);
+ if (typeof it !== 'undefined') {
+ accum.push(it);
+ }
+ return accum;
+ });
+ state.cursor = end - 1;
+ }
+
+ function expect(source, state, expected) {
+ expectSequence(source, state.cursor, source.length, expected);
+ }
+
+ function pipedSelect(datum, steps, fn) {
+ var s = -1
+ , data = Array.isArray(datum) ? datum : [datum]
+ , slen = steps.length
+ , accum
+ , i
+ , len
+ ;
+ while (++s < slen && data.length) {
+ i = -1;
+ len = data.length;
+ accum = [];
+ while (++i < len) {
+ accum = steps[s](data[i], accum, fn);
+ }
+ data = accum;
+ }
+ return data;
+ }
+
+ function descent(obj, steps, accum, fn) {
+ accum = accum || [];
+ var i = -1
+ , keys
+ , len
+ , data
+ ;
+ if (typeof obj === 'object' && obj !== null) {
+ data = pipedSelect(obj, steps, fn);
+ if (data.length) {
+ accum = accum.concat(data);
+ }
+ if (!Array.isArray(obj)) {
+ keys = Object.keys(obj);
+ len = keys.length;
+ while (++i < len) {
+ accum = descent(obj[keys[i]], steps, accum, fn);
+ }
+ }
+ }
+ return accum;
+ }
+
+ function prepareExhaustiveDescent(source, state) {
+ var res = state.result
+ , lift = [];
+ state.result = lift;
+ res.push(function (obj, _, fn) {
+ return descent(obj, lift, _, fn);
+ });
+ performParse(source, state);
+ state.result = res;
+ }
+
+ function selectAny(obj, accum) {
+ accum = accum || [];
+ if (typeof obj === 'object' && obj !== null) {
+ if (Array.isArray(obj)) {
+ accum = accum.concat(obj);
+ } else {
+ var i = -1
+ , keys = Object.keys(obj)
+ , len = keys.length;
+ while (++i < len) {
+ accum.push(obj[keys[i]]);
+ }
+ }
+ }
+ return accum;
+ }
+
+ function compilePredicate(expression, invert, offset) {
+ var i = -1
+ , len = expression.length
+ , ch
+ , variables = {}
+ , la
+ , v
+ , infix = []
+ ;
+ while (++i < len) {
+ ch = expression[i];
+ dbc([false], 'Expressions are not implemented in this version.');
+ switch (ch) {
+ case '#': {
+ la = expression.indexOf(' ', i);
+ if (la < i) {
+ la = len;
+ }
+ v = expression.substring(i, la);
+ if (!variables[v]) {
+ variables[v] = ptr.create(v);
+ }
+ infix.push({kind: 'v', ref: variables[v]});
+ i = la;
+ break;
+ }
+ }
+ }
+ }
+
+ function preparePredicate(source, state) {
+ var invert = source[state.cursor] === '!';
+ if (invert) {
+ state.cursor ++;
+ }
+ expect(source, state, '{');
+ var end = expectMatchingClose(source, state.cursor, '}')
+ , expression = source.substring(state.cursor + 1, end)
+ ;
+ state.result.push(compilePredicate(expression, invert, state.offset));
+ state.cursor = end;
+ }
+
+ function parseUserSelector(source, state) {
+ var cursor = state.cursor
+ , selectors = state.result
+ , len = source.length
+ , end = source.indexOf(']', cursor);
+ if (end < cursor) {
+ end = len;
+ }
+ var n = source.substring(cursor, end);
+ state.result.push(function (data, accum, sel) {
+ var target;
+ if (data) {
+ if (n.length === 0 && typeof sel === 'function') {
+ target = sel;
+ } else if (typeof sel === 'object' && sel) {
+ if (!sel[n] && sel.RESOLVER) {
+ target = sel.RESOLVER(n);
+ } else {
+ target = sel[n];
+ }
+ }
+ if (!target) {
+ throw new Error("Missing user-supplied function: `"
+ .concat((n.length) ? n : '@', "`."));
+ }
+ return target(data, accum, sel);
+ }
+ return accum;
+ });
+ state.cursor = end - 1;
+ }
+
+ function parseSelector(source) {
+ var state = {
+ result: [],
+ stack: [],
+ cursor: -1,
+ offset: 0
+ };
+ performParse(source, state);
+ return state.result;
+ }
+
+ function parseTake(source, state) {
+ var cursor = state.cursor
+ , end = source.indexOf(')', cursor)
+ ;
+ expectSequence(source, cursor, end, 'take(');
+ cursor += 5;
+ var them = source.slice(cursor, end).split(',')
+ , i = -1
+ , len = them.length
+ , it
+ ;
+ while (++i < len) {
+ it = them[i].split('=');
+ if (it.length === 1) {
+ it = ptr.create(it[0]);
+ it = { name: it.path[it.path.length - 1], ptr: it };
+ } else if (it.length === 2) {
+ it = { name: it[0], ptr: ptr.create(it[1]) };
+ } else {
+ throw new Error("Invalid `take` expression");
+ }
+ cursor += them[i].length;
+ them[i] = it;
+ }
+ state.result.push(function (obj, accum) {
+ accum = accum || [];
+ var it = {}
+ , i = -1
+ , len = them.length
+ ;
+ while (++i < len) {
+ it[them[i].name] = them[i].ptr.get(obj);
+ }
+ accum.push(it);
+ return accum;
+ });
+ state.cursor = end;
+ }
+
+ function expectInteger(source, cursor, end) {
+ var c = cursor;
+ while (source[c] >= '0' && source[c] <= '9') { c = c + 1; }
+ if (c === cursor) {
+ throw new Error('Expected an integer at position '
+ .concat(c, '.'));
+ }
+ return c - cursor;
+ }
+
+ function parseArrayVerb(source, cursor, end, verb, thems) {
+ var index = 1
+ , len
+ ;
+ expectSequence(source, cursor, end, verb);
+ cursor += (verb.length - 1);
+ if (source[cursor + 1] === '(') {
+ cursor += 2;
+ len = expectInteger(source, cursor, end);
+ index = parseInt(source.substring(cursor, cursor + len), 10);
+ cursor += len;
+ expectSequence(source, cursor, end, ')');
+ ++cursor;
+ }
+ thems.push({ kind: verb[0], index: index});
+ return cursor;
+ }
+
+ function parseSelectByIndex(source, state) {
+ var cursor = state.cursor - 1
+ , len = source.length
+ , end = source.indexOf(']', state.cursor)
+ , it = null
+ , num = null
+ , punct = false
+ , thems = []
+ ;
+ if (end < cursor) {
+ end = len;
+ }
+ while (++cursor < end) {
+ switch (source[cursor]) {
+ case ' ':
+ if (num !== null) {
+ thems.push({ kind: 'i', index: parseInt(source.substring(num, cursor), 10)});
+ num = null;
+ punct = true;
+ }
+ break;
+ case ',': {
+ if (num !== null) {
+ thems.push({ kind: 'i', index: parseInt(source.substring(num, cursor), 10)});
+ num = null;
+ }
+ if (punct) { punct = false; }
+ }
+ break;
+ case '.': {
+ expectSequence(source, cursor, end, '..');
+ if (num !== null) {
+ thems.push({ kind: 's', index: parseInt(source.substring(num, cursor), 10)});
+ num = null;
+ }
+ cursor++;
+ if (punct) { punct = false; }
+ }
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9': {
+ if (punct) {
+ throw new Error("Unexpected numeral at position "
+ .concat(cursor, " expected punctuation."));
+ }
+ if (num === null) {
+ num = cursor;
+ }
+ }
+ break;
+ case 'l': {
+ if (punct) {
+ throw new Error("Unexpected numeral at position "
+ .concat(cursor, " expected punctuation."));
+ }
+ cursor = parseArrayVerb(source, cursor, end, "last", thems);
+ }
+ break;
+ case 'f': {
+ if (punct) {
+ throw new Error("Unexpected numeral at position "
+ .concat(cursor, " expected punctuation."));
+ }
+ cursor = parseArrayVerb(source, cursor, end, "first", thems);
+ }
+ break;
+ case 'c': {
+ if (punct) {
+ throw new Error("Unexpected numeral at position "
+ .concat(cursor, " expected punctuation."));
+ }
+ cursor = parseArrayVerb(source, cursor, end, "count", thems);
+ break;
+ }
+ }
+ }
+ if (num !== null) {
+ thems.push({ kind: 'i', index: parseInt(source.substring(num, cursor), 10)});
+ }
+ state.result.push(function (obj, accum) {
+ accum = accum || [];
+ if (Array.isArray(obj)) {
+ var i = -1
+ , len = thems.length
+ , alen = obj.length
+ , j, last
+ ;
+ while (++i < len) {
+ var it = thems[i];
+ switch (it.kind) {
+ case 'c':
+ accum.push(alen);
+ break;
+ case 'f': {
+ j = -1;
+ while (++j < it.index && j < alen) {
+ accum.push(obj[j]);
+ }
+ }
+ break;
+ case 'l': {
+ j = alen;
+ last = alen - it.index;
+ while (--j >= last && j > 0) {
+ accum.push(obj[j]);
+ }
+ }
+ break;
+ case 'i':
+ case 's': {
+ if (it.index < alen) {
+ accum.push(obj[it.index]);
+ if (it.kind === 's') {
+ j = it.index;
+ last = (++i < len) ? thems[i].index : alen - 1;
+ while (++j <= last) {
+ accum.push(obj[j]);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return accum;
+ });
+ state.cursor = end - 1;
+ }
+
+ function performParse(source, state) {
+ dbc([typeof source === "string"], "Selector must be a string.");
+ if (source.length === 0) { return []; }
+ var len = source.length
+ , ch
+ ;
+
+ while (++state.cursor < len) {
+ ch = source[state.cursor];
+ switch (ch) {
+ case '/':
+ case '#': {
+ fromJsonPointer(source, state);
+ }
+ break;
+ case '[': {
+ state.stack.push(state.cursor);
+ }
+ break;
+ case ']': {
+ if (state.stack.length) {
+ state.stack.pop();
+ } else {
+ throw new Error("Unexpected `]` at cursor position ".concat(state.cursor, '.'));
+ }
+ }
+ break;
+ case '.': {
+ expect(source, state, '..');
+ ++state.cursor;
+ prepareExhaustiveDescent(source, state);
+ }
+ break;
+ case '*': {
+ expect(source, state, '*]');
+ state.result.push(selectAny);
+ }
+ break;
+ case '{':
+ case '!': {
+ preparePredicate(source, state);
+ }
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9': {
+ parseSelectByIndex(source, state);
+ }
+ break;
+ case 'l': {
+ parseSelectByIndex(source, state);
+ }
+ break;
+ case 'f': {
+ parseSelectByIndex(source, state);
+ }
+ break;
+ case 'c': {
+ parseSelectByIndex(source, state);
+ }
+ break;
+ case 't': {
+ parseTake(source, state);
+ }
+ break;
+ case '@': {
+ state.cursor += 1;
+ parseUserSelector(source, state);
+ }
+ break;
+ default: {
+ throw new Error("Unexpected character at position ".concat(state.cursor, ": ", ch, "."));
+ }
+ }
+ }
+ dbc([!state.stack.length], function () {
+ return "Unexpected end; unclosed scope beginning at cursor position ".concat(state.stack.pop(), '.');
+ });
+ }
+
+ function executeSelectors(obj, sel, fn) {
+ return pipedSelect(obj, sel, fn);
+ }
+
+ function JsonPath(selector) {
+ Object.defineProperties(this, {
+ selectors: {
+ value: parseSelector(selector),
+ enumerable: true
+ },
+ resolve: {
+ value: function (data, fn) {
+ return pipedSelect(data, this.selectors, fn);
+ },
+ enumerable: true
+ }
+ });
+ }
+
+ JsonPath.parseSelector = parseSelector;
+ JsonPath.executeSelectors = executeSelectors;
+ JsonPath.create = function (path) { return new JsonPath(path); };
+ JsonPath.resolve = function (data, selector, fn) {
+ var path = parseSelector(selector);
+ return pipedSelect(data, path, fn);
+ };
+ JsonPath.noConflict = function (conflictPtr) {
+ if (conflictResolution) {
+ conflictResolution.forEach(function (it) { it(conflictPtr); });
+ conflictResolution = null;
+ }
+ return JsonPath;
+ };
+
+ if (typeof module !== 'undefined' && module && typeof exports === 'object' && exports && module.exports === exports) {
+ module.exports = JsonPath; // nodejs
+ } else {
+ $scope.JsonPath = JsonPath; // other... browser?
+ }
+}(typeof JsonPointer !== 'undefined' ? JsonPointer : null));
diff --git a/bin/node_modules/json-path/node_modules/json-ptr/.npmignore b/bin/node_modules/json-path/node_modules/json-ptr/.npmignore
new file mode 100644
index 00000000..4fab4df2
--- /dev/null
+++ b/bin/node_modules/json-path/node_modules/json-ptr/.npmignore
@@ -0,0 +1 @@
+component.json
\ No newline at end of file
diff --git a/bin/node_modules/json-path/node_modules/json-ptr/.travis.yml b/bin/node_modules/json-path/node_modules/json-ptr/.travis.yml
new file mode 100644
index 00000000..9c700cee
--- /dev/null
+++ b/bin/node_modules/json-path/node_modules/json-ptr/.travis.yml
@@ -0,0 +1,12 @@
+language: node_js
+branches:
+ only:
+ - master
+node_js:
+ - "0.10"
+ - "0.9"
+ - "0.8"
+
+notifications:
+ email:
+ - phillip@flitbit.com
\ No newline at end of file
diff --git a/bin/node_modules/json-path/node_modules/json-ptr/README.md b/bin/node_modules/json-path/node_modules/json-ptr/README.md
new file mode 100644
index 00000000..ae805354
--- /dev/null
+++ b/bin/node_modules/json-path/node_modules/json-ptr/README.md
@@ -0,0 +1,133 @@
+# json-ptr [](http://travis-ci.org/flitbit/json-ptr)
+
+A complete implementation of JSON Pointer (RFC 6901) for nodejs and modern browsers.
+
+## Installation
+
+[node.js](http://nodejs.org)
+```bash
+$ npm install json-ptr
+```
+
+## Tests
+
+Tests use [mocha](http://visionmedia.github.io/mocha/) and [expect.js](https://github.com/LearnBoost/expect.js/), so if you clone the [github repository](https://github.com/flitbit/json-ptr) you'll need to run:
+
+```bash
+npm install
+```
+
+... followed by ...
+
+```bash
+npm test
+```
+
+... or ...
+
+```bash
+mocha -R spec
+```
+
+## Basics
+
+!! This document is a work in progress even though the module is considered *complete*. See the [examples of its use for more](https://github.com/flitbit/json-ptr/tree/master/examples).
+
+JSON Pointer provides a standardized syntax for reliably referencing data within an object's structure.
+
+### Importing
+
+**nodejs**
+```javascript
+var JsonPointer = require('json-ptr')
+```
+
+**browser**
+```html
+
+```
+
+### Working with Pointers
+
+Since most non-trivial code will make use of the same pointers over and over again (after all they represent the fixed points within a larger structure), with `json-ptr`you can create these pointers once and reuse them against different data items.
+
+```javascript
+var manager = JsonPointer.create('/people/workplace/reporting/manager');
+var director = JsonPointer.create('/people/workplace/reporting/director');
+```
+
+Pointers have a few simple operations:
+
+* `#get` - given an origin object, returns the referenced value
+* `#set` - given an origin object and a value, sets the referenced value
+
+And a few useful properties:
+
+* `#pointer` - an RFC 6901 formatted JSON pointer
+* `#uriFragmentIdentifier` - an RFC 6901 formatted URI fragment identifier
+* `#path` - an array of property names used to descend the object graph from the origin to the referenced item
+
+## Example
+
+
+This example queries the live flikr api for recent images with 'surf' and 'pipeline'. It then extracts the author and the referenced media item.
+
+Clone the repo and run it on the command line using `node example/example1.js` and you'll see the output. Of note: `json-ptr` will return `undefined` when any part of a pointer's path cannot be resolved, which makes this type of extraction very convenient and compact.
+
+[flikr example](https://github.com/flitbit/json-ptr/blob/master/examples/example1.js)
+```javascript
+var ptr = require('json-ptr')
+, http = require('http')
+, util = require('util')
+;
+
+var feed = "http://api.flickr.com/services/feeds/photos_public.gne?tags=surf,pipeline&tagmode=all&format=json&jsoncallback=processResponse"
+/*
+ * Set up some JSON pointers we'll use later...
+*/
+, items = ptr.create("#/items")
+, author = ptr.create("#/author")
+, media = ptr.create("#/media/m")
+;
+
+function extractItems(it) {
+ return items.get(it);
+}
+
+function extractAuthorAndMedia(it, i) {
+ this.push({
+ author: author.get(it),
+ media : media.get(it)
+ });
+}
+
+function processResponse(json) {
+ var items = extractItems(json)
+ , accum = []
+ ;
+
+ if (items && Array.isArray(items)) {
+ items.forEach(extractAuthorAndMedia, accum);
+ }
+
+ console.log( util.inspect(accum, true, 99) );
+}
+
+http.get(feed, function(res) {
+ console.log("Got response: " + res.statusCode);
+
+ var data = '';
+
+ res.on('data', function (chunk){
+ data += chunk;
+ });
+
+ res.on('end',function(){
+ // result is formatted as jsonp... this is for illustration only.
+ eval(data);
+ })
+}).on('error', function(e) {
+ console.log("Got error: " + e.message);
+});
+```
+
diff --git a/bin/node_modules/json-path/node_modules/json-ptr/examples/example1.js b/bin/node_modules/json-path/node_modules/json-ptr/examples/example1.js
new file mode 100644
index 00000000..9ed78c81
--- /dev/null
+++ b/bin/node_modules/json-path/node_modules/json-ptr/examples/example1.js
@@ -0,0 +1,53 @@
+var ptr = require('..')
+, http = require('http')
+, util = require('util')
+;
+
+var feed = "http://api.flickr.com/services/feeds/photos_public.gne?tags=surf,pipeline&tagmode=all&format=json&jsoncallback=processResponse"
+/*
+ * Set up some JSON pointers we'll use later...
+*/
+, items = ptr.create("#/items")
+, author = ptr.create("#/author")
+, media = ptr.create("#/media/m")
+;
+
+function extractItems(it) {
+ return items.get(it);
+}
+
+function extractAuthorAndMedia(it, i) {
+ this.push({
+ author: author.get(it),
+ media : media.get(it)
+ });
+}
+
+function processResponse(json) {
+ var items = extractItems(json)
+ , accum = []
+ ;
+
+ if (items && Array.isArray(items)) {
+ items.forEach(extractAuthorAndMedia, accum);
+ }
+
+ console.log( util.inspect(accum, true, 99) );
+}
+
+http.get(feed, function(res) {
+ console.log("Got response: " + res.statusCode);
+
+ var data = '';
+
+ res.on('data', function (chunk){
+ data += chunk;
+ });
+
+ res.on('end',function(){
+ // result is formatted as jsonp... this is for illustration only.
+ eval(data);
+ })
+}).on('error', function(e) {
+ console.log("Got error: " + e.message);
+});
diff --git a/bin/node_modules/json-path/node_modules/json-ptr/examples/various-json-pointers.js b/bin/node_modules/json-path/node_modules/json-ptr/examples/various-json-pointers.js
new file mode 100644
index 00000000..5b3a186d
--- /dev/null
+++ b/bin/node_modules/json-path/node_modules/json-ptr/examples/various-json-pointers.js
@@ -0,0 +1,169 @@
+var assert = require('assert'),
+ptr = require('..')
+;
+
+var obj = {
+ a: 1,
+ b: {
+ c: 2
+ },
+ d: {
+ e: [{a:3}, {b:4}, {c:5}]
+ }
+};
+
+// JSON Pointers (as strings)
+
+var n = -1
+, ub = 10000
+, start = process.hrtime();
+
+
+while(++n < ub) {
+
+ assert.equal(ptr.get(obj, "/a"), n + 1);
+ assert.equal(ptr.get(obj, "/b/c"), n + 2);
+ assert.equal(ptr.get(obj, "/d/e/0/a"), n + 3);
+ assert.equal(ptr.get(obj, "/d/e/1/b"), n + 4);
+ assert.equal(ptr.get(obj, "/d/e/2/c"), n + 5);
+
+ assert.equal(ptr.set(obj, "/a", n + 2), n + 1);
+ assert.equal(ptr.set(obj, "/b/c", n + 3), n + 2);
+ assert.equal(ptr.set(obj, "/d/e/0/a", n + 4), n + 3);
+ assert.equal(ptr.set(obj, "/d/e/1/b", n + 5), n + 4);
+ assert.equal(ptr.set(obj, "/d/e/2/c", n + 6), n + 5);
+
+ assert.equal(ptr.get(obj, "/a"), n + 2);
+ assert.equal(ptr.get(obj, "/b/c"), n + 3);
+ assert.equal(ptr.get(obj, "/d/e/0/a"), n + 4);
+ assert.equal(ptr.get(obj, "/d/e/1/b"), n + 5);
+ assert.equal(ptr.get(obj, "/d/e/2/c"), n + 6);
+
+ assert.equal(ptr.get(obj, ""), obj);
+}
+
+assert.throws(function() {
+ ptr.get(obj, "a");
+});
+
+assert.throws(function() {
+ ptr.set(obj, "a", {a: "value"});
+});
+
+// JSON Pointers (as URI fragments)
+ub = ub * 2;
+n--;
+while(++n < ub) {
+
+ assert.equal(ptr.get(obj, "#/a"), n + 1);
+ assert.equal(ptr.get(obj, "#/b/c"), n + 2);
+ assert.equal(ptr.get(obj, "#/d/e/0/a"), n + 3);
+ assert.equal(ptr.get(obj, "#/d/e/1/b"), n + 4);
+ assert.equal(ptr.get(obj, "#/d/e/2/c"), n + 5);
+
+ assert.equal(ptr.set(obj, "#/a", n + 2), n + 1);
+ assert.equal(ptr.set(obj, "#/b/c", n + 3), n + 2);
+ assert.equal(ptr.set(obj, "#/d/e/0/a", n + 4), n + 3);
+ assert.equal(ptr.set(obj, "#/d/e/1/b", n + 5), n + 4);
+ assert.equal(ptr.set(obj, "#/d/e/2/c", n + 6), n + 5);
+
+ assert.equal(ptr.get(obj, "#/a"), n + 2);
+ assert.equal(ptr.get(obj, "#/b/c"), n + 3);
+ assert.equal(ptr.get(obj, "#/d/e/0/a"), n + 4);
+ assert.equal(ptr.get(obj, "#/d/e/1/b"), n + 5);
+ assert.equal(ptr.get(obj, "#/d/e/2/c"), n + 6);
+
+ assert.equal(ptr.get(obj, ""), obj);
+}
+
+assert.throws(function() {
+ // Cannot assign the root object:
+ ptr.set(obj, "#", {});
+});
+
+assert.throws(function() {
+ ptr.get(obj, "#a");
+});
+assert.throws(function() {
+ ptr.set(obj, "#a", {a: "value"});
+});
+
+assert.throws(function() {
+ ptr.get(obj, "a/");
+});
+
+var complexKeys = {
+ "a/b": {
+ c: 1
+ },
+ d: {
+ "e/f": 2
+ },
+ "~1": 3,
+ "01": 4
+}
+
+assert.equal(ptr.get(complexKeys, "/a~1b/c"), 1);
+assert.equal(ptr.get(complexKeys, "/d/e~1f"), 2);
+assert.equal(ptr.get(complexKeys, "/~01"), 3);
+assert.equal(ptr.get(complexKeys, "/01"), 4);
+assert.equal(ptr.get(complexKeys, "/a/b/c"), null);
+assert.equal(ptr.get(complexKeys, "/~1"), null);
+
+// draft-ietf-appsawg-json-pointer-08 has special array rules
+var ary = [ "zero", "one", "two" ];
+assert.equal(ptr.get(ary, "/01"), null);
+
+// we should be able to push the end of an array with the special pointer '-'
+assert.equal(ptr.set(ary, "/-", "three"), null);
+assert.equal(ary[3], "three");
+assert.equal(ptr.set(ary, "/-", "four"), null);
+assert.equal(ary[4], "four");
+
+// Examples from the draft:
+var example = {
+ "foo": ["bar", "baz"],
+ "": 0,
+ "a/b": 1,
+ "c%d": 2,
+ "e^f": 3,
+ "g|h": 4,
+ "i\\j": 5,
+ "k\"l": 6,
+ " ": 7,
+ "m~n": 8
+};
+
+assert.equal(ptr.get(example, ""), example);
+var ans = ptr.get(example, "/foo");
+assert.equal(ans.length, 2);
+assert.equal(ans[0], "bar");
+assert.equal(ans[1], "baz");
+assert.equal(ptr.get(example, "/foo/0"), "bar");
+assert.equal(ptr.get(example, "/"), 0);
+assert.equal(ptr.get(example, "/a~1b"), 1);
+assert.equal(ptr.get(example, "/c%d"), 2);
+assert.equal(ptr.get(example, "/e^f"), 3);
+assert.equal(ptr.get(example, "/g|h"), 4);
+assert.equal(ptr.get(example, "/i\\j"), 5);
+assert.equal(ptr.get(example, "/k\"l"), 6);
+assert.equal(ptr.get(example, "/ "), 7);
+assert.equal(ptr.get(example, "/m~0n"), 8);
+
+assert.equal(ptr.get(example, "#"), example);
+var ans = ptr.get(example, "#/foo");
+assert.equal(ans.length, 2);
+assert.equal(ans[0], "bar");
+assert.equal(ans[1], "baz");
+assert.equal(ptr.get(example, "#/foo/0"), "bar");
+assert.equal(ptr.get(example, "#/"), 0);
+assert.equal(ptr.get(example, "#/a~1b"), 1);
+assert.equal(ptr.get(example, "#/c%25d"), 2);
+assert.equal(ptr.get(example, "#/e%5Ef"), 3);
+assert.equal(ptr.get(example, "#/g%7Ch"), 4);
+assert.equal(ptr.get(example, "#/i%5Cj"), 5);
+assert.equal(ptr.get(example, "#/k%22l"), 6);
+assert.equal(ptr.get(example, "#/%20"), 7);
+assert.equal(ptr.get(example, "#/m~0n"), 8);
+
+console.log("All tests pass.");
\ No newline at end of file
diff --git a/bin/node_modules/json-path/node_modules/json-ptr/index.js b/bin/node_modules/json-path/node_modules/json-ptr/index.js
new file mode 100644
index 00000000..4e205846
--- /dev/null
+++ b/bin/node_modules/json-path/node_modules/json-ptr/index.js
@@ -0,0 +1,236 @@
+/* jshint laxbreak: true, laxcomma: true*/
+/* global global, window */
+
+(function (undefined) {
+ "use strict";
+
+ var $scope
+ , conflict, conflictResolution = [];
+ if (typeof global === 'object' && global) {
+ $scope = global;
+ conflict = global.JsonPointer;
+ } else if (typeof window !== 'undefined') {
+ $scope = window;
+ conflict = window.JsonPointer;
+ } else {
+ $scope = {};
+ }
+ if (conflict) {
+ conflictResolution.push(
+ function () {
+ if ($scope.JsonPointer === JsonPointer) {
+ $scope.JsonPointer = conflict;
+ conflict = undefined;
+ }
+ });
+ }
+
+ function decodePointer(ptr) {
+ if (typeof ptr !== 'string') { throw new TypeError('Invalid type: JSON Pointers are represented as strings.'); }
+ if (ptr.length === 0) { return []; }
+ if (ptr[0] !== '/') { throw new ReferenceError('Invalid JSON Pointer syntax. Non-empty pointer must begin with a solidus `/`.'); }
+ var path = ptr.substring(1).split('/')
+ , i = -1
+ , len = path.length
+ ;
+ while (++i < len) {
+ path[i] = path[i].replace('~1', '/').replace('~0', '~');
+ }
+ return path;
+ }
+
+ function encodePointer(path) {
+ if (path && !Array.isArray(path)) { throw new TypeError('Invalid type: path must be an array of segments.'); }
+ if (path.length === 0) { return ''; }
+ var res = []
+ , i = -1
+ , len = path.length
+ ;
+ while (++i < len) {
+ res.push(path[i].replace('~', '~0').replace('/', '~1'));
+ }
+ return "/".concat(res.join('/'));
+ }
+
+ function decodeUriFragmentIdentifier(ptr) {
+ if (typeof ptr !== 'string') { throw new TypeError('Invalid type: JSON Pointers are represented as strings.'); }
+ if (ptr.length === 0 || ptr[0] !== '#') { throw new ReferenceError('Invalid JSON Pointer syntax; URI fragment idetifiers must begin with a hash.'); }
+ if (ptr.length === 1) { return []; }
+ if (ptr[1] !== '/') { throw new ReferenceError('Invalid JSON Pointer syntax.'); }
+ var path = ptr.substring(2).split('/')
+ , i = -1
+ , len = path.length
+ ;
+ while (++i < len) {
+ path[i] = decodeURIComponent(path[i]).replace('~1', '/').replace('~0', '~');
+ }
+ return path;
+ }
+
+ function encodeUriFragmentIdentifier(path) {
+ if (path && !Array.isArray(path)) { throw new TypeError('Invalid type: path must be an array of segments.'); }
+ if (path.length === 0) { return '#'; }
+ var res = []
+ , i = -1
+ , len = path.length
+ ;
+ while (++i < len) {
+ res.push(encodeURIComponent(path[i].replace('~', '~0').replace('/', '~1')));
+ }
+ return "#/".concat(res.join('/'));
+ }
+
+ function toArrayIndexReference(arr, idx) {
+ var len = idx.length
+ , cursor = 0
+ ;
+ if (len === 0 || len > 1 && idx[0] === '0') { return -1; }
+ if (len === 1 && idx[0] === '-') { return arr.length; }
+
+ while (++cursor < len) {
+ if (idx[cursor] < '0' || idx[cursor] > '9') { return -1; }
+ }
+ return parseInt(idx, 10);
+ }
+
+ function get(obj, path) {
+ if (typeof obj !== 'undefined') {
+ var it = obj
+ , len = path.length
+ , cursor = -1
+ , step, p;
+ if (len) {
+ while (++cursor < len && it) {
+ step = path[cursor];
+ if (Array.isArray(it)) {
+ if (isNaN(step)) {
+ return;
+ }
+ p = toArrayIndexReference(it, step);
+ if (it.length > p) {
+ it = it[p];
+ } else {
+ return;
+ }
+ } else {
+ it = it[step];
+ }
+ }
+ return it;
+ } else {
+ return obj;
+ }
+ }
+ }
+
+ function set(obj, val, path, enc) {
+ if (path.length === 0) { throw new Error("Cannot set the root object; assign it directly."); }
+ if (typeof obj !== 'undefined') {
+ var it = obj
+ , len = path.length
+ , end = path.length - 1
+ , cursor = -1
+ , step, p, rem;
+ if (len) {
+ while (++cursor < len) {
+ step = path[cursor];
+ if (Array.isArray(it)) {
+ p = toArrayIndexReference(it, step);
+ if (it.length > p) {
+ if (cursor === end) {
+ rem = it[p];
+ it[p] = val;
+ return rem;
+ }
+ it = it[p];
+ } else if (it.length === p) {
+ it.push(val);
+ return undefined;
+ } else {
+ throw new ReferenceError("Not found: "
+ .concat(enc(path.slice(0, cursor + 1), true), '.'));
+ }
+ } else {
+ if (cursor === end) {
+ rem = it[step];
+ it[step] = val;
+ return rem;
+ }
+ it = it[step];
+ if (typeof it === 'undefined') {
+ throw new ReferenceError("Not found: "
+ .concat(enc(path.slice(0, cursor + 1), true), '.'));
+ }
+ }
+ }
+ if (cursor === len) {
+ return it;
+ }
+ } else {
+ return it;
+ }
+ }
+ }
+
+ function JsonPointer(ptr) {
+ this.encode = (ptr.length > 0 && ptr[0] === '#') ? encodeUriFragmentIdentifier : encodePointer;
+ if (Array.isArray(ptr)) {
+ this.path = ptr;
+ } else {
+ var decode = (ptr.length > 0 && ptr[0] === '#') ? decodeUriFragmentIdentifier : decodePointer;
+ this.path = decode(ptr);
+ }
+ }
+
+ Object.defineProperty(JsonPointer.prototype, 'pointer', {
+ enumerable: true,
+ get: function () { return encodePointer(this.path); }
+ });
+
+ Object.defineProperty(JsonPointer.prototype, 'uriFragmentIdentifier', {
+ enumerable: true,
+ get: function () { return encodeUriFragmentIdentifier(this.path); }
+ });
+
+ JsonPointer.prototype.get = function (obj) {
+ return get(obj, this.path);
+ };
+
+ JsonPointer.prototype.set = function (obj, val) {
+ return set(obj, val, this.path, this.encode);
+ };
+
+ JsonPointer.prototype.toString = function () {
+ return this.pointer;
+ };
+
+ JsonPointer.create = function (ptr) { return new JsonPointer(ptr); };
+ JsonPointer.get = function (obj, ptr) {
+ var decode = (ptr.length > 0 && ptr[0] === '#') ? decodeUriFragmentIdentifier : decodePointer;
+ return get(obj, decode(ptr));
+ };
+ JsonPointer.set = function (obj, ptr, val) {
+ var encode = (ptr.length > 0 && ptr[0] === '#') ? encodeUriFragmentIdentifier : encodePointer;
+ var decode = (ptr.length > 0 && ptr[0] === '#') ? decodeUriFragmentIdentifier : decodePointer;
+
+ return set(obj, val, decode(ptr), encode);
+ };
+ JsonPointer.decodePointer = decodePointer;
+ JsonPointer.encodePointer = encodePointer;
+ JsonPointer.decodeUriFragmentIdentifier = decodeUriFragmentIdentifier;
+ JsonPointer.encodeUriFragmentIdentifier = encodeUriFragmentIdentifier;
+
+ JsonPointer.noConflict = function () {
+ if (conflictResolution) {
+ conflictResolution.forEach(function (it) { it(); });
+ conflictResolution = null;
+ }
+ return JsonPointer;
+ };
+
+ if (typeof module !== 'undefined' && module && typeof exports === 'object' && exports && module.exports === exports) {
+ module.exports = JsonPointer; // nodejs
+ } else {
+ $scope.JsonPointer = JsonPointer; // other... browser?
+ }
+}());
diff --git a/bin/node_modules/json-path/node_modules/json-ptr/package.json b/bin/node_modules/json-path/node_modules/json-ptr/package.json
new file mode 100644
index 00000000..7ed06a36
--- /dev/null
+++ b/bin/node_modules/json-path/node_modules/json-ptr/package.json
@@ -0,0 +1,51 @@
+{
+ "name": "json-ptr",
+ "version": "0.1.1",
+ "author": {
+ "name": "Phillip Clark",
+ "email": "phillip@flitbit.com"
+ },
+ "description": "A complete implementation of JSON Pointer (RFC 6901) for nodejs and modern browsers.",
+ "main": "index.js",
+ "directories": {
+ "example": "examples",
+ "test": "test"
+ },
+ "scripts": {
+ "test": "mocha -R spec"
+ },
+ "devDependencies": {
+ "expect.js": "~0.2.x",
+ "mocha": "~1.10.x"
+ },
+ "license": "MIT",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/flitbit/json-ptr"
+ },
+ "readme": "# json-ptr [](http://travis-ci.org/flitbit/json-ptr)\n\nA complete implementation of JSON Pointer (RFC 6901) for nodejs and modern browsers.\n\n## Installation\n\n[node.js](http://nodejs.org)\n```bash\n$ npm install json-ptr\n```\n\n## Tests\n\nTests use [mocha](http://visionmedia.github.io/mocha/) and [expect.js](https://github.com/LearnBoost/expect.js/), so if you clone the [github repository](https://github.com/flitbit/json-ptr) you'll need to run:\n\n```bash\nnpm install\n```\n\n... followed by ...\n\n```bash\nnpm test\n```\n\n... or ...\n\n```bash\nmocha -R spec\n```\n\n## Basics\n\n!! This document is a work in progress even though the module is considered *complete*. See the [examples of its use for more](https://github.com/flitbit/json-ptr/tree/master/examples).\n\nJSON Pointer provides a standardized syntax for reliably referencing data within an object's structure.\n\n### Importing\n\n**nodejs**\n```javascript\nvar JsonPointer = require('json-ptr')\n```\n\n**browser**\n```html\n\n```\n\n### Working with Pointers\n\nSince most non-trivial code will make use of the same pointers over and over again (after all they represent the fixed points within a larger structure), with `json-ptr`you can create these pointers once and reuse them against different data items.\n\n```javascript\nvar manager = JsonPointer.create('/people/workplace/reporting/manager');\nvar director = JsonPointer.create('/people/workplace/reporting/director');\n```\n\nPointers have a few simple operations:\n\n* `#get` - given an origin object, returns the referenced value\n* `#set` - given an origin object and a value, sets the referenced value\n\nAnd a few useful properties:\n\n* `#pointer` - an RFC 6901 formatted JSON pointer\n* `#uriFragmentIdentifier` - an RFC 6901 formatted URI fragment identifier\n* `#path` - an array of property names used to descend the object graph from the origin to the referenced item\n\n## Example\n\n\nThis example queries the live flikr api for recent images with 'surf' and 'pipeline'. It then extracts the author and the referenced media item.\n\nClone the repo and run it on the command line using `node example/example1.js` and you'll see the output. Of note: `json-ptr` will return `undefined` when any part of a pointer's path cannot be resolved, which makes this type of extraction very convenient and compact.\n\n[flikr example](https://github.com/flitbit/json-ptr/blob/master/examples/example1.js)\n```javascript\nvar ptr = require('json-ptr')\n, http = require('http')\n, util = require('util')\n;\n\nvar feed = \"http://api.flickr.com/services/feeds/photos_public.gne?tags=surf,pipeline&tagmode=all&format=json&jsoncallback=processResponse\"\n/*\n * Set up some JSON pointers we'll use later...\n*/\n, items = ptr.create(\"#/items\")\n, author = ptr.create(\"#/author\")\n, media = ptr.create(\"#/media/m\")\n;\n\nfunction extractItems(it) {\n\treturn items.get(it);\n}\n\nfunction extractAuthorAndMedia(it, i) {\n\tthis.push({\n\t\tauthor: author.get(it),\n\t\tmedia : media.get(it)\n\t});\n}\n\nfunction processResponse(json) {\n\tvar items = extractItems(json)\n\t, accum = []\n\t;\n\n\tif (items && Array.isArray(items)) {\n\t\titems.forEach(extractAuthorAndMedia, accum);\n\t}\n\n\tconsole.log( util.inspect(accum, true, 99) );\n}\n\nhttp.get(feed, function(res) {\n\tconsole.log(\"Got response: \" + res.statusCode);\n\n\tvar data = '';\n\n\tres.on('data', function (chunk){\n\t\tdata += chunk;\n\t});\n\n\tres.on('end',function(){\n\t\t// result is formatted as jsonp... this is for illustration only.\n\t\teval(data);\n\t})\n}).on('error', function(e) {\n\tconsole.log(\"Got error: \" + e.message);\n});\n```\n\n",
+ "readmeFilename": "README.md",
+ "bugs": {
+ "url": "https://github.com/flitbit/json-ptr/issues"
+ },
+ "_id": "json-ptr@0.1.1",
+ "dist": {
+ "shasum": "bab82a31e292ce7af9e3fc7fd65acd1bbb9248e8",
+ "tarball": "http://registry.npmjs.org/json-ptr/-/json-ptr-0.1.1.tgz"
+ },
+ "_from": "json-ptr@>=0.1.1-0 <0.2.0-0",
+ "_npmVersion": "1.3.8",
+ "_npmUser": {
+ "name": "flitbit",
+ "email": "phillip@flitbit.com"
+ },
+ "maintainers": [
+ {
+ "name": "flitbit",
+ "email": "phillip@flitbit.com"
+ }
+ ],
+ "_shasum": "bab82a31e292ce7af9e3fc7fd65acd1bbb9248e8",
+ "_resolved": "https://registry.npmjs.org/json-ptr/-/json-ptr-0.1.1.tgz",
+ "homepage": "https://github.com/flitbit/json-ptr"
+}
diff --git a/bin/node_modules/json-path/node_modules/json-ptr/releases/json-ptr-0.1.0.min.js b/bin/node_modules/json-path/node_modules/json-ptr/releases/json-ptr-0.1.0.min.js
new file mode 100644
index 00000000..4619a1dc
--- /dev/null
+++ b/bin/node_modules/json-path/node_modules/json-ptr/releases/json-ptr-0.1.0.min.js
@@ -0,0 +1 @@
+!function(e){"use strict";var r,t,n=[];if(typeof global=="object"&&global){r=global;t=global.JsonPointer}else if(typeof window!=="undefined"){r=window;t=window.JsonPointer}else{r={}}if(t){n.push(function(){if(r.JsonPointer===h){r.JsonPointer=t;t=e}})}function i(e){if(typeof e!=="string")throw new TypeError("Invalid type: JSON Pointers are represented as strings.");if(e.length===0)return[];if(e[0]!=="/")throw new ReferenceError("Invalid JSON Pointer syntax. Non-empty pointer must begin with a solidus `/`.");var r=e.substring(1).split("/"),t=-1,n=r.length;while(++t1&&r[0]==="0")return-1;if(t===1&&r[0]==="-")return e.length;while(++n"9")return-1}return parseInt(r)}function u(e,r){if(typeof e!=="undefined"){var t=e,n=r.length,i=-1,o,f;if(n){while(++if){t=t[f]}else{return}}else{t=t[o]}}return t}else{return e}}}function l(r,t,n,i){if(n.length===0)throw new Error("Cannot set the root object; assign it directly.");if(typeof r!=="undefined"){var o=r,f=n.length,s=n.length-1,u=-1,l,h,p;if(f){while(++uh){if(u===s){p=o[h];o[h]=t;return p}o=o[h]}else if(o.length===h){o.push(t);return e}else{throw new ReferenceError("Not found: ".concat(encode(n.slice(0,u+1),true),"."))}}else{if(u===s){p=o[l];o[l]=t;return p}o=o[l];if(typeof o==="undefined"){throw new ReferenceError("Not found: ".concat(encode(n.slice(0,u+1),true),"."))}}}if(u===f){return o}}else{return o}}}function h(e){this.encode=e.length>0&&e[0]==="#"?s:o;if(Array.isArray(e)){this.path=e}else{var r=e.length>0&&e[0]==="#"?f:i;this.path=r(e)}}Object.defineProperty(h.prototype,"pointer",{enumerable:true,get:function(){return o(this.path)}});Object.defineProperty(h.prototype,"uriFragmentIdentifier",{enumerable:true,get:function(){return s(this.path)}});h.prototype.get=function(e){return u(e,this.path)};h.prototype.set=function(e,r){return l(e,r,this.path,this.encode)};h.prototype.toString=function(){return this.pointer};h.create=function(e){return new h(e)};h.get=function(e,r){var t=r.length>0&&r[0]==="#"?f:i;return u(e,t(r))};h.set=function(e,r,t){var n=r.length>0&&r[0]==="#"?s:o;var a=r.length>0&&r[0]==="#"?f:i;return l(e,t,a(r),n)};h.decodePointer=i;h.encodePointer=o;h.decodeUriFragmentIdentifier=f;h.encodeUriFragmentIdentifier=s;h.noConflict=function(){if(n){n.forEach(function(e){e()});n=null}return Define};if(typeof module!="undefined"&&module&&typeof exports=="object"&&exports&&module.exports===exports){module.exports=h}else{r.JsonPointer=h}}();
\ No newline at end of file
diff --git a/bin/node_modules/json-path/node_modules/json-ptr/releases/json-ptr-0.1.1.min.js b/bin/node_modules/json-path/node_modules/json-ptr/releases/json-ptr-0.1.1.min.js
new file mode 100644
index 00000000..ce6d8b39
--- /dev/null
+++ b/bin/node_modules/json-path/node_modules/json-ptr/releases/json-ptr-0.1.1.min.js
@@ -0,0 +1 @@
+!function(e){"use strict";var r,t,n=[];if(typeof global==="object"&&global){r=global;t=global.JsonPointer}else if(typeof window!=="undefined"){r=window;t=window.JsonPointer}else{r={}}if(t){n.push(function(){if(r.JsonPointer===h){r.JsonPointer=t;t=e}})}function i(e){if(typeof e!=="string"){throw new TypeError("Invalid type: JSON Pointers are represented as strings.")}if(e.length===0){return[]}if(e[0]!=="/"){throw new ReferenceError("Invalid JSON Pointer syntax. Non-empty pointer must begin with a solidus `/`.")}var r=e.substring(1).split("/"),t=-1,n=r.length;while(++t1&&r[0]==="0"){return-1}if(t===1&&r[0]==="-"){return e.length}while(++n"9"){return-1}}return parseInt(r,10)}function u(e,r){if(typeof e!=="undefined"){var t=e,n=r.length,i=-1,o,f;if(n){while(++if){t=t[f]}else{return}}else{t=t[o]}}return t}else{return e}}}function l(r,t,n,i){if(n.length===0){throw new Error("Cannot set the root object; assign it directly.")}if(typeof r!=="undefined"){var o=r,f=n.length,s=n.length-1,u=-1,l,h,p;if(f){while(++uh){if(u===s){p=o[h];o[h]=t;return p}o=o[h]}else if(o.length===h){o.push(t);return e}else{throw new ReferenceError("Not found: ".concat(i(n.slice(0,u+1),true),"."))}}else{if(u===s){p=o[l];o[l]=t;return p}o=o[l];if(typeof o==="undefined"){throw new ReferenceError("Not found: ".concat(i(n.slice(0,u+1),true),"."))}}}if(u===f){return o}}else{return o}}}function h(e){this.encode=e.length>0&&e[0]==="#"?s:o;if(Array.isArray(e)){this.path=e}else{var r=e.length>0&&e[0]==="#"?f:i;this.path=r(e)}}Object.defineProperty(h.prototype,"pointer",{enumerable:true,get:function(){return o(this.path)}});Object.defineProperty(h.prototype,"uriFragmentIdentifier",{enumerable:true,get:function(){return s(this.path)}});h.prototype.get=function(e){return u(e,this.path)};h.prototype.set=function(e,r){return l(e,r,this.path,this.encode)};h.prototype.toString=function(){return this.pointer};h.create=function(e){return new h(e)};h.get=function(e,r){var t=r.length>0&&r[0]==="#"?f:i;return u(e,t(r))};h.set=function(e,r,t){var n=r.length>0&&r[0]==="#"?s:o;var a=r.length>0&&r[0]==="#"?f:i;return l(e,t,a(r),n)};h.decodePointer=i;h.encodePointer=o;h.decodeUriFragmentIdentifier=f;h.encodeUriFragmentIdentifier=s;h.noConflict=function(){if(n){n.forEach(function(e){e()});n=null}return h};if(typeof module!=="undefined"&&module&&typeof exports==="object"&&exports&&module.exports===exports){module.exports=h}else{r.JsonPointer=h}}();
\ No newline at end of file
diff --git a/bin/node_modules/json-path/node_modules/json-ptr/test/tests.html b/bin/node_modules/json-path/node_modules/json-ptr/test/tests.html
new file mode 100644
index 00000000..00b62230
--- /dev/null
+++ b/bin/node_modules/json-path/node_modules/json-ptr/test/tests.html
@@ -0,0 +1,30 @@
+
+
+
+ Mocha Tests
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bin/node_modules/json-path/node_modules/json-ptr/test/tests.js b/bin/node_modules/json-path/node_modules/json-ptr/test/tests.js
new file mode 100644
index 00000000..c4c65510
--- /dev/null
+++ b/bin/node_modules/json-path/node_modules/json-ptr/test/tests.js
@@ -0,0 +1,798 @@
+/*jshint laxcomma: true*/
+/*globals describe, it*/
+
+if (typeof require === 'function') {
+ var expect = require('expect.js')
+ , JsonPointer = require('..')
+ ;
+}
+
+var ptr = JsonPointer;
+
+describe('JsonPointer', function () {
+ 'use strict';
+
+ describe('when working with the example data from the rfc', function () {
+ var data = {
+ "foo": ["bar", "baz"],
+ "": 0,
+ "a/b": 1,
+ "c%d": 2,
+ "e^f": 3,
+ "g|h": 4,
+ "i\\j": 5,
+ "k\"l": 6,
+ " ": 7,
+ "m~n": 8
+ };
+
+ describe('with a JSON pointer to the root ``', function () {
+ var p = ptr.create('');
+
+ it('#get should resolve to the object itself', function () {
+ expect(p.get(data)).to.eql(data);
+ });
+
+ it('#set should throw', function () {
+ expect(function () {
+ p.set(data, { this: "should cause an exception"});
+ }).to.throwError();
+ });
+
+ it('should have an empty path', function () {
+ expect(p.path).to.have.length(0);
+ });
+
+ it('should have a pointer that is empty', function () {
+ expect(p.pointer).to.eql('');
+ });
+
+ it('should have a URI fragment identfier that is empty', function () {
+ expect(p.uriFragmentIdentifier).to.eql('#');
+ });
+ });
+
+ describe('a URI fragment identfier to the root #', function () {
+ var p = ptr.create('#');
+
+ it('#get should resolve to the object itself', function () {
+ expect(p.get(data)).to.equal(data);
+ });
+
+ it('#set should throw', function () {
+ expect(function () {
+ p.set(data, { this: "should cause an exception"});
+ }).to.throwError();
+ });
+
+ it('should have an empty path', function () {
+ expect(p.path).to.have.length(0);
+ });
+
+ it('should have a pointer that is empty', function () {
+ expect(p.pointer).to.eql('');
+ });
+
+ it('should have a URI fragment identfier that is empty', function () {
+ expect(p.uriFragmentIdentifier).to.eql('#');
+ });
+ });
+
+ describe('with a JSON pointer of `/foo`', function () {
+ var p = ptr.create('/foo');
+
+ it('#get should resolve to data["foo"]', function () {
+ expect(p.get(data)).to.equal(data["foo"]);
+ });
+
+ it('#set should succeed changing the referenced value', function () {
+ var capture = p.get(data);
+ var updated = { this: "should succeed" };
+ p.set(data, updated);
+ expect(p.get(data)).to.eql(updated);
+ p.set(data, capture);
+ });
+
+ it('should have a path of [ "foo" ]', function () {
+ expect(p.path).to.eql(["foo"]);
+ });
+
+ it('should have the pointer `/foo`', function () {
+ expect(p.pointer).to.eql('/foo');
+ });
+
+ it('should have the URI fragment identfier `#/foo`', function () {
+ expect(p.uriFragmentIdentifier).to.eql('#/foo');
+ });
+ });
+
+ describe('a URI fragment identifier of `#/foo`', function () {
+ var p = ptr.create('#/foo');
+
+ it('#get should resolve to data["foo"]', function () {
+ expect(p.get(data)).to.equal(data["foo"]);
+ });
+
+ it('#set should succeed changing the referenced value', function () {
+ var capture = p.get(data);
+ var updated = { this: "should succeed" };
+ p.set(data, updated);
+ expect(p.get(data)).to.eql(updated);
+ p.set(data, capture);
+ });
+
+ it('should have a path of [ "foo" ]', function () {
+ expect(p.path).to.eql(["foo"]);
+ });
+
+ it('should have the pointer `/foo`', function () {
+ expect(p.pointer).to.eql('/foo');
+ });
+
+ it('should have the URI fragment identfier `#/foo`', function () {
+ expect(p.uriFragmentIdentifier).to.eql('#/foo');
+ });
+ });
+
+ describe('with a JSON pointer of `/foo/0`', function () {
+ var p = ptr.create('/foo/0');
+
+ it('#get should resolve to data.foo[0]', function () {
+ expect(p.get(data)).to.equal(data.foo[0]);
+ });
+
+ it('#set should succeed changing the referenced value', function () {
+ var capture = p.get(data);
+ var updated = { this: "should succeed" };
+ p.set(data, updated);
+ expect(p.get(data)).to.eql(updated);
+ p.set(data, capture);
+ });
+
+ it('should have a path of [ "foo", "0" ]', function () {
+ expect(p.path).to.eql(["foo", "0"]);
+ });
+
+ it('should have the pointer `/foo/0`', function () {
+ expect(p.pointer).to.eql('/foo/0');
+ });
+
+ it('should have the URI fragment identfier `#/foo/0`', function () {
+ expect(p.uriFragmentIdentifier).to.eql('#/foo/0');
+ });
+ });
+
+ describe('a URI fragment identifier of `#/foo/0`', function () {
+ var p = ptr.create('#/foo/0');
+
+ it('#get should resolve to data.foo[0]', function () {
+ expect(p.get(data)).to.equal(data.foo[0]);
+ });
+
+ it('#set should succeed changing the referenced value', function () {
+ var capture = p.get(data);
+ var updated = { this: "should succeed" };
+ p.set(data, updated);
+ expect(p.get(data)).to.eql(updated);
+ p.set(data, capture);
+ });
+
+ it('should have a path of [ "foo", "0" ]', function () {
+ expect(p.path).to.eql(["foo", "0"]);
+ });
+
+ it('should have the pointer `/foo/0`', function () {
+ expect(p.pointer).to.eql('/foo/0');
+ });
+
+ it('should have the URI fragment identfier `#/foo/0`', function () {
+ expect(p.uriFragmentIdentifier).to.eql('#/foo/0');
+ });
+ });
+
+ describe('with a JSON pointer of `/`', function () {
+ var p = ptr.create('/');
+
+ it('#get should resolve to data[""]', function () {
+ expect(p.get(data)).to.equal(data[""]);
+ });
+
+ it('#set should succeed changing the referenced value', function () {
+ var capture = p.get(data);
+ var updated = { this: "should succeed" };
+ p.set(data, updated);
+ expect(p.get(data)).to.eql(updated);
+ p.set(data, capture);
+ });
+
+ it('should have a path of [ "" ]', function () {
+ expect(p.path).to.eql([""]);
+ });
+
+ it('should have the pointer `/`', function () {
+ expect(p.pointer).to.eql('/');
+ });
+
+ it('should have the URI fragment identfier `#/`', function () {
+ expect(p.uriFragmentIdentifier).to.eql('#/');
+ });
+ });
+
+ describe('a URI fragment identifier of `#/`', function () {
+ var p = ptr.create('#/');
+
+ it('#get should resolve to data[""]', function () {
+ expect(p.get(data)).to.equal(data[""]);
+ });
+
+ it('#set should succeed changing the referenced value', function () {
+ var capture = p.get(data);
+ var updated = { this: "should succeed" };
+ p.set(data, updated);
+ expect(p.get(data)).to.eql(updated);
+ p.set(data, capture);
+ });
+
+ it('should have a path of [ "" ]', function () {
+ expect(p.path).to.eql([""]);
+ });
+
+ it('should have the pointer `/`', function () {
+ expect(p.pointer).to.eql('/');
+ });
+
+ it('should have the URI fragment identfier `#/`', function () {
+ expect(p.uriFragmentIdentifier).to.eql('#/');
+ });
+ });
+
+ describe('with a JSON pointer of `/a~1b`', function () {
+ var p = ptr.create('/a~1b');
+
+ it('#get should resolve to data["a/b"]', function () {
+ expect(p.get(data)).to.equal(data["a/b"]);
+ });
+
+ it('#set should succeed changing the referenced value', function () {
+ var capture = p.get(data);
+ var updated = { this: "should succeed" };
+ p.set(data, updated);
+ expect(p.get(data)).to.eql(updated);
+ p.set(data, capture);
+ });
+
+ it('should have a path of [ "a/b" ]', function () {
+ expect(p.path).to.eql(["a/b"]);
+ });
+
+ it('should have the pointer `/a~1b`', function () {
+ expect(p.pointer).to.eql('/a~1b');
+ });
+
+ it('should have the URI fragment identfier `#/a~1b`', function () {
+ expect(p.uriFragmentIdentifier).to.eql('#/a~1b');
+ });
+ });
+
+ describe('a URI fragment identifier of `#/a~1b`', function () {
+ var p = ptr.create('#/a~1b');
+
+ it('#get should resolve to data["a/b"]', function () {
+ expect(p.get(data)).to.equal(data["a/b"]);
+ });
+
+ it('#set should succeed changing the referenced value', function () {
+ var capture = p.get(data);
+ var updated = { this: "should succeed" };
+ p.set(data, updated);
+ expect(p.get(data)).to.eql(updated);
+ p.set(data, capture);
+ });
+
+ it('should have a path of [ "a/b" ]', function () {
+ expect(p.path).to.eql(["a/b"]);
+ });
+
+ it('should have the pointer `/a~1b`', function () {
+ expect(p.pointer).to.eql('/a~1b');
+ });
+
+ it('should have the URI fragment identfier `#/a~1b`', function () {
+ expect(p.uriFragmentIdentifier).to.eql('#/a~1b');
+ });
+ });
+
+ describe('with a JSON pointer of `/c%d`', function () {
+ var p = ptr.create('/c%d');
+
+ it('#get should resolve to data["c%d"]', function () {
+ expect(p.get(data)).to.equal(data["c%d"]);
+ });
+
+ it('#set should succeed changing the referenced value', function () {
+ var capture = p.get(data);
+ var updated = { this: "should succeed" };
+ p.set(data, updated);
+ expect(p.get(data)).to.eql(updated);
+ p.set(data, capture);
+ });
+
+ it('should have a path of [ "c%d" ]', function () {
+ expect(p.path).to.eql(["c%d"]);
+ });
+
+ it('should have the pointer `/c%d`', function () {
+ expect(p.pointer).to.eql('/c%d');
+ });
+
+ it('should have the URI fragment identfier `#/c%25d`', function () {
+ expect(p.uriFragmentIdentifier).to.eql('#/c%25d');
+ });
+ });
+
+ describe('a URI fragment identifier of `#/c%25d`', function () {
+ var p = ptr.create('#/c%25d');
+
+ it('#get should resolve to data["c%d"]', function () {
+ expect(p.get(data)).to.equal(data["c%d"]);
+ });
+
+ it('#set should succeed changing the referenced value', function () {
+ var capture = p.get(data);
+ var updated = { this: "should succeed" };
+ p.set(data, updated);
+ expect(p.get(data)).to.eql(updated);
+ p.set(data, capture);
+ });
+
+ it('should have a path of [ "c%d" ]', function () {
+ expect(p.path).to.eql(["c%d"]);
+ });
+
+ it('should have the pointer `/c%d`', function () {
+ expect(p.pointer).to.eql('/c%d');
+ });
+
+ it('should have the URI fragment identfier `#/c%25d`', function () {
+ expect(p.uriFragmentIdentifier).to.eql('#/c%25d');
+ });
+ });
+
+ describe('with a JSON pointer of `/e^f`', function () {
+ var p = ptr.create('/e^f');
+
+ it('#get should resolve to data["e^f"]', function () {
+ expect(p.get(data)).to.equal(data["e^f"]);
+ });
+
+ it('#set should succeed changing the referenced value', function () {
+ var capture = p.get(data);
+ var updated = { this: "should succeed" };
+ p.set(data, updated);
+ expect(p.get(data)).to.eql(updated);
+ p.set(data, capture);
+ });
+
+ it('should have a path of [ "e^f" ]', function () {
+ expect(p.path).to.eql(["e^f"]);
+ });
+
+ it('should have the pointer `/e^f`', function () {
+ expect(p.pointer).to.eql('/e^f');
+ });
+
+ it('should have the URI fragment identfier `#/e%5Ef`', function () {
+ expect(p.uriFragmentIdentifier).to.eql('#/e%5Ef');
+ });
+ });
+
+ describe('a URI fragment identifier of `#/e%5Ef`', function () {
+ var p = ptr.create('#/e%5Ef');
+
+ it('#get should resolve to data["e^f"]', function () {
+ expect(p.get(data)).to.equal(data["e^f"]);
+ });
+
+ it('#set should succeed changing the referenced value', function () {
+ var capture = p.get(data);
+ var updated = { this: "should succeed" };
+ p.set(data, updated);
+ expect(p.get(data)).to.eql(updated);
+ p.set(data, capture);
+ });
+
+ it('should have a path of [ "e^f" ]', function () {
+ expect(p.path).to.eql(["e^f"]);
+ });
+
+ it('should have the pointer `/e^f`', function () {
+ expect(p.pointer).to.eql('/e^f');
+ });
+
+ it('should have the URI fragment identfier `#/e%5Ef`', function () {
+ expect(p.uriFragmentIdentifier).to.eql('#/e%5Ef');
+ });
+ });
+
+ describe('with a JSON pointer of `/g|h`', function () {
+ var p = ptr.create('/g|h');
+
+ it('#get should resolve to data["g|h"]', function () {
+ expect(p.get(data)).to.equal(data["g|h"]);
+ });
+
+ it('#set should succeed changing the referenced value', function () {
+ var capture = p.get(data);
+ var updated = { this: "should succeed" };
+ p.set(data, updated);
+ expect(p.get(data)).to.eql(updated);
+ p.set(data, capture);
+ });
+
+ it('should have a path of [ "g|h" ]', function () {
+ expect(p.path).to.eql(["g|h"]);
+ });
+
+ it('should have the pointer `/g|h`', function () {
+ expect(p.pointer).to.eql('/g|h');
+ });
+
+ it('should have the URI fragment identfier `#/g%7Ch`', function () {
+ expect(p.uriFragmentIdentifier).to.eql('#/g%7Ch');
+ });
+ });
+
+ describe('a URI fragment identifier of `#/g%7Ch`', function () {
+ var p = ptr.create('#/g%7Ch');
+
+ it('#get should resolve to data["g|h"]', function () {
+ expect(p.get(data)).to.equal(data["g|h"]);
+ });
+
+ it('#set should succeed changing the referenced value', function () {
+ var capture = p.get(data);
+ var updated = { this: "should succeed" };
+ p.set(data, updated);
+ expect(p.get(data)).to.eql(updated);
+ p.set(data, capture);
+ });
+
+ it('should have a path of [ "g|h" ]', function () {
+ expect(p.path).to.eql(["g|h"]);
+ });
+
+ it('should have the pointer `/g|h`', function () {
+ expect(p.pointer).to.eql('/g|h');
+ });
+
+ it('should have the URI fragment identfier `#/g%7Ch`', function () {
+ expect(p.uriFragmentIdentifier).to.eql('#/g%7Ch');
+ });
+ });
+
+ describe('with a JSON pointer of `/i\\j`', function () {
+ var p = ptr.create('/i\\j');
+
+ it('#get should resolve to data["i\\j"]', function () {
+ expect(p.get(data)).to.equal(data["i\\j"]);
+ });
+
+ it('#set should succeed changing the referenced value', function () {
+ var capture = p.get(data);
+ var updated = { this: "should succeed" };
+ p.set(data, updated);
+ expect(p.get(data)).to.eql(updated);
+ p.set(data, capture);
+ });
+
+ it('should have a path of [ "i\\j" ]', function () {
+ expect(p.path).to.eql(["i\\j"]);
+ });
+
+ it('should have the pointer `/i\\j`', function () {
+ expect(p.pointer).to.eql('/i\\j');
+ });
+
+ it('should have the URI fragment identfier `#/i%5Cj`', function () {
+ expect(p.uriFragmentIdentifier).to.eql('#/i%5Cj');
+ });
+ });
+
+ describe('a URI fragment identifier of `#/i%5Cj`', function () {
+ var p = ptr.create('#/i%5Cj');
+
+ it('#get should resolve to data["i\\j"]', function () {
+ expect(p.get(data)).to.equal(data["i\\j"]);
+ });
+
+ it('#set should succeed changing the referenced value', function () {
+ var capture = p.get(data);
+ var updated = { this: "should succeed" };
+ p.set(data, updated);
+ expect(p.get(data)).to.eql(updated);
+ p.set(data, capture);
+ });
+
+ it('should have a path of [ "i\\j" ]', function () {
+ expect(p.path).to.eql(["i\\j"]);
+ });
+
+ it('should have the pointer `/i\\j`', function () {
+ expect(p.pointer).to.eql('/i\\j');
+ });
+
+ it('should have the URI fragment identfier `#/i%5Cj`', function () {
+ expect(p.uriFragmentIdentifier).to.eql('#/i%5Cj');
+ });
+ });
+
+ describe('with a JSON pointer of `/k\"l`', function () {
+ var p = ptr.create('/k\"l');
+
+ it('#get should resolve to data["k\"l"]', function () {
+ expect(p.get(data)).to.equal(data["k\"l"]);
+ });
+
+ it('#set should succeed changing the referenced value', function () {
+ var capture = p.get(data);
+ var updated = { this: "should succeed" };
+ p.set(data, updated);
+ expect(p.get(data)).to.eql(updated);
+ p.set(data, capture);
+ });
+
+ it('should have a path of [ "k\"l" ]', function () {
+ expect(p.path).to.eql(["k\"l"]);
+ });
+
+ it('should have the pointer `/k\"l`', function () {
+ expect(p.pointer).to.eql('/k\"l');
+ });
+
+ it('should have the URI fragment identfier `#/k%22l`', function () {
+ expect(p.uriFragmentIdentifier).to.eql('#/k%22l');
+ });
+ });
+
+ describe('a URI fragment identifier of `#/k%22l`', function () {
+ var p = ptr.create('#/k%22l');
+
+ it('#get should resolve to data["k\"l"]', function () {
+ expect(p.get(data)).to.equal(data["k\"l"]);
+ });
+
+ it('#set should succeed changing the referenced value', function () {
+ var capture = p.get(data);
+ var updated = { this: "should succeed" };
+ p.set(data, updated);
+ expect(p.get(data)).to.eql(updated);
+ p.set(data, capture);
+ });
+
+ it('should have a path of [ "k\"l" ]', function () {
+ expect(p.path).to.eql(["k\"l"]);
+ });
+
+ it('should have the pointer `/k\"l`', function () {
+ expect(p.pointer).to.eql('/k\"l');
+ });
+
+ it('should have the URI fragment identfier `#/k%22l`', function () {
+ expect(p.uriFragmentIdentifier).to.eql('#/k%22l');
+ });
+ });
+
+ describe('with a JSON pointer of `/ `', function () {
+ var p = ptr.create('/ ');
+
+ it('#get should resolve to data[" "]', function () {
+ expect(p.get(data)).to.equal(data[" "]);
+ });
+
+ it('#set should succeed changing the referenced value', function () {
+ var capture = p.get(data);
+ var updated = { this: "should succeed" };
+ p.set(data, updated);
+ expect(p.get(data)).to.eql(updated);
+ p.set(data, capture);
+ });
+
+ it('should have a path of [ " " ]', function () {
+ expect(p.path).to.eql([" "]);
+ });
+
+ it('should have the pointer `/ `', function () {
+ expect(p.pointer).to.eql('/ ');
+ });
+
+ it('should have the URI fragment identfier `#/%20`', function () {
+ expect(p.uriFragmentIdentifier).to.eql('#/%20');
+ });
+ });
+
+ describe('a URI fragment identifier of `#/%20`', function () {
+ var p = ptr.create('#/%20');
+
+ it('#get should resolve to data[" "]', function () {
+ expect(p.get(data)).to.equal(data[" "]);
+ });
+
+ it('#set should succeed changing the referenced value', function () {
+ var capture = p.get(data);
+ var updated = { this: "should succeed" };
+ p.set(data, updated);
+ expect(p.get(data)).to.eql(updated);
+ p.set(data, capture);
+ });
+
+ it('should have a path of [ " " ]', function () {
+ expect(p.path).to.eql([" "]);
+ });
+
+ it('should have the pointer `/ `', function () {
+ expect(p.pointer).to.eql('/ ');
+ });
+
+ it('should have the URI fragment identfier `#/%20`', function () {
+ expect(p.uriFragmentIdentifier).to.eql('#/%20');
+ });
+ });
+
+ describe('with a JSON pointer of `/m~0n`', function () {
+ var p = ptr.create('/m~0n');
+
+ it('#get should resolve to data["m~n"]', function () {
+ expect(p.get(data)).to.equal(data["m~n"]);
+ });
+
+ it('#set should succeed changing the referenced value', function () {
+ var capture = p.get(data);
+ var updated = { this: "should succeed" };
+ p.set(data, updated);
+ expect(p.get(data)).to.eql(updated);
+ p.set(data, capture);
+ });
+
+ it('should have a path of [ "m~n" ]', function () {
+ expect(p.path).to.eql(["m~n"]);
+ });
+
+ it('should have the pointer `/m~0n`', function () {
+ expect(p.pointer).to.eql('/m~0n');
+ });
+
+ it('should have the URI fragment identfier `#/m~0n`', function () {
+ expect(p.uriFragmentIdentifier).to.eql('#/m~0n');
+ });
+ });
+
+ describe('a URI fragment identifier of `#/m~0n`', function () {
+ var p = ptr.create('#/m~0n');
+
+ it('#get should resolve to data["m~n"]', function () {
+ expect(p.get(data)).to.equal(data["m~n"]);
+ });
+
+ it('#set should succeed changing the referenced value', function () {
+ var capture = p.get(data);
+ var updated = { this: "should succeed" };
+ p.set(data, updated);
+ expect(p.get(data)).to.eql(updated);
+ p.set(data, capture);
+ });
+
+ it('should have a path of [ "m~n" ]', function () {
+ expect(p.path).to.eql(["m~n"]);
+ });
+
+ it('should have the pointer `/m~0n`', function () {
+ expect(p.pointer).to.eql('/m~0n');
+ });
+
+ it('should have the URI fragment identfier `#/m~0n`', function () {
+ expect(p.uriFragmentIdentifier).to.eql('#/m~0n');
+ });
+ });
+
+ describe('a special array pointer from draft-ietf-appsawg-json-pointer-08 `/foo/-`', function () {
+ var p = ptr.create('/foo/-');
+
+ it('should not resolve via #get', function () {
+ expect(p.get(data)).to.not.be.ok();
+ });
+
+ it('should set the next element of the array, repeatedly...', function () {
+ p.set(data, 'qux');
+ expect(data.foo[2]).to.eql('qux');
+ });
+
+ it('...', function () {
+ p.set(data, 'quux');
+ expect(data.foo[3]).to.eql('quux');
+ });
+
+ it('...', function () {
+ p.set(data, 'corge');
+ expect(data.foo[4]).to.eql('corge');
+ });
+
+ it('...', function () {
+ p.set(data, 'grault');
+ expect(data.foo[5]).to.eql('grault');
+ });
+ });
+
+ describe('an invalid pointer', function () {
+
+ it('should fail to parse', function () {
+ expect(function () {
+ ptr.create('a/');
+ }).to.throwError();
+ });
+ });
+
+ describe('an invalid URI fragment identifier', function () {
+
+ it('should fail to parse', function () {
+ expect(function () {
+ ptr.create('#a');
+ }).to.throwError();
+ });
+
+ });
+ });
+
+ describe('can revert namespace using noConflict', function () {
+ ptr = ptr.noConflict();
+
+ it('conflict is restored (when applicable)', function () {
+ // In node there is no global conflict.
+ if (typeof globalConflict !== 'undefined') {
+ expect(JsonPointer).to.be(globalConflict);
+ }
+ });
+
+ it('JsonPointer functionality available through result of noConflict()', function () {
+ expect(ptr).to.have.property('get');
+ });
+ });
+
+ describe('when working with complex data', function () {
+ var data = {
+ a: 1,
+ b: {
+ c: 2
+ },
+ d: {
+ e: [{a:3}, {b:4}, {c:5}]
+ },
+ f: null
+ };
+
+
+ it('#get should return `undefined` when the requested element is undefined (#/g/h)', function () {
+ var unk = ptr.get(data, '#/g/h');
+ expect(unk).to.be.an('undefined');
+ });
+
+
+ it('#get should return null when the requested element has a null value (#/f)', function () {
+ var unk = ptr.get(data, '#/f');
+ expect(unk).to.be(null);
+ });
+ });
+
+ describe('given an sequence of property names ["d", "e~f", "2"]', function () {
+ var path = ["d", "e~f", "2"];
+
+ it('#encodePointer should produce a pointer (/d/e~0f/2)', function () {
+ expect(ptr.encodePointer(path)).to.be('/d/e~0f/2');
+ });
+
+ it('#encodeUriFragmentIdentifier should produce a pointer (#/d/e~0f/2)', function () {
+ expect(ptr.encodeUriFragmentIdentifier(path)).to.be('#/d/e~0f/2');
+ });
+
+ });
+
+});
diff --git a/bin/node_modules/json-path/package.json b/bin/node_modules/json-path/package.json
new file mode 100644
index 00000000..b3e6dc58
--- /dev/null
+++ b/bin/node_modules/json-path/package.json
@@ -0,0 +1,54 @@
+{
+ "name": "json-path",
+ "version": "0.1.3",
+ "author": {
+ "name": "Phillip Clark",
+ "email": "phillip@flitbit.com"
+ },
+ "description": "JSON-Path utility (XPath for JSON) for nodejs and modern browsers.",
+ "main": "index.js",
+ "directories": {
+ "example": "examples",
+ "test": "test"
+ },
+ "scripts": {
+ "test": "mocha -R spec"
+ },
+ "dependencies": {
+ "json-ptr": "~0.1.1"
+ },
+ "devDependencies": {
+ "expect.js": "~0.2.0",
+ "mocha": "~1.13.0"
+ },
+ "license": "MIT",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/flitbit/json-path"
+ },
+ "readme": "json-path (alpha) [](http://travis-ci.org/flitbit/json-path)\n=========\n\nJSON-Path utility (XPath for JSON) for nodejs and modern browsers.\n\nYou may be looking for the prior work [found here](http://goessner.net/articles/JsonPath/). This implementation is a new JSON-Path syntax building on [JSON Pointer (RFC 6901)](http://tools.ietf.org/html/rfc6901) in order to ensure that any valid JSON pointer is also valid JSON-Path.\n\n**Warning:** This is a work in progress - I am actively adding selection expressions and have yet to optimize, but as I use it in a few other projects I went ahead and made it available via `npm`. Until I take the **alpha** tag off you should look to the examples and test to understand the selection path syntax.\n\n## Example\n\n[flikr-example-2.js](https://github.com/flitbit/json-path/blob/master/examples/flikr-example-2.js)\n```javascript\nvar jpath = require('json-path')\n, http = require('http')\n, util = require('util')\n;\n\nvar feed = \"http://api.flickr.com/services/feeds/photos_public.gne?tags=beach,pipeline&tagmode=all&format=json&jsoncallback=processResponse\"\n;\n\nfunction processResponse(json) {\n\tvar res = jpath.resolve(json, \"#/items[first(3)]take(/title,/author,media=/media/m)\")\n\tconsole.log( util.inspect(res, false, 5) );\n}\n\nhttp.get(feed, function(res) {\n\tconsole.log(\"Got response: \" + res.statusCode);\n\n\tvar data = '';\n\n\tres.on('data', function (chunk){\n\t\tdata += chunk;\n\t});\n\n\tres.on('end',function(){\n\t\t// result is formatted as jsonp... this is for illustration only.\n\t\teval(data);\n\t})\n}).on('error', function(e) {\n\tconsole.log(\"Got error: \" + e.message);\n});\n```\n\n## Installation\n\n[node.js](http://nodejs.org)\n```bash\n$ npm install json-path\n```\n\n## Basics\n\nJSON-Path takes a specially formatted *path* statement and applies it to an object graph in order to *select* results. The results are returned as an array of data that matches the path.\n\nMost paths start out looking like a JSON Pointer...\n\n```javascript\n// From: http://goessner.net/articles/JsonPath/\nvar data = {\n store: {\n book: [\n { category: \"reference\",\n author: \"Nigel Rees\",\n title: \"Sayings of the Century\",\n price: 8.95\n },\n { category: \"fiction\",\n author: \"Evelyn Waugh\",\n title: \"Sword of Honour\",\n price: 12.99\n },\n { category: \"fiction\",\n author: \"Herman Melville\",\n title: \"Moby Dick\",\n isbn: \"0-553-21311-3\",\n price: 8.99\n },\n { category: \"fiction\",\n author: \"J. R. R. Tolkien\",\n title: \"The Lord of the Rings\",\n isbn: \"0-395-19395-8\",\n price: 22.99\n }\n ],\n bicycle: {\n color: \"red\",\n price: 19.95\n }\n }\n};\n```\n\nThe pointer `/store/book/0` refers to the first book in the array of books (the one by Nigen Rees).\n\n**Differentiator**\n\nThe thing that makes JSON-Path different from JSON-Pointer is that you can do more than reference a single point in a structure. Instead, you are able to `select` many pieces of data out of a structure, such as:\n\n`/store/book[*]/price`\n```javascript\n[8.95, 12.99, 8.99, 22.99]\n```\n\nIn the preceding example, the path `/store/book[*]/price` has three distinct statements:\n\nStatement | Meaning\n--- | ---\n`/store/book` | Get the book property from store. This is similar to `data.store.book` in javascript.\n`*` | Select any element (or property).\n`/price` | Select the price property.\n\nStarting with the original data, each statement refines the data, usually by selecting parts. As each statement is processed, it is given the results from the previous statement and may make further selections, until the final selections are returned to the caller. It works something like map-reduce; or if you like, something like list-comprehensions.\n\n**Distinguishing Statements**\n\nStatements are distinguished from one another using the square-brackets `[` and `]`. In many cases, the parser can infer where one statement ends and another begins, such as in the preceding example `/store/book[*]/price`. However, the parser understands the equivelant, fully specified path `[/store/book][*][/price]`.\n\nPaths can have as many distinct statements as you need to select just the right data. Since it extends JSON-Pointer, you must take care when your path contains square-brackets as part of property names such as the following contrived example:\n\n```javascript\nvar data = {\n\t'my[': {\n\t\tcontrived: {\n\t\t\t'example]': { should: \"mess with\", your: \"noodel\" } } }\n};\n```\n\nIn this data, the property names `my[` and `example]` are valid but would cuase ambiguities for either the parser or the processing of statements. In these cases, you must use the URI fragment identifier representation described in [RFC 6901 Section 6](http://tools.ietf.org/html/rfc6901#section-6). For instance, to access `data['my['].contrived['example]'].your` you would need the path `#/my%5B/contrived/example%5D/your`.\n\n### More Power\n\nJSON-Path becomes more powerful with a few additional types of statements:\n\nStatement | Meaning\n--- | ---\n`..` | Makes an exhaustive descent, executing the next statement against each branch of the object-graph.\n`take(s0,s1,...)` | Takes one or more items from the structure, each specified as a [JSON Pointer](http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-09).\n`@` | Uses the user-supplied function to select or filter data.\n\nConsider the following examples using the same preceding data:\n\nPath | Result\n--- | ---\n`/store[..]/price` | Selects all prices, from books and the bicycle.\n`../isbn` | Selects all ISBN numbers, wherever they are in the structure.\n`/store/book[*]take(/author,/title)` | Selects author and title from each book.\n`/store/book[*][@]` | Selects all books, providing each to the user-supplied selection method.\n\n**User Supplied Selection Methods**\n\nJSON-Path supports the use of user-supplied selections - which will need to fill in until the expression syntax is completed. Mindful of the preceding data, consider the following code:\n\n```javascript\nvar jpath = require('json-path')\n, expect = require('expect.js')\n, data = require('./example-data')\n\nvar p = jpath.create(\"#/store/book[*][@]\");\n\nvar res = p.resolve(data, function(obj, accum) {\n if (typeof obj.price === 'number' && obj.price < 10)\n accum.push(obj);\n return accum;\n});\n\n// Expect the result to have the two books priced under $10...\nexpect(res).to.contain(data[\"store\"][\"book\"][0]);\nexpect(res).to.contain(data[\"store\"][\"book\"][2]);\nexpect(res).to.have.length(2);\n\n```\n\nThe example above illustrates user-defined selection given to `resolve` used in place of the `@`.\n\nTo use more than one user-defined selections, refer to selection functions by name and provide implementations when resolving the path:\n\n```javascript\nvar jpath = require('json-path')\n, expect = require('expect.js')\n, data = require('./example-data')\n\nvar p = jpath.create(\"#/store/book[*][@lt10][@format]\");\n\nvar res = p.resolve(data, {\n\n\tlt10: function(obj, accum) {\n\t\tif (typeof obj.price === 'number' && obj.price < 10)\n\t\t\taccum.push(obj);\n\t\treturn accum;\n\t},\n\n\tformat: function(obj, accum) {\n\t\taccum.push(obj.title.concat(\n\t\t\t\": $\", obj.price\n\t\t\t));\n\t\treturn accum;\n\t}\n\n});\n\n// Expect the result to have formatted strings for\n// the twb books priced under $10...\nexpect(res).to.contain(\"Sayings of the Century: $8.95\");\nexpect(res).to.contain(\"Moby Dick: $8.99\");\nexpect(res).to.have.length(2);\n```\n",
+ "readmeFilename": "README.md",
+ "bugs": {
+ "url": "https://github.com/flitbit/json-path/issues"
+ },
+ "_id": "json-path@0.1.3",
+ "dist": {
+ "shasum": "dce61357b3b281b28ac647ec0a709bc58a155bf8",
+ "tarball": "http://registry.npmjs.org/json-path/-/json-path-0.1.3.tgz"
+ },
+ "_from": "json-path@*",
+ "_npmVersion": "1.3.8",
+ "_npmUser": {
+ "name": "flitbit",
+ "email": "phillip@flitbit.com"
+ },
+ "maintainers": [
+ {
+ "name": "flitbit",
+ "email": "phillip@flitbit.com"
+ }
+ ],
+ "_shasum": "dce61357b3b281b28ac647ec0a709bc58a155bf8",
+ "_resolved": "https://registry.npmjs.org/json-path/-/json-path-0.1.3.tgz",
+ "homepage": "https://github.com/flitbit/json-path"
+}
diff --git a/bin/node_modules/json-path/releases/json-path+json-ptr-0.1.3.min.js b/bin/node_modules/json-path/releases/json-path+json-ptr-0.1.3.min.js
new file mode 100644
index 00000000..2f3f5602
--- /dev/null
+++ b/bin/node_modules/json-path/releases/json-path+json-ptr-0.1.3.min.js
@@ -0,0 +1 @@
+!function(e){"use strict";var r,n,t=[];if(typeof global==="object"&&global){r=global;n=global.JsonPointer}else if(typeof window!=="undefined"){r=window;n=window.JsonPointer}else{r={}}if(n){t.push(function(){if(r.JsonPointer===f){r.JsonPointer=n;n=e}})}function i(e){if(typeof e!=="string"){throw new TypeError("Invalid type: JSON Pointers are represented as strings.")}if(e.length===0){return[]}if(e[0]!=="/"){throw new ReferenceError("Invalid JSON Pointer syntax. Non-empty pointer must begin with a solidus `/`.")}var r=e.substring(1).split("/"),n=-1,t=r.length;while(++n1&&r[0]==="0"){return-1}if(n===1&&r[0]==="-"){return e.length}while(++t"9"){return-1}}return parseInt(r,10)}function c(e,r){if(typeof e!=="undefined"){var n=e,t=r.length,i=-1,o,s;if(t){while(++is){n=n[s]}else{return}}else{n=n[o]}}return n}else{return e}}}function l(r,n,t,i){if(t.length===0){throw new Error("Cannot set the root object; assign it directly.")}if(typeof r!=="undefined"){var o=r,s=t.length,a=t.length-1,c=-1,l,f,h;if(s){while(++cf){if(c===a){h=o[f];o[f]=n;return h}o=o[f]}else if(o.length===f){o.push(n);return e}else{throw new ReferenceError("Not found: ".concat(i(t.slice(0,c+1),true),"."))}}else{if(c===a){h=o[l];o[l]=n;return h}o=o[l];if(typeof o==="undefined"){throw new ReferenceError("Not found: ".concat(i(t.slice(0,c+1),true),"."))}}}if(c===s){return o}}else{return o}}}function f(e){this.encode=e.length>0&&e[0]==="#"?a:o;if(Array.isArray(e)){this.path=e}else{var r=e.length>0&&e[0]==="#"?s:i;this.path=r(e)}}Object.defineProperty(f.prototype,"pointer",{enumerable:true,get:function(){return o(this.path)}});Object.defineProperty(f.prototype,"uriFragmentIdentifier",{enumerable:true,get:function(){return a(this.path)}});f.prototype.get=function(e){return c(e,this.path)};f.prototype.set=function(e,r){return l(e,r,this.path,this.encode)};f.prototype.toString=function(){return this.pointer};f.create=function(e){return new f(e)};f.get=function(e,r){var n=r.length>0&&r[0]==="#"?s:i;return c(e,n(r))};f.set=function(e,r,n){var t=r.length>0&&r[0]==="#"?a:o;var u=r.length>0&&r[0]==="#"?s:i;return l(e,n,u(r),t)};f.decodePointer=i;f.encodePointer=o;f.decodeUriFragmentIdentifier=s;f.encodeUriFragmentIdentifier=a;f.noConflict=function(){if(t){t.forEach(function(e){e()});t=null}return f};if(typeof module!=="undefined"&&module&&typeof exports==="object"&&exports&&module.exports===exports){module.exports=f}else{r.JsonPointer=f}}();!function(e){"use strict";var r,n,t=[];if(typeof global==="object"&&global){r=global;n=global.JsonPath}else if(typeof window!=="undefined"){r=window;n=window.JsonPath}else{r={}}if(n){t.push(function(){if(r.JsonPath===P){r.JsonPath=n;n=null}})}if(e){t.push(function(r){if(r){e=r}})}else if(!e){if(typeof r.JsonPointer!=="undefined"){e=r.JsonPointer;t.push(function(r){if(r){e=r}})}else if(typeof require==="function"){e=require("json-ptr")}else{throw new Error("Missing JsonPointer (https://github.com/flitbit/json-ptr).")}}function i(e,r){e=Array.isArray(e)?e:[e];var n,t;for(n=0;n="0"&&e[t]<="9"){t=t+1}if(t===r){throw new Error("Expected an integer at position ".concat(t,"."))}return t-r}function x(e,r,n,t,i){var o=1,a;s(e,r,n,t);r+=t.length-1;if(e[r+1]==="("){r+=2;a=v(e,r,n);o=parseInt(e.substring(r,r+a),10);r+=a;s(e,r,n,")");++r}i.push({kind:t[0],index:o});return r}function k(e,r){var n=r.cursor-1,t=e.length,i=e.indexOf("]",r.cursor),o=null,a=null,u=false,c=[];if(i=s&&o>0){r.push(e[o])}}break;case"i":case"s":{if(a.index="0"&&e[t]<="9"){t=t+1}if(t===r){throw new Error("Expected an integer at position ".concat(t,"."))}return t-r}function v(e,r,n,t,i){var s=1,c;o(e,r,n,t);r+=t.length-1;if(e[r+1]==="("){r+=2;c=x(e,r,n);s=parseInt(e.substring(r,r+c),10);r+=c;o(e,r,n,")");++r}i.push({kind:t[0],index:s});return r}function y(e,r){var n=r.cursor-1,t=e.length,i=e.indexOf("]",r.cursor),s=null,c=null,a=false,u=[];if(i=o&&s>0){r.push(e[s])}}break;case"i":case"s":{if(c.index
+
+
+ Mocha Tests
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+