Repository: socrata/soda-js
Branch: main
Commit: d6d528c919b6
Files: 17
Total size: 144.4 KB
Directory structure:
gitextract_x01kdq_z/
├── .gitignore
├── .travis.yml
├── Cakefile
├── README.textile
├── lib/
│ ├── README
│ ├── soda-js.bundle.js
│ └── soda-js.js
├── package.json
├── sample/
│ ├── basic_producer.js
│ ├── basic_query.js
│ └── browser.html
├── src/
│ └── soda-js.coffee
└── test/
├── connection_tests.coffee
├── consumer_tests.coffee
├── operation_tests.coffee
├── producer_tests.coffee
└── query_tests.coffee
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
.DS_Store
*.swp
*.swo
node_modules/
================================================
FILE: .travis.yml
================================================
language: node_js
node_js:
- 0.8
before_install:
- npm install -g npm@'>=1.4.3'
================================================
FILE: Cakefile
================================================
# Taken almost entirely from https://github.com/twilson63/cakefile-template
#
# Il y a 5 tasks:
#
# * build - compiles your src directory to your lib directory
# * watch - watches any changes in your src directory and automatically compiles to the lib directory
# * test - runs mocha test framework, you can edit this task to use your favorite test framework
# * docs - generates annotated documentation using docco
# * clean - clean generated .js files
files = [
'lib'
'src'
]
fs = require 'fs'
{print} = require 'util'
{spawn, exec} = require 'child_process'
try
which = require('which').sync
catch err
which = null
# ANSI Terminal Colors
bold = '\x1b[0;1m'
green = '\x1b[0;32m'
reset = '\x1b[0m'
red = '\x1b[0;31m'
# Cakefile Tasks
#
# ## *docs*
#
# Generate Annotated Documentation
#
# <small>Usage</small>
#
# ```
# cake docs
# ```
task 'docs', 'generate documentation', -> docco()
# ## *build*
#
# Builds Source
#
# <small>Usage</small>
#
# ```
# cake build
# ```
task 'build', 'compile source', -> build -> log ":)", green
# ## *watch*
#
# Builds your source whenever it changes
#
# <small>Usage</small>
#
# ```
# cake watch
# ```
task 'watch', 'compile and watch', -> build true, -> log ":-)", green
# ## *test*
#
# Runs your test suite.
#
# <small>Usage</small>
#
# ```
# cake test
# ```
task 'test', 'run tests', -> build -> expresso [ 'test/*' ], -> log ":)", green
# ## *clean*
#
# Cleans up generated js files
#
# <small>Ussage</small>
#
# ```
# cake clean
# ```
task 'clean', 'clean generated files', -> clean -> log ";)", green
# Internal Functions
#
# ## *walk*
#
# **given** string as dir which represents a directory in relation to local directory
# **and** callback as done in the form of (err, results)
# **then** recurse through directory returning an array of files
walk = (dir, done) ->
results = []
fs.readdir dir, (err, list) ->
return done(err, []) if err
pending = list.length
return done(null, results) unless pending
for name in list
file = "#{dir}/#{name}"
try
stat = fs.statSync file
catch err
stat = null
if stat?.isDirectory()
walk file, (err, res) ->
results.push name for name in res
done(null, results) unless --pending
else
results.push file
done(null, results) unless --pending
# ## *log*
#
# **given** string as a message
# **and** string as a color
# **and** optional string as an explaination
# **then** builds a statement and logs to console.
log = (message, color, explanation) -> console.log color + message + reset + ' ' + (explanation or '')
# ## *launch*
#
# **given** string as a cmd
# **and** optional array and option flags
# **and** optional callback
# **then** spawn cmd with options
# **and** pipe to process stdout and stderr respectively
# **and** on child process exit emit callback if set and status is 0
launch = (cmd, options=[], callback) ->
cmd = which(cmd) if which
app = spawn cmd, options
app.stdout.pipe(process.stdout)
app.stderr.pipe(process.stderr)
app.on 'exit', (status) -> callback?() if status is 0
# ## *build*
#
# **given** optional boolean as watch
# **and** optional function as callback
# **then** invoke launch passing coffee command
# **and** defaulted options to compile src to lib
build = (watch, callback) ->
if typeof watch is 'function'
callback = watch
watch = false
options = ['-c', '-b', '-o' ]
options = options.concat files
options.unshift '-w' if watch
launch 'coffee', options, callback
# ## *unlinkIfCoffeeFile*
#
# **given** string as file
# **and** file ends in '.coffee'
# **then** convert '.coffee' to '.js'
# **and** remove the result
unlinkIfCoffeeFile = (file) ->
if file.match /\.coffee$/
fs.unlink file.replace(/\.coffee$/, '.js')
true
else false
# ## *clean*
#
# **given** optional function as callback
# **then** loop through files variable
# **and** call unlinkIfCoffeeFile on each
clean = (callback) ->
try
for file in files
unless unlinkIfCoffeeFile file
walk file, (err, results) ->
for f in results
unlinkIfCoffeeFile f
callback?()
catch err
# ## *moduleExists*
#
# **given** name for module
# **when** trying to require module
# **and** not found
# **then* print not found message with install helper in red
# **and* return false if not found
moduleExists = (name) ->
try
require name
catch err
log "#{name} required: npm install #{name}", red
false
# ## *expresso*
#
# **given** optional array of option flags
# **and** optional function as callback
# **then** invoke launch passing expresso command
expresso = (options, callback) ->
if typeof options is 'function'
callback = options
options = []
launch './node_modules/expresso/bin/expresso', options, callback
# ## *docco*
#
# **given** optional function as callback
# **then** invoke launch passing docco command
docco = (callback) ->
#if moduleExists('docco')
walk 'src', (err, files) -> launch 'docco', files, callback
================================================
FILE: README.textile
================================================
h1. soda-js "!https://secure.travis-ci.org/socrata/soda-js.png!":http://travis-ci.org/socrata/soda-js
A client implementation of the Socrata Open Data API in Coffeescript and Javascript.
h2. Important Note
In order to access the SODA API via HTTPS, clients must now "support the Server Name Indication (SNI)":https://dev.socrata.com/changelog/2016/08/24/sni-now-required-for-https-connections.html extension to the TLS protocol. What does this mean? It means that if you're using @soda-js@, you must use a JavaScript VM that supports SNI:
* "Internet Explorer 7+":https://en.wikipedia.org/wiki/Server_Name_Indication#Support
* "Mozilla Firefox 2+":https://en.wikipedia.org/wiki/Server_Name_Indication#Support
* "Apple Safari (all versions)":https://en.wikipedia.org/wiki/Server_Name_Indication#Support
* "Google Chrome 6.0+":https://en.wikipedia.org/wiki/Server_Name_Indication#Support
* "node.js 0.5.3+":https://github.com/nodejs/node/blob/e1643ccc5a5ecf7cb779472d244459469c9971a1/doc/changelogs/CHANGELOG_ARCHIVE.md#20110801-version-053-unstable
h2. Supported Operations
Supports both consumer and producer API, but does not currently support creating datasets or the import workflow.
h2. Usage
See the @sample/@ directory for sample code, but here's the general idea:
bc.. var soda = require('soda-js');
h3. Consumer API
You can query a dataset by SODA2 clauses, or supply a custom SoQL query to be run.
bc.. var consumer = new soda.Consumer('explore.data.gov');
consumer.query()
.withDataset('644b-gaut')
.limit(5)
.where({ namelast: 'SMITH' })
.order('namelast')
.getRows()
.on('success', function(rows) { console.log(rows); })
.on('error', function(error) { console.error(error); });
p. Using 'like' in a where clause:
bc.. .where("namelast like '%MITH'")
h3. Producer API
You can add, update, replace, delete, and upsert rows, as well as truncate a dataset.
bc.. var producer = new soda.Producer('sandbox.demo.socrata.com', sodaConnectionOptions);
var data = { mynum : 42, mytext: "hello world" }
producer.operation()
.withDataset('rphc-ayt9')
.add(data)
.on('success', function(row) { console.log(row); })
.on('error', function(error) { console.error(error); })
h2. License
Provided under the MIT license.
================================================
FILE: lib/README
================================================
this directory contains autogenerated files. do not edit them! edit the files in src/ instead.
================================================
FILE: lib/soda-js.bundle.js
================================================
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.soda = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
(function (Buffer){
// Generated by CoffeeScript 1.6.3
var Connection, Consumer, Dataset, EventEmitter, Operation, Producer, Query, addExpr, base64Lookup, eelib, expr, extend, handleLiteral, handleOrder, httpClient, isArray, isNumber, isString, rawToBase64, toBase64, toQuerystring,
__slice = [].slice,
__hasProp = {}.hasOwnProperty;
eelib = require('eventemitter2');
EventEmitter = eelib.EventEmitter2 || eelib;
httpClient = require('superagent');
isString = function(obj) {
return typeof obj === 'string';
};
isArray = function(obj) {
return Array.isArray(obj);
};
isNumber = function(obj) {
return !isNaN(parseFloat(obj));
};
extend = function() {
var k, source, sources, target, v, _i, _len;
target = arguments[0], sources = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
for (_i = 0, _len = sources.length; _i < _len; _i++) {
source = sources[_i];
for (k in source) {
v = source[k];
target[k] = v;
}
}
return null;
};
toBase64 = typeof Buffer !== "undefined" && Buffer !== null ? function(str) {
return new Buffer(str).toString('base64');
} : (base64Lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='.split(''), rawToBase64 = typeof btoa !== "undefined" && btoa !== null ? btoa : function(str) {
var chr1, chr2, chr3, enc1, enc2, enc3, enc4, i, result;
result = [];
i = 0;
while (i < str.length) {
chr1 = str.charCodeAt(i++);
chr2 = str.charCodeAt(i++);
chr3 = str.charCodeAt(i++);
if (Math.max(chr1, chr2, chr3) > 0xFF) {
throw new Error('Invalid character!');
}
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
result.push(base64Lookup[enc1]);
result.push(base64Lookup[enc2]);
result.push(base64Lookup[enc3]);
result.push(base64Lookup[enc4]);
}
return result.join('');
}, function(str) {
return rawToBase64(unescape(encodeURIComponent(str)));
});
handleLiteral = function(literal) {
if (isString(literal)) {
return "'" + literal + "'";
} else if (isNumber(literal)) {
return literal;
} else {
return literal;
}
};
handleOrder = function(order) {
if (/( asc$| desc$)/i.test(order)) {
return order;
} else {
return order + ' asc';
}
};
addExpr = function(target, args) {
var arg, k, v, _i, _len, _results;
_results = [];
for (_i = 0, _len = args.length; _i < _len; _i++) {
arg = args[_i];
if (isString(arg)) {
_results.push(target.push(arg));
} else {
_results.push((function() {
var _results1;
_results1 = [];
for (k in arg) {
v = arg[k];
_results1.push(target.push("" + k + " = " + (handleLiteral(v))));
}
return _results1;
})());
}
}
return _results;
};
expr = {
and: function() {
var clause, clauses;
clauses = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
return ((function() {
var _i, _len, _results;
_results = [];
for (_i = 0, _len = clauses.length; _i < _len; _i++) {
clause = clauses[_i];
_results.push("(" + clause + ")");
}
return _results;
})()).join(' and ');
},
or: function() {
var clause, clauses;
clauses = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
return ((function() {
var _i, _len, _results;
_results = [];
for (_i = 0, _len = clauses.length; _i < _len; _i++) {
clause = clauses[_i];
_results.push("(" + clause + ")");
}
return _results;
})()).join(' or ');
},
gt: function(column, literal) {
return "" + column + " > " + (handleLiteral(literal));
},
gte: function(column, literal) {
return "" + column + " >= " + (handleLiteral(literal));
},
lt: function(column, literal) {
return "" + column + " < " + (handleLiteral(literal));
},
lte: function(column, literal) {
return "" + column + " <= " + (handleLiteral(literal));
},
eq: function(column, literal) {
return "" + column + " = " + (handleLiteral(literal));
}
};
toQuerystring = function(obj) {
var key, str, val;
str = [];
for (key in obj) {
if (!__hasProp.call(obj, key)) continue;
val = obj[key];
str.push(encodeURIComponent(key) + '=' + encodeURIComponent(val));
}
return str.join('&');
};
Connection = (function() {
function Connection(dataSite, sodaOpts) {
var _ref;
this.dataSite = dataSite;
this.sodaOpts = sodaOpts != null ? sodaOpts : {};
if (!/^[a-z0-9-_.]+(:[0-9]+)?$/i.test(this.dataSite)) {
throw new Error('dataSite does not appear to be valid! Please supply a domain name, eg data.seattle.gov');
}
this.emitterOpts = (_ref = this.sodaOpts.emitterOpts) != null ? _ref : {
wildcard: true,
delimiter: '.',
maxListeners: 15
};
this.networker = function(opts, data) {
var client, url,
_this = this;
url = "https://" + this.dataSite + opts.path;
client = httpClient(opts.method, url);
if (data != null) {
client.set('Accept', "application/json");
}
if (data != null) {
client.set('Content-type', "application/json");
}
if (this.sodaOpts.apiToken != null) {
client.set('X-App-Token', this.sodaOpts.apiToken);
}
if ((this.sodaOpts.username != null) && (this.sodaOpts.password != null)) {
client.set('Authorization', "Basic " + toBase64("" + this.sodaOpts.username + ":" + this.sodaOpts.password));
}
if (this.sodaOpts.accessToken != null) {
client.set('Authorization', "OAuth " + accessToken);
}
if (opts.query != null) {
client.query(opts.query);
}
if (data != null) {
client.send(data);
}
return function(responseHandler) {
return client.end(responseHandler || _this.getDefaultHandler());
};
};
}
Connection.prototype.getDefaultHandler = function() {
var emitter, handler;
this.emitter = emitter = new EventEmitter(this.emitterOpts);
return handler = function(error, response) {
var _ref;
if (response.ok) {
if (response.accepted) {
emitter.emit('progress', response.body);
setTimeout((function() {
return this.consumer.networker(opts)(handler);
}), 5000);
} else {
emitter.emit('success', response.body);
}
} else {
emitter.emit('error', (_ref = response.body) != null ? _ref : response.text);
}
return emitter.emit('complete', response);
};
};
return Connection;
})();
Consumer = (function() {
function Consumer(dataSite, sodaOpts) {
this.dataSite = dataSite;
this.sodaOpts = sodaOpts != null ? sodaOpts : {};
this.connection = new Connection(this.dataSite, this.sodaOpts);
}
Consumer.prototype.query = function() {
return new Query(this);
};
Consumer.prototype.getDataset = function(id) {
var emitter;
return emitter = new EventEmitter(this.emitterOpts);
};
return Consumer;
})();
Producer = (function() {
function Producer(dataSite, sodaOpts) {
this.dataSite = dataSite;
this.sodaOpts = sodaOpts != null ? sodaOpts : {};
this.connection = new Connection(this.dataSite, this.sodaOpts);
}
Producer.prototype.operation = function() {
return new Operation(this);
};
return Producer;
})();
Operation = (function() {
function Operation(producer) {
this.producer = producer;
}
Operation.prototype.withDataset = function(datasetId) {
this._datasetId = datasetId;
return this;
};
Operation.prototype.truncate = function() {
var opts;
opts = {
method: 'delete'
};
opts.path = "/resource/" + this._datasetId;
return this._exec(opts);
};
Operation.prototype.add = function(data) {
var obj, opts, _data, _i, _len;
opts = {
method: 'post'
};
opts.path = "/resource/" + this._datasetId;
_data = JSON.parse(JSON.stringify(data));
delete _data[':id'];
delete _data[':delete'];
for (_i = 0, _len = _data.length; _i < _len; _i++) {
obj = _data[_i];
delete obj[':id'];
delete obj[':delete'];
}
return this._exec(opts, _data);
};
Operation.prototype["delete"] = function(id) {
var opts;
opts = {
method: 'delete'
};
opts.path = "/resource/" + this._datasetId + "/" + id;
return this._exec(opts);
};
Operation.prototype.update = function(id, data) {
var opts;
opts = {
method: 'post'
};
opts.path = "/resource/" + this._datasetId + "/" + id;
return this._exec(opts, data);
};
Operation.prototype.replace = function(id, data) {
var opts;
opts = {
method: 'put'
};
opts.path = "/resource/" + this._datasetId + "/" + id;
return this._exec(opts, data);
};
Operation.prototype.upsert = function(data) {
var opts;
opts = {
method: 'post'
};
opts.path = "/resource/" + this._datasetId;
return this._exec(opts, data);
};
Operation.prototype._exec = function(opts, data) {
if (this._datasetId == null) {
throw new Error('no dataset given to work against!');
}
this.producer.connection.networker(opts, data)();
return this.producer.connection.emitter;
};
return Operation;
})();
Query = (function() {
function Query(consumer) {
this.consumer = consumer;
this._select = [];
this._where = [];
this._group = [];
this._having = [];
this._order = [];
this._offset = this._limit = this._q = null;
}
Query.prototype.withDataset = function(datasetId) {
this._datasetId = datasetId;
return this;
};
Query.prototype.soql = function(query) {
this._soql = query;
return this;
};
Query.prototype.select = function() {
var select, selects, _i, _len;
selects = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
for (_i = 0, _len = selects.length; _i < _len; _i++) {
select = selects[_i];
this._select.push(select);
}
return this;
};
Query.prototype.where = function() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
addExpr(this._where, args);
return this;
};
Query.prototype.having = function() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
addExpr(this._having, args);
return this;
};
Query.prototype.group = function() {
var group, groups, _i, _len;
groups = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
for (_i = 0, _len = groups.length; _i < _len; _i++) {
group = groups[_i];
this._group.push(group);
}
return this;
};
Query.prototype.order = function() {
var order, orders, _i, _len;
orders = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
for (_i = 0, _len = orders.length; _i < _len; _i++) {
order = orders[_i];
this._order.push(handleOrder(order));
}
return this;
};
Query.prototype.offset = function(offset) {
this._offset = offset;
return this;
};
Query.prototype.limit = function(limit) {
this._limit = limit;
return this;
};
Query.prototype.q = function(q) {
this._q = q;
return this;
};
Query.prototype.getOpts = function() {
var k, opts, queryComponents, v;
opts = {
method: 'get'
};
if (this._datasetId == null) {
throw new Error('no dataset given to work against!');
}
opts.path = "/resource/" + this._datasetId + ".json";
queryComponents = this._buildQueryComponents();
opts.query = {};
for (k in queryComponents) {
v = queryComponents[k];
opts.query['$' + k] = v;
}
return opts;
};
Query.prototype.getURL = function() {
var opts, query;
opts = this.getOpts();
query = toQuerystring(opts.query);
return ("https://" + this.consumer.dataSite + opts.path) + (query ? "?" + query : "");
};
Query.prototype.getRows = function() {
var opts;
opts = this.getOpts();
this.consumer.connection.networker(opts)();
return this.consumer.connection.emitter;
};
Query.prototype._buildQueryComponents = function() {
var query;
query = {};
if (this._soql != null) {
query.query = this._soql;
} else {
if (this._select.length > 0) {
query.select = this._select.join(', ');
}
if (this._where.length > 0) {
query.where = expr.and.apply(this, this._where);
}
if (this._group.length > 0) {
query.group = this._group.join(', ');
}
if (this._having.length > 0) {
if (!(this._group.length > 0)) {
throw new Error('Having provided without group by!');
}
query.having = expr.and.apply(this, this._having);
}
if (this._order.length > 0) {
query.order = this._order.join(', ');
}
if (isNumber(this._offset)) {
query.offset = this._offset;
}
if (isNumber(this._limit)) {
query.limit = this._limit;
}
if (this._q) {
query.q = this._q;
}
}
return query;
};
return Query;
})();
Dataset = (function() {
function Dataset(data, client) {
this.data = data;
this.client = client;
}
return Dataset;
})();
extend(typeof exports !== "undefined" && exports !== null ? exports : this.soda, {
Consumer: Consumer,
Producer: Producer,
expr: expr,
_internal: {
Connection: Connection,
Query: Query,
Operation: Operation,
util: {
toBase64: toBase64,
handleLiteral: handleLiteral,
handleOrder: handleOrder
}
}
});
}).call(this,require("buffer").Buffer)
},{"buffer":3,"eventemitter2":6,"superagent":9}],2:[function(require,module,exports){
var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
;(function (exports) {
'use strict';
var Arr = (typeof Uint8Array !== 'undefined')
? Uint8Array
: Array
var PLUS = '+'.charCodeAt(0)
var SLASH = '/'.charCodeAt(0)
var NUMBER = '0'.charCodeAt(0)
var LOWER = 'a'.charCodeAt(0)
var UPPER = 'A'.charCodeAt(0)
var PLUS_URL_SAFE = '-'.charCodeAt(0)
var SLASH_URL_SAFE = '_'.charCodeAt(0)
function decode (elt) {
var code = elt.charCodeAt(0)
if (code === PLUS ||
code === PLUS_URL_SAFE)
return 62 // '+'
if (code === SLASH ||
code === SLASH_URL_SAFE)
return 63 // '/'
if (code < NUMBER)
return -1 //no match
if (code < NUMBER + 10)
return code - NUMBER + 26 + 26
if (code < UPPER + 26)
return code - UPPER
if (code < LOWER + 26)
return code - LOWER + 26
}
function b64ToByteArray (b64) {
var i, j, l, tmp, placeHolders, arr
if (b64.length % 4 > 0) {
throw new Error('Invalid string. Length must be a multiple of 4')
}
// the number of equal signs (place holders)
// if there are two placeholders, than the two characters before it
// represent one byte
// if there is only one, then the three characters before it represent 2 bytes
// this is just a cheap hack to not do indexOf twice
var len = b64.length
placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0
// base64 is 4/3 + up to two characters of the original data
arr = new Arr(b64.length * 3 / 4 - placeHolders)
// if there are placeholders, only get up to the last complete 4 chars
l = placeHolders > 0 ? b64.length - 4 : b64.length
var L = 0
function push (v) {
arr[L++] = v
}
for (i = 0, j = 0; i < l; i += 4, j += 3) {
tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3))
push((tmp & 0xFF0000) >> 16)
push((tmp & 0xFF00) >> 8)
push(tmp & 0xFF)
}
if (placeHolders === 2) {
tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4)
push(tmp & 0xFF)
} else if (placeHolders === 1) {
tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2)
push((tmp >> 8) & 0xFF)
push(tmp & 0xFF)
}
return arr
}
function uint8ToBase64 (uint8) {
var i,
extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes
output = "",
temp, length
function encode (num) {
return lookup.charAt(num)
}
function tripletToBase64 (num) {
return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F)
}
// go through the array every three bytes, we'll deal with trailing stuff later
for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) {
temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])
output += tripletToBase64(temp)
}
// pad the end with zeros, but make sure to not forget the extra bytes
switch (extraBytes) {
case 1:
temp = uint8[uint8.length - 1]
output += encode(temp >> 2)
output += encode((temp << 4) & 0x3F)
output += '=='
break
case 2:
temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1])
output += encode(temp >> 10)
output += encode((temp >> 4) & 0x3F)
output += encode((temp << 2) & 0x3F)
output += '='
break
}
return output
}
exports.toByteArray = b64ToByteArray
exports.fromByteArray = uint8ToBase64
}(typeof exports === 'undefined' ? (this.base64js = {}) : exports))
},{}],3:[function(require,module,exports){
(function (global){
/*!
* The buffer module from node.js, for the browser.
*
* @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
* @license MIT
*/
/* eslint-disable no-proto */
'use strict'
var base64 = require('base64-js')
var ieee754 = require('ieee754')
var isArray = require('isarray')
exports.Buffer = Buffer
exports.SlowBuffer = SlowBuffer
exports.INSPECT_MAX_BYTES = 50
Buffer.poolSize = 8192 // not used by this implementation
var rootParent = {}
/**
* If `Buffer.TYPED_ARRAY_SUPPORT`:
* === true Use Uint8Array implementation (fastest)
* === false Use Object implementation (most compatible, even IE6)
*
* Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
* Opera 11.6+, iOS 4.2+.
*
* Due to various browser bugs, sometimes the Object implementation will be used even
* when the browser supports typed arrays.
*
* Note:
*
* - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,
* See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.
*
* - Safari 5-7 lacks support for changing the `Object.prototype.constructor` property
* on objects.
*
* - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.
*
* - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of
* incorrect length in some situations.
* We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they
* get the Object implementation, which is slower but behaves correctly.
*/
Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined
? global.TYPED_ARRAY_SUPPORT
: typedArraySupport()
function typedArraySupport () {
function Bar () {}
try {
var arr = new Uint8Array(1)
arr.foo = function () { return 42 }
arr.constructor = Bar
return arr.foo() === 42 && // typed array instances can be augmented
arr.constructor === Bar && // constructor can be set
typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`
arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`
} catch (e) {
return false
}
}
function kMaxLength () {
return Buffer.TYPED_ARRAY_SUPPORT
? 0x7fffffff
: 0x3fffffff
}
/**
* Class: Buffer
* =============
*
* The Buffer constructor returns instances of `Uint8Array` that are augmented
* with function properties for all the node `Buffer` API functions. We use
* `Uint8Array` so that square bracket notation works as expected -- it returns
* a single octet.
*
* By augmenting the instances, we can avoid modifying the `Uint8Array`
* prototype.
*/
function Buffer (arg) {
if (!(this instanceof Buffer)) {
// Avoid going through an ArgumentsAdaptorTrampoline in the common case.
if (arguments.length > 1) return new Buffer(arg, arguments[1])
return new Buffer(arg)
}
if (!Buffer.TYPED_ARRAY_SUPPORT) {
this.length = 0
this.parent = undefined
}
// Common case.
if (typeof arg === 'number') {
return fromNumber(this, arg)
}
// Slightly less common case.
if (typeof arg === 'string') {
return fromString(this, arg, arguments.length > 1 ? arguments[1] : 'utf8')
}
// Unusual.
return fromObject(this, arg)
}
function fromNumber (that, length) {
that = allocate(that, length < 0 ? 0 : checked(length) | 0)
if (!Buffer.TYPED_ARRAY_SUPPORT) {
for (var i = 0; i < length; i++) {
that[i] = 0
}
}
return that
}
function fromString (that, string, encoding) {
if (typeof encoding !== 'string' || encoding === '') encoding = 'utf8'
// Assumption: byteLength() return value is always < kMaxLength.
var length = byteLength(string, encoding) | 0
that = allocate(that, length)
that.write(string, encoding)
return that
}
function fromObject (that, object) {
if (Buffer.isBuffer(object)) return fromBuffer(that, object)
if (isArray(object)) return fromArray(that, object)
if (object == null) {
throw new TypeError('must start with number, buffer, array or string')
}
if (typeof ArrayBuffer !== 'undefined') {
if (object.buffer instanceof ArrayBuffer) {
return fromTypedArray(that, object)
}
if (object instanceof ArrayBuffer) {
return fromArrayBuffer(that, object)
}
}
if (object.length) return fromArrayLike(that, object)
return fromJsonObject(that, object)
}
function fromBuffer (that, buffer) {
var length = checked(buffer.length) | 0
that = allocate(that, length)
buffer.copy(that, 0, 0, length)
return that
}
function fromArray (that, array) {
var length = checked(array.length) | 0
that = allocate(that, length)
for (var i = 0; i < length; i += 1) {
that[i] = array[i] & 255
}
return that
}
// Duplicate of fromArray() to keep fromArray() monomorphic.
function fromTypedArray (that, array) {
var length = checked(array.length) | 0
that = allocate(that, length)
// Truncating the elements is probably not what people expect from typed
// arrays with BYTES_PER_ELEMENT > 1 but it's compatible with the behavior
// of the old Buffer constructor.
for (var i = 0; i < length; i += 1) {
that[i] = array[i] & 255
}
return that
}
function fromArrayBuffer (that, array) {
if (Buffer.TYPED_ARRAY_SUPPORT) {
// Return an augmented `Uint8Array` instance, for best performance
array.byteLength
that = Buffer._augment(new Uint8Array(array))
} else {
// Fallback: Return an object instance of the Buffer class
that = fromTypedArray(that, new Uint8Array(array))
}
return that
}
function fromArrayLike (that, array) {
var length = checked(array.length) | 0
that = allocate(that, length)
for (var i = 0; i < length; i += 1) {
that[i] = array[i] & 255
}
return that
}
// Deserialize { type: 'Buffer', data: [1,2,3,...] } into a Buffer object.
// Returns a zero-length buffer for inputs that don't conform to the spec.
function fromJsonObject (that, object) {
var array
var length = 0
if (object.type === 'Buffer' && isArray(object.data)) {
array = object.data
length = checked(array.length) | 0
}
that = allocate(that, length)
for (var i = 0; i < length; i += 1) {
that[i] = array[i] & 255
}
return that
}
if (Buffer.TYPED_ARRAY_SUPPORT) {
Buffer.prototype.__proto__ = Uint8Array.prototype
Buffer.__proto__ = Uint8Array
} else {
// pre-set for values that may exist in the future
Buffer.prototype.length = undefined
Buffer.prototype.parent = undefined
}
function allocate (that, length) {
if (Buffer.TYPED_ARRAY_SUPPORT) {
// Return an augmented `Uint8Array` instance, for best performance
that = Buffer._augment(new Uint8Array(length))
that.__proto__ = Buffer.prototype
} else {
// Fallback: Return an object instance of the Buffer class
that.length = length
that._isBuffer = true
}
var fromPool = length !== 0 && length <= Buffer.poolSize >>> 1
if (fromPool) that.parent = rootParent
return that
}
function checked (length) {
// Note: cannot use `length < kMaxLength` here because that fails when
// length is NaN (which is otherwise coerced to zero.)
if (length >= kMaxLength()) {
throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
'size: 0x' + kMaxLength().toString(16) + ' bytes')
}
return length | 0
}
function SlowBuffer (subject, encoding) {
if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding)
var buf = new Buffer(subject, encoding)
delete buf.parent
return buf
}
Buffer.isBuffer = function isBuffer (b) {
return !!(b != null && b._isBuffer)
}
Buffer.compare = function compare (a, b) {
if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
throw new TypeError('Arguments must be Buffers')
}
if (a === b) return 0
var x = a.length
var y = b.length
var i = 0
var len = Math.min(x, y)
while (i < len) {
if (a[i] !== b[i]) break
++i
}
if (i !== len) {
x = a[i]
y = b[i]
}
if (x < y) return -1
if (y < x) return 1
return 0
}
Buffer.isEncoding = function isEncoding (encoding) {
switch (String(encoding).toLowerCase()) {
case 'hex':
case 'utf8':
case 'utf-8':
case 'ascii':
case 'binary':
case 'base64':
case 'raw':
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return true
default:
return false
}
}
Buffer.concat = function concat (list, length) {
if (!isArray(list)) throw new TypeError('list argument must be an Array of Buffers.')
if (list.length === 0) {
return new Buffer(0)
}
var i
if (length === undefined) {
length = 0
for (i = 0; i < list.length; i++) {
length += list[i].length
}
}
var buf = new Buffer(length)
var pos = 0
for (i = 0; i < list.length; i++) {
var item = list[i]
item.copy(buf, pos)
pos += item.length
}
return buf
}
function byteLength (string, encoding) {
if (typeof string !== 'string') string = '' + string
var len = string.length
if (len === 0) return 0
// Use a for loop to avoid recursion
var loweredCase = false
for (;;) {
switch (encoding) {
case 'ascii':
case 'binary':
// Deprecated
case 'raw':
case 'raws':
return len
case 'utf8':
case 'utf-8':
return utf8ToBytes(string).length
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return len * 2
case 'hex':
return len >>> 1
case 'base64':
return base64ToBytes(string).length
default:
if (loweredCase) return utf8ToBytes(string).length // assume utf8
encoding = ('' + encoding).toLowerCase()
loweredCase = true
}
}
}
Buffer.byteLength = byteLength
function slowToString (encoding, start, end) {
var loweredCase = false
start = start | 0
end = end === undefined || end === Infinity ? this.length : end | 0
if (!encoding) encoding = 'utf8'
if (start < 0) start = 0
if (end > this.length) end = this.length
if (end <= start) return ''
while (true) {
switch (encoding) {
case 'hex':
return hexSlice(this, start, end)
case 'utf8':
case 'utf-8':
return utf8Slice(this, start, end)
case 'ascii':
return asciiSlice(this, start, end)
case 'binary':
return binarySlice(this, start, end)
case 'base64':
return base64Slice(this, start, end)
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return utf16leSlice(this, start, end)
default:
if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
encoding = (encoding + '').toLowerCase()
loweredCase = true
}
}
}
Buffer.prototype.toString = function toString () {
var length = this.length | 0
if (length === 0) return ''
if (arguments.length === 0) return utf8Slice(this, 0, length)
return slowToString.apply(this, arguments)
}
Buffer.prototype.equals = function equals (b) {
if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
if (this === b) return true
return Buffer.compare(this, b) === 0
}
Buffer.prototype.inspect = function inspect () {
var str = ''
var max = exports.INSPECT_MAX_BYTES
if (this.length > 0) {
str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')
if (this.length > max) str += ' ... '
}
return '<Buffer ' + str + '>'
}
Buffer.prototype.compare = function compare (b) {
if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
if (this === b) return 0
return Buffer.compare(this, b)
}
Buffer.prototype.indexOf = function indexOf (val, byteOffset) {
if (byteOffset > 0x7fffffff) byteOffset = 0x7fffffff
else if (byteOffset < -0x80000000) byteOffset = -0x80000000
byteOffset >>= 0
if (this.length === 0) return -1
if (byteOffset >= this.length) return -1
// Negative offsets start from the end of the buffer
if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0)
if (typeof val === 'string') {
if (val.length === 0) return -1 // special case: looking for empty string always fails
return String.prototype.indexOf.call(this, val, byteOffset)
}
if (Buffer.isBuffer(val)) {
return arrayIndexOf(this, val, byteOffset)
}
if (typeof val === 'number') {
if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') {
return Uint8Array.prototype.indexOf.call(this, val, byteOffset)
}
return arrayIndexOf(this, [ val ], byteOffset)
}
function arrayIndexOf (arr, val, byteOffset) {
var foundIndex = -1
for (var i = 0; byteOffset + i < arr.length; i++) {
if (arr[byteOffset + i] === val[foundIndex === -1 ? 0 : i - foundIndex]) {
if (foundIndex === -1) foundIndex = i
if (i - foundIndex + 1 === val.length) return byteOffset + foundIndex
} else {
foundIndex = -1
}
}
return -1
}
throw new TypeError('val must be string, number or Buffer')
}
// `get` is deprecated
Buffer.prototype.get = function get (offset) {
console.log('.get() is deprecated. Access using array indexes instead.')
return this.readUInt8(offset)
}
// `set` is deprecated
Buffer.prototype.set = function set (v, offset) {
console.log('.set() is deprecated. Access using array indexes instead.')
return this.writeUInt8(v, offset)
}
function hexWrite (buf, string, offset, length) {
offset = Number(offset) || 0
var remaining = buf.length - offset
if (!length) {
length = remaining
} else {
length = Number(length)
if (length > remaining) {
length = remaining
}
}
// must be an even number of digits
var strLen = string.length
if (strLen % 2 !== 0) throw new Error('Invalid hex string')
if (length > strLen / 2) {
length = strLen / 2
}
for (var i = 0; i < length; i++) {
var parsed = parseInt(string.substr(i * 2, 2), 16)
if (isNaN(parsed)) throw new Error('Invalid hex string')
buf[offset + i] = parsed
}
return i
}
function utf8Write (buf, string, offset, length) {
return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
}
function asciiWrite (buf, string, offset, length) {
return blitBuffer(asciiToBytes(string), buf, offset, length)
}
function binaryWrite (buf, string, offset, length) {
return asciiWrite(buf, string, offset, length)
}
function base64Write (buf, string, offset, length) {
return blitBuffer(base64ToBytes(string), buf, offset, length)
}
function ucs2Write (buf, string, offset, length) {
return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
}
Buffer.prototype.write = function write (string, offset, length, encoding) {
// Buffer#write(string)
if (offset === undefined) {
encoding = 'utf8'
length = this.length
offset = 0
// Buffer#write(string, encoding)
} else if (length === undefined && typeof offset === 'string') {
encoding = offset
length = this.length
offset = 0
// Buffer#write(string, offset[, length][, encoding])
} else if (isFinite(offset)) {
offset = offset | 0
if (isFinite(length)) {
length = length | 0
if (encoding === undefined) encoding = 'utf8'
} else {
encoding = length
length = undefined
}
// legacy write(string, encoding, offset, length) - remove in v0.13
} else {
var swap = encoding
encoding = offset
offset = length | 0
length = swap
}
var remaining = this.length - offset
if (length === undefined || length > remaining) length = remaining
if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
throw new RangeError('attempt to write outside buffer bounds')
}
if (!encoding) encoding = 'utf8'
var loweredCase = false
for (;;) {
switch (encoding) {
case 'hex':
return hexWrite(this, string, offset, length)
case 'utf8':
case 'utf-8':
return utf8Write(this, string, offset, length)
case 'ascii':
return asciiWrite(this, string, offset, length)
case 'binary':
return binaryWrite(this, string, offset, length)
case 'base64':
// Warning: maxLength not taken into account in base64Write
return base64Write(this, string, offset, length)
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return ucs2Write(this, string, offset, length)
default:
if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
encoding = ('' + encoding).toLowerCase()
loweredCase = true
}
}
}
Buffer.prototype.toJSON = function toJSON () {
return {
type: 'Buffer',
data: Array.prototype.slice.call(this._arr || this, 0)
}
}
function base64Slice (buf, start, end) {
if (start === 0 && end === buf.length) {
return base64.fromByteArray(buf)
} else {
return base64.fromByteArray(buf.slice(start, end))
}
}
function utf8Slice (buf, start, end) {
end = Math.min(buf.length, end)
var res = []
var i = start
while (i < end) {
var firstByte = buf[i]
var codePoint = null
var bytesPerSequence = (firstByte > 0xEF) ? 4
: (firstByte > 0xDF) ? 3
: (firstByte > 0xBF) ? 2
: 1
if (i + bytesPerSequence <= end) {
var secondByte, thirdByte, fourthByte, tempCodePoint
switch (bytesPerSequence) {
case 1:
if (firstByte < 0x80) {
codePoint = firstByte
}
break
case 2:
secondByte = buf[i + 1]
if ((secondByte & 0xC0) === 0x80) {
tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
if (tempCodePoint > 0x7F) {
codePoint = tempCodePoint
}
}
break
case 3:
secondByte = buf[i + 1]
thirdByte = buf[i + 2]
if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
codePoint = tempCodePoint
}
}
break
case 4:
secondByte = buf[i + 1]
thirdByte = buf[i + 2]
fourthByte = buf[i + 3]
if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
codePoint = tempCodePoint
}
}
}
}
if (codePoint === null) {
// we did not generate a valid codePoint so insert a
// replacement char (U+FFFD) and advance only 1 byte
codePoint = 0xFFFD
bytesPerSequence = 1
} else if (codePoint > 0xFFFF) {
// encode to utf16 (surrogate pair dance)
codePoint -= 0x10000
res.push(codePoint >>> 10 & 0x3FF | 0xD800)
codePoint = 0xDC00 | codePoint & 0x3FF
}
res.push(codePoint)
i += bytesPerSequence
}
return decodeCodePointsArray(res)
}
// Based on http://stackoverflow.com/a/22747272/680742, the browser with
// the lowest limit is Chrome, with 0x10000 args.
// We go 1 magnitude less, for safety
var MAX_ARGUMENTS_LENGTH = 0x1000
function decodeCodePointsArray (codePoints) {
var len = codePoints.length
if (len <= MAX_ARGUMENTS_LENGTH) {
return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
}
// Decode in chunks to avoid "call stack size exceeded".
var res = ''
var i = 0
while (i < len) {
res += String.fromCharCode.apply(
String,
codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
)
}
return res
}
function asciiSlice (buf, start, end) {
var ret = ''
end = Math.min(buf.length, end)
for (var i = start; i < end; i++) {
ret += String.fromCharCode(buf[i] & 0x7F)
}
return ret
}
function binarySlice (buf, start, end) {
var ret = ''
end = Math.min(buf.length, end)
for (var i = start; i < end; i++) {
ret += String.fromCharCode(buf[i])
}
return ret
}
function hexSlice (buf, start, end) {
var len = buf.length
if (!start || start < 0) start = 0
if (!end || end < 0 || end > len) end = len
var out = ''
for (var i = start; i < end; i++) {
out += toHex(buf[i])
}
return out
}
function utf16leSlice (buf, start, end) {
var bytes = buf.slice(start, end)
var res = ''
for (var i = 0; i < bytes.length; i += 2) {
res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)
}
return res
}
Buffer.prototype.slice = function slice (start, end) {
var len = this.length
start = ~~start
end = end === undefined ? len : ~~end
if (start < 0) {
start += len
if (start < 0) start = 0
} else if (start > len) {
start = len
}
if (end < 0) {
end += len
if (end < 0) end = 0
} else if (end > len) {
end = len
}
if (end < start) end = start
var newBuf
if (Buffer.TYPED_ARRAY_SUPPORT) {
newBuf = Buffer._augment(this.subarray(start, end))
} else {
var sliceLen = end - start
newBuf = new Buffer(sliceLen, undefined)
for (var i = 0; i < sliceLen; i++) {
newBuf[i] = this[i + start]
}
}
if (newBuf.length) newBuf.parent = this.parent || this
return newBuf
}
/*
* Need to make sure that buffer isn't trying to write out of bounds.
*/
function checkOffset (offset, ext, length) {
if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
}
Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) checkOffset(offset, byteLength, this.length)
var val = this[offset]
var mul = 1
var i = 0
while (++i < byteLength && (mul *= 0x100)) {
val += this[offset + i] * mul
}
return val
}
Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) {
checkOffset(offset, byteLength, this.length)
}
var val = this[offset + --byteLength]
var mul = 1
while (byteLength > 0 && (mul *= 0x100)) {
val += this[offset + --byteLength] * mul
}
return val
}
Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
if (!noAssert) checkOffset(offset, 1, this.length)
return this[offset]
}
Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 2, this.length)
return this[offset] | (this[offset + 1] << 8)
}
Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 2, this.length)
return (this[offset] << 8) | this[offset + 1]
}
Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return ((this[offset]) |
(this[offset + 1] << 8) |
(this[offset + 2] << 16)) +
(this[offset + 3] * 0x1000000)
}
Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return (this[offset] * 0x1000000) +
((this[offset + 1] << 16) |
(this[offset + 2] << 8) |
this[offset + 3])
}
Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) checkOffset(offset, byteLength, this.length)
var val = this[offset]
var mul = 1
var i = 0
while (++i < byteLength && (mul *= 0x100)) {
val += this[offset + i] * mul
}
mul *= 0x80
if (val >= mul) val -= Math.pow(2, 8 * byteLength)
return val
}
Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) checkOffset(offset, byteLength, this.length)
var i = byteLength
var mul = 1
var val = this[offset + --i]
while (i > 0 && (mul *= 0x100)) {
val += this[offset + --i] * mul
}
mul *= 0x80
if (val >= mul) val -= Math.pow(2, 8 * byteLength)
return val
}
Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
if (!noAssert) checkOffset(offset, 1, this.length)
if (!(this[offset] & 0x80)) return (this[offset])
return ((0xff - this[offset] + 1) * -1)
}
Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 2, this.length)
var val = this[offset] | (this[offset + 1] << 8)
return (val & 0x8000) ? val | 0xFFFF0000 : val
}
Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 2, this.length)
var val = this[offset + 1] | (this[offset] << 8)
return (val & 0x8000) ? val | 0xFFFF0000 : val
}
Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return (this[offset]) |
(this[offset + 1] << 8) |
(this[offset + 2] << 16) |
(this[offset + 3] << 24)
}
Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return (this[offset] << 24) |
(this[offset + 1] << 16) |
(this[offset + 2] << 8) |
(this[offset + 3])
}
Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return ieee754.read(this, offset, true, 23, 4)
}
Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return ieee754.read(this, offset, false, 23, 4)
}
Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 8, this.length)
return ieee754.read(this, offset, true, 52, 8)
}
Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 8, this.length)
return ieee754.read(this, offset, false, 52, 8)
}
function checkInt (buf, value, offset, ext, max, min) {
if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance')
if (value > max || value < min) throw new RangeError('value is out of bounds')
if (offset + ext > buf.length) throw new RangeError('index out of range')
}
Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
value = +value
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)
var mul = 1
var i = 0
this[offset] = value & 0xFF
while (++i < byteLength && (mul *= 0x100)) {
this[offset + i] = (value / mul) & 0xFF
}
return offset + byteLength
}
Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
value = +value
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)
var i = byteLength - 1
var mul = 1
this[offset + i] = value & 0xFF
while (--i >= 0 && (mul *= 0x100)) {
this[offset + i] = (value / mul) & 0xFF
}
return offset + byteLength
}
Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
this[offset] = (value & 0xff)
return offset + 1
}
function objectWriteUInt16 (buf, value, offset, littleEndian) {
if (value < 0) value = 0xffff + value + 1
for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) {
buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>
(littleEndian ? i : 1 - i) * 8
}
}
Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value & 0xff)
this[offset + 1] = (value >>> 8)
} else {
objectWriteUInt16(this, value, offset, true)
}
return offset + 2
}
Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value >>> 8)
this[offset + 1] = (value & 0xff)
} else {
objectWriteUInt16(this, value, offset, false)
}
return offset + 2
}
function objectWriteUInt32 (buf, value, offset, littleEndian) {
if (value < 0) value = 0xffffffff + value + 1
for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) {
buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff
}
}
Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset + 3] = (value >>> 24)
this[offset + 2] = (value >>> 16)
this[offset + 1] = (value >>> 8)
this[offset] = (value & 0xff)
} else {
objectWriteUInt32(this, value, offset, true)
}
return offset + 4
}
Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value >>> 24)
this[offset + 1] = (value >>> 16)
this[offset + 2] = (value >>> 8)
this[offset + 3] = (value & 0xff)
} else {
objectWriteUInt32(this, value, offset, false)
}
return offset + 4
}
Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) {
var limit = Math.pow(2, 8 * byteLength - 1)
checkInt(this, value, offset, byteLength, limit - 1, -limit)
}
var i = 0
var mul = 1
var sub = value < 0 ? 1 : 0
this[offset] = value & 0xFF
while (++i < byteLength && (mul *= 0x100)) {
this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
}
return offset + byteLength
}
Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) {
var limit = Math.pow(2, 8 * byteLength - 1)
checkInt(this, value, offset, byteLength, limit - 1, -limit)
}
var i = byteLength - 1
var mul = 1
var sub = value < 0 ? 1 : 0
this[offset + i] = value & 0xFF
while (--i >= 0 && (mul *= 0x100)) {
this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
}
return offset + byteLength
}
Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
if (value < 0) value = 0xff + value + 1
this[offset] = (value & 0xff)
return offset + 1
}
Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value & 0xff)
this[offset + 1] = (value >>> 8)
} else {
objectWriteUInt16(this, value, offset, true)
}
return offset + 2
}
Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value >>> 8)
this[offset + 1] = (value & 0xff)
} else {
objectWriteUInt16(this, value, offset, false)
}
return offset + 2
}
Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value & 0xff)
this[offset + 1] = (value >>> 8)
this[offset + 2] = (value >>> 16)
this[offset + 3] = (value >>> 24)
} else {
objectWriteUInt32(this, value, offset, true)
}
return offset + 4
}
Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
if (value < 0) value = 0xffffffff + value + 1
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value >>> 24)
this[offset + 1] = (value >>> 16)
this[offset + 2] = (value >>> 8)
this[offset + 3] = (value & 0xff)
} else {
objectWriteUInt32(this, value, offset, false)
}
return offset + 4
}
function checkIEEE754 (buf, value, offset, ext, max, min) {
if (value > max || value < min) throw new RangeError('value is out of bounds')
if (offset + ext > buf.length) throw new RangeError('index out of range')
if (offset < 0) throw new RangeError('index out of range')
}
function writeFloat (buf, value, offset, littleEndian, noAssert) {
if (!noAssert) {
checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
}
ieee754.write(buf, value, offset, littleEndian, 23, 4)
return offset + 4
}
Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
return writeFloat(this, value, offset, true, noAssert)
}
Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
return writeFloat(this, value, offset, false, noAssert)
}
function writeDouble (buf, value, offset, littleEndian, noAssert) {
if (!noAssert) {
checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
}
ieee754.write(buf, value, offset, littleEndian, 52, 8)
return offset + 8
}
Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
return writeDouble(this, value, offset, true, noAssert)
}
Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
return writeDouble(this, value, offset, false, noAssert)
}
// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
Buffer.prototype.copy = function copy (target, targetStart, start, end) {
if (!start) start = 0
if (!end && end !== 0) end = this.length
if (targetStart >= target.length) targetStart = target.length
if (!targetStart) targetStart = 0
if (end > 0 && end < start) end = start
// Copy 0 bytes; we're done
if (end === start) return 0
if (target.length === 0 || this.length === 0) return 0
// Fatal error conditions
if (targetStart < 0) {
throw new RangeError('targetStart out of bounds')
}
if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')
if (end < 0) throw new RangeError('sourceEnd out of bounds')
// Are we oob?
if (end > this.length) end = this.length
if (target.length - targetStart < end - start) {
end = target.length - targetStart + start
}
var len = end - start
var i
if (this === target && start < targetStart && targetStart < end) {
// descending copy from end
for (i = len - 1; i >= 0; i--) {
target[i + targetStart] = this[i + start]
}
} else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {
// ascending copy from start
for (i = 0; i < len; i++) {
target[i + targetStart] = this[i + start]
}
} else {
target._set(this.subarray(start, start + len), targetStart)
}
return len
}
// fill(value, start=0, end=buffer.length)
Buffer.prototype.fill = function fill (value, start, end) {
if (!value) value = 0
if (!start) start = 0
if (!end) end = this.length
if (end < start) throw new RangeError('end < start')
// Fill 0 bytes; we're done
if (end === start) return
if (this.length === 0) return
if (start < 0 || start >= this.length) throw new RangeError('start out of bounds')
if (end < 0 || end > this.length) throw new RangeError('end out of bounds')
var i
if (typeof value === 'number') {
for (i = start; i < end; i++) {
this[i] = value
}
} else {
var bytes = utf8ToBytes(value.toString())
var len = bytes.length
for (i = start; i < end; i++) {
this[i] = bytes[i % len]
}
}
return this
}
/**
* Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance.
* Added in Node 0.12. Only available in browsers that support ArrayBuffer.
*/
Buffer.prototype.toArrayBuffer = function toArrayBuffer () {
if (typeof Uint8Array !== 'undefined') {
if (Buffer.TYPED_ARRAY_SUPPORT) {
return (new Buffer(this)).buffer
} else {
var buf = new Uint8Array(this.length)
for (var i = 0, len = buf.length; i < len; i += 1) {
buf[i] = this[i]
}
return buf.buffer
}
} else {
throw new TypeError('Buffer.toArrayBuffer not supported in this browser')
}
}
// HELPER FUNCTIONS
// ================
var BP = Buffer.prototype
/**
* Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods
*/
Buffer._augment = function _augment (arr) {
arr.constructor = Buffer
arr._isBuffer = true
// save reference to original Uint8Array set method before overwriting
arr._set = arr.set
// deprecated
arr.get = BP.get
arr.set = BP.set
arr.write = BP.write
arr.toString = BP.toString
arr.toLocaleString = BP.toString
arr.toJSON = BP.toJSON
arr.equals = BP.equals
arr.compare = BP.compare
arr.indexOf = BP.indexOf
arr.copy = BP.copy
arr.slice = BP.slice
arr.readUIntLE = BP.readUIntLE
arr.readUIntBE = BP.readUIntBE
arr.readUInt8 = BP.readUInt8
arr.readUInt16LE = BP.readUInt16LE
arr.readUInt16BE = BP.readUInt16BE
arr.readUInt32LE = BP.readUInt32LE
arr.readUInt32BE = BP.readUInt32BE
arr.readIntLE = BP.readIntLE
arr.readIntBE = BP.readIntBE
arr.readInt8 = BP.readInt8
arr.readInt16LE = BP.readInt16LE
arr.readInt16BE = BP.readInt16BE
arr.readInt32LE = BP.readInt32LE
arr.readInt32BE = BP.readInt32BE
arr.readFloatLE = BP.readFloatLE
arr.readFloatBE = BP.readFloatBE
arr.readDoubleLE = BP.readDoubleLE
arr.readDoubleBE = BP.readDoubleBE
arr.writeUInt8 = BP.writeUInt8
arr.writeUIntLE = BP.writeUIntLE
arr.writeUIntBE = BP.writeUIntBE
arr.writeUInt16LE = BP.writeUInt16LE
arr.writeUInt16BE = BP.writeUInt16BE
arr.writeUInt32LE = BP.writeUInt32LE
arr.writeUInt32BE = BP.writeUInt32BE
arr.writeIntLE = BP.writeIntLE
arr.writeIntBE = BP.writeIntBE
arr.writeInt8 = BP.writeInt8
arr.writeInt16LE = BP.writeInt16LE
arr.writeInt16BE = BP.writeInt16BE
arr.writeInt32LE = BP.writeInt32LE
arr.writeInt32BE = BP.writeInt32BE
arr.writeFloatLE = BP.writeFloatLE
arr.writeFloatBE = BP.writeFloatBE
arr.writeDoubleLE = BP.writeDoubleLE
arr.writeDoubleBE = BP.writeDoubleBE
arr.fill = BP.fill
arr.inspect = BP.inspect
arr.toArrayBuffer = BP.toArrayBuffer
return arr
}
var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g
function base64clean (str) {
// Node strips out invalid characters like \n and \t from the string, base64-js does not
str = stringtrim(str).replace(INVALID_BASE64_RE, '')
// Node converts strings with length < 2 to ''
if (str.length < 2) return ''
// Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
while (str.length % 4 !== 0) {
str = str + '='
}
return str
}
function stringtrim (str) {
if (str.trim) return str.trim()
return str.replace(/^\s+|\s+$/g, '')
}
function toHex (n) {
if (n < 16) return '0' + n.toString(16)
return n.toString(16)
}
function utf8ToBytes (string, units) {
units = units || Infinity
var codePoint
var length = string.length
var leadSurrogate = null
var bytes = []
for (var i = 0; i < length; i++) {
codePoint = string.charCodeAt(i)
// is surrogate component
if (codePoint > 0xD7FF && codePoint < 0xE000) {
// last char was a lead
if (!leadSurrogate) {
// no lead yet
if (codePoint > 0xDBFF) {
// unexpected trail
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
continue
} else if (i + 1 === length) {
// unpaired lead
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
continue
}
// valid lead
leadSurrogate = codePoint
continue
}
// 2 leads in a row
if (codePoint < 0xDC00) {
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
leadSurrogate = codePoint
continue
}
// valid surrogate pair
codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000
} else if (leadSurrogate) {
// valid bmp char, but last char was a lead
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
}
leadSurrogate = null
// encode utf8
if (codePoint < 0x80) {
if ((units -= 1) < 0) break
bytes.push(codePoint)
} else if (codePoint < 0x800) {
if ((units -= 2) < 0) break
bytes.push(
codePoint >> 0x6 | 0xC0,
codePoint & 0x3F | 0x80
)
} else if (codePoint < 0x10000) {
if ((units -= 3) < 0) break
bytes.push(
codePoint >> 0xC | 0xE0,
codePoint >> 0x6 & 0x3F | 0x80,
codePoint & 0x3F | 0x80
)
} else if (codePoint < 0x110000) {
if ((units -= 4) < 0) break
bytes.push(
codePoint >> 0x12 | 0xF0,
codePoint >> 0xC & 0x3F | 0x80,
codePoint >> 0x6 & 0x3F | 0x80,
codePoint & 0x3F | 0x80
)
} else {
throw new Error('Invalid code point')
}
}
return bytes
}
function asciiToBytes (str) {
var byteArray = []
for (var i = 0; i < str.length; i++) {
// Node's code seems to be doing this and not & 0x7F..
byteArray.push(str.charCodeAt(i) & 0xFF)
}
return byteArray
}
function utf16leToBytes (str, units) {
var c, hi, lo
var byteArray = []
for (var i = 0; i < str.length; i++) {
if ((units -= 2) < 0) break
c = str.charCodeAt(i)
hi = c >> 8
lo = c % 256
byteArray.push(lo)
byteArray.push(hi)
}
return byteArray
}
function base64ToBytes (str) {
return base64.toByteArray(base64clean(str))
}
function blitBuffer (src, dst, offset, length) {
for (var i = 0; i < length; i++) {
if ((i + offset >= dst.length) || (i >= src.length)) break
dst[i + offset] = src[i]
}
return i
}
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"base64-js":2,"ieee754":7,"isarray":4}],4:[function(require,module,exports){
var toString = {}.toString;
module.exports = Array.isArray || function (arr) {
return toString.call(arr) == '[object Array]';
};
},{}],5:[function(require,module,exports){
/**
* Expose `Emitter`.
*/
module.exports = Emitter;
/**
* Initialize a new `Emitter`.
*
* @api public
*/
function Emitter(obj) {
if (obj) return mixin(obj);
};
/**
* Mixin the emitter properties.
*
* @param {Object} obj
* @return {Object}
* @api private
*/
function mixin(obj) {
for (var key in Emitter.prototype) {
obj[key] = Emitter.prototype[key];
}
return obj;
}
/**
* Listen on the given `event` with `fn`.
*
* @param {String} event
* @param {Function} fn
* @return {Emitter}
* @api public
*/
Emitter.prototype.on =
Emitter.prototype.addEventListener = function(event, fn){
this._callbacks = this._callbacks || {};
(this._callbacks[event] = this._callbacks[event] || [])
.push(fn);
return this;
};
/**
* Adds an `event` listener that will be invoked a single
* time then automatically removed.
*
* @param {String} event
* @param {Function} fn
* @return {Emitter}
* @api public
*/
Emitter.prototype.once = function(event, fn){
var self = this;
this._callbacks = this._callbacks || {};
function on() {
self.off(event, on);
fn.apply(this, arguments);
}
on.fn = fn;
this.on(event, on);
return this;
};
/**
* Remove the given callback for `event` or all
* registered callbacks.
*
* @param {String} event
* @param {Function} fn
* @return {Emitter}
* @api public
*/
Emitter.prototype.off =
Emitter.prototype.removeListener =
Emitter.prototype.removeAllListeners =
Emitter.prototype.removeEventListener = function(event, fn){
this._callbacks = this._callbacks || {};
// all
if (0 == arguments.length) {
this._callbacks = {};
return this;
}
// specific event
var callbacks = this._callbacks[event];
if (!callbacks) return this;
// remove all handlers
if (1 == arguments.length) {
delete this._callbacks[event];
return this;
}
// remove specific handler
var cb;
for (var i = 0; i < callbacks.length; i++) {
cb = callbacks[i];
if (cb === fn || cb.fn === fn) {
callbacks.splice(i, 1);
break;
}
}
return this;
};
/**
* Emit `event` with the given args.
*
* @param {String} event
* @param {Mixed} ...
* @return {Emitter}
*/
Emitter.prototype.emit = function(event){
this._callbacks = this._callbacks || {};
var args = [].slice.call(arguments, 1)
, callbacks = this._callbacks[event];
if (callbacks) {
callbacks = callbacks.slice(0);
for (var i = 0, len = callbacks.length; i < len; ++i) {
callbacks[i].apply(this, args);
}
}
return this;
};
/**
* Return array of callbacks for `event`.
*
* @param {String} event
* @return {Array}
* @api public
*/
Emitter.prototype.listeners = function(event){
this._callbacks = this._callbacks || {};
return this._callbacks[event] || [];
};
/**
* Check if this emitter has `event` handlers.
*
* @param {String} event
* @return {Boolean}
* @api public
*/
Emitter.prototype.hasListeners = function(event){
return !! this.listeners(event).length;
};
},{}],6:[function(require,module,exports){
/*!
* EventEmitter2
* https://github.com/hij1nx/EventEmitter2
*
* Copyright (c) 2013 hij1nx
* Licensed under the MIT license.
*/
;!function(undefined) {
var isArray = Array.isArray ? Array.isArray : function _isArray(obj) {
return Object.prototype.toString.call(obj) === "[object Array]";
};
var defaultMaxListeners = 10;
function init() {
this._events = {};
if (this._conf) {
configure.call(this, this._conf);
}
}
function configure(conf) {
if (conf) {
this._conf = conf;
conf.delimiter && (this.delimiter = conf.delimiter);
conf.maxListeners && (this._events.maxListeners = conf.maxListeners);
conf.wildcard && (this.wildcard = conf.wildcard);
conf.newListener && (this.newListener = conf.newListener);
if (this.wildcard) {
this.listenerTree = {};
}
}
}
function EventEmitter(conf) {
this._events = {};
this.newListener = false;
configure.call(this, conf);
}
//
// Attention, function return type now is array, always !
// It has zero elements if no any matches found and one or more
// elements (leafs) if there are matches
//
function searchListenerTree(handlers, type, tree, i) {
if (!tree) {
return [];
}
var listeners=[], leaf, len, branch, xTree, xxTree, isolatedBranch, endReached,
typeLength = type.length, currentType = type[i], nextType = type[i+1];
if (i === typeLength && tree._listeners) {
//
// If at the end of the event(s) list and the tree has listeners
// invoke those listeners.
//
if (typeof tree._listeners === 'function') {
handlers && handlers.push(tree._listeners);
return [tree];
} else {
for (leaf = 0, len = tree._listeners.length; leaf < len; leaf++) {
handlers && handlers.push(tree._listeners[leaf]);
}
return [tree];
}
}
if ((currentType === '*' || currentType === '**') || tree[currentType]) {
//
// If the event emitted is '*' at this part
// or there is a concrete match at this patch
//
if (currentType === '*') {
for (branch in tree) {
if (branch !== '_listeners' && tree.hasOwnProperty(branch)) {
listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i+1));
}
}
return listeners;
} else if(currentType === '**') {
endReached = (i+1 === typeLength || (i+2 === typeLength && nextType === '*'));
if(endReached && tree._listeners) {
// The next element has a _listeners, add it to the handlers.
listeners = listeners.concat(searchListenerTree(handlers, type, tree, typeLength));
}
for (branch in tree) {
if (branch !== '_listeners' && tree.hasOwnProperty(branch)) {
if(branch === '*' || branch === '**') {
if(tree[branch]._listeners && !endReached) {
listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], typeLength));
}
listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i));
} else if(branch === nextType) {
listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i+2));
} else {
// No match on this one, shift into the tree but not in the type array.
listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i));
}
}
}
return listeners;
}
listeners = listeners.concat(searchListenerTree(handlers, type, tree[currentType], i+1));
}
xTree = tree['*'];
if (xTree) {
//
// If the listener tree will allow any match for this part,
// then recursively explore all branches of the tree
//
searchListenerTree(handlers, type, xTree, i+1);
}
xxTree = tree['**'];
if(xxTree) {
if(i < typeLength) {
if(xxTree._listeners) {
// If we have a listener on a '**', it will catch all, so add its handler.
searchListenerTree(handlers, type, xxTree, typeLength);
}
// Build arrays of matching next branches and others.
for(branch in xxTree) {
if(branch !== '_listeners' && xxTree.hasOwnProperty(branch)) {
if(branch === nextType) {
// We know the next element will match, so jump twice.
searchListenerTree(handlers, type, xxTree[branch], i+2);
} else if(branch === currentType) {
// Current node matches, move into the tree.
searchListenerTree(handlers, type, xxTree[branch], i+1);
} else {
isolatedBranch = {};
isolatedBranch[branch] = xxTree[branch];
searchListenerTree(handlers, type, { '**': isolatedBranch }, i+1);
}
}
}
} else if(xxTree._listeners) {
// We have reached the end and still on a '**'
searchListenerTree(handlers, type, xxTree, typeLength);
} else if(xxTree['*'] && xxTree['*']._listeners) {
searchListenerTree(handlers, type, xxTree['*'], typeLength);
}
}
return listeners;
}
function growListenerTree(type, listener) {
type = typeof type === 'string' ? type.split(this.delimiter) : type.slice();
//
// Looks for two consecutive '**', if so, don't add the event at all.
//
for(var i = 0, len = type.length; i+1 < len; i++) {
if(type[i] === '**' && type[i+1] === '**') {
return;
}
}
var tree = this.listenerTree;
var name = type.shift();
while (name) {
if (!tree[name]) {
tree[name] = {};
}
tree = tree[name];
if (type.length === 0) {
if (!tree._listeners) {
tree._listeners = listener;
}
else if(typeof tree._listeners === 'function') {
tree._listeners = [tree._listeners, listener];
}
else if (isArray(tree._listeners)) {
tree._listeners.push(listener);
if (!tree._listeners.warned) {
var m = defaultMaxListeners;
if (typeof this._events.maxListeners !== 'undefined') {
m = this._events.maxListeners;
}
if (m > 0 && tree._listeners.length > m) {
tree._listeners.warned = true;
console.error('(node) warning: possible EventEmitter memory ' +
'leak detected. %d listeners added. ' +
'Use emitter.setMaxListeners() to increase limit.',
tree._listeners.length);
console.trace();
}
}
}
return true;
}
name = type.shift();
}
return true;
}
// By default EventEmitters will print a warning if more than
// 10 listeners are added to it. This is a useful default which
// helps finding memory leaks.
//
// Obviously not all Emitters should be limited to 10. This function allows
// that to be increased. Set to zero for unlimited.
EventEmitter.prototype.delimiter = '.';
EventEmitter.prototype.setMaxListeners = function(n) {
this._events || init.call(this);
this._events.maxListeners = n;
if (!this._conf) this._conf = {};
this._conf.maxListeners = n;
};
EventEmitter.prototype.event = '';
EventEmitter.prototype.once = function(event, fn) {
this.many(event, 1, fn);
return this;
};
EventEmitter.prototype.many = function(event, ttl, fn) {
var self = this;
if (typeof fn !== 'function') {
throw new Error('many only accepts instances of Function');
}
function listener() {
if (--ttl === 0) {
self.off(event, listener);
}
fn.apply(this, arguments);
}
listener._origin = fn;
this.on(event, listener);
return self;
};
EventEmitter.prototype.emit = function() {
this._events || init.call(this);
var type = arguments[0];
if (type === 'newListener' && !this.newListener) {
if (!this._events.newListener) { return false; }
}
// Loop through the *_all* functions and invoke them.
if (this._all) {
var l = arguments.length;
var args = new Array(l - 1);
for (var i = 1; i < l; i++) args[i - 1] = arguments[i];
for (i = 0, l = this._all.length; i < l; i++) {
this.event = type;
this._all[i].apply(this, args);
}
}
// If there is no 'error' event listener then throw.
if (type === 'error') {
if (!this._all &&
!this._events.error &&
!(this.wildcard && this.listenerTree.error)) {
if (arguments[1] instanceof Error) {
throw arguments[1]; // Unhandled 'error' event
} else {
throw new Error("Uncaught, unspecified 'error' event.");
}
return false;
}
}
var handler;
if(this.wildcard) {
handler = [];
var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice();
searchListenerTree.call(this, handler, ns, this.listenerTree, 0);
}
else {
handler = this._events[type];
}
if (typeof handler === 'function') {
this.event = type;
if (arguments.length === 1) {
handler.call(this);
}
else if (arguments.length > 1)
switch (arguments.length) {
case 2:
handler.call(this, arguments[1]);
break;
case 3:
handler.call(this, arguments[1], arguments[2]);
break;
// slower
default:
var l = arguments.length;
var args = new Array(l - 1);
for (var i = 1; i < l; i++) args[i - 1] = arguments[i];
handler.apply(this, args);
}
return true;
}
else if (handler) {
var l = arguments.length;
var args = new Array(l - 1);
for (var i = 1; i < l; i++) args[i - 1] = arguments[i];
var listeners = handler.slice();
for (var i = 0, l = listeners.length; i < l; i++) {
this.event = type;
listeners[i].apply(this, args);
}
return (listeners.length > 0) || !!this._all;
}
else {
return !!this._all;
}
};
EventEmitter.prototype.on = function(type, listener) {
if (typeof type === 'function') {
this.onAny(type);
return this;
}
if (typeof listener !== 'function') {
throw new Error('on only accepts instances of Function');
}
this._events || init.call(this);
// To avoid recursion in the case that type == "newListeners"! Before
// adding it to the listeners, first emit "newListeners".
this.emit('newListener', type, listener);
if(this.wildcard) {
growListenerTree.call(this, type, listener);
return this;
}
if (!this._events[type]) {
// Optimize the case of one listener. Don't need the extra array object.
this._events[type] = listener;
}
else if(typeof this._events[type] === 'function') {
// Adding the second element, need to change to array.
this._events[type] = [this._events[type], listener];
}
else if (isArray(this._events[type])) {
// If we've already got an array, just append.
this._events[type].push(listener);
// Check for listener leak
if (!this._events[type].warned) {
var m = defaultMaxListeners;
if (typeof this._events.maxListeners !== 'undefined') {
m = this._events.maxListeners;
}
if (m > 0 && this._events[type].length > m) {
this._events[type].warned = true;
console.error('(node) warning: possible EventEmitter memory ' +
'leak detected. %d listeners added. ' +
'Use emitter.setMaxListeners() to increase limit.',
this._events[type].length);
console.trace();
}
}
}
return this;
};
EventEmitter.prototype.onAny = function(fn) {
if (typeof fn !== 'function') {
throw new Error('onAny only accepts instances of Function');
}
if(!this._all) {
this._all = [];
}
// Add the function to the event listener collection.
this._all.push(fn);
return this;
};
EventEmitter.prototype.addListener = EventEmitter.prototype.on;
EventEmitter.prototype.off = function(type, listener) {
if (typeof listener !== 'function') {
throw new Error('removeListener only takes instances of Function');
}
var handlers,leafs=[];
if(this.wildcard) {
var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice();
leafs = searchListenerTree.call(this, null, ns, this.listenerTree, 0);
}
else {
// does not use listeners(), so no side effect of creating _events[type]
if (!this._events[type]) return this;
handlers = this._events[type];
leafs.push({_listeners:handlers});
}
for (var iLeaf=0; iLeaf<leafs.length; iLeaf++) {
var leaf = leafs[iLeaf];
handlers = leaf._listeners;
if (isArray(handlers)) {
var position = -1;
for (var i = 0, length = handlers.length; i < length; i++) {
if (handlers[i] === listener ||
(handlers[i].listener && handlers[i].listener === listener) ||
(handlers[i]._origin && handlers[i]._origin === listener)) {
position = i;
break;
}
}
if (position < 0) {
continue;
}
if(this.wildcard) {
leaf._listeners.splice(position, 1);
}
else {
this._events[type].splice(position, 1);
}
if (handlers.length === 0) {
if(this.wildcard) {
delete leaf._listeners;
}
else {
delete this._events[type];
}
}
return this;
}
else if (handlers === listener ||
(handlers.listener && handlers.listener === listener) ||
(handlers._origin && handlers._origin === listener)) {
if(this.wildcard) {
delete leaf._listeners;
}
else {
delete this._events[type];
}
}
}
return this;
};
EventEmitter.prototype.offAny = function(fn) {
var i = 0, l = 0, fns;
if (fn && this._all && this._all.length > 0) {
fns = this._all;
for(i = 0, l = fns.length; i < l; i++) {
if(fn === fns[i]) {
fns.splice(i, 1);
return this;
}
}
} else {
this._all = [];
}
return this;
};
EventEmitter.prototype.removeListener = EventEmitter.prototype.off;
EventEmitter.prototype.removeAllListeners = function(type) {
if (arguments.length === 0) {
!this._events || init.call(this);
return this;
}
if(this.wildcard) {
var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice();
var leafs = searchListenerTree.call(this, null, ns, this.listenerTree, 0);
for (var iLeaf=0; iLeaf<leafs.length; iLeaf++) {
var leaf = leafs[iLeaf];
leaf._listeners = null;
}
}
else {
if (!this._events[type]) return this;
this._events[type] = null;
}
return this;
};
EventEmitter.prototype.listeners = function(type) {
if(this.wildcard) {
var handlers = [];
var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice();
searchListenerTree.call(this, handlers, ns, this.listenerTree, 0);
return handlers;
}
this._events || init.call(this);
if (!this._events[type]) this._events[type] = [];
if (!isArray(this._events[type])) {
this._events[type] = [this._events[type]];
}
return this._events[type];
};
EventEmitter.prototype.listenersAny = function() {
if(this._all) {
return this._all;
}
else {
return [];
}
};
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(function() {
return EventEmitter;
});
} else if (typeof exports === 'object') {
// CommonJS
exports.EventEmitter2 = EventEmitter;
}
else {
// Browser global.
window.EventEmitter2 = EventEmitter;
}
}();
},{}],7:[function(require,module,exports){
exports.read = function (buffer, offset, isLE, mLen, nBytes) {
var e, m
var eLen = nBytes * 8 - mLen - 1
var eMax = (1 << eLen) - 1
var eBias = eMax >> 1
var nBits = -7
var i = isLE ? (nBytes - 1) : 0
var d = isLE ? -1 : 1
var s = buffer[offset + i]
i += d
e = s & ((1 << (-nBits)) - 1)
s >>= (-nBits)
nBits += eLen
for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}
m = e & ((1 << (-nBits)) - 1)
e >>= (-nBits)
nBits += mLen
for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}
if (e === 0) {
e = 1 - eBias
} else if (e === eMax) {
return m ? NaN : ((s ? -1 : 1) * Infinity)
} else {
m = m + Math.pow(2, mLen)
e = e - eBias
}
return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
}
exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
var e, m, c
var eLen = nBytes * 8 - mLen - 1
var eMax = (1 << eLen) - 1
var eBias = eMax >> 1
var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
var i = isLE ? 0 : (nBytes - 1)
var d = isLE ? 1 : -1
var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0
value = Math.abs(value)
if (isNaN(value) || value === Infinity) {
m = isNaN(value) ? 1 : 0
e = eMax
} else {
e = Math.floor(Math.log(value) / Math.LN2)
if (value * (c = Math.pow(2, -e)) < 1) {
e--
c *= 2
}
if (e + eBias >= 1) {
value += rt / c
} else {
value += rt * Math.pow(2, 1 - eBias)
}
if (value * c >= 2) {
e++
c /= 2
}
if (e + eBias >= eMax) {
m = 0
e = eMax
} else if (e + eBias >= 1) {
m = (value * c - 1) * Math.pow(2, mLen)
e = e + eBias
} else {
m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
e = 0
}
}
for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
e = (e << mLen) | m
eLen += mLen
for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
buffer[offset + i - d] |= s * 128
}
},{}],8:[function(require,module,exports){
/**
* Reduce `arr` with `fn`.
*
* @param {Array} arr
* @param {Function} fn
* @param {Mixed} initial
*
* TODO: combatible error handling?
*/
module.exports = function(arr, fn, initial){
var idx = 0;
var len = arr.length;
var curr = arguments.length == 3
? initial
: arr[idx++];
while (idx < len) {
curr = fn.call(null, curr, arr[idx], ++idx, arr);
}
return curr;
};
},{}],9:[function(require,module,exports){
/**
* Module dependencies.
*/
var Emitter = require('emitter');
var reduce = require('reduce');
/**
* Root reference for iframes.
*/
var root = 'undefined' == typeof window
? this
: window;
/**
* Noop.
*/
function noop(){};
/**
* Check if `obj` is a host object,
* we don't want to serialize these :)
*
* TODO: future proof, move to compoent land
*
* @param {Object} obj
* @return {Boolean}
* @api private
*/
function isHost(obj) {
var str = {}.toString.call(obj);
switch (str) {
case '[object File]':
case '[object Blob]':
case '[object FormData]':
return true;
default:
return false;
}
}
/**
* Determine XHR.
*/
function getXHR() {
if (root.XMLHttpRequest
&& ('file:' != root.location.protocol || !root.ActiveXObject)) {
return new XMLHttpRequest;
} else {
try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {}
try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {}
try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {}
try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {}
}
return false;
}
/**
* Removes leading and trailing whitespace, added to support IE.
*
* @param {String} s
* @return {String}
* @api private
*/
var trim = ''.trim
? function(s) { return s.trim(); }
: function(s) { return s.replace(/(^\s*|\s*$)/g, ''); };
/**
* Check if `obj` is an object.
*
* @param {Object} obj
* @return {Boolean}
* @api private
*/
function isObject(obj) {
return obj === Object(obj);
}
/**
* Serialize the given `obj`.
*
* @param {Object} obj
* @return {String}
* @api private
*/
function serialize(obj) {
if (!isObject(obj)) return obj;
var pairs = [];
for (var key in obj) {
if (null != obj[key]) {
pairs.push(encodeURIComponent(key)
+ '=' + encodeURIComponent(obj[key]));
}
}
return pairs.join('&');
}
/**
* Expose serialization method.
*/
request.serializeObject = serialize;
/**
* Parse the given x-www-form-urlencoded `str`.
*
* @param {String} str
* @return {Object}
* @api private
*/
function parseString(str) {
var obj = {};
var pairs = str.split('&');
var parts;
var pair;
for (var i = 0, len = pairs.length; i < len; ++i) {
pair = pairs[i];
parts = pair.split('=');
obj[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]);
}
return obj;
}
/**
* Expose parser.
*/
request.parseString = parseString;
/**
* Default MIME type map.
*
* superagent.types.xml = 'application/xml';
*
*/
request.types = {
html: 'text/html',
json: 'application/json',
xml: 'application/xml',
urlencoded: 'application/x-www-form-urlencoded',
'form': 'application/x-www-form-urlencoded',
'form-data': 'application/x-www-form-urlencoded'
};
/**
* Default serialization map.
*
* superagent.serialize['application/xml'] = function(obj){
* return 'generated xml here';
* };
*
*/
request.serialize = {
'application/x-www-form-urlencoded': serialize,
'application/json': JSON.stringify
};
/**
* Default parsers.
*
* superagent.parse['application/xml'] = function(str){
* return { object parsed from str };
* };
*
*/
request.parse = {
'application/x-www-form-urlencoded': parseString,
'application/json': JSON.parse
};
/**
* Parse the given header `str` into
* an object containing the mapped fields.
*
* @param {String} str
* @return {Object}
* @api private
*/
function parseHeader(str) {
var lines = str.split(/\r?\n/);
var fields = {};
var index;
var line;
var field;
var val;
lines.pop(); // trailing CRLF
for (var i = 0, len = lines.length; i < len; ++i) {
line = lines[i];
index = line.indexOf(':');
field = line.slice(0, index).toLowerCase();
val = trim(line.slice(index + 1));
fields[field] = val;
}
return fields;
}
/**
* Return the mime type for the given `str`.
*
* @param {String} str
* @return {String}
* @api private
*/
function type(str){
return str.split(/ *; */).shift();
};
/**
* Return header field parameters.
*
* @param {String} str
* @return {Object}
* @api private
*/
function params(str){
return reduce(str.split(/ *; */), function(obj, str){
var parts = str.split(/ *= */)
, key = parts.shift()
, val = parts.shift();
if (key && val) obj[key] = val;
return obj;
}, {});
};
/**
* Initialize a new `Response` with the given `xhr`.
*
* - set flags (.ok, .error, etc)
* - parse header
*
* Examples:
*
* Aliasing `superagent` as `request` is nice:
*
* request = superagent;
*
* We can use the promise-like API, or pass callbacks:
*
* request.get('/').end(function(res){});
* request.get('/', function(res){});
*
* Sending data can be chained:
*
* request
* .post('/user')
* .send({ name: 'tj' })
* .end(function(res){});
*
* Or passed to `.send()`:
*
* request
* .post('/user')
* .send({ name: 'tj' }, function(res){});
*
* Or passed to `.post()`:
*
* request
* .post('/user', { name: 'tj' })
* .end(function(res){});
*
* Or further reduced to a single call for simple cases:
*
* request
* .post('/user', { name: 'tj' }, function(res){});
*
* @param {XMLHTTPRequest} xhr
* @param {Object} options
* @api private
*/
function Response(req, options) {
options = options || {};
this.req = req;
this.xhr = this.req.xhr;
this.text = this.req.method !='HEAD'
? this.xhr.responseText
: null;
this.setStatusProperties(this.xhr.status);
this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders());
// getAllResponseHeaders sometimes falsely returns "" for CORS requests, but
// getResponseHeader still works. so we get content-type even if getting
// other headers fails.
this.header['content-type'] = this.xhr.getResponseHeader('content-type');
this.setHeaderProperties(this.header);
this.body = this.req.method != 'HEAD'
? this.parseBody(this.text)
: null;
}
/**
* Get case-insensitive `field` value.
*
* @param {String} field
* @return {String}
* @api public
*/
Response.prototype.get = function(field){
return this.header[field.toLowerCase()];
};
/**
* Set header related properties:
*
* - `.type` the content type without params
*
* A response of "Content-Type: text/plain; charset=utf-8"
* will provide you with a `.type` of "text/plain".
*
* @param {Object} header
* @api private
*/
Response.prototype.setHeaderProperties = function(header){
// content-type
var ct = this.header['content-type'] || '';
this.type = type(ct);
// params
var obj = params(ct);
for (var key in obj) this[key] = obj[key];
};
/**
* Parse the given body `str`.
*
* Used for auto-parsing of bodies. Parsers
* are defined on the `superagent.parse` object.
*
* @param {String} str
* @return {Mixed}
* @api private
*/
Response.prototype.parseBody = function(str){
var parse = request.parse[this.type];
return parse && str && str.length
? parse(str)
: null;
};
/**
* Set flags such as `.ok` based on `status`.
*
* For example a 2xx response will give you a `.ok` of __true__
* whereas 5xx will be __false__ and `.error` will be __true__. The
* `.clientError` and `.serverError` are also available to be more
* specific, and `.statusType` is the class of error ranging from 1..5
* sometimes useful for mapping respond colors etc.
*
* "sugar" properties are also defined for common cases. Currently providing:
*
* - .noContent
* - .badRequest
* - .unauthorized
* - .notAcceptable
* - .notFound
*
* @param {Number} status
* @api private
*/
Response.prototype.setStatusProperties = function(status){
var type = status / 100 | 0;
// status / class
this.status = status;
this.statusType = type;
// basics
this.info = 1 == type;
this.ok = 2 == type;
this.clientError = 4 == type;
this.serverError = 5 == type;
this.error = (4 == type || 5 == type)
? this.toError()
: false;
// sugar
this.accepted = 202 == status;
this.noContent = 204 == status || 1223 == status;
this.badRequest = 400 == status;
this.unauthorized = 401 == status;
this.notAcceptable = 406 == status;
this.notFound = 404 == status;
this.forbidden = 403 == status;
};
/**
* Return an `Error` representative of this response.
*
* @return {Error}
* @api public
*/
Response.prototype.toError = function(){
var req = this.req;
var method = req.method;
var url = req.url;
var msg = 'cannot ' + method + ' ' + url + ' (' + this.status + ')';
var err = new Error(msg);
err.status = this.status;
err.method = method;
err.url = url;
return err;
};
/**
* Expose `Response`.
*/
request.Response = Response;
/**
* Initialize a new `Request` with the given `method` and `url`.
*
* @param {String} method
* @param {String} url
* @api public
*/
function Request(method, url) {
var self = this;
Emitter.call(this);
this._query = this._query || [];
this.method = method;
this.url = url;
this.header = {};
this._header = {};
this.on('end', function(){
var err = null;
var res = null;
try {
res = new Response(self);
} catch(e) {
err = new Error('Parser is unable to parse the response');
err.parse = true;
err.original = e;
}
self.callback(err, res);
});
}
/**
* Mixin `Emitter`.
*/
Emitter(Request.prototype);
/**
* Allow for extension
*/
Request.prototype.use = function(fn) {
fn(this);
return this;
}
/**
* Set timeout to `ms`.
*
* @param {Number} ms
* @return {Request} for chaining
* @api public
*/
Request.prototype.timeout = function(ms){
this._timeout = ms;
return this;
};
/**
* Clear previous timeout.
*
* @return {Request} for chaining
* @api public
*/
Request.prototype.clearTimeout = function(){
this._timeout = 0;
clearTimeout(this._timer);
return this;
};
/**
* Abort the request, and clear potential timeout.
*
* @return {Request}
* @api public
*/
Request.prototype.abort = function(){
if (this.aborted) return;
this.aborted = true;
this.xhr.abort();
this.clearTimeout();
this.emit('abort');
return this;
};
/**
* Set header `field` to `val`, or multiple fields with one object.
*
* Examples:
*
* req.get('/')
* .set('Accept', 'application/json')
* .set('X-API-Key', 'foobar')
* .end(callback);
*
* req.get('/')
* .set({ Accept: 'application/json', 'X-API-Key': 'foobar' })
* .end(callback);
*
* @param {String|Object} field
* @param {String} val
* @return {Request} for chaining
* @api public
*/
Request.prototype.set = function(field, val){
if (isObject(field)) {
for (var key in field) {
this.set(key, field[key]);
}
return this;
}
this._header[field.toLowerCase()] = val;
this.header[field] = val;
return this;
};
/**
* Remove header `field`.
*
* Example:
*
* req.get('/')
* .unset('User-Agent')
* .end(callback);
*
* @param {String} field
* @return {Request} for chaining
* @api public
*/
Request.prototype.unset = function(field){
delete this._header[field.toLowerCase()];
delete this.header[field];
return this;
};
/**
* Get case-insensitive header `field` value.
*
* @param {String} field
* @return {String}
* @api private
*/
Request.prototype.getHeader = function(field){
return this._header[field.toLowerCase()];
};
/**
* Set Content-Type to `type`, mapping values from `request.types`.
*
* Examples:
*
* superagent.types.xml = 'application/xml';
*
* request.post('/')
* .type('xml')
* .send(xmlstring)
* .end(callback);
*
* request.post('/')
* .type('application/xml')
* .send(xmlstring)
* .end(callback);
*
* @param {String} type
* @return {Request} for chaining
* @api public
*/
Request.prototype.type = function(type){
this.set('Content-Type', request.types[type] || type);
return this;
};
/**
* Set Accept to `type`, mapping values from `request.types`.
*
* Examples:
*
* superagent.types.json = 'application/json';
*
* request.get('/agent')
* .accept('json')
* .end(callback);
*
* request.get('/agent')
* .accept('application/json')
* .end(callback);
*
* @param {String} accept
* @return {Request} for chaining
* @api public
*/
Request.prototype.accept = function(type){
this.set('Accept', request.types[type] || type);
return this;
};
/**
* Set Authorization field value with `user` and `pass`.
*
* @param {String} user
* @param {String} pass
* @return {Request} for chaining
* @api public
*/
Request.prototype.auth = function(user, pass){
var str = btoa(user + ':' + pass);
this.set('Authorization', 'Basic ' + str);
return this;
};
/**
* Add query-string `val`.
*
* Examples:
*
* request.get('/shoes')
* .query('size=10')
* .query({ color: 'blue' })
*
* @param {Object|String} val
* @return {Request} for chaining
* @api public
*/
Request.prototype.query = function(val){
if ('string' != typeof val) val = serialize(val);
if (val) this._query.push(val);
return this;
};
/**
* Write the field `name` and `val` for "multipart/form-data"
* request bodies.
*
* ``` js
* request.post('/upload')
* .field('foo', 'bar')
* .end(callback);
* ```
*
* @param {String} name
* @param {String|Blob|File} val
* @return {Request} for chaining
* @api public
*/
Request.prototype.field = function(name, val){
if (!this._formData) this._formData = new FormData();
this._formData.append(name, val);
return this;
};
/**
* Queue the given `file` as an attachment to the specified `field`,
* with optional `filename`.
*
* ``` js
* request.post('/upload')
* .attach(new Blob(['<a id="a"><b id="b">hey!</b></a>'], { type: "text/html"}))
* .end(callback);
* ```
*
* @param {String} field
* @param {Blob|File} file
* @param {String} filename
* @return {Request} for chaining
* @api public
*/
Request.prototype.attach = function(field, file, filename){
if (!this._formData) this._formData = new FormData();
this._formData.append(field, file, filename);
return this;
};
/**
* Send `data`, defaulting the `.type()` to "json" when
* an object is given.
*
* Examples:
*
* // querystring
* request.get('/search')
* .end(callback)
*
* // multiple data "writes"
* request.get('/search')
* .send({ search: 'query' })
* .send({ range: '1..5' })
* .send({ order: 'desc' })
* .end(callback)
*
* // manual json
* request.post('/user')
* .type('json')
* .send('{"name":"tj"})
* .end(callback)
*
* // auto json
* request.post('/user')
* .send({ name: 'tj' })
* .end(callback)
*
* // manual x-www-form-urlencoded
* request.post('/user')
* .type('form')
* .send('name=tj')
* .end(callback)
*
* // auto x-www-form-urlencoded
* request.post('/user')
* .type('form')
* .send({ name: 'tj' })
* .end(callback)
*
* // defaults to x-www-form-urlencoded
* request.post('/user')
* .send('name=tobi')
* .send('species=ferret')
* .end(callback)
*
* @param {String|Object} data
* @return {Request} for chaining
* @api public
*/
Request.prototype.send = function(data){
var obj = isObject(data);
var type = this.getHeader('Content-Type');
// merge
if (obj && isObject(this._data)) {
for (var key in data) {
this._data[key] = data[key];
}
} else if ('string' == typeof data) {
if (!type) this.type('form');
type = this.getHeader('Content-Type');
if ('application/x-www-form-urlencoded' == type) {
this._data = this._data
? this._data + '&' + data
: data;
} else {
this._data = (this._data || '') + data;
}
} else {
this._data = data;
}
if (!obj) return this;
if (!type) this.type('json');
return this;
};
/**
* Invoke the callback with `err` and `res`
* and handle arity check.
*
* @param {Error} err
* @param {Response} res
* @api private
*/
Request.prototype.callback = function(err, res){
var fn = this._callback;
this.clearTimeout();
if (2 == fn.length) return fn(err, res);
if (err) return this.emit('error', err);
fn(res);
};
/**
* Invoke callback with x-domain error.
*
* @api private
*/
Request.prototype.crossDomainError = function(){
var err = new Error('Origin is not allowed by Access-Control-Allow-Origin');
err.crossDomain = true;
this.callback(err);
};
/**
* Invoke callback with timeout error.
*
* @api private
*/
Request.prototype.timeoutError = function(){
var timeout = this._timeout;
var err = new Error('timeout of ' + timeout + 'ms exceeded');
err.timeout = timeout;
this.callback(err);
};
/**
* Enable transmission of cookies with x-domain requests.
*
* Note that for this to work the origin must not be
* using "Access-Control-Allow-Origin" with a wildcard,
* and also must set "Access-Control-Allow-Credentials"
* to "true".
*
* @api public
*/
Request.prototype.withCredentials = function(){
this._withCredentials = true;
return this;
};
/**
* Initiate request, invoking callback `fn(res)`
* with an instanceof `Response`.
*
* @param {Function} fn
* @return {Request} for chaining
* @api public
*/
Request.prototype.end = function(fn){
var self = this;
var xhr = this.xhr = getXHR();
var query = this._query.join('&');
var timeout = this._timeout;
var data = this._formData || this._data;
// store callback
this._callback = fn || noop;
// state change
xhr.onreadystatechange = function(){
if (4 != xhr.readyState) return;
if (0 == xhr.status) {
if (self.aborted) return self.timeoutError();
return self.crossDomainError();
}
self.emit('end');
};
// progress
if (xhr.upload) {
xhr.upload.onprogress = function(e){
e.percent = e.loaded / e.total * 100;
self.emit('progress', e);
};
}
// timeout
if (timeout && !this._timer) {
this._timer = setTimeout(function(){
self.abort();
}, timeout);
}
// querystring
if (query) {
query = request.serializeObject(query);
this.url += ~this.url.indexOf('?')
? '&' + query
: '?' + query;
}
// initiate request
xhr.open(this.method, this.url, true);
// CORS
if (this._withCredentials) xhr.withCredentials = true;
// body
if ('GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !isHost(data)) {
// serialize stuff
var serialize = request.serialize[this.getHeader('Content-Type')];
if (serialize) data = serialize(data);
}
// set header fields
for (var field in this.header) {
if (null == this.header[field]) continue;
xhr.setRequestHeader(field, this.header[field]);
}
// send stuff
this.emit('request', this);
xhr.send(data);
return this;
};
/**
* Expose `Request`.
*/
request.Request = Request;
/**
* Issue a request:
*
* Examples:
*
* request('GET', '/users').end(callback)
* request('/users').end(callback)
* request('/users', callback)
*
* @param {String} method
* @param {String|Function} url or callback
* @return {Request}
* @api public
*/
function request(method, url) {
// callback
if ('function' == typeof url) {
return new Request('GET', method).end(url);
}
// url first
if (1 == arguments.length) {
return new Request('GET', method);
}
return new Request(method, url);
}
/**
* GET `url` with optional callback `fn(res)`.
*
* @param {String} url
* @param {Mixed|Function} data or fn
* @param {Function} fn
* @return {Request}
* @api public
*/
request.get = function(url, data, fn){
var req = request('GET', url);
if ('function' == typeof data) fn = data, data = null;
if (data) req.query(data);
if (fn) req.end(fn);
return req;
};
/**
* HEAD `url` with optional callback `fn(res)`.
*
* @param {String} url
* @param {Mixed|Function} data or fn
* @param {Function} fn
* @return {Request}
* @api public
*/
request.head = function(url, data, fn){
var req = request('HEAD', url);
if ('function' == typeof data) fn = data, data = null;
if (data) req.send(data);
if (fn) req.end(fn);
return req;
};
/**
* DELETE `url` with optional callback `fn(res)`.
*
* @param {String} url
* @param {Function} fn
* @return {Request}
* @api public
*/
request.del = function(url, fn){
var req = request('DELETE', url);
if (fn) req.end(fn);
return req;
};
/**
* PATCH `url` with optional `data` and callback `fn(res)`.
*
* @param {String} url
* @param {Mixed} data
* @param {Function} fn
* @return {Request}
* @api public
*/
request.patch = function(url, data, fn){
var req = request('PATCH', url);
if ('function' == typeof data) fn = data, data = null;
if (data) req.send(data);
if (fn) req.end(fn);
return req;
};
/**
* POST `url` with optional `data` and callback `fn(res)`.
*
* @param {String} url
* @param {Mixed} data
* @param {Function} fn
* @return {Request}
* @api public
*/
request.post = function(url, data, fn){
var req = request('POST', url);
if ('function' == typeof data) fn = data, data = null;
if (data) req.send(data);
if (fn) req.end(fn);
return req;
};
/**
* PUT `url` with optional `data` and callback `fn(res)`.
*
* @param {String} url
* @param {Mixed|Function} data or fn
* @param {Function} fn
* @return {Request}
* @api public
*/
request.put = function(url, data, fn){
var req = request('PUT', url);
if ('function' == typeof data) fn = data, data = null;
if (data) req.send(data);
if (fn) req.end(fn);
return req;
};
/**
* Expose `request`.
*/
module.exports = request;
},{"emitter":5,"reduce":8}]},{},[1])(1)
});
================================================
FILE: lib/soda-js.js
================================================
// Generated by CoffeeScript 1.6.3
var Connection, Consumer, Dataset, EventEmitter, Operation, Producer, Query, addExpr, base64Lookup, eelib, expr, extend, handleLiteral, handleOrder, httpClient, isArray, isNumber, isString, rawToBase64, toBase64, toQuerystring,
__slice = [].slice,
__hasProp = {}.hasOwnProperty;
eelib = require('eventemitter2');
EventEmitter = eelib.EventEmitter2 || eelib;
httpClient = require('superagent');
isString = function(obj) {
return typeof obj === 'string';
};
isArray = function(obj) {
return Array.isArray(obj);
};
isNumber = function(obj) {
return !isNaN(parseFloat(obj));
};
extend = function() {
var k, source, sources, target, v, _i, _len;
target = arguments[0], sources = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
for (_i = 0, _len = sources.length; _i < _len; _i++) {
source = sources[_i];
for (k in source) {
v = source[k];
target[k] = v;
}
}
return null;
};
toBase64 = typeof Buffer !== "undefined" && Buffer !== null ? function(str) {
return new Buffer(str).toString('base64');
} : (base64Lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='.split(''), rawToBase64 = typeof btoa !== "undefined" && btoa !== null ? btoa : function(str) {
var chr1, chr2, chr3, enc1, enc2, enc3, enc4, i, result;
result = [];
i = 0;
while (i < str.length) {
chr1 = str.charCodeAt(i++);
chr2 = str.charCodeAt(i++);
chr3 = str.charCodeAt(i++);
if (Math.max(chr1, chr2, chr3) > 0xFF) {
throw new Error('Invalid character!');
}
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
result.push(base64Lookup[enc1]);
result.push(base64Lookup[enc2]);
result.push(base64Lookup[enc3]);
result.push(base64Lookup[enc4]);
}
return result.join('');
}, function(str) {
return rawToBase64(unescape(encodeURIComponent(str)));
});
handleLiteral = function(literal) {
if (isString(literal)) {
return "'" + literal + "'";
} else if (isNumber(literal)) {
return literal;
} else {
return literal;
}
};
handleOrder = function(order) {
if (/( asc$| desc$)/i.test(order)) {
return order;
} else {
return order + ' asc';
}
};
addExpr = function(target, args) {
var arg, k, v, _i, _len, _results;
_results = [];
for (_i = 0, _len = args.length; _i < _len; _i++) {
arg = args[_i];
if (isString(arg)) {
_results.push(target.push(arg));
} else {
_results.push((function() {
var _results1;
_results1 = [];
for (k in arg) {
v = arg[k];
_results1.push(target.push("" + k + " = " + (handleLiteral(v))));
}
return _results1;
})());
}
}
return _results;
};
expr = {
and: function() {
var clause, clauses;
clauses = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
return ((function() {
var _i, _len, _results;
_results = [];
for (_i = 0, _len = clauses.length; _i < _len; _i++) {
clause = clauses[_i];
_results.push("(" + clause + ")");
}
return _results;
})()).join(' and ');
},
or: function() {
var clause, clauses;
clauses = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
return ((function() {
var _i, _len, _results;
_results = [];
for (_i = 0, _len = clauses.length; _i < _len; _i++) {
clause = clauses[_i];
_results.push("(" + clause + ")");
}
return _results;
})()).join(' or ');
},
gt: function(column, literal) {
return "" + column + " > " + (handleLiteral(literal));
},
gte: function(column, literal) {
return "" + column + " >= " + (handleLiteral(literal));
},
lt: function(column, literal) {
return "" + column + " < " + (handleLiteral(literal));
},
lte: function(column, literal) {
return "" + column + " <= " + (handleLiteral(literal));
},
eq: function(column, literal) {
return "" + column + " = " + (handleLiteral(literal));
}
};
toQuerystring = function(obj) {
var key, str, val;
str = [];
for (key in obj) {
if (!__hasProp.call(obj, key)) continue;
val = obj[key];
str.push(encodeURIComponent(key) + '=' + encodeURIComponent(val));
}
return str.join('&');
};
Connection = (function() {
function Connection(dataSite, sodaOpts) {
var _ref;
this.dataSite = dataSite;
this.sodaOpts = sodaOpts != null ? sodaOpts : {};
if (!/^[a-z0-9-_.]+(:[0-9]+)?$/i.test(this.dataSite)) {
throw new Error('dataSite does not appear to be valid! Please supply a domain name, eg data.seattle.gov');
}
this.emitterOpts = (_ref = this.sodaOpts.emitterOpts) != null ? _ref : {
wildcard: true,
delimiter: '.',
maxListeners: 15
};
this.networker = function(opts, data) {
var client, url,
_this = this;
url = "https://" + this.dataSite + opts.path;
client = httpClient(opts.method, url);
if (data != null) {
client.set('Accept', "application/json");
}
if (data != null) {
client.set('Content-type', "application/json");
}
if (this.sodaOpts.apiToken != null) {
client.set('X-App-Token', this.sodaOpts.apiToken);
}
if ((this.sodaOpts.username != null) && (this.sodaOpts.password != null)) {
client.set('Authorization', "Basic " + toBase64("" + this.sodaOpts.username + ":" + this.sodaOpts.password));
}
if (this.sodaOpts.accessToken != null) {
client.set('Authorization', "OAuth " + accessToken);
}
if (opts.query != null) {
client.query(opts.query);
}
if (data != null) {
client.send(data);
}
return function(responseHandler) {
return client.end(responseHandler || _this.getDefaultHandler());
};
};
}
Connection.prototype.getDefaultHandler = function() {
var emitter, handler;
this.emitter = emitter = new EventEmitter(this.emitterOpts);
return handler = function(error, response) {
var _ref;
if (response.ok) {
if (response.accepted) {
emitter.emit('progress', response.body);
setTimeout((function() {
return this.consumer.networker(opts)(handler);
}), 5000);
} else {
emitter.emit('success', response.body);
}
} else {
emitter.emit('error', (_ref = response.body) != null ? _ref : response.text);
}
return emitter.emit('complete', response);
};
};
return Connection;
})();
Consumer = (function() {
function Consumer(dataSite, sodaOpts) {
this.dataSite = dataSite;
this.sodaOpts = sodaOpts != null ? sodaOpts : {};
this.connection = new Connection(this.dataSite, this.sodaOpts);
}
Consumer.prototype.query = function() {
return new Query(this);
};
Consumer.prototype.getDataset = function(id) {
var emitter;
return emitter = new EventEmitter(this.emitterOpts);
};
return Consumer;
})();
Producer = (function() {
function Producer(dataSite, sodaOpts) {
this.dataSite = dataSite;
this.sodaOpts = sodaOpts != null ? sodaOpts : {};
this.connection = new Connection(this.dataSite, this.sodaOpts);
}
Producer.prototype.operation = function() {
return new Operation(this);
};
return Producer;
})();
Operation = (function() {
function Operation(producer) {
this.producer = producer;
}
Operation.prototype.withDataset = function(datasetId) {
this._datasetId = datasetId;
return this;
};
Operation.prototype.truncate = function() {
var opts;
opts = {
method: 'delete'
};
opts.path = "/resource/" + this._datasetId;
return this._exec(opts);
};
Operation.prototype.add = function(data) {
var obj, opts, _data, _i, _len;
opts = {
method: 'post'
};
opts.path = "/resource/" + this._datasetId;
_data = JSON.parse(JSON.stringify(data));
delete _data[':id'];
delete _data[':delete'];
for (_i = 0, _len = _data.length; _i < _len; _i++) {
obj = _data[_i];
delete obj[':id'];
delete obj[':delete'];
}
return this._exec(opts, _data);
};
Operation.prototype["delete"] = function(id) {
var opts;
opts = {
method: 'delete'
};
opts.path = "/resource/" + this._datasetId + "/" + id;
return this._exec(opts);
};
Operation.prototype.update = function(id, data) {
var opts;
opts = {
method: 'post'
};
opts.path = "/resource/" + this._datasetId + "/" + id;
return this._exec(opts, data);
};
Operation.prototype.replace = function(id, data) {
var opts;
opts = {
method: 'put'
};
opts.path = "/resource/" + this._datasetId + "/" + id;
return this._exec(opts, data);
};
Operation.prototype.upsert = function(data) {
var opts;
opts = {
method: 'post'
};
opts.path = "/resource/" + this._datasetId;
return this._exec(opts, data);
};
Operation.prototype._exec = function(opts, data) {
if (this._datasetId == null) {
throw new Error('no dataset given to work against!');
}
this.producer.connection.networker(opts, data)();
return this.producer.connection.emitter;
};
return Operation;
})();
Query = (function() {
function Query(consumer) {
this.consumer = consumer;
this._select = [];
this._where = [];
this._group = [];
this._having = [];
this._order = [];
this._offset = this._limit = this._q = null;
}
Query.prototype.withDataset = function(datasetId) {
this._datasetId = datasetId;
return this;
};
Query.prototype.soql = function(query) {
this._soql = query;
return this;
};
Query.prototype.select = function() {
var select, selects, _i, _len;
selects = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
for (_i = 0, _len = selects.length; _i < _len; _i++) {
select = selects[_i];
this._select.push(select);
}
return this;
};
Query.prototype.where = function() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
addExpr(this._where, args);
return this;
};
Query.prototype.having = function() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
addExpr(this._having, args);
return this;
};
Query.prototype.group = function() {
var group, groups, _i, _len;
groups = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
for (_i = 0, _len = groups.length; _i < _len; _i++) {
group = groups[_i];
this._group.push(group);
}
return this;
};
Query.prototype.order = function() {
var order, orders, _i, _len;
orders = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
for (_i = 0, _len = orders.length; _i < _len; _i++) {
order = orders[_i];
this._order.push(handleOrder(order));
}
return this;
};
Query.prototype.offset = function(offset) {
this._offset = offset;
return this;
};
Query.prototype.limit = function(limit) {
this._limit = limit;
return this;
};
Query.prototype.q = function(q) {
this._q = q;
return this;
};
Query.prototype.getOpts = function() {
var k, opts, queryComponents, v;
opts = {
method: 'get'
};
if (this._datasetId == null) {
throw new Error('no dataset given to work against!');
}
opts.path = "/resource/" + this._datasetId + ".json";
queryComponents = this._buildQueryComponents();
opts.query = {};
for (k in queryComponents) {
v = queryComponents[k];
opts.query['$' + k] = v;
}
return opts;
};
Query.prototype.getURL = function() {
var opts, query;
opts = this.getOpts();
query = toQuerystring(opts.query);
return ("https://" + this.consumer.dataSite + opts.path) + (query ? "?" + query : "");
};
Query.prototype.getRows = function() {
var opts;
opts = this.getOpts();
this.consumer.connection.networker(opts)();
return this.consumer.connection.emitter;
};
Query.prototype._buildQueryComponents = function() {
var query;
query = {};
if (this._soql != null) {
query.query = this._soql;
} else {
if (this._select.length > 0) {
query.select = this._select.join(', ');
}
if (this._where.length > 0) {
query.where = expr.and.apply(this, this._where);
}
if (this._group.length > 0) {
query.group = this._group.join(', ');
}
if (this._having.length > 0) {
if (!(this._group.length > 0)) {
throw new Error('Having provided without group by!');
}
query.having = expr.and.apply(this, this._having);
}
if (this._order.length > 0) {
query.order = this._order.join(', ');
}
if (isNumber(this._offset)) {
query.offset = this._offset;
}
if (isNumber(this._limit)) {
query.limit = this._limit;
}
if (this._q) {
query.q = this._q;
}
}
return query;
};
return Query;
})();
Dataset = (function() {
function Dataset(data, client) {
this.data = data;
this.client = client;
}
return Dataset;
})();
extend(typeof exports !== "undefined" && exports !== null ? exports : this.soda, {
Consumer: Consumer,
Producer: Producer,
expr: expr,
_internal: {
Connection: Connection,
Query: Query,
Operation: Operation,
util: {
toBase64: toBase64,
handleLiteral: handleLiteral,
handleOrder: handleOrder
}
}
});
================================================
FILE: package.json
================================================
{
"name": "soda-js",
"description": "js library for accessing a soda2 api",
"homepage": "https://github.com/socrata/soda-js",
"keywords": [
"socrata",
"soda",
"api",
"opendata",
"open data"
],
"contributors": [
{
"name": "Clint Tseng",
"email": "clint.tseng@socrata.com"
}
],
"dependencies": {
"eventemitter2": "~0.4.14",
"superagent": "^3.7.0"
},
"devDependencies": {
"coffee-script": "~1.6.3",
"expresso": "~0.9.2",
"browserify": "^12.0.1"
},
"licenses": [
{
"type": "MIT"
}
],
"scripts": {
"test": "node_modules/expresso/bin/expresso test/*",
"coffee": "node_modules/coffee-script/bin/cake build",
"bundle": "browserify lib/soda-js.js --standalone soda > lib/soda-js.bundle.js",
"build": "npm run coffee && npm run bundle"
},
"main": "./lib/soda-js.js",
"version": "0.2.4"
}
================================================
FILE: sample/basic_producer.js
================================================
var soda = require('../lib/soda-js');
var sodaOpts = {
"username": "testuser@gmail.com",
"password" : "OpenData",
"apiToken" : "D8Atrg62F2j017ZTdkMpuZ9vY"
}
var producer = new soda.Producer('sandbox.demo.socrata.com', sodaOpts);
var addSample = function() {
var data = {
mynum : 42,
mytext: "hello world",
mymoney: 999.99
}
console.log("Adding Sample")
producer.operation()
.withDataset('rphc-ayt9')
.add(data)
.on('success', function(row) { console.log(row); updateSample(row[':id']); })
.on('error', function(error) { console.error(error); })
}
var updateSample = function(id) {
var data = { mytext: "goodbye world" }
console.log("\nUpdating Sample")
producer.operation()
.withDataset('rphc-ayt9')
.update(id, data)
.on('success', function(row) { console.log(row); deleteSample(row[':id']); })
.on('error', function(error) { console.error(error); })
}
var deleteSample = function(id) {
console.log("\nDeleting Sample")
producer.operation()
.withDataset('rphc-ayt9')
.delete(id)
.on('success', function(row) { console.log(row); })
.on('error', function(error) { console.error(error); })
}
addSample();
================================================
FILE: sample/basic_query.js
================================================
var soda = require('../lib/soda-js');
var consumer = new soda.Consumer('open.whitehouse.gov');
consumer.query()
.withDataset('p86s-ychb')
.limit(5)
.where({ namelast: 'SMITH' })
.order('namelast')
.getRows()
.on('success', function(rows) { console.log(rows); })
.on('error', function(error) { console.error(error); });
================================================
FILE: sample/browser.html
================================================
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>soda-js sample</title>
</head>
<body>
<script src="../lib/soda-js.bundle.js"></script>
<script>
var consumer = new soda.Consumer('data.phila.gov');
consumer.query()
.withDataset('2pfz-fnns')
.limit(5)
.where({ issuing_agency: 'POLICE' })
.order('fine')
.getRows()
.on('success', function(rows) { console.log(rows); })
.on('error', function(error) { console.error(error); });
</script>
</body>
</html>
================================================
FILE: src/soda-js.coffee
================================================
# soda.coffee -- chained, evented, buzzworded library for accessing SODA via JS.
# sodaOpts options:
# username: https basic auth username
# password: https basic auth password
# apiToken: socrata api token
#
# emitterOpts: options to override EventEmitter2 declaration options
# TODO:
# * we're inconsistent about validating query correctness. do we continue with catch-what-we-can,
# or do we just back off and leave all failures to the api to return?
eelib = require('eventemitter2')
EventEmitter = eelib.EventEmitter2 || eelib
httpClient = require('superagent')
# internal util funcs
isString = (obj) -> typeof obj == 'string'
isArray = (obj) -> Array.isArray(obj)
isNumber = (obj) -> !isNaN(parseFloat(obj))
extend = (target, sources...) -> (target[k] = v for k, v of source) for source in sources; null
# it's really, really, really stupid that i have to solve this problem here
toBase64 =
if Buffer?
(str) -> new Buffer(str).toString('base64')
else
# adapted/modified from https://github.com/rwz/base64.coffee
base64Lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='.split('')
rawToBase64 = btoa ? (str) ->
result = []
i = 0
while i < str.length
chr1 = str.charCodeAt(i++)
chr2 = str.charCodeAt(i++)
chr3 = str.charCodeAt(i++)
throw new Error('Invalid character!') if Math.max(chr1, chr2, chr3) > 0xFF
enc1 = chr1 >> 2
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4)
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6)
enc4 = chr3 & 63
if isNaN(chr2)
enc3 = enc4 = 64
else if isNaN(chr3)
enc4 = 64
result.push(base64Lookup[enc1])
result.push(base64Lookup[enc2])
result.push(base64Lookup[enc3])
result.push(base64Lookup[enc4])
result.join('')
(str) -> rawToBase64(unescape(encodeURIComponent(str)))
handleLiteral = (literal) ->
if isString(literal)
"'#{literal}'"
else if isNumber(literal)
# TODO: possibly ensure number cleanliness for sending to the api? sci not?
literal
else
literal
handleOrder = (order) ->
if /( asc$| desc$)/i.test(order)
order
else
order + ' asc'
addExpr = (target, args) ->
for arg in args
if isString(arg)
target.push(arg)
else
target.push("#{k} = #{handleLiteral(v)}") for k, v of arg
# extern util funcs
# convenience functions for building where clauses, if so desired
expr =
and: (clauses...) -> ("(#{clause})" for clause in clauses).join(' and ')
or: (clauses...) -> ("(#{clause})" for clause in clauses).join(' or ')
gt: (column, literal) -> "#{column} > #{handleLiteral(literal)}"
gte: (column, literal) -> "#{column} >= #{handleLiteral(literal)}"
lt: (column, literal) -> "#{column} < #{handleLiteral(literal)}"
lte: (column, literal) -> "#{column} <= #{handleLiteral(literal)}"
eq: (column, literal) -> "#{column} = #{handleLiteral(literal)}"
# serialize object to querystring
toQuerystring = (obj) ->
str = []
for own key, val of obj
str.push encodeURIComponent(key) + '=' + encodeURIComponent(val)
str.join '&'
class Connection
constructor: (@dataSite, @sodaOpts = {}) ->
throw new Error('dataSite does not appear to be valid! Please supply a domain name, eg data.seattle.gov') unless /^[a-z0-9-_.]+(:[0-9]+)?$/i.test(@dataSite)
# options passed directly into EventEmitter2 construction
@emitterOpts = @sodaOpts.emitterOpts ?
wildcard: true,
delimiter: '.',
maxListeners: 15
@networker = (opts, data) ->
url = "https://#{@dataSite}#{opts.path}"
client = httpClient(opts.method, url)
client.set('Accept', "application/json") if data?
client.set('Content-type', "application/json") if data?
client.set('X-App-Token', @sodaOpts.apiToken) if @sodaOpts.apiToken?
client.set('Authorization', "Basic " + toBase64("#{@sodaOpts.username}:#{@sodaOpts.password}")) if @sodaOpts.username? and @sodaOpts.password?
client.set('Authorization', "OAuth " + accessToken) if @sodaOpts.accessToken?
client.query(opts.query) if opts.query?
client.send(data) if data?
(responseHandler) => client.end(responseHandler || @getDefaultHandler())
getDefaultHandler: ->
# instance variable for easy chaining
@emitter = emitter = new EventEmitter(@emitterOpts)
# return the handler
handler = (error, response) ->
# TODO: possibly more granular handling?
if response.ok
if response.accepted
# handle 202 by remaking request. inform of possible progress.
emitter.emit('progress', response.body)
setTimeout((-> @consumer.networker(opts)(handler)), 5000)
else
emitter.emit('success', response.body)
else
emitter.emit('error', response.body ? response.text)
# just emit the raw superagent obj if they just want complete event
emitter.emit('complete', response)
# main class
class Consumer
constructor: (@dataSite, @sodaOpts = {}) ->
@connection = new Connection(@dataSite, @sodaOpts)
query: ->
new Query(this)
getDataset: (id) ->
emitter = new EventEmitter(@emitterOpts)
# TODO: implement me
# Producer class
class Producer
constructor: (@dataSite, @sodaOpts = {}) ->
@connection = new Connection(@dataSite, @sodaOpts)
operation: ->
new Operation(this)
class Operation
constructor: (@producer) ->
withDataset: (datasetId) -> @_datasetId = datasetId; this
# truncate the entire dataset
truncate: ->
opts = method: 'delete'
opts.path = "/resource/#{@_datasetId}"
this._exec(opts)
# add a new row - explicitly avoids upserting (updating/deleting existing rows)
add: (data) ->
opts = method: 'post'
opts.path = "/resource/#{@_datasetId}"
_data = JSON.parse(JSON.stringify(data))
delete _data[':id']
delete _data[':delete']
for obj in _data
delete obj[':id']
delete obj[':delete']
this._exec(opts, _data)
# modify existing rows
delete: (id) ->
opts = method: 'delete'
opts.path = "/resource/#{@_datasetId}/#{id}"
this._exec(opts)
update: (id, data) ->
opts = method: 'post'
opts.path = "/resource/#{@_datasetId}/#{id}"
this._exec(opts, data)
replace: (id, data) ->
opts = method: 'put'
opts.path = "/resource/#{@_datasetId}/#{id}"
this._exec(opts, data)
# add objects, update if existing, delete if :delete=true
upsert: (data) ->
opts = method: 'post'
opts.path = "/resource/#{@_datasetId}"
this._exec(opts, data)
_exec: (opts, data) ->
throw new Error('no dataset given to work against!') unless @_datasetId?
@producer.connection.networker(opts, data)()
@producer.connection.emitter
# querybuilder class
class Query
constructor: (@consumer) ->
@_select = []
@_where = []
@_group = []
@_having = []
@_order = []
@_offset = @_limit = @_q = null
withDataset: (datasetId) -> @_datasetId = datasetId; this
# for passing in a fully formed soql query. all other params will be ignored
soql: (query) -> @_soql = query; this
select: (selects...) -> @_select.push(select) for select in selects; this
# args: ('clause', [...])
# ({ column: value1, columnb: value2 }, [...]])
# multiple calls are assumed to be and-chained
where: (args...) -> addExpr(@_where, args); this
having: (args...) -> addExpr(@_having, args); this
group: (groups...) -> @_group.push(group) for group in groups; this
# args: ("column direction", ["column direction", [...]])
order: (orders...) -> @_order.push(handleOrder(order)) for order in orders; this
offset: (offset) -> @_offset = offset; this
limit: (limit) -> @_limit = limit; this
q: (q) -> @_q = q; this
getOpts: ->
opts = method: 'get'
throw new Error('no dataset given to work against!') unless @_datasetId?
opts.path = "/resource/#{@_datasetId}.json"
queryComponents = this._buildQueryComponents()
opts.query = {}
opts.query['$' + k] = v for k, v of queryComponents
opts
getURL: ->
opts = this.getOpts()
query = toQuerystring(opts.query)
"https://#{@consumer.dataSite}#{opts.path}" + (if query then "?#{query}" else "")
getRows: ->
opts = this.getOpts()
@consumer.connection.networker(opts)()
@consumer.connection.emitter
_buildQueryComponents: ->
query = {}
if @_soql?
query.query = @_soql
else
query.select = @_select.join(', ') if @_select.length > 0
query.where = expr.and.apply(this, @_where) if @_where.length > 0
query.group = @_group.join(', ') if @_group.length > 0
if @_having.length > 0
throw new Error('Having provided without group by!') unless @_group.length > 0
query.having = expr.and.apply(this, @_having)
query.order = @_order.join(', ') if @_order.length > 0
query.offset = @_offset if isNumber(@_offset)
query.limit = @_limit if isNumber(@_limit)
query.q = @_q if @_q
query
class Dataset
constructor: (@data, @client) ->
# TODO: implement me
extend(exports ? this.soda,
Consumer: Consumer,
Producer: Producer,
expr: expr,
# exported for testing reasons
_internal:
Connection: Connection,
Query: Query,
Operation: Operation,
util:
toBase64: toBase64,
handleLiteral: handleLiteral,
handleOrder: handleOrder
)
================================================
FILE: test/connection_tests.coffee
================================================
soda = require('../lib/soda-js')
module.exports =
'basic construction': (beforeExit, assert) ->
connection = new soda._internal.Connection('opendata.socrata.com')
assert.eql(connection.dataSite, 'opendata.socrata.com')
'failed construction': (beforeExit, assert) ->
caught = false
try
connection = new soda._internal.Connection('http://data.cityofchicago.org')
catch ex
caught = true
assert.ok(caught)
================================================
FILE: test/consumer_tests.coffee
================================================
soda = require('../lib/soda-js')
module.exports =
'create consumer connection': (beforeExit, assert) ->
consumer = new soda.Producer('data.seattle.gov')
assert.ok(consumer.connection instanceof soda._internal.Connection)
assert.eql(consumer.connection.dataSite, 'data.seattle.gov')
'create query': (beforeExit, assert) ->
consumer = new soda.Consumer('data.seattle.gov')
query = consumer.query()
assert.ok(query instanceof soda._internal.Query)
assert.eql(query.consumer, consumer)
================================================
FILE: test/operation_tests.coffee
================================================
soda = require('../lib/soda-js')
# fixture generator to allow injecting verifiers as networkers
producer = (verifier) ->
connection:
networker: ((opts, data) -> verifier(opts, data); -> null),
emitterOpts:
wildcard: true,
delimiter: '.',
maxListeners: 15
# convenience func for using the above fixture with an operation
operateWith = (networker) -> new soda._internal.Operation(producer(networker))
module.exports =
'basic add': (beforeExit, assert) ->
verifier = (opts, data) ->
assert.eql(opts.method, "post")
assert.eql(opts.path, "/resource/abcd-1234")
assert.eql(data, { hello: "world" })
operateWith(verifier)
.withDataset('abcd-1234')
.add( {hello: "world" })
'multiple add': (beforeExit, assert) ->
verifier = (opts, data) ->
assert.eql(opts.method, "post")
assert.eql(opts.path, "/resource/abcd-1234")
assert.eql(data.length, 3)
operateWith(verifier)
.withDataset('abcd-1234')
.add( [{col:"a"}, {col:"b"}, {col:"c"}] )
'add prevents upsert of object': (beforeExit, assert) ->
verifier = (opts, data) ->
assert.eql(opts.method, "post")
assert.eql(opts.path, "/resource/abcd-1234")
assert.eql(data, { col: "c" })
operateWith(verifier)
.withDataset('abcd-1234')
.add( { ":id": 3, ":delete": true, col:"c"} )
'add prevents upsert of array': (beforeExit, assert) ->
verifier = (opts, data) ->
assert.eql(opts.method, "post")
assert.eql(opts.path, "/resource/abcd-1234")
assert.eql(data, [
{col:"a"},
{col:"b"},
{col:"c"},
{col:"d"}
])
operateWith(verifier)
.withDataset('abcd-1234')
.add([
{ ":id": 1, col: "a"},
{ col: "b", ":delete": true },
{ ":id": 3, ":delete": true, col:"c"},
{ col: "d" }
])
'upsert array': (beforeExit, assert) ->
verifier = (opts, data) ->
assert.eql(opts.method, "post")
assert.eql(opts.path, "/resource/abcd-1234")
assert.eql(data, [
{ col: "a", ":id": 1},
{ col: "b", ":delete": true },
{ col: "c", ":id": 3, ":delete": true },
{ col: "d" }
])
operateWith(verifier)
.withDataset('abcd-1234')
.upsert([
{ ":id": 1, col: "a"},
{ col: "b", ":delete": true },
{ ":id": 3, ":delete": true, col:"c"},
{ col: "d" }
])
'basic truncate': (beforeExit, assert) ->
verifier = (opts, data) ->
assert.eql(opts.method, "delete")
assert.eql(opts.path, "/resource/lmno-9876")
assert.isUndefined(data)
operateWith(verifier)
.withDataset('lmno-9876')
.truncate()
'basic delete': (beforeExit, assert) ->
verifier = (opts, data) ->
assert.eql(opts.method, "delete")
assert.eql(opts.path, "/resource/lmno-9876/123")
assert.isUndefined(data)
operateWith(verifier)
.withDataset('lmno-9876')
.delete(123)
'basic update': (beforeExit, assert) ->
verifier = (opts, data) ->
assert.eql(opts.method, "post") # seriously, why isn't this patch?
assert.eql(opts.path, "/resource/lmno-9876/123")
assert.eql(data, { num : 987 })
operateWith(verifier)
.withDataset("lmno-9876")
.update(123, { num : 987 })
'basic replace': (beforeExit, assert) ->
verifier = (opts, data) ->
assert.eql(opts.method, "put")
assert.eql(opts.path, "/resource/lmno-1234/987")
assert.eql(data, { num : 456 })
operateWith(verifier)
.withDataset("lmno-1234")
.replace(987, { num : 456 })
================================================
FILE: test/producer_tests.coffee
================================================
soda = require('../lib/soda-js')
module.exports =
'create producer connection': (beforeExit, assert) ->
producer = new soda.Producer('data.seattle.gov')
assert.ok(producer.connection instanceof soda._internal.Connection)
assert.eql(producer.connection.dataSite, 'data.seattle.gov')
'create producer operation': (beforeExit, assert) ->
producer = new soda.Producer('data.seattle.gov')
operation = producer.operation()
assert.ok(operation instanceof soda._internal.Operation)
assert.eql(operation.producer, producer)
================================================
FILE: test/query_tests.coffee
================================================
soda = require('../lib/soda-js')
# fixture generator to allow injecting verifiers as networkers
consumer = (verifier) ->
connection:
networker: ((opts) -> verifier(opts); -> null),
emitterOpts:
wildcard: true,
delimiter: '.',
maxListeners: 15
# convenience func for using the above fixture with a query
queryWith = (networker) -> new soda._internal.Query(consumer(networker))
module.exports =
'basic query': (beforeExit, assert) ->
verifier = (opts) ->
assert.eql(opts.path, '/resource/hospitals.json')
queryWith(verifier)
.withDataset('hospitals')
.getRows()
'col select': (beforeExit, assert) ->
verifier = (opts) ->
assert.eql(opts.query, { $select: 'street, city, state, zip' })
queryWith(verifier)
.withDataset('hospitals')
.select('street', 'city', 'state', 'zip')
.getRows()
'string expr': (beforeExit, assert) ->
expr = soda.expr.eq('name', 'bob')
assert.eql(expr, "name = 'bob'")
'number expr': (beforeExit, assert) ->
expr = soda.expr.eq('age', 15)
assert.eql(expr, "age = 15")
'compound expr': (beforeExit, assert) ->
expr = soda.expr.and(soda.expr.eq('columnone', 1), soda.expr.eq('columntwo', 2))
assert.eql(expr, '(columnone = 1) and (columntwo = 2)')
'string where': (beforeExit, assert) ->
verifier = (opts) ->
assert.eql(opts.query, { $where: '(salary > 35000) and (yearsWorked >= 5)' })
queryWith(verifier)
.withDataset('salaries')
.where('salary > 35000', 'yearsWorked >= 5')
.getRows()
'obj where': (beforeExit, assert) ->
verifier = (opts) ->
assert.eql(opts.query, { $where: "(firstname = 'abed') and (lastname = 'nadir')" })
queryWith(verifier)
.withDataset('people')
.where({ firstname: 'abed', lastname: 'nadir' })
.getRows()
'groupby': (beforeExit, assert) ->
verifier = (opts) ->
assert.eql(opts.query, { $group: 'department, type' })
queryWith(verifier)
.withDataset('payments')
.group('department', 'type')
.getRows()
'having': (beforeExit, assert) ->
# having is the same implementation as where, so just test a maxiquery
verifier = (opts) ->
assert.eql(opts.query,
$group: 'firstname, lastname, total_salary',
$having: "((firstname = 'jeff') or (lastname = 'winger')) and (total_salary > 100000)")
queryWith(verifier)
.withDataset('salaries')
.group('firstname', 'lastname', 'total_salary') # of course in reality total_salary would be an aggr func..
.having(soda.expr.or(soda.expr.eq('firstname', 'jeff'), soda.expr.eq('lastname', 'winger')), 'total_salary > 100000')
.getRows()
'orderby': (beforeExit, assert) ->
verifier = (opts) ->
assert.eql(opts.query, { $order: 'lastname asc, firstname desc' })
queryWith(verifier)
.withDataset('salaries')
.order('lastname', 'firstname desc')
.getRows()
'offset and limit': (beforeExit, assert) ->
verifier = (opts) ->
assert.eql(opts.query, { $offset: 5, $limit: 10 })
queryWith(verifier)
.withDataset('hospitals')
.offset(5)
.limit(10)
.getRows()
gitextract_x01kdq_z/
├── .gitignore
├── .travis.yml
├── Cakefile
├── README.textile
├── lib/
│ ├── README
│ ├── soda-js.bundle.js
│ └── soda-js.js
├── package.json
├── sample/
│ ├── basic_producer.js
│ ├── basic_query.js
│ └── browser.html
├── src/
│ └── soda-js.coffee
└── test/
├── connection_tests.coffee
├── consumer_tests.coffee
├── operation_tests.coffee
├── producer_tests.coffee
└── query_tests.coffee
SYMBOL INDEX (83 symbols across 2 files)
FILE: lib/soda-js.bundle.js
function s (line 1) | function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&re...
function Connection (line 167) | function Connection(dataSite, sodaOpts) {
function Consumer (line 237) | function Consumer(dataSite, sodaOpts) {
function Producer (line 257) | function Producer(dataSite, sodaOpts) {
function Operation (line 272) | function Operation(producer) {
function Query (line 356) | function Query(consumer) {
function Dataset (line 509) | function Dataset(data, client) {
function decode (line 553) | function decode (elt) {
function b64ToByteArray (line 571) | function b64ToByteArray (b64) {
function uint8ToBase64 (line 617) | function uint8ToBase64 (uint8) {
function typedArraySupport (line 715) | function typedArraySupport () {
function kMaxLength (line 730) | function kMaxLength () {
function Buffer (line 748) | function Buffer (arg) {
function fromNumber (line 774) | function fromNumber (that, length) {
function fromString (line 784) | function fromString (that, string, encoding) {
function fromObject (line 795) | function fromObject (that, object) {
function fromBuffer (line 818) | function fromBuffer (that, buffer) {
function fromArray (line 825) | function fromArray (that, array) {
function fromTypedArray (line 835) | function fromTypedArray (that, array) {
function fromArrayBuffer (line 847) | function fromArrayBuffer (that, array) {
function fromArrayLike (line 859) | function fromArrayLike (that, array) {
function fromJsonObject (line 870) | function fromJsonObject (that, object) {
function allocate (line 895) | function allocate (that, length) {
function checked (line 912) | function checked (length) {
function SlowBuffer (line 922) | function SlowBuffer (subject, encoding) {
function byteLength (line 1006) | function byteLength (string, encoding) {
function slowToString (line 1043) | function slowToString (encoding, start, end) {
function arrayIndexOf (line 1140) | function arrayIndexOf (arr, val, byteOffset) {
function hexWrite (line 1168) | function hexWrite (buf, string, offset, length) {
function utf8Write (line 1195) | function utf8Write (buf, string, offset, length) {
function asciiWrite (line 1199) | function asciiWrite (buf, string, offset, length) {
function binaryWrite (line 1203) | function binaryWrite (buf, string, offset, length) {
function base64Write (line 1207) | function base64Write (buf, string, offset, length) {
function ucs2Write (line 1211) | function ucs2Write (buf, string, offset, length) {
function base64Slice (line 1294) | function base64Slice (buf, start, end) {
function utf8Slice (line 1302) | function utf8Slice (buf, start, end) {
function decodeCodePointsArray (line 1380) | function decodeCodePointsArray (codePoints) {
function asciiSlice (line 1398) | function asciiSlice (buf, start, end) {
function binarySlice (line 1408) | function binarySlice (buf, start, end) {
function hexSlice (line 1418) | function hexSlice (buf, start, end) {
function utf16leSlice (line 1431) | function utf16leSlice (buf, start, end) {
function checkOffset (line 1480) | function checkOffset (offset, ext, length) {
function checkInt (line 1641) | function checkInt (buf, value, offset, ext, max, min) {
function objectWriteUInt16 (line 1688) | function objectWriteUInt16 (buf, value, offset, littleEndian) {
function objectWriteUInt32 (line 1722) | function objectWriteUInt32 (buf, value, offset, littleEndian) {
function checkIEEE754 (line 1866) | function checkIEEE754 (buf, value, offset, ext, max, min) {
function writeFloat (line 1872) | function writeFloat (buf, value, offset, littleEndian, noAssert) {
function writeDouble (line 1888) | function writeDouble (buf, value, offset, littleEndian, noAssert) {
function base64clean (line 2073) | function base64clean (str) {
function stringtrim (line 2085) | function stringtrim (str) {
function toHex (line 2090) | function toHex (n) {
function utf8ToBytes (line 2095) | function utf8ToBytes (string, units) {
function asciiToBytes (line 2175) | function asciiToBytes (str) {
function utf16leToBytes (line 2184) | function utf16leToBytes (str, units) {
function base64ToBytes (line 2200) | function base64ToBytes (str) {
function blitBuffer (line 2204) | function blitBuffer (src, dst, offset, length) {
function Emitter (line 2234) | function Emitter(obj) {
function mixin (line 2246) | function mixin(obj) {
function on (line 2284) | function on() {
function init (line 2401) | function init() {
function configure (line 2408) | function configure(conf) {
function EventEmitter (line 2424) | function EventEmitter(conf) {
function searchListenerTree (line 2435) | function searchListenerTree(handlers, type, tree, i) {
function growListenerTree (line 2541) | function growListenerTree(type, listener) {
function listener (line 2633) | function listener() {
function noop (line 3092) | function noop(){}
function isHost (line 3105) | function isHost(obj) {
function getXHR (line 3122) | function getXHR() {
function isObject (line 3155) | function isObject(obj) {
function serialize (line 3167) | function serialize(obj) {
function parseString (line 3193) | function parseString(str) {
function parseHeader (line 3267) | function parseHeader(str) {
function type (line 3296) | function type(str){
function params (line 3308) | function params(str){
function Response (line 3365) | function Response(req, options) {
function Request (line 3518) | function Request(method, url) {
function request (line 4030) | function request(method, url) {
FILE: lib/soda-js.js
function Connection (line 165) | function Connection(dataSite, sodaOpts) {
function Consumer (line 235) | function Consumer(dataSite, sodaOpts) {
function Producer (line 255) | function Producer(dataSite, sodaOpts) {
function Operation (line 270) | function Operation(producer) {
function Query (line 354) | function Query(consumer) {
function Dataset (line 507) | function Dataset(data, client) {
Condensed preview — 17 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (155K chars).
[
{
"path": ".gitignore",
"chars": 36,
"preview": ".DS_Store\n*.swp\n*.swo\nnode_modules/\n"
},
{
"path": ".travis.yml",
"chars": 84,
"preview": "language: node_js\nnode_js:\n - 0.8\nbefore_install:\n - npm install -g npm@'>=1.4.3'\n"
},
{
"path": "Cakefile",
"chars": 5057,
"preview": "# Taken almost entirely from https://github.com/twilson63/cakefile-template\n# \n# Il y a 5 tasks:\n#\n# * build - compiles "
},
{
"path": "README.textile",
"chars": 2267,
"preview": "h1. soda-js \"!https://secure.travis-ci.org/socrata/soda-js.png!\":http://travis-ci.org/socrata/soda-js\n\nA client implemen"
},
{
"path": "lib/README",
"chars": 95,
"preview": "this directory contains autogenerated files. do not edit them! edit the files in src/ instead.\n"
},
{
"path": "lib/soda-js.bundle.js",
"chars": 105641,
"preview": "(function(f){if(typeof exports===\"object\"&&typeof module!==\"undefined\"){module.exports=f()}else if(typeof define===\"func"
},
{
"path": "lib/soda-js.js",
"chars": 13786,
"preview": "// Generated by CoffeeScript 1.6.3\nvar Connection, Consumer, Dataset, EventEmitter, Operation, Producer, Query, addExpr,"
},
{
"path": "package.json",
"chars": 902,
"preview": "{\n \"name\": \"soda-js\",\n \"description\": \"js library for accessing a soda2 api\",\n \"homepage\": \"https://github.com/socrat"
},
{
"path": "sample/basic_producer.js",
"chars": 1227,
"preview": "var soda = require('../lib/soda-js');\n\nvar sodaOpts = {\n \"username\": \"testuser@gmail.com\",\n \"password\" : \""
},
{
"path": "sample/basic_query.js",
"chars": 340,
"preview": "var soda = require('../lib/soda-js');\n\nvar consumer = new soda.Consumer('open.whitehouse.gov');\n\nconsumer.query()\n .wit"
},
{
"path": "sample/browser.html",
"chars": 511,
"preview": "<!DOCTYPE html>\n<html>\n\t<head>\n\t\t<meta charset=\"utf-8\">\n\t\t<title>soda-js sample</title>\n\t</head>\n\t<body>\n\t\t<script src=\""
},
{
"path": "src/soda-js.coffee",
"chars": 9482,
"preview": "# soda.coffee -- chained, evented, buzzworded library for accessing SODA via JS.\n\n# sodaOpts options:\n# username: http"
},
{
"path": "test/connection_tests.coffee",
"chars": 447,
"preview": "\nsoda = require('../lib/soda-js')\n\nmodule.exports =\n \n 'basic construction': (beforeExit, assert) ->\n connection = "
},
{
"path": "test/consumer_tests.coffee",
"chars": 518,
"preview": "\nsoda = require('../lib/soda-js')\n\nmodule.exports =\n 'create consumer connection': (beforeExit, assert) ->\n consumer"
},
{
"path": "test/operation_tests.coffee",
"chars": 3691,
"preview": "\nsoda = require('../lib/soda-js')\n\n# fixture generator to allow injecting verifiers as networkers\nproducer = (verifier) "
},
{
"path": "test/producer_tests.coffee",
"chars": 549,
"preview": "\nsoda = require('../lib/soda-js')\n\nmodule.exports =\n 'create producer connection': (beforeExit, assert) ->\n producer"
},
{
"path": "test/query_tests.coffee",
"chars": 3202,
"preview": "\nsoda = require('../lib/soda-js')\n\n# fixture generator to allow injecting verifiers as networkers\nconsumer = (verifier) "
}
]
About this extraction
This page contains the full source code of the socrata/soda-js GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 17 files (144.4 KB), approximately 41.9k tokens, and a symbol index with 83 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.