diff --git a/fril/node_modules/.bin/wellknown b/fril/node_modules/.bin/wellknown
new file mode 100644
index 0000000..d405e1d
--- /dev/null
+++ b/fril/node_modules/.bin/wellknown
@@ -0,0 +1,15 @@
+#!/bin/sh
+basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
+
+case `uname` in
+ *CYGWIN*) basedir=`cygpath -w "$basedir"`;;
+esac
+
+if [ -x "$basedir/node" ]; then
+ "$basedir/node" "$basedir/../wellknown/cli.js" "$@"
+ ret=$?
+else
+ node "$basedir/../wellknown/cli.js" "$@"
+ ret=$?
+fi
+exit $ret
diff --git a/fril/node_modules/.bin/wellknown.cmd b/fril/node_modules/.bin/wellknown.cmd
new file mode 100644
index 0000000..6288b6e
--- /dev/null
+++ b/fril/node_modules/.bin/wellknown.cmd
@@ -0,0 +1,7 @@
+@IF EXIST "%~dp0\node.exe" (
+ "%~dp0\node.exe" "%~dp0\..\wellknown\cli.js" %*
+) ELSE (
+ @SETLOCAL
+ @SET PATHEXT=%PATHEXT:;.JS;=;%
+ node "%~dp0\..\wellknown\cli.js" %*
+)
\ No newline at end of file
diff --git a/fril/node_modules/concat-stream/LICENSE b/fril/node_modules/concat-stream/LICENSE
new file mode 100644
index 0000000..99c130e
--- /dev/null
+++ b/fril/node_modules/concat-stream/LICENSE
@@ -0,0 +1,24 @@
+The MIT License
+
+Copyright (c) 2013 Max Ogden
+
+Permission is hereby granted, free of charge,
+to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to
+deal in the Software without restriction, including
+without limitation the rights to use, copy, modify,
+merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom
+the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/fril/node_modules/concat-stream/index.js b/fril/node_modules/concat-stream/index.js
new file mode 100644
index 0000000..b16ad13
--- /dev/null
+++ b/fril/node_modules/concat-stream/index.js
@@ -0,0 +1,143 @@
+var Writable = require('readable-stream').Writable
+var inherits = require('inherits')
+
+if (typeof Uint8Array === 'undefined') {
+ var U8 = require('typedarray').Uint8Array
+} else {
+ var U8 = Uint8Array
+}
+
+function ConcatStream(opts, cb) {
+ if (!(this instanceof ConcatStream)) return new ConcatStream(opts, cb)
+
+ if (typeof opts === 'function') {
+ cb = opts
+ opts = {}
+ }
+ if (!opts) opts = {}
+
+ var encoding = opts.encoding
+ var shouldInferEncoding = false
+
+ if (!encoding) {
+ shouldInferEncoding = true
+ } else {
+ encoding = String(encoding).toLowerCase()
+ if (encoding === 'u8' || encoding === 'uint8') {
+ encoding = 'uint8array'
+ }
+ }
+
+ Writable.call(this, { objectMode: true })
+
+ this.encoding = encoding
+ this.shouldInferEncoding = shouldInferEncoding
+
+ if (cb) this.on('finish', function () { cb(this.getBody()) })
+ this.body = []
+}
+
+module.exports = ConcatStream
+inherits(ConcatStream, Writable)
+
+ConcatStream.prototype._write = function(chunk, enc, next) {
+ this.body.push(chunk)
+ next()
+}
+
+ConcatStream.prototype.inferEncoding = function (buff) {
+ var firstBuffer = buff === undefined ? this.body[0] : buff;
+ if (Buffer.isBuffer(firstBuffer)) return 'buffer'
+ if (typeof Uint8Array !== 'undefined' && firstBuffer instanceof Uint8Array) return 'uint8array'
+ if (Array.isArray(firstBuffer)) return 'array'
+ if (typeof firstBuffer === 'string') return 'string'
+ if (Object.prototype.toString.call(firstBuffer) === "[object Object]") return 'object'
+ return 'buffer'
+}
+
+ConcatStream.prototype.getBody = function () {
+ if (!this.encoding && this.body.length === 0) return []
+ if (this.shouldInferEncoding) this.encoding = this.inferEncoding()
+ if (this.encoding === 'array') return arrayConcat(this.body)
+ if (this.encoding === 'string') return stringConcat(this.body)
+ if (this.encoding === 'buffer') return bufferConcat(this.body)
+ if (this.encoding === 'uint8array') return u8Concat(this.body)
+ return this.body
+}
+
+var isArray = Array.isArray || function (arr) {
+ return Object.prototype.toString.call(arr) == '[object Array]'
+}
+
+function isArrayish (arr) {
+ return /Array\]$/.test(Object.prototype.toString.call(arr))
+}
+
+function isBufferish (p) {
+ return typeof p === 'string' || isArrayish(p) || (p && typeof p.subarray === 'function')
+}
+
+function stringConcat (parts) {
+ var strings = []
+ var needsToString = false
+ for (var i = 0; i < parts.length; i++) {
+ var p = parts[i]
+ if (typeof p === 'string') {
+ strings.push(p)
+ } else if (Buffer.isBuffer(p)) {
+ strings.push(p)
+ } else if (isBufferish(p)) {
+ strings.push(new Buffer(p))
+ } else {
+ strings.push(new Buffer(String(p)))
+ }
+ }
+ if (Buffer.isBuffer(parts[0])) {
+ strings = Buffer.concat(strings)
+ strings = strings.toString('utf8')
+ } else {
+ strings = strings.join('')
+ }
+ return strings
+}
+
+function bufferConcat (parts) {
+ var bufs = []
+ for (var i = 0; i < parts.length; i++) {
+ var p = parts[i]
+ if (Buffer.isBuffer(p)) {
+ bufs.push(p)
+ } else if (isBufferish(p)) {
+ bufs.push(new Buffer(p))
+ } else {
+ bufs.push(new Buffer(String(p)))
+ }
+ }
+ return Buffer.concat(bufs)
+}
+
+function arrayConcat (parts) {
+ var res = []
+ for (var i = 0; i < parts.length; i++) {
+ res.push.apply(res, parts[i])
+ }
+ return res
+}
+
+function u8Concat (parts) {
+ var len = 0
+ for (var i = 0; i < parts.length; i++) {
+ if (typeof parts[i] === 'string') {
+ parts[i] = new Buffer(parts[i])
+ }
+ len += parts[i].length
+ }
+ var u8 = new U8(len)
+ for (var i = 0, offset = 0; i < parts.length; i++) {
+ var part = parts[i]
+ for (var j = 0; j < part.length; j++) {
+ u8[offset++] = part[j]
+ }
+ }
+ return u8
+}
diff --git a/fril/node_modules/concat-stream/package.json b/fril/node_modules/concat-stream/package.json
new file mode 100644
index 0000000..9fc696a
--- /dev/null
+++ b/fril/node_modules/concat-stream/package.json
@@ -0,0 +1,122 @@
+{
+ "_args": [
+ [
+ {
+ "raw": "concat-stream@~1.5.0",
+ "scope": null,
+ "escapedName": "concat-stream",
+ "name": "concat-stream",
+ "rawSpec": "~1.5.0",
+ "spec": ">=1.5.0 <1.6.0",
+ "type": "range"
+ },
+ "D:\\Workspace\\Dokument\\Skolarbete\\KTH\\Web & Mobile GIS - AG2417\\Project\\dev\\fril\\node_modules\\wellknown"
+ ]
+ ],
+ "_from": "concat-stream@>=1.5.0 <1.6.0",
+ "_id": "concat-stream@1.5.2",
+ "_inCache": true,
+ "_location": "/concat-stream",
+ "_nodeVersion": "4.4.3",
+ "_npmOperationalInternal": {
+ "host": "packages-12-west.internal.npmjs.com",
+ "tmp": "tmp/concat-stream-1.5.2.tgz_1472715196934_0.010375389130786061"
+ },
+ "_npmUser": {
+ "name": "mafintosh",
+ "email": "mathiasbuus@gmail.com"
+ },
+ "_npmVersion": "2.15.9",
+ "_phantomChildren": {},
+ "_requested": {
+ "raw": "concat-stream@~1.5.0",
+ "scope": null,
+ "escapedName": "concat-stream",
+ "name": "concat-stream",
+ "rawSpec": "~1.5.0",
+ "spec": ">=1.5.0 <1.6.0",
+ "type": "range"
+ },
+ "_requiredBy": [
+ "/wellknown"
+ ],
+ "_resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.2.tgz",
+ "_shasum": "708978624d856af41a5a741defdd261da752c266",
+ "_shrinkwrap": null,
+ "_spec": "concat-stream@~1.5.0",
+ "_where": "D:\\Workspace\\Dokument\\Skolarbete\\KTH\\Web & Mobile GIS - AG2417\\Project\\dev\\fril\\node_modules\\wellknown",
+ "author": {
+ "name": "Max Ogden",
+ "email": "max@maxogden.com"
+ },
+ "bugs": {
+ "url": "http://github.com/maxogden/concat-stream/issues"
+ },
+ "dependencies": {
+ "inherits": "~2.0.1",
+ "readable-stream": "~2.0.0",
+ "typedarray": "~0.0.5"
+ },
+ "description": "writable stream that concatenates strings or binary data and calls a callback with the result",
+ "devDependencies": {
+ "tape": "~2.3.2"
+ },
+ "directories": {},
+ "dist": {
+ "shasum": "708978624d856af41a5a741defdd261da752c266",
+ "tarball": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.2.tgz"
+ },
+ "engines": [
+ "node >= 0.8"
+ ],
+ "files": [
+ "index.js"
+ ],
+ "gitHead": "731fedd137eae89d066c249fdca070f8f16afbb8",
+ "homepage": "https://github.com/maxogden/concat-stream#readme",
+ "license": "MIT",
+ "main": "index.js",
+ "maintainers": [
+ {
+ "name": "mafintosh",
+ "email": "mathiasbuus@gmail.com"
+ },
+ {
+ "name": "maxogden",
+ "email": "max@maxogden.com"
+ }
+ ],
+ "name": "concat-stream",
+ "optionalDependencies": {},
+ "readme": "ERROR: No README data found!",
+ "repository": {
+ "type": "git",
+ "url": "git+ssh://git@github.com/maxogden/concat-stream.git"
+ },
+ "scripts": {
+ "test": "tape test/*.js test/server/*.js"
+ },
+ "tags": [
+ "stream",
+ "simple",
+ "util",
+ "utility"
+ ],
+ "testling": {
+ "files": "test/*.js",
+ "browsers": [
+ "ie/8..latest",
+ "firefox/17..latest",
+ "firefox/nightly",
+ "chrome/22..latest",
+ "chrome/canary",
+ "opera/12..latest",
+ "opera/next",
+ "safari/5.1..latest",
+ "ipad/6.0..latest",
+ "iphone/6.0..latest",
+ "android-browser/4.2..latest"
+ ]
+ },
+ "version": "1.5.2"
+}
diff --git a/fril/node_modules/concat-stream/readme.md b/fril/node_modules/concat-stream/readme.md
new file mode 100644
index 0000000..8ad4197
--- /dev/null
+++ b/fril/node_modules/concat-stream/readme.md
@@ -0,0 +1,102 @@
+# concat-stream
+
+Writable stream that concatenates all the data from a stream and calls a callback with the result. Use this when you want to collect all the data from a stream into a single buffer.
+
+[](https://travis-ci.org/maxogden/concat-stream)
+
+[](https://nodei.co/npm/concat-stream/)
+
+### description
+
+Streams emit many buffers. If you want to collect all of the buffers, and when the stream ends concatenate all of the buffers together and receive a single buffer then this is the module for you.
+
+Only use this if you know you can fit all of the output of your stream into a single Buffer (e.g. in RAM).
+
+There are also `objectMode` streams that emit things other than Buffers, and you can concatenate these too. See below for details.
+
+## Related
+
+`stream-each` is part of the [mississippi stream utility collection](https://github.com/maxogden/mississippi) which includes more useful stream modules similar to this one.
+
+### examples
+
+#### Buffers
+
+```js
+var fs = require('fs')
+var concat = require('concat-stream')
+
+var readStream = fs.createReadStream('cat.png')
+var concatStream = concat(gotPicture)
+
+readStream.on('error', handleError)
+readStream.pipe(concatStream)
+
+function gotPicture(imageBuffer) {
+ // imageBuffer is all of `cat.png` as a node.js Buffer
+}
+
+function handleError(err) {
+ // handle your error appropriately here, e.g.:
+ console.error(err) // print the error to STDERR
+ process.exit(1) // exit program with non-zero exit code
+}
+
+```
+
+#### Arrays
+
+```js
+var write = concat(function(data) {})
+write.write([1,2,3])
+write.write([4,5,6])
+write.end()
+// data will be [1,2,3,4,5,6] in the above callback
+```
+
+#### Uint8Arrays
+
+```js
+var write = concat(function(data) {})
+var a = new Uint8Array(3)
+a[0] = 97; a[1] = 98; a[2] = 99
+write.write(a)
+write.write('!')
+write.end(Buffer('!!1'))
+```
+
+See `test/` for more examples
+
+# methods
+
+```js
+var concat = require('concat-stream')
+```
+
+## var writable = concat(opts={}, cb)
+
+Return a `writable` stream that will fire `cb(data)` with all of the data that
+was written to the stream. Data can be written to `writable` as strings,
+Buffers, arrays of byte integers, and Uint8Arrays.
+
+By default `concat-stream` will give you back the same data type as the type of the first buffer written to the stream. Use `opts.encoding` to set what format `data` should be returned as, e.g. if you if you don't want to rely on the built-in type checking or for some other reason.
+
+* `string` - get a string
+* `buffer` - get back a Buffer
+* `array` - get an array of byte integers
+* `uint8array`, `u8`, `uint8` - get back a Uint8Array
+* `object`, get back an array of Objects
+
+If you don't specify an encoding, and the types can't be inferred (e.g. you write things that aren't in the list above), it will try to convert concat them into a `Buffer`.
+
+If nothing is written to `writable` then `data` will be an empty array `[]`.
+
+# error handling
+
+`concat-stream` does not handle errors for you, so you must handle errors on whatever streams you pipe into `concat-stream`. This is a general rule when programming with node.js streams: always handle errors on each and every stream. Since `concat-stream` is not itself a stream it does not emit errors.
+
+We recommend using [`end-of-stream`](https://npmjs.org/end-of-stream) or [`pump`](https://npmjs.org/pump) for writing error tolerant stream code.
+
+# license
+
+MIT LICENSE
diff --git a/fril/node_modules/core-util-is/LICENSE b/fril/node_modules/core-util-is/LICENSE
new file mode 100644
index 0000000..d8d7f94
--- /dev/null
+++ b/fril/node_modules/core-util-is/LICENSE
@@ -0,0 +1,19 @@
+Copyright Node.js contributors. All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
diff --git a/fril/node_modules/core-util-is/README.md b/fril/node_modules/core-util-is/README.md
new file mode 100644
index 0000000..5a76b41
--- /dev/null
+++ b/fril/node_modules/core-util-is/README.md
@@ -0,0 +1,3 @@
+# core-util-is
+
+The `util.is*` functions introduced in Node v0.12.
diff --git a/fril/node_modules/core-util-is/float.patch b/fril/node_modules/core-util-is/float.patch
new file mode 100644
index 0000000..a06d5c0
--- /dev/null
+++ b/fril/node_modules/core-util-is/float.patch
@@ -0,0 +1,604 @@
+diff --git a/lib/util.js b/lib/util.js
+index a03e874..9074e8e 100644
+--- a/lib/util.js
++++ b/lib/util.js
+@@ -19,430 +19,6 @@
+ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ // USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+-var formatRegExp = /%[sdj%]/g;
+-exports.format = function(f) {
+- if (!isString(f)) {
+- var objects = [];
+- for (var i = 0; i < arguments.length; i++) {
+- objects.push(inspect(arguments[i]));
+- }
+- return objects.join(' ');
+- }
+-
+- var i = 1;
+- var args = arguments;
+- var len = args.length;
+- var str = String(f).replace(formatRegExp, function(x) {
+- if (x === '%%') return '%';
+- if (i >= len) return x;
+- switch (x) {
+- case '%s': return String(args[i++]);
+- case '%d': return Number(args[i++]);
+- case '%j':
+- try {
+- return JSON.stringify(args[i++]);
+- } catch (_) {
+- return '[Circular]';
+- }
+- default:
+- return x;
+- }
+- });
+- for (var x = args[i]; i < len; x = args[++i]) {
+- if (isNull(x) || !isObject(x)) {
+- str += ' ' + x;
+- } else {
+- str += ' ' + inspect(x);
+- }
+- }
+- return str;
+-};
+-
+-
+-// Mark that a method should not be used.
+-// Returns a modified function which warns once by default.
+-// If --no-deprecation is set, then it is a no-op.
+-exports.deprecate = function(fn, msg) {
+- // Allow for deprecating things in the process of starting up.
+- if (isUndefined(global.process)) {
+- return function() {
+- return exports.deprecate(fn, msg).apply(this, arguments);
+- };
+- }
+-
+- if (process.noDeprecation === true) {
+- return fn;
+- }
+-
+- var warned = false;
+- function deprecated() {
+- if (!warned) {
+- if (process.throwDeprecation) {
+- throw new Error(msg);
+- } else if (process.traceDeprecation) {
+- console.trace(msg);
+- } else {
+- console.error(msg);
+- }
+- warned = true;
+- }
+- return fn.apply(this, arguments);
+- }
+-
+- return deprecated;
+-};
+-
+-
+-var debugs = {};
+-var debugEnviron;
+-exports.debuglog = function(set) {
+- if (isUndefined(debugEnviron))
+- debugEnviron = process.env.NODE_DEBUG || '';
+- set = set.toUpperCase();
+- if (!debugs[set]) {
+- if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
+- var pid = process.pid;
+- debugs[set] = function() {
+- var msg = exports.format.apply(exports, arguments);
+- console.error('%s %d: %s', set, pid, msg);
+- };
+- } else {
+- debugs[set] = function() {};
+- }
+- }
+- return debugs[set];
+-};
+-
+-
+-/**
+- * Echos the value of a value. Trys to print the value out
+- * in the best way possible given the different types.
+- *
+- * @param {Object} obj The object to print out.
+- * @param {Object} opts Optional options object that alters the output.
+- */
+-/* legacy: obj, showHidden, depth, colors*/
+-function inspect(obj, opts) {
+- // default options
+- var ctx = {
+- seen: [],
+- stylize: stylizeNoColor
+- };
+- // legacy...
+- if (arguments.length >= 3) ctx.depth = arguments[2];
+- if (arguments.length >= 4) ctx.colors = arguments[3];
+- if (isBoolean(opts)) {
+- // legacy...
+- ctx.showHidden = opts;
+- } else if (opts) {
+- // got an "options" object
+- exports._extend(ctx, opts);
+- }
+- // set default options
+- if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
+- if (isUndefined(ctx.depth)) ctx.depth = 2;
+- if (isUndefined(ctx.colors)) ctx.colors = false;
+- if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
+- if (ctx.colors) ctx.stylize = stylizeWithColor;
+- return formatValue(ctx, obj, ctx.depth);
+-}
+-exports.inspect = inspect;
+-
+-
+-// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
+-inspect.colors = {
+- 'bold' : [1, 22],
+- 'italic' : [3, 23],
+- 'underline' : [4, 24],
+- 'inverse' : [7, 27],
+- 'white' : [37, 39],
+- 'grey' : [90, 39],
+- 'black' : [30, 39],
+- 'blue' : [34, 39],
+- 'cyan' : [36, 39],
+- 'green' : [32, 39],
+- 'magenta' : [35, 39],
+- 'red' : [31, 39],
+- 'yellow' : [33, 39]
+-};
+-
+-// Don't use 'blue' not visible on cmd.exe
+-inspect.styles = {
+- 'special': 'cyan',
+- 'number': 'yellow',
+- 'boolean': 'yellow',
+- 'undefined': 'grey',
+- 'null': 'bold',
+- 'string': 'green',
+- 'date': 'magenta',
+- // "name": intentionally not styling
+- 'regexp': 'red'
+-};
+-
+-
+-function stylizeWithColor(str, styleType) {
+- var style = inspect.styles[styleType];
+-
+- if (style) {
+- return '\u001b[' + inspect.colors[style][0] + 'm' + str +
+- '\u001b[' + inspect.colors[style][1] + 'm';
+- } else {
+- return str;
+- }
+-}
+-
+-
+-function stylizeNoColor(str, styleType) {
+- return str;
+-}
+-
+-
+-function arrayToHash(array) {
+- var hash = {};
+-
+- array.forEach(function(val, idx) {
+- hash[val] = true;
+- });
+-
+- return hash;
+-}
+-
+-
+-function formatValue(ctx, value, recurseTimes) {
+- // Provide a hook for user-specified inspect functions.
+- // Check that value is an object with an inspect function on it
+- if (ctx.customInspect &&
+- value &&
+- isFunction(value.inspect) &&
+- // Filter out the util module, it's inspect function is special
+- value.inspect !== exports.inspect &&
+- // Also filter out any prototype objects using the circular check.
+- !(value.constructor && value.constructor.prototype === value)) {
+- var ret = value.inspect(recurseTimes, ctx);
+- if (!isString(ret)) {
+- ret = formatValue(ctx, ret, recurseTimes);
+- }
+- return ret;
+- }
+-
+- // Primitive types cannot have properties
+- var primitive = formatPrimitive(ctx, value);
+- if (primitive) {
+- return primitive;
+- }
+-
+- // Look up the keys of the object.
+- var keys = Object.keys(value);
+- var visibleKeys = arrayToHash(keys);
+-
+- if (ctx.showHidden) {
+- keys = Object.getOwnPropertyNames(value);
+- }
+-
+- // Some type of object without properties can be shortcutted.
+- if (keys.length === 0) {
+- if (isFunction(value)) {
+- var name = value.name ? ': ' + value.name : '';
+- return ctx.stylize('[Function' + name + ']', 'special');
+- }
+- if (isRegExp(value)) {
+- return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
+- }
+- if (isDate(value)) {
+- return ctx.stylize(Date.prototype.toString.call(value), 'date');
+- }
+- if (isError(value)) {
+- return formatError(value);
+- }
+- }
+-
+- var base = '', array = false, braces = ['{', '}'];
+-
+- // Make Array say that they are Array
+- if (isArray(value)) {
+- array = true;
+- braces = ['[', ']'];
+- }
+-
+- // Make functions say that they are functions
+- if (isFunction(value)) {
+- var n = value.name ? ': ' + value.name : '';
+- base = ' [Function' + n + ']';
+- }
+-
+- // Make RegExps say that they are RegExps
+- if (isRegExp(value)) {
+- base = ' ' + RegExp.prototype.toString.call(value);
+- }
+-
+- // Make dates with properties first say the date
+- if (isDate(value)) {
+- base = ' ' + Date.prototype.toUTCString.call(value);
+- }
+-
+- // Make error with message first say the error
+- if (isError(value)) {
+- base = ' ' + formatError(value);
+- }
+-
+- if (keys.length === 0 && (!array || value.length == 0)) {
+- return braces[0] + base + braces[1];
+- }
+-
+- if (recurseTimes < 0) {
+- if (isRegExp(value)) {
+- return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
+- } else {
+- return ctx.stylize('[Object]', 'special');
+- }
+- }
+-
+- ctx.seen.push(value);
+-
+- var output;
+- if (array) {
+- output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
+- } else {
+- output = keys.map(function(key) {
+- return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
+- });
+- }
+-
+- ctx.seen.pop();
+-
+- return reduceToSingleString(output, base, braces);
+-}
+-
+-
+-function formatPrimitive(ctx, value) {
+- if (isUndefined(value))
+- return ctx.stylize('undefined', 'undefined');
+- if (isString(value)) {
+- var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
+- .replace(/'/g, "\\'")
+- .replace(/\\"/g, '"') + '\'';
+- return ctx.stylize(simple, 'string');
+- }
+- if (isNumber(value)) {
+- // Format -0 as '-0'. Strict equality won't distinguish 0 from -0,
+- // so instead we use the fact that 1 / -0 < 0 whereas 1 / 0 > 0 .
+- if (value === 0 && 1 / value < 0)
+- return ctx.stylize('-0', 'number');
+- return ctx.stylize('' + value, 'number');
+- }
+- if (isBoolean(value))
+- return ctx.stylize('' + value, 'boolean');
+- // For some reason typeof null is "object", so special case here.
+- if (isNull(value))
+- return ctx.stylize('null', 'null');
+-}
+-
+-
+-function formatError(value) {
+- return '[' + Error.prototype.toString.call(value) + ']';
+-}
+-
+-
+-function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
+- var output = [];
+- for (var i = 0, l = value.length; i < l; ++i) {
+- if (hasOwnProperty(value, String(i))) {
+- output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
+- String(i), true));
+- } else {
+- output.push('');
+- }
+- }
+- keys.forEach(function(key) {
+- if (!key.match(/^\d+$/)) {
+- output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
+- key, true));
+- }
+- });
+- return output;
+-}
+-
+-
+-function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
+- var name, str, desc;
+- desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
+- if (desc.get) {
+- if (desc.set) {
+- str = ctx.stylize('[Getter/Setter]', 'special');
+- } else {
+- str = ctx.stylize('[Getter]', 'special');
+- }
+- } else {
+- if (desc.set) {
+- str = ctx.stylize('[Setter]', 'special');
+- }
+- }
+- if (!hasOwnProperty(visibleKeys, key)) {
+- name = '[' + key + ']';
+- }
+- if (!str) {
+- if (ctx.seen.indexOf(desc.value) < 0) {
+- if (isNull(recurseTimes)) {
+- str = formatValue(ctx, desc.value, null);
+- } else {
+- str = formatValue(ctx, desc.value, recurseTimes - 1);
+- }
+- if (str.indexOf('\n') > -1) {
+- if (array) {
+- str = str.split('\n').map(function(line) {
+- return ' ' + line;
+- }).join('\n').substr(2);
+- } else {
+- str = '\n' + str.split('\n').map(function(line) {
+- return ' ' + line;
+- }).join('\n');
+- }
+- }
+- } else {
+- str = ctx.stylize('[Circular]', 'special');
+- }
+- }
+- if (isUndefined(name)) {
+- if (array && key.match(/^\d+$/)) {
+- return str;
+- }
+- name = JSON.stringify('' + key);
+- if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
+- name = name.substr(1, name.length - 2);
+- name = ctx.stylize(name, 'name');
+- } else {
+- name = name.replace(/'/g, "\\'")
+- .replace(/\\"/g, '"')
+- .replace(/(^"|"$)/g, "'");
+- name = ctx.stylize(name, 'string');
+- }
+- }
+-
+- return name + ': ' + str;
+-}
+-
+-
+-function reduceToSingleString(output, base, braces) {
+- var numLinesEst = 0;
+- var length = output.reduce(function(prev, cur) {
+- numLinesEst++;
+- if (cur.indexOf('\n') >= 0) numLinesEst++;
+- return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
+- }, 0);
+-
+- if (length > 60) {
+- return braces[0] +
+- (base === '' ? '' : base + '\n ') +
+- ' ' +
+- output.join(',\n ') +
+- ' ' +
+- braces[1];
+- }
+-
+- return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
+-}
+-
+-
+ // NOTE: These type checking functions intentionally don't use `instanceof`
+ // because it is fragile and can be easily faked with `Object.create()`.
+ function isArray(ar) {
+@@ -522,166 +98,10 @@ function isPrimitive(arg) {
+ exports.isPrimitive = isPrimitive;
+
+ function isBuffer(arg) {
+- return arg instanceof Buffer;
++ return Buffer.isBuffer(arg);
+ }
+ exports.isBuffer = isBuffer;
+
+ function objectToString(o) {
+ return Object.prototype.toString.call(o);
+-}
+-
+-
+-function pad(n) {
+- return n < 10 ? '0' + n.toString(10) : n.toString(10);
+-}
+-
+-
+-var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
+- 'Oct', 'Nov', 'Dec'];
+-
+-// 26 Feb 16:19:34
+-function timestamp() {
+- var d = new Date();
+- var time = [pad(d.getHours()),
+- pad(d.getMinutes()),
+- pad(d.getSeconds())].join(':');
+- return [d.getDate(), months[d.getMonth()], time].join(' ');
+-}
+-
+-
+-// log is just a thin wrapper to console.log that prepends a timestamp
+-exports.log = function() {
+- console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
+-};
+-
+-
+-/**
+- * Inherit the prototype methods from one constructor into another.
+- *
+- * The Function.prototype.inherits from lang.js rewritten as a standalone
+- * function (not on Function.prototype). NOTE: If this file is to be loaded
+- * during bootstrapping this function needs to be rewritten using some native
+- * functions as prototype setup using normal JavaScript does not work as
+- * expected during bootstrapping (see mirror.js in r114903).
+- *
+- * @param {function} ctor Constructor function which needs to inherit the
+- * prototype.
+- * @param {function} superCtor Constructor function to inherit prototype from.
+- */
+-exports.inherits = function(ctor, superCtor) {
+- ctor.super_ = superCtor;
+- ctor.prototype = Object.create(superCtor.prototype, {
+- constructor: {
+- value: ctor,
+- enumerable: false,
+- writable: true,
+- configurable: true
+- }
+- });
+-};
+-
+-exports._extend = function(origin, add) {
+- // Don't do anything if add isn't an object
+- if (!add || !isObject(add)) return origin;
+-
+- var keys = Object.keys(add);
+- var i = keys.length;
+- while (i--) {
+- origin[keys[i]] = add[keys[i]];
+- }
+- return origin;
+-};
+-
+-function hasOwnProperty(obj, prop) {
+- return Object.prototype.hasOwnProperty.call(obj, prop);
+-}
+-
+-
+-// Deprecated old stuff.
+-
+-exports.p = exports.deprecate(function() {
+- for (var i = 0, len = arguments.length; i < len; ++i) {
+- console.error(exports.inspect(arguments[i]));
+- }
+-}, 'util.p: Use console.error() instead');
+-
+-
+-exports.exec = exports.deprecate(function() {
+- return require('child_process').exec.apply(this, arguments);
+-}, 'util.exec is now called `child_process.exec`.');
+-
+-
+-exports.print = exports.deprecate(function() {
+- for (var i = 0, len = arguments.length; i < len; ++i) {
+- process.stdout.write(String(arguments[i]));
+- }
+-}, 'util.print: Use console.log instead');
+-
+-
+-exports.puts = exports.deprecate(function() {
+- for (var i = 0, len = arguments.length; i < len; ++i) {
+- process.stdout.write(arguments[i] + '\n');
+- }
+-}, 'util.puts: Use console.log instead');
+-
+-
+-exports.debug = exports.deprecate(function(x) {
+- process.stderr.write('DEBUG: ' + x + '\n');
+-}, 'util.debug: Use console.error instead');
+-
+-
+-exports.error = exports.deprecate(function(x) {
+- for (var i = 0, len = arguments.length; i < len; ++i) {
+- process.stderr.write(arguments[i] + '\n');
+- }
+-}, 'util.error: Use console.error instead');
+-
+-
+-exports.pump = exports.deprecate(function(readStream, writeStream, callback) {
+- var callbackCalled = false;
+-
+- function call(a, b, c) {
+- if (callback && !callbackCalled) {
+- callback(a, b, c);
+- callbackCalled = true;
+- }
+- }
+-
+- readStream.addListener('data', function(chunk) {
+- if (writeStream.write(chunk) === false) readStream.pause();
+- });
+-
+- writeStream.addListener('drain', function() {
+- readStream.resume();
+- });
+-
+- readStream.addListener('end', function() {
+- writeStream.end();
+- });
+-
+- readStream.addListener('close', function() {
+- call();
+- });
+-
+- readStream.addListener('error', function(err) {
+- writeStream.end();
+- call(err);
+- });
+-
+- writeStream.addListener('error', function(err) {
+- readStream.destroy();
+- call(err);
+- });
+-}, 'util.pump(): Use readableStream.pipe() instead');
+-
+-
+-var uv;
+-exports._errnoException = function(err, syscall) {
+- if (isUndefined(uv)) uv = process.binding('uv');
+- var errname = uv.errname(err);
+- var e = new Error(syscall + ' ' + errname);
+- e.code = errname;
+- e.errno = errname;
+- e.syscall = syscall;
+- return e;
+-};
++}
\ No newline at end of file
diff --git a/fril/node_modules/core-util-is/lib/util.js b/fril/node_modules/core-util-is/lib/util.js
new file mode 100644
index 0000000..ff4c851
--- /dev/null
+++ b/fril/node_modules/core-util-is/lib/util.js
@@ -0,0 +1,107 @@
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// NOTE: These type checking functions intentionally don't use `instanceof`
+// because it is fragile and can be easily faked with `Object.create()`.
+
+function isArray(arg) {
+ if (Array.isArray) {
+ return Array.isArray(arg);
+ }
+ return objectToString(arg) === '[object Array]';
+}
+exports.isArray = isArray;
+
+function isBoolean(arg) {
+ return typeof arg === 'boolean';
+}
+exports.isBoolean = isBoolean;
+
+function isNull(arg) {
+ return arg === null;
+}
+exports.isNull = isNull;
+
+function isNullOrUndefined(arg) {
+ return arg == null;
+}
+exports.isNullOrUndefined = isNullOrUndefined;
+
+function isNumber(arg) {
+ return typeof arg === 'number';
+}
+exports.isNumber = isNumber;
+
+function isString(arg) {
+ return typeof arg === 'string';
+}
+exports.isString = isString;
+
+function isSymbol(arg) {
+ return typeof arg === 'symbol';
+}
+exports.isSymbol = isSymbol;
+
+function isUndefined(arg) {
+ return arg === void 0;
+}
+exports.isUndefined = isUndefined;
+
+function isRegExp(re) {
+ return objectToString(re) === '[object RegExp]';
+}
+exports.isRegExp = isRegExp;
+
+function isObject(arg) {
+ return typeof arg === 'object' && arg !== null;
+}
+exports.isObject = isObject;
+
+function isDate(d) {
+ return objectToString(d) === '[object Date]';
+}
+exports.isDate = isDate;
+
+function isError(e) {
+ return (objectToString(e) === '[object Error]' || e instanceof Error);
+}
+exports.isError = isError;
+
+function isFunction(arg) {
+ return typeof arg === 'function';
+}
+exports.isFunction = isFunction;
+
+function isPrimitive(arg) {
+ return arg === null ||
+ typeof arg === 'boolean' ||
+ typeof arg === 'number' ||
+ typeof arg === 'string' ||
+ typeof arg === 'symbol' || // ES6 symbol
+ typeof arg === 'undefined';
+}
+exports.isPrimitive = isPrimitive;
+
+exports.isBuffer = Buffer.isBuffer;
+
+function objectToString(o) {
+ return Object.prototype.toString.call(o);
+}
diff --git a/fril/node_modules/core-util-is/package.json b/fril/node_modules/core-util-is/package.json
new file mode 100644
index 0000000..91ff191
--- /dev/null
+++ b/fril/node_modules/core-util-is/package.json
@@ -0,0 +1,94 @@
+{
+ "_args": [
+ [
+ {
+ "raw": "core-util-is@~1.0.0",
+ "scope": null,
+ "escapedName": "core-util-is",
+ "name": "core-util-is",
+ "rawSpec": "~1.0.0",
+ "spec": ">=1.0.0 <1.1.0",
+ "type": "range"
+ },
+ "D:\\Workspace\\Dokument\\Skolarbete\\KTH\\Web & Mobile GIS - AG2417\\Project\\dev\\fril\\node_modules\\readable-stream"
+ ]
+ ],
+ "_from": "core-util-is@>=1.0.0 <1.1.0",
+ "_id": "core-util-is@1.0.2",
+ "_inCache": true,
+ "_location": "/core-util-is",
+ "_nodeVersion": "4.0.0",
+ "_npmUser": {
+ "name": "isaacs",
+ "email": "i@izs.me"
+ },
+ "_npmVersion": "3.3.2",
+ "_phantomChildren": {},
+ "_requested": {
+ "raw": "core-util-is@~1.0.0",
+ "scope": null,
+ "escapedName": "core-util-is",
+ "name": "core-util-is",
+ "rawSpec": "~1.0.0",
+ "spec": ">=1.0.0 <1.1.0",
+ "type": "range"
+ },
+ "_requiredBy": [
+ "/readable-stream"
+ ],
+ "_resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "_shasum": "b5fd54220aa2bc5ab57aab7140c940754503c1a7",
+ "_shrinkwrap": null,
+ "_spec": "core-util-is@~1.0.0",
+ "_where": "D:\\Workspace\\Dokument\\Skolarbete\\KTH\\Web & Mobile GIS - AG2417\\Project\\dev\\fril\\node_modules\\readable-stream",
+ "author": {
+ "name": "Isaac Z. Schlueter",
+ "email": "i@izs.me",
+ "url": "http://blog.izs.me/"
+ },
+ "bugs": {
+ "url": "https://github.com/isaacs/core-util-is/issues"
+ },
+ "dependencies": {},
+ "description": "The `util.is*` functions introduced in Node v0.12.",
+ "devDependencies": {
+ "tap": "^2.3.0"
+ },
+ "directories": {},
+ "dist": {
+ "shasum": "b5fd54220aa2bc5ab57aab7140c940754503c1a7",
+ "tarball": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz"
+ },
+ "gitHead": "a177da234df5638b363ddc15fa324619a38577c8",
+ "homepage": "https://github.com/isaacs/core-util-is#readme",
+ "keywords": [
+ "util",
+ "isBuffer",
+ "isArray",
+ "isNumber",
+ "isString",
+ "isRegExp",
+ "isThis",
+ "isThat",
+ "polyfill"
+ ],
+ "license": "MIT",
+ "main": "lib/util.js",
+ "maintainers": [
+ {
+ "name": "isaacs",
+ "email": "i@izs.me"
+ }
+ ],
+ "name": "core-util-is",
+ "optionalDependencies": {},
+ "readme": "ERROR: No README data found!",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/isaacs/core-util-is.git"
+ },
+ "scripts": {
+ "test": "tap test.js"
+ },
+ "version": "1.0.2"
+}
diff --git a/fril/node_modules/core-util-is/test.js b/fril/node_modules/core-util-is/test.js
new file mode 100644
index 0000000..1a490c6
--- /dev/null
+++ b/fril/node_modules/core-util-is/test.js
@@ -0,0 +1,68 @@
+var assert = require('tap');
+
+var t = require('./lib/util');
+
+assert.equal(t.isArray([]), true);
+assert.equal(t.isArray({}), false);
+
+assert.equal(t.isBoolean(null), false);
+assert.equal(t.isBoolean(true), true);
+assert.equal(t.isBoolean(false), true);
+
+assert.equal(t.isNull(null), true);
+assert.equal(t.isNull(undefined), false);
+assert.equal(t.isNull(false), false);
+assert.equal(t.isNull(), false);
+
+assert.equal(t.isNullOrUndefined(null), true);
+assert.equal(t.isNullOrUndefined(undefined), true);
+assert.equal(t.isNullOrUndefined(false), false);
+assert.equal(t.isNullOrUndefined(), true);
+
+assert.equal(t.isNumber(null), false);
+assert.equal(t.isNumber('1'), false);
+assert.equal(t.isNumber(1), true);
+
+assert.equal(t.isString(null), false);
+assert.equal(t.isString('1'), true);
+assert.equal(t.isString(1), false);
+
+assert.equal(t.isSymbol(null), false);
+assert.equal(t.isSymbol('1'), false);
+assert.equal(t.isSymbol(1), false);
+assert.equal(t.isSymbol(Symbol()), true);
+
+assert.equal(t.isUndefined(null), false);
+assert.equal(t.isUndefined(undefined), true);
+assert.equal(t.isUndefined(false), false);
+assert.equal(t.isUndefined(), true);
+
+assert.equal(t.isRegExp(null), false);
+assert.equal(t.isRegExp('1'), false);
+assert.equal(t.isRegExp(new RegExp()), true);
+
+assert.equal(t.isObject({}), true);
+assert.equal(t.isObject([]), true);
+assert.equal(t.isObject(new RegExp()), true);
+assert.equal(t.isObject(new Date()), true);
+
+assert.equal(t.isDate(null), false);
+assert.equal(t.isDate('1'), false);
+assert.equal(t.isDate(new Date()), true);
+
+assert.equal(t.isError(null), false);
+assert.equal(t.isError({ err: true }), false);
+assert.equal(t.isError(new Error()), true);
+
+assert.equal(t.isFunction(null), false);
+assert.equal(t.isFunction({ }), false);
+assert.equal(t.isFunction(function() {}), true);
+
+assert.equal(t.isPrimitive(null), true);
+assert.equal(t.isPrimitive(''), true);
+assert.equal(t.isPrimitive(0), true);
+assert.equal(t.isPrimitive(new Date()), false);
+
+assert.equal(t.isBuffer(null), false);
+assert.equal(t.isBuffer({}), false);
+assert.equal(t.isBuffer(new Buffer(0)), true);
diff --git a/fril/node_modules/isarray/.npmignore b/fril/node_modules/isarray/.npmignore
new file mode 100644
index 0000000..3c3629e
--- /dev/null
+++ b/fril/node_modules/isarray/.npmignore
@@ -0,0 +1 @@
+node_modules
diff --git a/fril/node_modules/isarray/.travis.yml b/fril/node_modules/isarray/.travis.yml
new file mode 100644
index 0000000..cc4dba2
--- /dev/null
+++ b/fril/node_modules/isarray/.travis.yml
@@ -0,0 +1,4 @@
+language: node_js
+node_js:
+ - "0.8"
+ - "0.10"
diff --git a/fril/node_modules/isarray/Makefile b/fril/node_modules/isarray/Makefile
new file mode 100644
index 0000000..787d56e
--- /dev/null
+++ b/fril/node_modules/isarray/Makefile
@@ -0,0 +1,6 @@
+
+test:
+ @node_modules/.bin/tape test.js
+
+.PHONY: test
+
diff --git a/fril/node_modules/isarray/README.md b/fril/node_modules/isarray/README.md
new file mode 100644
index 0000000..16d2c59
--- /dev/null
+++ b/fril/node_modules/isarray/README.md
@@ -0,0 +1,60 @@
+
+# isarray
+
+`Array#isArray` for older browsers.
+
+[](http://travis-ci.org/juliangruber/isarray)
+[](https://www.npmjs.org/package/isarray)
+
+[
+](https://ci.testling.com/juliangruber/isarray)
+
+## Usage
+
+```js
+var isArray = require('isarray');
+
+console.log(isArray([])); // => true
+console.log(isArray({})); // => false
+```
+
+## Installation
+
+With [npm](http://npmjs.org) do
+
+```bash
+$ npm install isarray
+```
+
+Then bundle for the browser with
+[browserify](https://github.com/substack/browserify).
+
+With [component](http://component.io) do
+
+```bash
+$ component install juliangruber/isarray
+```
+
+## License
+
+(MIT)
+
+Copyright (c) 2013 Julian Gruber <julian@juliangruber.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/fril/node_modules/isarray/component.json b/fril/node_modules/isarray/component.json
new file mode 100644
index 0000000..9e31b68
--- /dev/null
+++ b/fril/node_modules/isarray/component.json
@@ -0,0 +1,19 @@
+{
+ "name" : "isarray",
+ "description" : "Array#isArray for older browsers",
+ "version" : "0.0.1",
+ "repository" : "juliangruber/isarray",
+ "homepage": "https://github.com/juliangruber/isarray",
+ "main" : "index.js",
+ "scripts" : [
+ "index.js"
+ ],
+ "dependencies" : {},
+ "keywords": ["browser","isarray","array"],
+ "author": {
+ "name": "Julian Gruber",
+ "email": "mail@juliangruber.com",
+ "url": "http://juliangruber.com"
+ },
+ "license": "MIT"
+}
diff --git a/fril/node_modules/isarray/index.js b/fril/node_modules/isarray/index.js
new file mode 100644
index 0000000..a57f634
--- /dev/null
+++ b/fril/node_modules/isarray/index.js
@@ -0,0 +1,5 @@
+var toString = {}.toString;
+
+module.exports = Array.isArray || function (arr) {
+ return toString.call(arr) == '[object Array]';
+};
diff --git a/fril/node_modules/isarray/package.json b/fril/node_modules/isarray/package.json
new file mode 100644
index 0000000..6f044c7
--- /dev/null
+++ b/fril/node_modules/isarray/package.json
@@ -0,0 +1,104 @@
+{
+ "_args": [
+ [
+ {
+ "raw": "isarray@~1.0.0",
+ "scope": null,
+ "escapedName": "isarray",
+ "name": "isarray",
+ "rawSpec": "~1.0.0",
+ "spec": ">=1.0.0 <1.1.0",
+ "type": "range"
+ },
+ "D:\\Workspace\\Dokument\\Skolarbete\\KTH\\Web & Mobile GIS - AG2417\\Project\\dev\\fril\\node_modules\\readable-stream"
+ ]
+ ],
+ "_from": "isarray@>=1.0.0 <1.1.0",
+ "_id": "isarray@1.0.0",
+ "_inCache": true,
+ "_location": "/isarray",
+ "_nodeVersion": "5.1.0",
+ "_npmUser": {
+ "name": "juliangruber",
+ "email": "julian@juliangruber.com"
+ },
+ "_npmVersion": "3.3.12",
+ "_phantomChildren": {},
+ "_requested": {
+ "raw": "isarray@~1.0.0",
+ "scope": null,
+ "escapedName": "isarray",
+ "name": "isarray",
+ "rawSpec": "~1.0.0",
+ "spec": ">=1.0.0 <1.1.0",
+ "type": "range"
+ },
+ "_requiredBy": [
+ "/readable-stream"
+ ],
+ "_resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "_shasum": "bb935d48582cba168c06834957a54a3e07124f11",
+ "_shrinkwrap": null,
+ "_spec": "isarray@~1.0.0",
+ "_where": "D:\\Workspace\\Dokument\\Skolarbete\\KTH\\Web & Mobile GIS - AG2417\\Project\\dev\\fril\\node_modules\\readable-stream",
+ "author": {
+ "name": "Julian Gruber",
+ "email": "mail@juliangruber.com",
+ "url": "http://juliangruber.com"
+ },
+ "bugs": {
+ "url": "https://github.com/juliangruber/isarray/issues"
+ },
+ "dependencies": {},
+ "description": "Array#isArray for older browsers",
+ "devDependencies": {
+ "tape": "~2.13.4"
+ },
+ "directories": {},
+ "dist": {
+ "shasum": "bb935d48582cba168c06834957a54a3e07124f11",
+ "tarball": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz"
+ },
+ "gitHead": "2a23a281f369e9ae06394c0fb4d2381355a6ba33",
+ "homepage": "https://github.com/juliangruber/isarray",
+ "keywords": [
+ "browser",
+ "isarray",
+ "array"
+ ],
+ "license": "MIT",
+ "main": "index.js",
+ "maintainers": [
+ {
+ "name": "juliangruber",
+ "email": "julian@juliangruber.com"
+ }
+ ],
+ "name": "isarray",
+ "optionalDependencies": {},
+ "readme": "ERROR: No README data found!",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/juliangruber/isarray.git"
+ },
+ "scripts": {
+ "test": "tape test.js"
+ },
+ "testling": {
+ "files": "test.js",
+ "browsers": [
+ "ie/8..latest",
+ "firefox/17..latest",
+ "firefox/nightly",
+ "chrome/22..latest",
+ "chrome/canary",
+ "opera/12..latest",
+ "opera/next",
+ "safari/5.1..latest",
+ "ipad/6.0..latest",
+ "iphone/6.0..latest",
+ "android-browser/4.2..latest"
+ ]
+ },
+ "version": "1.0.0"
+}
diff --git a/fril/node_modules/isarray/test.js b/fril/node_modules/isarray/test.js
new file mode 100644
index 0000000..e0c3444
--- /dev/null
+++ b/fril/node_modules/isarray/test.js
@@ -0,0 +1,20 @@
+var isArray = require('./');
+var test = require('tape');
+
+test('is array', function(t){
+ t.ok(isArray([]));
+ t.notOk(isArray({}));
+ t.notOk(isArray(null));
+ t.notOk(isArray(false));
+
+ var obj = {};
+ obj[0] = true;
+ t.notOk(isArray(obj));
+
+ var arr = [];
+ arr.foo = 'bar';
+ t.ok(isArray(arr));
+
+ t.end();
+});
+
diff --git a/fril/node_modules/minimist/.travis.yml b/fril/node_modules/minimist/.travis.yml
new file mode 100644
index 0000000..74c57bf
--- /dev/null
+++ b/fril/node_modules/minimist/.travis.yml
@@ -0,0 +1,8 @@
+language: node_js
+node_js:
+ - "0.8"
+ - "0.10"
+ - "0.12"
+ - "iojs"
+before_install:
+ - npm install -g npm@~1.4.6
diff --git a/fril/node_modules/minimist/LICENSE b/fril/node_modules/minimist/LICENSE
new file mode 100644
index 0000000..ee27ba4
--- /dev/null
+++ b/fril/node_modules/minimist/LICENSE
@@ -0,0 +1,18 @@
+This software is released under the MIT license:
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/fril/node_modules/minimist/example/parse.js b/fril/node_modules/minimist/example/parse.js
new file mode 100644
index 0000000..abff3e8
--- /dev/null
+++ b/fril/node_modules/minimist/example/parse.js
@@ -0,0 +1,2 @@
+var argv = require('../')(process.argv.slice(2));
+console.dir(argv);
diff --git a/fril/node_modules/minimist/index.js b/fril/node_modules/minimist/index.js
new file mode 100644
index 0000000..6a0559d
--- /dev/null
+++ b/fril/node_modules/minimist/index.js
@@ -0,0 +1,236 @@
+module.exports = function (args, opts) {
+ if (!opts) opts = {};
+
+ var flags = { bools : {}, strings : {}, unknownFn: null };
+
+ if (typeof opts['unknown'] === 'function') {
+ flags.unknownFn = opts['unknown'];
+ }
+
+ if (typeof opts['boolean'] === 'boolean' && opts['boolean']) {
+ flags.allBools = true;
+ } else {
+ [].concat(opts['boolean']).filter(Boolean).forEach(function (key) {
+ flags.bools[key] = true;
+ });
+ }
+
+ var aliases = {};
+ Object.keys(opts.alias || {}).forEach(function (key) {
+ aliases[key] = [].concat(opts.alias[key]);
+ aliases[key].forEach(function (x) {
+ aliases[x] = [key].concat(aliases[key].filter(function (y) {
+ return x !== y;
+ }));
+ });
+ });
+
+ [].concat(opts.string).filter(Boolean).forEach(function (key) {
+ flags.strings[key] = true;
+ if (aliases[key]) {
+ flags.strings[aliases[key]] = true;
+ }
+ });
+
+ var defaults = opts['default'] || {};
+
+ var argv = { _ : [] };
+ Object.keys(flags.bools).forEach(function (key) {
+ setArg(key, defaults[key] === undefined ? false : defaults[key]);
+ });
+
+ var notFlags = [];
+
+ if (args.indexOf('--') !== -1) {
+ notFlags = args.slice(args.indexOf('--')+1);
+ args = args.slice(0, args.indexOf('--'));
+ }
+
+ function argDefined(key, arg) {
+ return (flags.allBools && /^--[^=]+$/.test(arg)) ||
+ flags.strings[key] || flags.bools[key] || aliases[key];
+ }
+
+ function setArg (key, val, arg) {
+ if (arg && flags.unknownFn && !argDefined(key, arg)) {
+ if (flags.unknownFn(arg) === false) return;
+ }
+
+ var value = !flags.strings[key] && isNumber(val)
+ ? Number(val) : val
+ ;
+ setKey(argv, key.split('.'), value);
+
+ (aliases[key] || []).forEach(function (x) {
+ setKey(argv, x.split('.'), value);
+ });
+ }
+
+ function setKey (obj, keys, value) {
+ var o = obj;
+ keys.slice(0,-1).forEach(function (key) {
+ if (o[key] === undefined) o[key] = {};
+ o = o[key];
+ });
+
+ var key = keys[keys.length - 1];
+ if (o[key] === undefined || flags.bools[key] || typeof o[key] === 'boolean') {
+ o[key] = value;
+ }
+ else if (Array.isArray(o[key])) {
+ o[key].push(value);
+ }
+ else {
+ o[key] = [ o[key], value ];
+ }
+ }
+
+ function aliasIsBoolean(key) {
+ return aliases[key].some(function (x) {
+ return flags.bools[x];
+ });
+ }
+
+ for (var i = 0; i < args.length; i++) {
+ var arg = args[i];
+
+ if (/^--.+=/.test(arg)) {
+ // Using [\s\S] instead of . because js doesn't support the
+ // 'dotall' regex modifier. See:
+ // http://stackoverflow.com/a/1068308/13216
+ var m = arg.match(/^--([^=]+)=([\s\S]*)$/);
+ var key = m[1];
+ var value = m[2];
+ if (flags.bools[key]) {
+ value = value !== 'false';
+ }
+ setArg(key, value, arg);
+ }
+ else if (/^--no-.+/.test(arg)) {
+ var key = arg.match(/^--no-(.+)/)[1];
+ setArg(key, false, arg);
+ }
+ else if (/^--.+/.test(arg)) {
+ var key = arg.match(/^--(.+)/)[1];
+ var next = args[i + 1];
+ if (next !== undefined && !/^-/.test(next)
+ && !flags.bools[key]
+ && !flags.allBools
+ && (aliases[key] ? !aliasIsBoolean(key) : true)) {
+ setArg(key, next, arg);
+ i++;
+ }
+ else if (/^(true|false)$/.test(next)) {
+ setArg(key, next === 'true', arg);
+ i++;
+ }
+ else {
+ setArg(key, flags.strings[key] ? '' : true, arg);
+ }
+ }
+ else if (/^-[^-]+/.test(arg)) {
+ var letters = arg.slice(1,-1).split('');
+
+ var broken = false;
+ for (var j = 0; j < letters.length; j++) {
+ var next = arg.slice(j+2);
+
+ if (next === '-') {
+ setArg(letters[j], next, arg)
+ continue;
+ }
+
+ if (/[A-Za-z]/.test(letters[j]) && /=/.test(next)) {
+ setArg(letters[j], next.split('=')[1], arg);
+ broken = true;
+ break;
+ }
+
+ if (/[A-Za-z]/.test(letters[j])
+ && /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) {
+ setArg(letters[j], next, arg);
+ broken = true;
+ break;
+ }
+
+ if (letters[j+1] && letters[j+1].match(/\W/)) {
+ setArg(letters[j], arg.slice(j+2), arg);
+ broken = true;
+ break;
+ }
+ else {
+ setArg(letters[j], flags.strings[letters[j]] ? '' : true, arg);
+ }
+ }
+
+ var key = arg.slice(-1)[0];
+ if (!broken && key !== '-') {
+ if (args[i+1] && !/^(-|--)[^-]/.test(args[i+1])
+ && !flags.bools[key]
+ && (aliases[key] ? !aliasIsBoolean(key) : true)) {
+ setArg(key, args[i+1], arg);
+ i++;
+ }
+ else if (args[i+1] && /true|false/.test(args[i+1])) {
+ setArg(key, args[i+1] === 'true', arg);
+ i++;
+ }
+ else {
+ setArg(key, flags.strings[key] ? '' : true, arg);
+ }
+ }
+ }
+ else {
+ if (!flags.unknownFn || flags.unknownFn(arg) !== false) {
+ argv._.push(
+ flags.strings['_'] || !isNumber(arg) ? arg : Number(arg)
+ );
+ }
+ if (opts.stopEarly) {
+ argv._.push.apply(argv._, args.slice(i + 1));
+ break;
+ }
+ }
+ }
+
+ Object.keys(defaults).forEach(function (key) {
+ if (!hasKey(argv, key.split('.'))) {
+ setKey(argv, key.split('.'), defaults[key]);
+
+ (aliases[key] || []).forEach(function (x) {
+ setKey(argv, x.split('.'), defaults[key]);
+ });
+ }
+ });
+
+ if (opts['--']) {
+ argv['--'] = new Array();
+ notFlags.forEach(function(key) {
+ argv['--'].push(key);
+ });
+ }
+ else {
+ notFlags.forEach(function(key) {
+ argv._.push(key);
+ });
+ }
+
+ return argv;
+};
+
+function hasKey (obj, keys) {
+ var o = obj;
+ keys.slice(0,-1).forEach(function (key) {
+ o = (o[key] || {});
+ });
+
+ var key = keys[keys.length - 1];
+ return key in o;
+}
+
+function isNumber (x) {
+ if (typeof x === 'number') return true;
+ if (/^0x[0-9a-f]+$/i.test(x)) return true;
+ return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x);
+}
+
diff --git a/fril/node_modules/minimist/package.json b/fril/node_modules/minimist/package.json
new file mode 100644
index 0000000..133394f
--- /dev/null
+++ b/fril/node_modules/minimist/package.json
@@ -0,0 +1,105 @@
+{
+ "_args": [
+ [
+ {
+ "raw": "minimist@~1.2.0",
+ "scope": null,
+ "escapedName": "minimist",
+ "name": "minimist",
+ "rawSpec": "~1.2.0",
+ "spec": ">=1.2.0 <1.3.0",
+ "type": "range"
+ },
+ "D:\\Workspace\\Dokument\\Skolarbete\\KTH\\Web & Mobile GIS - AG2417\\Project\\dev\\fril\\node_modules\\wellknown"
+ ]
+ ],
+ "_from": "minimist@>=1.2.0 <1.3.0",
+ "_id": "minimist@1.2.0",
+ "_inCache": true,
+ "_location": "/minimist",
+ "_nodeVersion": "2.4.0",
+ "_npmUser": {
+ "name": "substack",
+ "email": "substack@gmail.com"
+ },
+ "_npmVersion": "3.2.2",
+ "_phantomChildren": {},
+ "_requested": {
+ "raw": "minimist@~1.2.0",
+ "scope": null,
+ "escapedName": "minimist",
+ "name": "minimist",
+ "rawSpec": "~1.2.0",
+ "spec": ">=1.2.0 <1.3.0",
+ "type": "range"
+ },
+ "_requiredBy": [
+ "/wellknown"
+ ],
+ "_resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "_shasum": "a35008b20f41383eec1fb914f4cd5df79a264284",
+ "_shrinkwrap": null,
+ "_spec": "minimist@~1.2.0",
+ "_where": "D:\\Workspace\\Dokument\\Skolarbete\\KTH\\Web & Mobile GIS - AG2417\\Project\\dev\\fril\\node_modules\\wellknown",
+ "author": {
+ "name": "James Halliday",
+ "email": "mail@substack.net",
+ "url": "http://substack.net"
+ },
+ "bugs": {
+ "url": "https://github.com/substack/minimist/issues"
+ },
+ "dependencies": {},
+ "description": "parse argument options",
+ "devDependencies": {
+ "covert": "^1.0.0",
+ "tap": "~0.4.0",
+ "tape": "^3.5.0"
+ },
+ "directories": {},
+ "dist": {
+ "shasum": "a35008b20f41383eec1fb914f4cd5df79a264284",
+ "tarball": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz"
+ },
+ "gitHead": "dc624482fcfec5bc669c68cdb861f00573ed4e64",
+ "homepage": "https://github.com/substack/minimist",
+ "keywords": [
+ "argv",
+ "getopt",
+ "parser",
+ "optimist"
+ ],
+ "license": "MIT",
+ "main": "index.js",
+ "maintainers": [
+ {
+ "name": "substack",
+ "email": "mail@substack.net"
+ }
+ ],
+ "name": "minimist",
+ "optionalDependencies": {},
+ "readme": "ERROR: No README data found!",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/substack/minimist.git"
+ },
+ "scripts": {
+ "coverage": "covert test/*.js",
+ "test": "tap test/*.js"
+ },
+ "testling": {
+ "files": "test/*.js",
+ "browsers": [
+ "ie/6..latest",
+ "ff/5",
+ "firefox/latest",
+ "chrome/10",
+ "chrome/latest",
+ "safari/5.1",
+ "safari/latest",
+ "opera/12"
+ ]
+ },
+ "version": "1.2.0"
+}
diff --git a/fril/node_modules/minimist/readme.markdown b/fril/node_modules/minimist/readme.markdown
new file mode 100644
index 0000000..30a74cf
--- /dev/null
+++ b/fril/node_modules/minimist/readme.markdown
@@ -0,0 +1,91 @@
+# minimist
+
+parse argument options
+
+This module is the guts of optimist's argument parser without all the
+fanciful decoration.
+
+[](http://ci.testling.com/substack/minimist)
+
+[](http://travis-ci.org/substack/minimist)
+
+# example
+
+``` js
+var argv = require('minimist')(process.argv.slice(2));
+console.dir(argv);
+```
+
+```
+$ node example/parse.js -a beep -b boop
+{ _: [], a: 'beep', b: 'boop' }
+```
+
+```
+$ node example/parse.js -x 3 -y 4 -n5 -abc --beep=boop foo bar baz
+{ _: [ 'foo', 'bar', 'baz' ],
+ x: 3,
+ y: 4,
+ n: 5,
+ a: true,
+ b: true,
+ c: true,
+ beep: 'boop' }
+```
+
+# methods
+
+``` js
+var parseArgs = require('minimist')
+```
+
+## var argv = parseArgs(args, opts={})
+
+Return an argument object `argv` populated with the array arguments from `args`.
+
+`argv._` contains all the arguments that didn't have an option associated with
+them.
+
+Numeric-looking arguments will be returned as numbers unless `opts.string` or
+`opts.boolean` is set for that argument name.
+
+Any arguments after `'--'` will not be parsed and will end up in `argv._`.
+
+options can be:
+
+* `opts.string` - a string or array of strings argument names to always treat as
+strings
+* `opts.boolean` - a boolean, string or array of strings to always treat as
+booleans. if `true` will treat all double hyphenated arguments without equal signs
+as boolean (e.g. affects `--foo`, not `-f` or `--foo=bar`)
+* `opts.alias` - an object mapping string names to strings or arrays of string
+argument names to use as aliases
+* `opts.default` - an object mapping string argument names to default values
+* `opts.stopEarly` - when true, populate `argv._` with everything after the
+first non-option
+* `opts['--']` - when true, populate `argv._` with everything before the `--`
+and `argv['--']` with everything after the `--`. Here's an example:
+* `opts.unknown` - a function which is invoked with a command line parameter not
+defined in the `opts` configuration object. If the function returns `false`, the
+unknown option is not added to `argv`.
+
+```
+> require('./')('one two three -- four five --six'.split(' '), { '--': true })
+{ _: [ 'one', 'two', 'three' ],
+ '--': [ 'four', 'five', '--six' ] }
+```
+
+Note that with `opts['--']` set, parsing for arguments still stops after the
+`--`.
+
+# install
+
+With [npm](https://npmjs.org) do:
+
+```
+npm install minimist
+```
+
+# license
+
+MIT
diff --git a/fril/node_modules/minimist/test/all_bool.js b/fril/node_modules/minimist/test/all_bool.js
new file mode 100644
index 0000000..ac83548
--- /dev/null
+++ b/fril/node_modules/minimist/test/all_bool.js
@@ -0,0 +1,32 @@
+var parse = require('../');
+var test = require('tape');
+
+test('flag boolean true (default all --args to boolean)', function (t) {
+ var argv = parse(['moo', '--honk', 'cow'], {
+ boolean: true
+ });
+
+ t.deepEqual(argv, {
+ honk: true,
+ _: ['moo', 'cow']
+ });
+
+ t.deepEqual(typeof argv.honk, 'boolean');
+ t.end();
+});
+
+test('flag boolean true only affects double hyphen arguments without equals signs', function (t) {
+ var argv = parse(['moo', '--honk', 'cow', '-p', '55', '--tacos=good'], {
+ boolean: true
+ });
+
+ t.deepEqual(argv, {
+ honk: true,
+ tacos: 'good',
+ p: 55,
+ _: ['moo', 'cow']
+ });
+
+ t.deepEqual(typeof argv.honk, 'boolean');
+ t.end();
+});
diff --git a/fril/node_modules/minimist/test/bool.js b/fril/node_modules/minimist/test/bool.js
new file mode 100644
index 0000000..14b0717
--- /dev/null
+++ b/fril/node_modules/minimist/test/bool.js
@@ -0,0 +1,166 @@
+var parse = require('../');
+var test = require('tape');
+
+test('flag boolean default false', function (t) {
+ var argv = parse(['moo'], {
+ boolean: ['t', 'verbose'],
+ default: { verbose: false, t: false }
+ });
+
+ t.deepEqual(argv, {
+ verbose: false,
+ t: false,
+ _: ['moo']
+ });
+
+ t.deepEqual(typeof argv.verbose, 'boolean');
+ t.deepEqual(typeof argv.t, 'boolean');
+ t.end();
+
+});
+
+test('boolean groups', function (t) {
+ var argv = parse([ '-x', '-z', 'one', 'two', 'three' ], {
+ boolean: ['x','y','z']
+ });
+
+ t.deepEqual(argv, {
+ x : true,
+ y : false,
+ z : true,
+ _ : [ 'one', 'two', 'three' ]
+ });
+
+ t.deepEqual(typeof argv.x, 'boolean');
+ t.deepEqual(typeof argv.y, 'boolean');
+ t.deepEqual(typeof argv.z, 'boolean');
+ t.end();
+});
+test('boolean and alias with chainable api', function (t) {
+ var aliased = [ '-h', 'derp' ];
+ var regular = [ '--herp', 'derp' ];
+ var opts = {
+ herp: { alias: 'h', boolean: true }
+ };
+ var aliasedArgv = parse(aliased, {
+ boolean: 'herp',
+ alias: { h: 'herp' }
+ });
+ var propertyArgv = parse(regular, {
+ boolean: 'herp',
+ alias: { h: 'herp' }
+ });
+ var expected = {
+ herp: true,
+ h: true,
+ '_': [ 'derp' ]
+ };
+
+ t.same(aliasedArgv, expected);
+ t.same(propertyArgv, expected);
+ t.end();
+});
+
+test('boolean and alias with options hash', function (t) {
+ var aliased = [ '-h', 'derp' ];
+ var regular = [ '--herp', 'derp' ];
+ var opts = {
+ alias: { 'h': 'herp' },
+ boolean: 'herp'
+ };
+ var aliasedArgv = parse(aliased, opts);
+ var propertyArgv = parse(regular, opts);
+ var expected = {
+ herp: true,
+ h: true,
+ '_': [ 'derp' ]
+ };
+ t.same(aliasedArgv, expected);
+ t.same(propertyArgv, expected);
+ t.end();
+});
+
+test('boolean and alias array with options hash', function (t) {
+ var aliased = [ '-h', 'derp' ];
+ var regular = [ '--herp', 'derp' ];
+ var alt = [ '--harp', 'derp' ];
+ var opts = {
+ alias: { 'h': ['herp', 'harp'] },
+ boolean: 'h'
+ };
+ var aliasedArgv = parse(aliased, opts);
+ var propertyArgv = parse(regular, opts);
+ var altPropertyArgv = parse(alt, opts);
+ var expected = {
+ harp: true,
+ herp: true,
+ h: true,
+ '_': [ 'derp' ]
+ };
+ t.same(aliasedArgv, expected);
+ t.same(propertyArgv, expected);
+ t.same(altPropertyArgv, expected);
+ t.end();
+});
+
+test('boolean and alias using explicit true', function (t) {
+ var aliased = [ '-h', 'true' ];
+ var regular = [ '--herp', 'true' ];
+ var opts = {
+ alias: { h: 'herp' },
+ boolean: 'h'
+ };
+ var aliasedArgv = parse(aliased, opts);
+ var propertyArgv = parse(regular, opts);
+ var expected = {
+ herp: true,
+ h: true,
+ '_': [ ]
+ };
+
+ t.same(aliasedArgv, expected);
+ t.same(propertyArgv, expected);
+ t.end();
+});
+
+// regression, see https://github.com/substack/node-optimist/issues/71
+test('boolean and --x=true', function(t) {
+ var parsed = parse(['--boool', '--other=true'], {
+ boolean: 'boool'
+ });
+
+ t.same(parsed.boool, true);
+ t.same(parsed.other, 'true');
+
+ parsed = parse(['--boool', '--other=false'], {
+ boolean: 'boool'
+ });
+
+ t.same(parsed.boool, true);
+ t.same(parsed.other, 'false');
+ t.end();
+});
+
+test('boolean --boool=true', function (t) {
+ var parsed = parse(['--boool=true'], {
+ default: {
+ boool: false
+ },
+ boolean: ['boool']
+ });
+
+ t.same(parsed.boool, true);
+ t.end();
+});
+
+test('boolean --boool=false', function (t) {
+ var parsed = parse(['--boool=false'], {
+ default: {
+ boool: true
+ },
+ boolean: ['boool']
+ });
+
+ t.same(parsed.boool, false);
+ t.end();
+});
diff --git a/fril/node_modules/minimist/test/dash.js b/fril/node_modules/minimist/test/dash.js
new file mode 100644
index 0000000..5a4fa5b
--- /dev/null
+++ b/fril/node_modules/minimist/test/dash.js
@@ -0,0 +1,31 @@
+var parse = require('../');
+var test = require('tape');
+
+test('-', function (t) {
+ t.plan(5);
+ t.deepEqual(parse([ '-n', '-' ]), { n: '-', _: [] });
+ t.deepEqual(parse([ '-' ]), { _: [ '-' ] });
+ t.deepEqual(parse([ '-f-' ]), { f: '-', _: [] });
+ t.deepEqual(
+ parse([ '-b', '-' ], { boolean: 'b' }),
+ { b: true, _: [ '-' ] }
+ );
+ t.deepEqual(
+ parse([ '-s', '-' ], { string: 's' }),
+ { s: '-', _: [] }
+ );
+});
+
+test('-a -- b', function (t) {
+ t.plan(3);
+ t.deepEqual(parse([ '-a', '--', 'b' ]), { a: true, _: [ 'b' ] });
+ t.deepEqual(parse([ '--a', '--', 'b' ]), { a: true, _: [ 'b' ] });
+ t.deepEqual(parse([ '--a', '--', 'b' ]), { a: true, _: [ 'b' ] });
+});
+
+test('move arguments after the -- into their own `--` array', function(t) {
+ t.plan(1);
+ t.deepEqual(
+ parse([ '--name', 'John', 'before', '--', 'after' ], { '--': true }),
+ { name: 'John', _: [ 'before' ], '--': [ 'after' ] });
+});
diff --git a/fril/node_modules/minimist/test/default_bool.js b/fril/node_modules/minimist/test/default_bool.js
new file mode 100644
index 0000000..780a311
--- /dev/null
+++ b/fril/node_modules/minimist/test/default_bool.js
@@ -0,0 +1,35 @@
+var test = require('tape');
+var parse = require('../');
+
+test('boolean default true', function (t) {
+ var argv = parse([], {
+ boolean: 'sometrue',
+ default: { sometrue: true }
+ });
+ t.equal(argv.sometrue, true);
+ t.end();
+});
+
+test('boolean default false', function (t) {
+ var argv = parse([], {
+ boolean: 'somefalse',
+ default: { somefalse: false }
+ });
+ t.equal(argv.somefalse, false);
+ t.end();
+});
+
+test('boolean default to null', function (t) {
+ var argv = parse([], {
+ boolean: 'maybe',
+ default: { maybe: null }
+ });
+ t.equal(argv.maybe, null);
+ var argv = parse(['--maybe'], {
+ boolean: 'maybe',
+ default: { maybe: null }
+ });
+ t.equal(argv.maybe, true);
+ t.end();
+
+})
diff --git a/fril/node_modules/minimist/test/dotted.js b/fril/node_modules/minimist/test/dotted.js
new file mode 100644
index 0000000..d8b3e85
--- /dev/null
+++ b/fril/node_modules/minimist/test/dotted.js
@@ -0,0 +1,22 @@
+var parse = require('../');
+var test = require('tape');
+
+test('dotted alias', function (t) {
+ var argv = parse(['--a.b', '22'], {default: {'a.b': 11}, alias: {'a.b': 'aa.bb'}});
+ t.equal(argv.a.b, 22);
+ t.equal(argv.aa.bb, 22);
+ t.end();
+});
+
+test('dotted default', function (t) {
+ var argv = parse('', {default: {'a.b': 11}, alias: {'a.b': 'aa.bb'}});
+ t.equal(argv.a.b, 11);
+ t.equal(argv.aa.bb, 11);
+ t.end();
+});
+
+test('dotted default with no alias', function (t) {
+ var argv = parse('', {default: {'a.b': 11}});
+ t.equal(argv.a.b, 11);
+ t.end();
+});
diff --git a/fril/node_modules/minimist/test/kv_short.js b/fril/node_modules/minimist/test/kv_short.js
new file mode 100644
index 0000000..f813b30
--- /dev/null
+++ b/fril/node_modules/minimist/test/kv_short.js
@@ -0,0 +1,16 @@
+var parse = require('../');
+var test = require('tape');
+
+test('short -k=v' , function (t) {
+ t.plan(1);
+
+ var argv = parse([ '-b=123' ]);
+ t.deepEqual(argv, { b: 123, _: [] });
+});
+
+test('multi short -k=v' , function (t) {
+ t.plan(1);
+
+ var argv = parse([ '-a=whatever', '-b=robots' ]);
+ t.deepEqual(argv, { a: 'whatever', b: 'robots', _: [] });
+});
diff --git a/fril/node_modules/minimist/test/long.js b/fril/node_modules/minimist/test/long.js
new file mode 100644
index 0000000..5d3a1e0
--- /dev/null
+++ b/fril/node_modules/minimist/test/long.js
@@ -0,0 +1,31 @@
+var test = require('tape');
+var parse = require('../');
+
+test('long opts', function (t) {
+ t.deepEqual(
+ parse([ '--bool' ]),
+ { bool : true, _ : [] },
+ 'long boolean'
+ );
+ t.deepEqual(
+ parse([ '--pow', 'xixxle' ]),
+ { pow : 'xixxle', _ : [] },
+ 'long capture sp'
+ );
+ t.deepEqual(
+ parse([ '--pow=xixxle' ]),
+ { pow : 'xixxle', _ : [] },
+ 'long capture eq'
+ );
+ t.deepEqual(
+ parse([ '--host', 'localhost', '--port', '555' ]),
+ { host : 'localhost', port : 555, _ : [] },
+ 'long captures sp'
+ );
+ t.deepEqual(
+ parse([ '--host=localhost', '--port=555' ]),
+ { host : 'localhost', port : 555, _ : [] },
+ 'long captures eq'
+ );
+ t.end();
+});
diff --git a/fril/node_modules/minimist/test/num.js b/fril/node_modules/minimist/test/num.js
new file mode 100644
index 0000000..2cc77f4
--- /dev/null
+++ b/fril/node_modules/minimist/test/num.js
@@ -0,0 +1,36 @@
+var parse = require('../');
+var test = require('tape');
+
+test('nums', function (t) {
+ var argv = parse([
+ '-x', '1234',
+ '-y', '5.67',
+ '-z', '1e7',
+ '-w', '10f',
+ '--hex', '0xdeadbeef',
+ '789'
+ ]);
+ t.deepEqual(argv, {
+ x : 1234,
+ y : 5.67,
+ z : 1e7,
+ w : '10f',
+ hex : 0xdeadbeef,
+ _ : [ 789 ]
+ });
+ t.deepEqual(typeof argv.x, 'number');
+ t.deepEqual(typeof argv.y, 'number');
+ t.deepEqual(typeof argv.z, 'number');
+ t.deepEqual(typeof argv.w, 'string');
+ t.deepEqual(typeof argv.hex, 'number');
+ t.deepEqual(typeof argv._[0], 'number');
+ t.end();
+});
+
+test('already a number', function (t) {
+ var argv = parse([ '-x', 1234, 789 ]);
+ t.deepEqual(argv, { x : 1234, _ : [ 789 ] });
+ t.deepEqual(typeof argv.x, 'number');
+ t.deepEqual(typeof argv._[0], 'number');
+ t.end();
+});
diff --git a/fril/node_modules/minimist/test/parse.js b/fril/node_modules/minimist/test/parse.js
new file mode 100644
index 0000000..7b4a2a1
--- /dev/null
+++ b/fril/node_modules/minimist/test/parse.js
@@ -0,0 +1,197 @@
+var parse = require('../');
+var test = require('tape');
+
+test('parse args', function (t) {
+ t.deepEqual(
+ parse([ '--no-moo' ]),
+ { moo : false, _ : [] },
+ 'no'
+ );
+ t.deepEqual(
+ parse([ '-v', 'a', '-v', 'b', '-v', 'c' ]),
+ { v : ['a','b','c'], _ : [] },
+ 'multi'
+ );
+ t.end();
+});
+
+test('comprehensive', function (t) {
+ t.deepEqual(
+ parse([
+ '--name=meowmers', 'bare', '-cats', 'woo',
+ '-h', 'awesome', '--multi=quux',
+ '--key', 'value',
+ '-b', '--bool', '--no-meep', '--multi=baz',
+ '--', '--not-a-flag', 'eek'
+ ]),
+ {
+ c : true,
+ a : true,
+ t : true,
+ s : 'woo',
+ h : 'awesome',
+ b : true,
+ bool : true,
+ key : 'value',
+ multi : [ 'quux', 'baz' ],
+ meep : false,
+ name : 'meowmers',
+ _ : [ 'bare', '--not-a-flag', 'eek' ]
+ }
+ );
+ t.end();
+});
+
+test('flag boolean', function (t) {
+ var argv = parse([ '-t', 'moo' ], { boolean: 't' });
+ t.deepEqual(argv, { t : true, _ : [ 'moo' ] });
+ t.deepEqual(typeof argv.t, 'boolean');
+ t.end();
+});
+
+test('flag boolean value', function (t) {
+ var argv = parse(['--verbose', 'false', 'moo', '-t', 'true'], {
+ boolean: [ 't', 'verbose' ],
+ default: { verbose: true }
+ });
+
+ t.deepEqual(argv, {
+ verbose: false,
+ t: true,
+ _: ['moo']
+ });
+
+ t.deepEqual(typeof argv.verbose, 'boolean');
+ t.deepEqual(typeof argv.t, 'boolean');
+ t.end();
+});
+
+test('newlines in params' , function (t) {
+ var args = parse([ '-s', "X\nX" ])
+ t.deepEqual(args, { _ : [], s : "X\nX" });
+
+ // reproduce in bash:
+ // VALUE="new
+ // line"
+ // node program.js --s="$VALUE"
+ args = parse([ "--s=X\nX" ])
+ t.deepEqual(args, { _ : [], s : "X\nX" });
+ t.end();
+});
+
+test('strings' , function (t) {
+ var s = parse([ '-s', '0001234' ], { string: 's' }).s;
+ t.equal(s, '0001234');
+ t.equal(typeof s, 'string');
+
+ var x = parse([ '-x', '56' ], { string: 'x' }).x;
+ t.equal(x, '56');
+ t.equal(typeof x, 'string');
+ t.end();
+});
+
+test('stringArgs', function (t) {
+ var s = parse([ ' ', ' ' ], { string: '_' })._;
+ t.same(s.length, 2);
+ t.same(typeof s[0], 'string');
+ t.same(s[0], ' ');
+ t.same(typeof s[1], 'string');
+ t.same(s[1], ' ');
+ t.end();
+});
+
+test('empty strings', function(t) {
+ var s = parse([ '-s' ], { string: 's' }).s;
+ t.equal(s, '');
+ t.equal(typeof s, 'string');
+
+ var str = parse([ '--str' ], { string: 'str' }).str;
+ t.equal(str, '');
+ t.equal(typeof str, 'string');
+
+ var letters = parse([ '-art' ], {
+ string: [ 'a', 't' ]
+ });
+
+ t.equal(letters.a, '');
+ t.equal(letters.r, true);
+ t.equal(letters.t, '');
+
+ t.end();
+});
+
+
+test('string and alias', function(t) {
+ var x = parse([ '--str', '000123' ], {
+ string: 's',
+ alias: { s: 'str' }
+ });
+
+ t.equal(x.str, '000123');
+ t.equal(typeof x.str, 'string');
+ t.equal(x.s, '000123');
+ t.equal(typeof x.s, 'string');
+
+ var y = parse([ '-s', '000123' ], {
+ string: 'str',
+ alias: { str: 's' }
+ });
+
+ t.equal(y.str, '000123');
+ t.equal(typeof y.str, 'string');
+ t.equal(y.s, '000123');
+ t.equal(typeof y.s, 'string');
+ t.end();
+});
+
+test('slashBreak', function (t) {
+ t.same(
+ parse([ '-I/foo/bar/baz' ]),
+ { I : '/foo/bar/baz', _ : [] }
+ );
+ t.same(
+ parse([ '-xyz/foo/bar/baz' ]),
+ { x : true, y : true, z : '/foo/bar/baz', _ : [] }
+ );
+ t.end();
+});
+
+test('alias', function (t) {
+ var argv = parse([ '-f', '11', '--zoom', '55' ], {
+ alias: { z: 'zoom' }
+ });
+ t.equal(argv.zoom, 55);
+ t.equal(argv.z, argv.zoom);
+ t.equal(argv.f, 11);
+ t.end();
+});
+
+test('multiAlias', function (t) {
+ var argv = parse([ '-f', '11', '--zoom', '55' ], {
+ alias: { z: [ 'zm', 'zoom' ] }
+ });
+ t.equal(argv.zoom, 55);
+ t.equal(argv.z, argv.zoom);
+ t.equal(argv.z, argv.zm);
+ t.equal(argv.f, 11);
+ t.end();
+});
+
+test('nested dotted objects', function (t) {
+ var argv = parse([
+ '--foo.bar', '3', '--foo.baz', '4',
+ '--foo.quux.quibble', '5', '--foo.quux.o_O',
+ '--beep.boop'
+ ]);
+
+ t.same(argv.foo, {
+ bar : 3,
+ baz : 4,
+ quux : {
+ quibble : 5,
+ o_O : true
+ }
+ });
+ t.same(argv.beep, { boop : true });
+ t.end();
+});
diff --git a/fril/node_modules/minimist/test/parse_modified.js b/fril/node_modules/minimist/test/parse_modified.js
new file mode 100644
index 0000000..ab620dc
--- /dev/null
+++ b/fril/node_modules/minimist/test/parse_modified.js
@@ -0,0 +1,9 @@
+var parse = require('../');
+var test = require('tape');
+
+test('parse with modifier functions' , function (t) {
+ t.plan(1);
+
+ var argv = parse([ '-b', '123' ], { boolean: 'b' });
+ t.deepEqual(argv, { b: true, _: [123] });
+});
diff --git a/fril/node_modules/minimist/test/short.js b/fril/node_modules/minimist/test/short.js
new file mode 100644
index 0000000..d513a1c
--- /dev/null
+++ b/fril/node_modules/minimist/test/short.js
@@ -0,0 +1,67 @@
+var parse = require('../');
+var test = require('tape');
+
+test('numeric short args', function (t) {
+ t.plan(2);
+ t.deepEqual(parse([ '-n123' ]), { n: 123, _: [] });
+ t.deepEqual(
+ parse([ '-123', '456' ]),
+ { 1: true, 2: true, 3: 456, _: [] }
+ );
+});
+
+test('short', function (t) {
+ t.deepEqual(
+ parse([ '-b' ]),
+ { b : true, _ : [] },
+ 'short boolean'
+ );
+ t.deepEqual(
+ parse([ 'foo', 'bar', 'baz' ]),
+ { _ : [ 'foo', 'bar', 'baz' ] },
+ 'bare'
+ );
+ t.deepEqual(
+ parse([ '-cats' ]),
+ { c : true, a : true, t : true, s : true, _ : [] },
+ 'group'
+ );
+ t.deepEqual(
+ parse([ '-cats', 'meow' ]),
+ { c : true, a : true, t : true, s : 'meow', _ : [] },
+ 'short group next'
+ );
+ t.deepEqual(
+ parse([ '-h', 'localhost' ]),
+ { h : 'localhost', _ : [] },
+ 'short capture'
+ );
+ t.deepEqual(
+ parse([ '-h', 'localhost', '-p', '555' ]),
+ { h : 'localhost', p : 555, _ : [] },
+ 'short captures'
+ );
+ t.end();
+});
+
+test('mixed short bool and capture', function (t) {
+ t.same(
+ parse([ '-h', 'localhost', '-fp', '555', 'script.js' ]),
+ {
+ f : true, p : 555, h : 'localhost',
+ _ : [ 'script.js' ]
+ }
+ );
+ t.end();
+});
+
+test('short and long', function (t) {
+ t.deepEqual(
+ parse([ '-h', 'localhost', '-fp', '555', 'script.js' ]),
+ {
+ f : true, p : 555, h : 'localhost',
+ _ : [ 'script.js' ]
+ }
+ );
+ t.end();
+});
diff --git a/fril/node_modules/minimist/test/stop_early.js b/fril/node_modules/minimist/test/stop_early.js
new file mode 100644
index 0000000..bdf9fbc
--- /dev/null
+++ b/fril/node_modules/minimist/test/stop_early.js
@@ -0,0 +1,15 @@
+var parse = require('../');
+var test = require('tape');
+
+test('stops parsing on the first non-option when stopEarly is set', function (t) {
+ var argv = parse(['--aaa', 'bbb', 'ccc', '--ddd'], {
+ stopEarly: true
+ });
+
+ t.deepEqual(argv, {
+ aaa: 'bbb',
+ _: ['ccc', '--ddd']
+ });
+
+ t.end();
+});
diff --git a/fril/node_modules/minimist/test/unknown.js b/fril/node_modules/minimist/test/unknown.js
new file mode 100644
index 0000000..462a36b
--- /dev/null
+++ b/fril/node_modules/minimist/test/unknown.js
@@ -0,0 +1,102 @@
+var parse = require('../');
+var test = require('tape');
+
+test('boolean and alias is not unknown', function (t) {
+ var unknown = [];
+ function unknownFn(arg) {
+ unknown.push(arg);
+ return false;
+ }
+ var aliased = [ '-h', 'true', '--derp', 'true' ];
+ var regular = [ '--herp', 'true', '-d', 'true' ];
+ var opts = {
+ alias: { h: 'herp' },
+ boolean: 'h',
+ unknown: unknownFn
+ };
+ var aliasedArgv = parse(aliased, opts);
+ var propertyArgv = parse(regular, opts);
+
+ t.same(unknown, ['--derp', '-d']);
+ t.end();
+});
+
+test('flag boolean true any double hyphen argument is not unknown', function (t) {
+ var unknown = [];
+ function unknownFn(arg) {
+ unknown.push(arg);
+ return false;
+ }
+ var argv = parse(['--honk', '--tacos=good', 'cow', '-p', '55'], {
+ boolean: true,
+ unknown: unknownFn
+ });
+ t.same(unknown, ['--tacos=good', 'cow', '-p']);
+ t.same(argv, {
+ honk: true,
+ _: []
+ });
+ t.end();
+});
+
+test('string and alias is not unknown', function (t) {
+ var unknown = [];
+ function unknownFn(arg) {
+ unknown.push(arg);
+ return false;
+ }
+ var aliased = [ '-h', 'hello', '--derp', 'goodbye' ];
+ var regular = [ '--herp', 'hello', '-d', 'moon' ];
+ var opts = {
+ alias: { h: 'herp' },
+ string: 'h',
+ unknown: unknownFn
+ };
+ var aliasedArgv = parse(aliased, opts);
+ var propertyArgv = parse(regular, opts);
+
+ t.same(unknown, ['--derp', '-d']);
+ t.end();
+});
+
+test('default and alias is not unknown', function (t) {
+ var unknown = [];
+ function unknownFn(arg) {
+ unknown.push(arg);
+ return false;
+ }
+ var aliased = [ '-h', 'hello' ];
+ var regular = [ '--herp', 'hello' ];
+ var opts = {
+ default: { 'h': 'bar' },
+ alias: { 'h': 'herp' },
+ unknown: unknownFn
+ };
+ var aliasedArgv = parse(aliased, opts);
+ var propertyArgv = parse(regular, opts);
+
+ t.same(unknown, []);
+ t.end();
+ unknownFn(); // exercise fn for 100% coverage
+});
+
+test('value following -- is not unknown', function (t) {
+ var unknown = [];
+ function unknownFn(arg) {
+ unknown.push(arg);
+ return false;
+ }
+ var aliased = [ '--bad', '--', 'good', 'arg' ];
+ var opts = {
+ '--': true,
+ unknown: unknownFn
+ };
+ var argv = parse(aliased, opts);
+
+ t.same(unknown, ['--bad']);
+ t.same(argv, {
+ '--': ['good', 'arg'],
+ '_': []
+ })
+ t.end();
+});
diff --git a/fril/node_modules/minimist/test/whitespace.js b/fril/node_modules/minimist/test/whitespace.js
new file mode 100644
index 0000000..8a52a58
--- /dev/null
+++ b/fril/node_modules/minimist/test/whitespace.js
@@ -0,0 +1,8 @@
+var parse = require('../');
+var test = require('tape');
+
+test('whitespace should be whitespace' , function (t) {
+ t.plan(1);
+ var x = parse([ '-x', '\t' ]).x;
+ t.equal(x, '\t');
+});
diff --git a/fril/node_modules/process-nextick-args/.travis.yml b/fril/node_modules/process-nextick-args/.travis.yml
new file mode 100644
index 0000000..36201b1
--- /dev/null
+++ b/fril/node_modules/process-nextick-args/.travis.yml
@@ -0,0 +1,12 @@
+language: node_js
+node_js:
+ - "0.8"
+ - "0.10"
+ - "0.11"
+ - "0.12"
+ - "1.7.1"
+ - 1
+ - 2
+ - 3
+ - 4
+ - 5
diff --git a/fril/node_modules/process-nextick-args/index.js b/fril/node_modules/process-nextick-args/index.js
new file mode 100644
index 0000000..a4f40f8
--- /dev/null
+++ b/fril/node_modules/process-nextick-args/index.js
@@ -0,0 +1,43 @@
+'use strict';
+
+if (!process.version ||
+ process.version.indexOf('v0.') === 0 ||
+ process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) {
+ module.exports = nextTick;
+} else {
+ module.exports = process.nextTick;
+}
+
+function nextTick(fn, arg1, arg2, arg3) {
+ if (typeof fn !== 'function') {
+ throw new TypeError('"callback" argument must be a function');
+ }
+ var len = arguments.length;
+ var args, i;
+ switch (len) {
+ case 0:
+ case 1:
+ return process.nextTick(fn);
+ case 2:
+ return process.nextTick(function afterTickOne() {
+ fn.call(null, arg1);
+ });
+ case 3:
+ return process.nextTick(function afterTickTwo() {
+ fn.call(null, arg1, arg2);
+ });
+ case 4:
+ return process.nextTick(function afterTickThree() {
+ fn.call(null, arg1, arg2, arg3);
+ });
+ default:
+ args = new Array(len - 1);
+ i = 0;
+ while (i < args.length) {
+ args[i++] = arguments[i];
+ }
+ return process.nextTick(function afterTick() {
+ fn.apply(null, args);
+ });
+ }
+}
diff --git a/fril/node_modules/process-nextick-args/license.md b/fril/node_modules/process-nextick-args/license.md
new file mode 100644
index 0000000..c67e353
--- /dev/null
+++ b/fril/node_modules/process-nextick-args/license.md
@@ -0,0 +1,19 @@
+# Copyright (c) 2015 Calvin Metcalf
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+**THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.**
diff --git a/fril/node_modules/process-nextick-args/package.json b/fril/node_modules/process-nextick-args/package.json
new file mode 100644
index 0000000..5cfa157
--- /dev/null
+++ b/fril/node_modules/process-nextick-args/package.json
@@ -0,0 +1,83 @@
+{
+ "_args": [
+ [
+ {
+ "raw": "process-nextick-args@~1.0.6",
+ "scope": null,
+ "escapedName": "process-nextick-args",
+ "name": "process-nextick-args",
+ "rawSpec": "~1.0.6",
+ "spec": ">=1.0.6 <1.1.0",
+ "type": "range"
+ },
+ "D:\\Workspace\\Dokument\\Skolarbete\\KTH\\Web & Mobile GIS - AG2417\\Project\\dev\\fril\\node_modules\\readable-stream"
+ ]
+ ],
+ "_from": "process-nextick-args@>=1.0.6 <1.1.0",
+ "_id": "process-nextick-args@1.0.7",
+ "_inCache": true,
+ "_location": "/process-nextick-args",
+ "_nodeVersion": "5.11.0",
+ "_npmOperationalInternal": {
+ "host": "packages-12-west.internal.npmjs.com",
+ "tmp": "tmp/process-nextick-args-1.0.7.tgz_1462394251778_0.36989671061746776"
+ },
+ "_npmUser": {
+ "name": "cwmma",
+ "email": "calvin.metcalf@gmail.com"
+ },
+ "_npmVersion": "3.8.6",
+ "_phantomChildren": {},
+ "_requested": {
+ "raw": "process-nextick-args@~1.0.6",
+ "scope": null,
+ "escapedName": "process-nextick-args",
+ "name": "process-nextick-args",
+ "rawSpec": "~1.0.6",
+ "spec": ">=1.0.6 <1.1.0",
+ "type": "range"
+ },
+ "_requiredBy": [
+ "/readable-stream"
+ ],
+ "_resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
+ "_shasum": "150e20b756590ad3f91093f25a4f2ad8bff30ba3",
+ "_shrinkwrap": null,
+ "_spec": "process-nextick-args@~1.0.6",
+ "_where": "D:\\Workspace\\Dokument\\Skolarbete\\KTH\\Web & Mobile GIS - AG2417\\Project\\dev\\fril\\node_modules\\readable-stream",
+ "author": "",
+ "bugs": {
+ "url": "https://github.com/calvinmetcalf/process-nextick-args/issues"
+ },
+ "dependencies": {},
+ "description": "process.nextTick but always with args",
+ "devDependencies": {
+ "tap": "~0.2.6"
+ },
+ "directories": {},
+ "dist": {
+ "shasum": "150e20b756590ad3f91093f25a4f2ad8bff30ba3",
+ "tarball": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz"
+ },
+ "gitHead": "5c00899ab01dd32f93ad4b5743da33da91404f39",
+ "homepage": "https://github.com/calvinmetcalf/process-nextick-args",
+ "license": "MIT",
+ "main": "index.js",
+ "maintainers": [
+ {
+ "name": "cwmma",
+ "email": "calvin.metcalf@gmail.com"
+ }
+ ],
+ "name": "process-nextick-args",
+ "optionalDependencies": {},
+ "readme": "ERROR: No README data found!",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/calvinmetcalf/process-nextick-args.git"
+ },
+ "scripts": {
+ "test": "node test.js"
+ },
+ "version": "1.0.7"
+}
diff --git a/fril/node_modules/process-nextick-args/readme.md b/fril/node_modules/process-nextick-args/readme.md
new file mode 100644
index 0000000..78e7cfa
--- /dev/null
+++ b/fril/node_modules/process-nextick-args/readme.md
@@ -0,0 +1,18 @@
+process-nextick-args
+=====
+
+[](https://travis-ci.org/calvinmetcalf/process-nextick-args)
+
+```bash
+npm install --save process-nextick-args
+```
+
+Always be able to pass arguments to process.nextTick, no matter the platform
+
+```js
+var nextTick = require('process-nextick-args');
+
+nextTick(function (a, b, c) {
+ console.log(a, b, c);
+}, 'step', 3, 'profit');
+```
diff --git a/fril/node_modules/process-nextick-args/test.js b/fril/node_modules/process-nextick-args/test.js
new file mode 100644
index 0000000..ef15721
--- /dev/null
+++ b/fril/node_modules/process-nextick-args/test.js
@@ -0,0 +1,24 @@
+var test = require("tap").test;
+var nextTick = require('./');
+
+test('should work', function (t) {
+ t.plan(5);
+ nextTick(function (a) {
+ t.ok(a);
+ nextTick(function (thing) {
+ t.equals(thing, 7);
+ }, 7);
+ }, true);
+ nextTick(function (a, b, c) {
+ t.equals(a, 'step');
+ t.equals(b, 3);
+ t.equals(c, 'profit');
+ }, 'step', 3, 'profit');
+});
+
+test('correct number of arguments', function (t) {
+ t.plan(1);
+ nextTick(function () {
+ t.equals(2, arguments.length, 'correct number');
+ }, 1, 2);
+});
diff --git a/fril/node_modules/readable-stream/.npmignore b/fril/node_modules/readable-stream/.npmignore
new file mode 100644
index 0000000..38344f8
--- /dev/null
+++ b/fril/node_modules/readable-stream/.npmignore
@@ -0,0 +1,5 @@
+build/
+test/
+examples/
+fs.js
+zlib.js
\ No newline at end of file
diff --git a/fril/node_modules/readable-stream/.travis.yml b/fril/node_modules/readable-stream/.travis.yml
new file mode 100644
index 0000000..1b82118
--- /dev/null
+++ b/fril/node_modules/readable-stream/.travis.yml
@@ -0,0 +1,52 @@
+sudo: false
+language: node_js
+before_install:
+ - npm install -g npm@2
+ - npm install -g npm
+notifications:
+ email: false
+matrix:
+ fast_finish: true
+ allow_failures:
+ - env: TASK=browser BROWSER_NAME=ipad BROWSER_VERSION="6.0..latest"
+ - env: TASK=browser BROWSER_NAME=iphone BROWSER_VERSION="6.0..latest"
+ include:
+ - node_js: '0.8'
+ env: TASK=test
+ - node_js: '0.10'
+ env: TASK=test
+ - node_js: '0.11'
+ env: TASK=test
+ - node_js: '0.12'
+ env: TASK=test
+ - node_js: 1
+ env: TASK=test
+ - node_js: 2
+ env: TASK=test
+ - node_js: 3
+ env: TASK=test
+ - node_js: 4
+ env: TASK=test
+ - node_js: 5
+ env: TASK=test
+ - node_js: 5
+ env: TASK=browser BROWSER_NAME=android BROWSER_VERSION="4.0..latest"
+ - node_js: 5
+ env: TASK=browser BROWSER_NAME=ie BROWSER_VERSION="9..latest"
+ - node_js: 5
+ env: TASK=browser BROWSER_NAME=opera BROWSER_VERSION="11..latest"
+ - node_js: 5
+ env: TASK=browser BROWSER_NAME=chrome BROWSER_VERSION="-3..latest"
+ - node_js: 5
+ env: TASK=browser BROWSER_NAME=firefox BROWSER_VERSION="-3..latest"
+ - node_js: 5
+ env: TASK=browser BROWSER_NAME=ipad BROWSER_VERSION="6.0..latest"
+ - node_js: 5
+ env: TASK=browser BROWSER_NAME=iphone BROWSER_VERSION="6.0..latest"
+ - node_js: 5
+ env: TASK=browser BROWSER_NAME=safari BROWSER_VERSION="5..latest"
+script: "npm run $TASK"
+env:
+ global:
+ - secure: rE2Vvo7vnjabYNULNyLFxOyt98BoJexDqsiOnfiD6kLYYsiQGfr/sbZkPMOFm9qfQG7pjqx+zZWZjGSswhTt+626C0t/njXqug7Yps4c3dFblzGfreQHp7wNX5TFsvrxd6dAowVasMp61sJcRnB2w8cUzoe3RAYUDHyiHktwqMc=
+ - secure: g9YINaKAdMatsJ28G9jCGbSaguXCyxSTy+pBO6Ch0Cf57ZLOTka3HqDj8p3nV28LUIHZ3ut5WO43CeYKwt4AUtLpBS3a0dndHdY6D83uY6b2qh5hXlrcbeQTq2cvw2y95F7hm4D1kwrgZ7ViqaKggRcEupAL69YbJnxeUDKWEdI=
diff --git a/fril/node_modules/readable-stream/.zuul.yml b/fril/node_modules/readable-stream/.zuul.yml
new file mode 100644
index 0000000..96d9cfb
--- /dev/null
+++ b/fril/node_modules/readable-stream/.zuul.yml
@@ -0,0 +1 @@
+ui: tape
diff --git a/fril/node_modules/readable-stream/LICENSE b/fril/node_modules/readable-stream/LICENSE
new file mode 100644
index 0000000..e3d4e69
--- /dev/null
+++ b/fril/node_modules/readable-stream/LICENSE
@@ -0,0 +1,18 @@
+Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
diff --git a/fril/node_modules/readable-stream/README.md b/fril/node_modules/readable-stream/README.md
new file mode 100644
index 0000000..86b95a3
--- /dev/null
+++ b/fril/node_modules/readable-stream/README.md
@@ -0,0 +1,36 @@
+# readable-stream
+
+***Node-core v5.8.0 streams for userland*** [](https://travis-ci.org/nodejs/readable-stream)
+
+
+[](https://nodei.co/npm/readable-stream/)
+[](https://nodei.co/npm/readable-stream/)
+
+
+[](https://saucelabs.com/u/readable-stream)
+
+```bash
+npm install --save readable-stream
+```
+
+***Node-core streams for userland***
+
+This package is a mirror of the Streams2 and Streams3 implementations in
+Node-core, including [documentation](doc/stream.markdown).
+
+If you want to guarantee a stable streams base, regardless of what version of
+Node you, or the users of your libraries are using, use **readable-stream** *only* and avoid the *"stream"* module in Node-core, for background see [this blogpost](http://r.va.gg/2014/06/why-i-dont-use-nodes-core-stream-module.html).
+
+As of version 2.0.0 **readable-stream** uses semantic versioning.
+
+# Streams WG Team Members
+
+* **Chris Dickinson** ([@chrisdickinson](https://github.com/chrisdickinson)) <christopher.s.dickinson@gmail.com>
+ - Release GPG key: 9554F04D7259F04124DE6B476D5A82AC7E37093B
+* **Calvin Metcalf** ([@calvinmetcalf](https://github.com/calvinmetcalf)) <calvin.metcalf@gmail.com>
+ - Release GPG key: F3EF5F62A87FC27A22E643F714CE4FF5015AA242
+* **Rod Vagg** ([@rvagg](https://github.com/rvagg)) <rod@vagg.org>
+ - Release GPG key: DD8F2338BAE7501E3DD5AC78C273792F7D83545D
+* **Sam Newman** ([@sonewman](https://github.com/sonewman)) <newmansam@outlook.com>
+* **Mathias Buus** ([@mafintosh](https://github.com/mafintosh)) <mathiasbuus@gmail.com>
+* **Domenic Denicola** ([@domenic](https://github.com/domenic)) <d@domenic.me>
diff --git a/fril/node_modules/readable-stream/doc/stream.markdown b/fril/node_modules/readable-stream/doc/stream.markdown
new file mode 100644
index 0000000..0bc3819
--- /dev/null
+++ b/fril/node_modules/readable-stream/doc/stream.markdown
@@ -0,0 +1,1760 @@
+# Stream
+
+ Stability: 2 - Stable
+
+A stream is an abstract interface implemented by various objects in
+Node.js. For example a [request to an HTTP server][http-incoming-message] is a
+stream, as is [`process.stdout`][]. Streams are readable, writable, or both. All
+streams are instances of [`EventEmitter`][].
+
+You can load the Stream base classes by doing `require('stream')`.
+There are base classes provided for [Readable][] streams, [Writable][]
+streams, [Duplex][] streams, and [Transform][] streams.
+
+This document is split up into 3 sections:
+
+1. The first section explains the parts of the API that you need to be
+ aware of to use streams in your programs.
+2. The second section explains the parts of the API that you need to
+ use if you implement your own custom streams yourself. The API is designed to
+ make this easy for you to do.
+3. The third section goes into more depth about how streams work,
+ including some of the internal mechanisms and functions that you
+ should probably not modify unless you definitely know what you are
+ doing.
+
+
+## API for Stream Consumers
+
+
+
+Streams can be either [Readable][], [Writable][], or both ([Duplex][]).
+
+All streams are EventEmitters, but they also have other custom methods
+and properties depending on whether they are Readable, Writable, or
+Duplex.
+
+If a stream is both Readable and Writable, then it implements all of
+the methods and events. So, a [Duplex][] or [Transform][] stream is
+fully described by this API, though their implementation may be
+somewhat different.
+
+It is not necessary to implement Stream interfaces in order to consume
+streams in your programs. If you **are** implementing streaming
+interfaces in your own program, please also refer to
+[API for Stream Implementors][].
+
+Almost all Node.js programs, no matter how simple, use Streams in some
+way. Here is an example of using Streams in an Node.js program:
+
+```js
+const http = require('http');
+
+var server = http.createServer( (req, res) => {
+ // req is an http.IncomingMessage, which is a Readable Stream
+ // res is an http.ServerResponse, which is a Writable Stream
+
+ var body = '';
+ // we want to get the data as utf8 strings
+ // If you don't set an encoding, then you'll get Buffer objects
+ req.setEncoding('utf8');
+
+ // Readable streams emit 'data' events once a listener is added
+ req.on('data', (chunk) => {
+ body += chunk;
+ });
+
+ // the end event tells you that you have entire body
+ req.on('end', () => {
+ try {
+ var data = JSON.parse(body);
+ } catch (er) {
+ // uh oh! bad json!
+ res.statusCode = 400;
+ return res.end(`error: ${er.message}`);
+ }
+
+ // write back something interesting to the user:
+ res.write(typeof data);
+ res.end();
+ });
+});
+
+server.listen(1337);
+
+// $ curl localhost:1337 -d '{}'
+// object
+// $ curl localhost:1337 -d '"foo"'
+// string
+// $ curl localhost:1337 -d 'not json'
+// error: Unexpected token o
+```
+
+### Class: stream.Duplex
+
+Duplex streams are streams that implement both the [Readable][] and
+[Writable][] interfaces.
+
+Examples of Duplex streams include:
+
+* [TCP sockets][]
+* [zlib streams][zlib]
+* [crypto streams][crypto]
+
+### Class: stream.Readable
+
+
+
+The Readable stream interface is the abstraction for a *source* of
+data that you are reading from. In other words, data comes *out* of a
+Readable stream.
+
+A Readable stream will not start emitting data until you indicate that
+you are ready to receive it.
+
+Readable streams have two "modes": a **flowing mode** and a **paused
+mode**. When in flowing mode, data is read from the underlying system
+and provided to your program as fast as possible. In paused mode, you
+must explicitly call [`stream.read()`][stream-read] to get chunks of data out.
+Streams start out in paused mode.
+
+**Note**: If no data event handlers are attached, and there are no
+[`stream.pipe()`][] destinations, and the stream is switched into flowing
+mode, then data will be lost.
+
+You can switch to flowing mode by doing any of the following:
+
+* Adding a [`'data'`][] event handler to listen for data.
+* Calling the [`stream.resume()`][stream-resume] method to explicitly open the
+ flow.
+* Calling the [`stream.pipe()`][] method to send the data to a [Writable][].
+
+You can switch back to paused mode by doing either of the following:
+
+* If there are no pipe destinations, by calling the
+ [`stream.pause()`][stream-pause] method.
+* If there are pipe destinations, by removing any [`'data'`][] event
+ handlers, and removing all pipe destinations by calling the
+ [`stream.unpipe()`][] method.
+
+Note that, for backwards compatibility reasons, removing [`'data'`][]
+event handlers will **not** automatically pause the stream. Also, if
+there are piped destinations, then calling [`stream.pause()`][stream-pause] will
+not guarantee that the stream will *remain* paused once those
+destinations drain and ask for more data.
+
+Examples of readable streams include:
+
+* [HTTP responses, on the client][http-incoming-message]
+* [HTTP requests, on the server][http-incoming-message]
+* [fs read streams][]
+* [zlib streams][zlib]
+* [crypto streams][crypto]
+* [TCP sockets][]
+* [child process stdout and stderr][]
+* [`process.stdin`][]
+
+#### Event: 'close'
+
+Emitted when the stream and any of its underlying resources (a file
+descriptor, for example) have been closed. The event indicates that
+no more events will be emitted, and no further computation will occur.
+
+Not all streams will emit the `'close'` event.
+
+#### Event: 'data'
+
+* `chunk` {Buffer|String} The chunk of data.
+
+Attaching a `'data'` event listener to a stream that has not been
+explicitly paused will switch the stream into flowing mode. Data will
+then be passed as soon as it is available.
+
+If you just want to get all the data out of the stream as fast as
+possible, this is the best way to do so.
+
+```js
+var readable = getReadableStreamSomehow();
+readable.on('data', (chunk) => {
+ console.log('got %d bytes of data', chunk.length);
+});
+```
+
+#### Event: 'end'
+
+This event fires when there will be no more data to read.
+
+Note that the `'end'` event **will not fire** unless the data is
+completely consumed. This can be done by switching into flowing mode,
+or by calling [`stream.read()`][stream-read] repeatedly until you get to the
+end.
+
+```js
+var readable = getReadableStreamSomehow();
+readable.on('data', (chunk) => {
+ console.log('got %d bytes of data', chunk.length);
+});
+readable.on('end', () => {
+ console.log('there will be no more data.');
+});
+```
+
+#### Event: 'error'
+
+* {Error Object}
+
+Emitted if there was an error receiving data.
+
+#### Event: 'readable'
+
+When a chunk of data can be read from the stream, it will emit a
+`'readable'` event.
+
+In some cases, listening for a `'readable'` event will cause some data
+to be read into the internal buffer from the underlying system, if it
+hadn't already.
+
+```javascript
+var readable = getReadableStreamSomehow();
+readable.on('readable', () => {
+ // there is some data to read now
+});
+```
+
+Once the internal buffer is drained, a `'readable'` event will fire
+again when more data is available.
+
+The `'readable'` event is not emitted in the "flowing" mode with the
+sole exception of the last one, on end-of-stream.
+
+The `'readable'` event indicates that the stream has new information:
+either new data is available or the end of the stream has been reached.
+In the former case, [`stream.read()`][stream-read] will return that data. In the
+latter case, [`stream.read()`][stream-read] will return null. For instance, in
+the following example, `foo.txt` is an empty file:
+
+```js
+const fs = require('fs');
+var rr = fs.createReadStream('foo.txt');
+rr.on('readable', () => {
+ console.log('readable:', rr.read());
+});
+rr.on('end', () => {
+ console.log('end');
+});
+```
+
+The output of running this script is:
+
+```
+$ node test.js
+readable: null
+end
+```
+
+#### readable.isPaused()
+
+* Return: {Boolean}
+
+This method returns whether or not the `readable` has been **explicitly**
+paused by client code (using [`stream.pause()`][stream-pause] without a
+corresponding [`stream.resume()`][stream-resume]).
+
+```js
+var readable = new stream.Readable
+
+readable.isPaused() // === false
+readable.pause()
+readable.isPaused() // === true
+readable.resume()
+readable.isPaused() // === false
+```
+
+#### readable.pause()
+
+* Return: `this`
+
+This method will cause a stream in flowing mode to stop emitting
+[`'data'`][] events, switching out of flowing mode. Any data that becomes
+available will remain in the internal buffer.
+
+```js
+var readable = getReadableStreamSomehow();
+readable.on('data', (chunk) => {
+ console.log('got %d bytes of data', chunk.length);
+ readable.pause();
+ console.log('there will be no more data for 1 second');
+ setTimeout(() => {
+ console.log('now data will start flowing again');
+ readable.resume();
+ }, 1000);
+});
+```
+
+#### readable.pipe(destination[, options])
+
+* `destination` {stream.Writable} The destination for writing data
+* `options` {Object} Pipe options
+ * `end` {Boolean} End the writer when the reader ends. Default = `true`
+
+This method pulls all the data out of a readable stream, and writes it
+to the supplied destination, automatically managing the flow so that
+the destination is not overwhelmed by a fast readable stream.
+
+Multiple destinations can be piped to safely.
+
+```js
+var readable = getReadableStreamSomehow();
+var writable = fs.createWriteStream('file.txt');
+// All the data from readable goes into 'file.txt'
+readable.pipe(writable);
+```
+
+This function returns the destination stream, so you can set up pipe
+chains like so:
+
+```js
+var r = fs.createReadStream('file.txt');
+var z = zlib.createGzip();
+var w = fs.createWriteStream('file.txt.gz');
+r.pipe(z).pipe(w);
+```
+
+For example, emulating the Unix `cat` command:
+
+```js
+process.stdin.pipe(process.stdout);
+```
+
+By default [`stream.end()`][stream-end] is called on the destination when the
+source stream emits [`'end'`][], so that `destination` is no longer writable.
+Pass `{ end: false }` as `options` to keep the destination stream open.
+
+This keeps `writer` open so that "Goodbye" can be written at the
+end.
+
+```js
+reader.pipe(writer, { end: false });
+reader.on('end', () => {
+ writer.end('Goodbye\n');
+});
+```
+
+Note that [`process.stderr`][] and [`process.stdout`][] are never closed until
+the process exits, regardless of the specified options.
+
+#### readable.read([size])
+
+* `size` {Number} Optional argument to specify how much data to read.
+* Return {String|Buffer|Null}
+
+The `read()` method pulls some data out of the internal buffer and
+returns it. If there is no data available, then it will return
+`null`.
+
+If you pass in a `size` argument, then it will return that many
+bytes. If `size` bytes are not available, then it will return `null`,
+unless we've ended, in which case it will return the data remaining
+in the buffer.
+
+If you do not specify a `size` argument, then it will return all the
+data in the internal buffer.
+
+This method should only be called in paused mode. In flowing mode,
+this method is called automatically until the internal buffer is
+drained.
+
+```js
+var readable = getReadableStreamSomehow();
+readable.on('readable', () => {
+ var chunk;
+ while (null !== (chunk = readable.read())) {
+ console.log('got %d bytes of data', chunk.length);
+ }
+});
+```
+
+If this method returns a data chunk, then it will also trigger the
+emission of a [`'data'`][] event.
+
+Note that calling [`stream.read([size])`][stream-read] after the [`'end'`][]
+event has been triggered will return `null`. No runtime error will be raised.
+
+#### readable.resume()
+
+* Return: `this`
+
+This method will cause the readable stream to resume emitting [`'data'`][]
+events.
+
+This method will switch the stream into flowing mode. If you do *not*
+want to consume the data from a stream, but you *do* want to get to
+its [`'end'`][] event, you can call [`stream.resume()`][stream-resume] to open
+the flow of data.
+
+```js
+var readable = getReadableStreamSomehow();
+readable.resume();
+readable.on('end', () => {
+ console.log('got to the end, but did not read anything');
+});
+```
+
+#### readable.setEncoding(encoding)
+
+* `encoding` {String} The encoding to use.
+* Return: `this`
+
+Call this function to cause the stream to return strings of the specified
+encoding instead of Buffer objects. For example, if you do
+`readable.setEncoding('utf8')`, then the output data will be interpreted as
+UTF-8 data, and returned as strings. If you do `readable.setEncoding('hex')`,
+then the data will be encoded in hexadecimal string format.
+
+This properly handles multi-byte characters that would otherwise be
+potentially mangled if you simply pulled the Buffers directly and
+called [`buf.toString(encoding)`][] on them. If you want to read the data
+as strings, always use this method.
+
+Also you can disable any encoding at all with `readable.setEncoding(null)`.
+This approach is very useful if you deal with binary data or with large
+multi-byte strings spread out over multiple chunks.
+
+```js
+var readable = getReadableStreamSomehow();
+readable.setEncoding('utf8');
+readable.on('data', (chunk) => {
+ assert.equal(typeof chunk, 'string');
+ console.log('got %d characters of string data', chunk.length);
+});
+```
+
+#### readable.unpipe([destination])
+
+* `destination` {stream.Writable} Optional specific stream to unpipe
+
+This method will remove the hooks set up for a previous [`stream.pipe()`][]
+call.
+
+If the destination is not specified, then all pipes are removed.
+
+If the destination is specified, but no pipe is set up for it, then
+this is a no-op.
+
+```js
+var readable = getReadableStreamSomehow();
+var writable = fs.createWriteStream('file.txt');
+// All the data from readable goes into 'file.txt',
+// but only for the first second
+readable.pipe(writable);
+setTimeout(() => {
+ console.log('stop writing to file.txt');
+ readable.unpipe(writable);
+ console.log('manually close the file stream');
+ writable.end();
+}, 1000);
+```
+
+#### readable.unshift(chunk)
+
+* `chunk` {Buffer|String} Chunk of data to unshift onto the read queue
+
+This is useful in certain cases where a stream is being consumed by a
+parser, which needs to "un-consume" some data that it has
+optimistically pulled out of the source, so that the stream can be
+passed on to some other party.
+
+Note that `stream.unshift(chunk)` cannot be called after the [`'end'`][] event
+has been triggered; a runtime error will be raised.
+
+If you find that you must often call `stream.unshift(chunk)` in your
+programs, consider implementing a [Transform][] stream instead. (See [API
+for Stream Implementors][].)
+
+```js
+// Pull off a header delimited by \n\n
+// use unshift() if we get too much
+// Call the callback with (error, header, stream)
+const StringDecoder = require('string_decoder').StringDecoder;
+function parseHeader(stream, callback) {
+ stream.on('error', callback);
+ stream.on('readable', onReadable);
+ var decoder = new StringDecoder('utf8');
+ var header = '';
+ function onReadable() {
+ var chunk;
+ while (null !== (chunk = stream.read())) {
+ var str = decoder.write(chunk);
+ if (str.match(/\n\n/)) {
+ // found the header boundary
+ var split = str.split(/\n\n/);
+ header += split.shift();
+ var remaining = split.join('\n\n');
+ var buf = new Buffer(remaining, 'utf8');
+ if (buf.length)
+ stream.unshift(buf);
+ stream.removeListener('error', callback);
+ stream.removeListener('readable', onReadable);
+ // now the body of the message can be read from the stream.
+ callback(null, header, stream);
+ } else {
+ // still reading the header.
+ header += str;
+ }
+ }
+ }
+}
+```
+
+Note that, unlike [`stream.push(chunk)`][stream-push], `stream.unshift(chunk)`
+will not end the reading process by resetting the internal reading state of the
+stream. This can cause unexpected results if `unshift()` is called during a
+read (i.e. from within a [`stream._read()`][stream-_read] implementation on a
+custom stream). Following the call to `unshift()` with an immediate
+[`stream.push('')`][stream-push] will reset the reading state appropriately,
+however it is best to simply avoid calling `unshift()` while in the process of
+performing a read.
+
+#### readable.wrap(stream)
+
+* `stream` {Stream} An "old style" readable stream
+
+Versions of Node.js prior to v0.10 had streams that did not implement the
+entire Streams API as it is today. (See [Compatibility][] for
+more information.)
+
+If you are using an older Node.js library that emits [`'data'`][] events and
+has a [`stream.pause()`][stream-pause] method that is advisory only, then you
+can use the `wrap()` method to create a [Readable][] stream that uses the old
+stream as its data source.
+
+You will very rarely ever need to call this function, but it exists
+as a convenience for interacting with old Node.js programs and libraries.
+
+For example:
+
+```js
+const OldReader = require('./old-api-module.js').OldReader;
+const Readable = require('stream').Readable;
+const oreader = new OldReader;
+const myReader = new Readable().wrap(oreader);
+
+myReader.on('readable', () => {
+ myReader.read(); // etc.
+});
+```
+
+### Class: stream.Transform
+
+Transform streams are [Duplex][] streams where the output is in some way
+computed from the input. They implement both the [Readable][] and
+[Writable][] interfaces.
+
+Examples of Transform streams include:
+
+* [zlib streams][zlib]
+* [crypto streams][crypto]
+
+### Class: stream.Writable
+
+
+
+The Writable stream interface is an abstraction for a *destination*
+that you are writing data *to*.
+
+Examples of writable streams include:
+
+* [HTTP requests, on the client][]
+* [HTTP responses, on the server][]
+* [fs write streams][]
+* [zlib streams][zlib]
+* [crypto streams][crypto]
+* [TCP sockets][]
+* [child process stdin][]
+* [`process.stdout`][], [`process.stderr`][]
+
+#### Event: 'drain'
+
+If a [`stream.write(chunk)`][stream-write] call returns `false`, then the
+`'drain'` event will indicate when it is appropriate to begin writing more data
+to the stream.
+
+```js
+// Write the data to the supplied writable stream one million times.
+// Be attentive to back-pressure.
+function writeOneMillionTimes(writer, data, encoding, callback) {
+ var i = 1000000;
+ write();
+ function write() {
+ var ok = true;
+ do {
+ i -= 1;
+ if (i === 0) {
+ // last time!
+ writer.write(data, encoding, callback);
+ } else {
+ // see if we should continue, or wait
+ // don't pass the callback, because we're not done yet.
+ ok = writer.write(data, encoding);
+ }
+ } while (i > 0 && ok);
+ if (i > 0) {
+ // had to stop early!
+ // write some more once it drains
+ writer.once('drain', write);
+ }
+ }
+}
+```
+
+#### Event: 'error'
+
+* {Error}
+
+Emitted if there was an error when writing or piping data.
+
+#### Event: 'finish'
+
+When the [`stream.end()`][stream-end] method has been called, and all data has
+been flushed to the underlying system, this event is emitted.
+
+```javascript
+var writer = getWritableStreamSomehow();
+for (var i = 0; i < 100; i ++) {
+ writer.write('hello, #${i}!\n');
+}
+writer.end('this is the end\n');
+writer.on('finish', () => {
+ console.error('all writes are now complete.');
+});
+```
+
+#### Event: 'pipe'
+
+* `src` {stream.Readable} source stream that is piping to this writable
+
+This is emitted whenever the [`stream.pipe()`][] method is called on a readable
+stream, adding this writable to its set of destinations.
+
+```js
+var writer = getWritableStreamSomehow();
+var reader = getReadableStreamSomehow();
+writer.on('pipe', (src) => {
+ console.error('something is piping into the writer');
+ assert.equal(src, reader);
+});
+reader.pipe(writer);
+```
+
+#### Event: 'unpipe'
+
+* `src` {[Readable][] Stream} The source stream that
+ [unpiped][`stream.unpipe()`] this writable
+
+This is emitted whenever the [`stream.unpipe()`][] method is called on a
+readable stream, removing this writable from its set of destinations.
+
+```js
+var writer = getWritableStreamSomehow();
+var reader = getReadableStreamSomehow();
+writer.on('unpipe', (src) => {
+ console.error('something has stopped piping into the writer');
+ assert.equal(src, reader);
+});
+reader.pipe(writer);
+reader.unpipe(writer);
+```
+
+#### writable.cork()
+
+Forces buffering of all writes.
+
+Buffered data will be flushed either at [`stream.uncork()`][] or at
+[`stream.end()`][stream-end] call.
+
+#### writable.end([chunk][, encoding][, callback])
+
+* `chunk` {String|Buffer} Optional data to write
+* `encoding` {String} The encoding, if `chunk` is a String
+* `callback` {Function} Optional callback for when the stream is finished
+
+Call this method when no more data will be written to the stream. If supplied,
+the callback is attached as a listener on the [`'finish'`][] event.
+
+Calling [`stream.write()`][stream-write] after calling
+[`stream.end()`][stream-end] will raise an error.
+
+```js
+// write 'hello, ' and then end with 'world!'
+var file = fs.createWriteStream('example.txt');
+file.write('hello, ');
+file.end('world!');
+// writing more now is not allowed!
+```
+
+#### writable.setDefaultEncoding(encoding)
+
+* `encoding` {String} The new default encoding
+
+Sets the default encoding for a writable stream.
+
+#### writable.uncork()
+
+Flush all data, buffered since [`stream.cork()`][] call.
+
+#### writable.write(chunk[, encoding][, callback])
+
+* `chunk` {String|Buffer} The data to write
+* `encoding` {String} The encoding, if `chunk` is a String
+* `callback` {Function} Callback for when this chunk of data is flushed
+* Returns: {Boolean} `true` if the data was handled completely.
+
+This method writes some data to the underlying system, and calls the
+supplied callback once the data has been fully handled.
+
+The return value indicates if you should continue writing right now.
+If the data had to be buffered internally, then it will return
+`false`. Otherwise, it will return `true`.
+
+This return value is strictly advisory. You MAY continue to write,
+even if it returns `false`. However, writes will be buffered in
+memory, so it is best not to do this excessively. Instead, wait for
+the [`'drain'`][] event before writing more data.
+
+
+## API for Stream Implementors
+
+
+
+To implement any sort of stream, the pattern is the same:
+
+1. Extend the appropriate parent class in your own subclass. (The
+ [`util.inherits()`][] method is particularly helpful for this.)
+2. Call the appropriate parent class constructor in your constructor,
+ to be sure that the internal mechanisms are set up properly.
+3. Implement one or more specific methods, as detailed below.
+
+The class to extend and the method(s) to implement depend on the sort
+of stream class you are writing:
+
+
+
+
+
+ Use-case
+ |
+
+ Class
+ |
+
+ Method(s) to implement
+ |
+
+
+
+
+ Reading only
+ |
+
+ [Readable](#stream_class_stream_readable_1)
+ |
+
+ [_read][stream-_read]
+ |
+
+
+
+ Writing only
+ |
+
+ [Writable](#stream_class_stream_writable_1)
+ |
+
+ [_write][stream-_write] , [_writev][stream-_writev]
+ |
+
+
+
+ Reading and writing
+ |
+
+ [Duplex](#stream_class_stream_duplex_1)
+ |
+
+ [_read][stream-_read] , [_write][stream-_write] , [_writev][stream-_writev]
+ |
+
+
+
+ Operate on written data, then read the result
+ |
+
+ [Transform](#stream_class_stream_transform_1)
+ |
+
+ [_transform][stream-_transform] , [_flush][stream-_flush]
+ |
+
+
+
+In your implementation code, it is very important to never call the methods
+described in [API for Stream Consumers][]. Otherwise, you can potentially cause
+adverse side effects in programs that consume your streaming interfaces.
+
+### Class: stream.Duplex
+
+
+
+A "duplex" stream is one that is both Readable and Writable, such as a TCP
+socket connection.
+
+Note that `stream.Duplex` is an abstract class designed to be extended
+with an underlying implementation of the [`stream._read(size)`][stream-_read]
+and [`stream._write(chunk, encoding, callback)`][stream-_write] methods as you
+would with a Readable or Writable stream class.
+
+Since JavaScript doesn't have multiple prototypal inheritance, this class
+prototypally inherits from Readable, and then parasitically from Writable. It is
+thus up to the user to implement both the low-level
+[`stream._read(n)`][stream-_read] method as well as the low-level
+[`stream._write(chunk, encoding, callback)`][stream-_write] method on extension
+duplex classes.
+
+#### new stream.Duplex(options)
+
+* `options` {Object} Passed to both Writable and Readable
+ constructors. Also has the following fields:
+ * `allowHalfOpen` {Boolean} Default = `true`. If set to `false`, then
+ the stream will automatically end the readable side when the
+ writable side ends and vice versa.
+ * `readableObjectMode` {Boolean} Default = `false`. Sets `objectMode`
+ for readable side of the stream. Has no effect if `objectMode`
+ is `true`.
+ * `writableObjectMode` {Boolean} Default = `false`. Sets `objectMode`
+ for writable side of the stream. Has no effect if `objectMode`
+ is `true`.
+
+In classes that extend the Duplex class, make sure to call the
+constructor so that the buffering settings can be properly
+initialized.
+
+### Class: stream.PassThrough
+
+This is a trivial implementation of a [Transform][] stream that simply
+passes the input bytes across to the output. Its purpose is mainly
+for examples and testing, but there are occasionally use cases where
+it can come in handy as a building block for novel sorts of streams.
+
+### Class: stream.Readable
+
+
+
+`stream.Readable` is an abstract class designed to be extended with an
+underlying implementation of the [`stream._read(size)`][stream-_read] method.
+
+Please see [API for Stream Consumers][] for how to consume
+streams in your programs. What follows is an explanation of how to
+implement Readable streams in your programs.
+
+#### new stream.Readable([options])
+
+* `options` {Object}
+ * `highWaterMark` {Number} The maximum number of bytes to store in
+ the internal buffer before ceasing to read from the underlying
+ resource. Default = `16384` (16kb), or `16` for `objectMode` streams
+ * `encoding` {String} If specified, then buffers will be decoded to
+ strings using the specified encoding. Default = `null`
+ * `objectMode` {Boolean} Whether this stream should behave
+ as a stream of objects. Meaning that [`stream.read(n)`][stream-read] returns
+ a single value instead of a Buffer of size n. Default = `false`
+ * `read` {Function} Implementation for the [`stream._read()`][stream-_read]
+ method.
+
+In classes that extend the Readable class, make sure to call the
+Readable constructor so that the buffering settings can be properly
+initialized.
+
+#### readable.\_read(size)
+
+* `size` {Number} Number of bytes to read asynchronously
+
+Note: **Implement this method, but do NOT call it directly.**
+
+This method is prefixed with an underscore because it is internal to the
+class that defines it and should only be called by the internal Readable
+class methods. All Readable stream implementations must provide a \_read
+method to fetch data from the underlying resource.
+
+When `_read()` is called, if data is available from the resource, the `_read()`
+implementation should start pushing that data into the read queue by calling
+[`this.push(dataChunk)`][stream-push]. `_read()` should continue reading from
+the resource and pushing data until push returns `false`, at which point it
+should stop reading from the resource. Only when `_read()` is called again after
+it has stopped should it start reading more data from the resource and pushing
+that data onto the queue.
+
+Note: once the `_read()` method is called, it will not be called again until
+the [`stream.push()`][stream-push] method is called.
+
+The `size` argument is advisory. Implementations where a "read" is a
+single call that returns data can use this to know how much data to
+fetch. Implementations where that is not relevant, such as TCP or
+TLS, may ignore this argument, and simply provide data whenever it
+becomes available. There is no need, for example to "wait" until
+`size` bytes are available before calling [`stream.push(chunk)`][stream-push].
+
+#### readable.push(chunk[, encoding])
+
+
+* `chunk` {Buffer|Null|String} Chunk of data to push into the read queue
+* `encoding` {String} Encoding of String chunks. Must be a valid
+ Buffer encoding, such as `'utf8'` or `'ascii'`
+* return {Boolean} Whether or not more pushes should be performed
+
+Note: **This method should be called by Readable implementors, NOT
+by consumers of Readable streams.**
+
+If a value other than null is passed, The `push()` method adds a chunk of data
+into the queue for subsequent stream processors to consume. If `null` is
+passed, it signals the end of the stream (EOF), after which no more data
+can be written.
+
+The data added with `push()` can be pulled out by calling the
+[`stream.read()`][stream-read] method when the [`'readable'`][] event fires.
+
+This API is designed to be as flexible as possible. For example,
+you may be wrapping a lower-level source which has some sort of
+pause/resume mechanism, and a data callback. In those cases, you
+could wrap the low-level source object by doing something like this:
+
+```js
+// source is an object with readStop() and readStart() methods,
+// and an `ondata` member that gets called when it has data, and
+// an `onend` member that gets called when the data is over.
+
+util.inherits(SourceWrapper, Readable);
+
+function SourceWrapper(options) {
+ Readable.call(this, options);
+
+ this._source = getLowlevelSourceObject();
+
+ // Every time there's data, we push it into the internal buffer.
+ this._source.ondata = (chunk) => {
+ // if push() returns false, then we need to stop reading from source
+ if (!this.push(chunk))
+ this._source.readStop();
+ };
+
+ // When the source ends, we push the EOF-signaling `null` chunk
+ this._source.onend = () => {
+ this.push(null);
+ };
+}
+
+// _read will be called when the stream wants to pull more data in
+// the advisory size argument is ignored in this case.
+SourceWrapper.prototype._read = function(size) {
+ this._source.readStart();
+};
+```
+
+#### Example: A Counting Stream
+
+
+
+This is a basic example of a Readable stream. It emits the numerals
+from 1 to 1,000,000 in ascending order, and then ends.
+
+```js
+const Readable = require('stream').Readable;
+const util = require('util');
+util.inherits(Counter, Readable);
+
+function Counter(opt) {
+ Readable.call(this, opt);
+ this._max = 1000000;
+ this._index = 1;
+}
+
+Counter.prototype._read = function() {
+ var i = this._index++;
+ if (i > this._max)
+ this.push(null);
+ else {
+ var str = '' + i;
+ var buf = new Buffer(str, 'ascii');
+ this.push(buf);
+ }
+};
+```
+
+#### Example: SimpleProtocol v1 (Sub-optimal)
+
+This is similar to the `parseHeader` function described
+[here](#stream_readable_unshift_chunk), but implemented as a custom stream.
+Also, note that this implementation does not convert the incoming data to a
+string.
+
+However, this would be better implemented as a [Transform][] stream. See
+[SimpleProtocol v2][] for a better implementation.
+
+```js
+// A parser for a simple data protocol.
+// The "header" is a JSON object, followed by 2 \n characters, and
+// then a message body.
+//
+// NOTE: This can be done more simply as a Transform stream!
+// Using Readable directly for this is sub-optimal. See the
+// alternative example below under the Transform section.
+
+const Readable = require('stream').Readable;
+const util = require('util');
+
+util.inherits(SimpleProtocol, Readable);
+
+function SimpleProtocol(source, options) {
+ if (!(this instanceof SimpleProtocol))
+ return new SimpleProtocol(source, options);
+
+ Readable.call(this, options);
+ this._inBody = false;
+ this._sawFirstCr = false;
+
+ // source is a readable stream, such as a socket or file
+ this._source = source;
+
+ var self = this;
+ source.on('end', () => {
+ self.push(null);
+ });
+
+ // give it a kick whenever the source is readable
+ // read(0) will not consume any bytes
+ source.on('readable', () => {
+ self.read(0);
+ });
+
+ this._rawHeader = [];
+ this.header = null;
+}
+
+SimpleProtocol.prototype._read = function(n) {
+ if (!this._inBody) {
+ var chunk = this._source.read();
+
+ // if the source doesn't have data, we don't have data yet.
+ if (chunk === null)
+ return this.push('');
+
+ // check if the chunk has a \n\n
+ var split = -1;
+ for (var i = 0; i < chunk.length; i++) {
+ if (chunk[i] === 10) { // '\n'
+ if (this._sawFirstCr) {
+ split = i;
+ break;
+ } else {
+ this._sawFirstCr = true;
+ }
+ } else {
+ this._sawFirstCr = false;
+ }
+ }
+
+ if (split === -1) {
+ // still waiting for the \n\n
+ // stash the chunk, and try again.
+ this._rawHeader.push(chunk);
+ this.push('');
+ } else {
+ this._inBody = true;
+ var h = chunk.slice(0, split);
+ this._rawHeader.push(h);
+ var header = Buffer.concat(this._rawHeader).toString();
+ try {
+ this.header = JSON.parse(header);
+ } catch (er) {
+ this.emit('error', new Error('invalid simple protocol data'));
+ return;
+ }
+ // now, because we got some extra data, unshift the rest
+ // back into the read queue so that our consumer will see it.
+ var b = chunk.slice(split);
+ this.unshift(b);
+ // calling unshift by itself does not reset the reading state
+ // of the stream; since we're inside _read, doing an additional
+ // push('') will reset the state appropriately.
+ this.push('');
+
+ // and let them know that we are done parsing the header.
+ this.emit('header', this.header);
+ }
+ } else {
+ // from there on, just provide the data to our consumer.
+ // careful not to push(null), since that would indicate EOF.
+ var chunk = this._source.read();
+ if (chunk) this.push(chunk);
+ }
+};
+
+// Usage:
+// var parser = new SimpleProtocol(source);
+// Now parser is a readable stream that will emit 'header'
+// with the parsed header data.
+```
+
+### Class: stream.Transform
+
+A "transform" stream is a duplex stream where the output is causally
+connected in some way to the input, such as a [zlib][] stream or a
+[crypto][] stream.
+
+There is no requirement that the output be the same size as the input,
+the same number of chunks, or arrive at the same time. For example, a
+Hash stream will only ever have a single chunk of output which is
+provided when the input is ended. A zlib stream will produce output
+that is either much smaller or much larger than its input.
+
+Rather than implement the [`stream._read()`][stream-_read] and
+[`stream._write()`][stream-_write] methods, Transform classes must implement the
+[`stream._transform()`][stream-_transform] method, and may optionally
+also implement the [`stream._flush()`][stream-_flush] method. (See below.)
+
+#### new stream.Transform([options])
+
+* `options` {Object} Passed to both Writable and Readable
+ constructors. Also has the following fields:
+ * `transform` {Function} Implementation for the
+ [`stream._transform()`][stream-_transform] method.
+ * `flush` {Function} Implementation for the [`stream._flush()`][stream-_flush]
+ method.
+
+In classes that extend the Transform class, make sure to call the
+constructor so that the buffering settings can be properly
+initialized.
+
+#### Events: 'finish' and 'end'
+
+The [`'finish'`][] and [`'end'`][] events are from the parent Writable
+and Readable classes respectively. The `'finish'` event is fired after
+[`stream.end()`][stream-end] is called and all chunks have been processed by
+[`stream._transform()`][stream-_transform], `'end'` is fired after all data has
+been output which is after the callback in [`stream._flush()`][stream-_flush]
+has been called.
+
+#### transform.\_flush(callback)
+
+* `callback` {Function} Call this function (optionally with an error
+ argument) when you are done flushing any remaining data.
+
+Note: **This function MUST NOT be called directly.** It MAY be implemented
+by child classes, and if so, will be called by the internal Transform
+class methods only.
+
+In some cases, your transform operation may need to emit a bit more
+data at the end of the stream. For example, a `Zlib` compression
+stream will store up some internal state so that it can optimally
+compress the output. At the end, however, it needs to do the best it
+can with what is left, so that the data will be complete.
+
+In those cases, you can implement a `_flush()` method, which will be
+called at the very end, after all the written data is consumed, but
+before emitting [`'end'`][] to signal the end of the readable side. Just
+like with [`stream._transform()`][stream-_transform], call
+`transform.push(chunk)` zero or more times, as appropriate, and call `callback`
+when the flush operation is complete.
+
+This method is prefixed with an underscore because it is internal to
+the class that defines it, and should not be called directly by user
+programs. However, you **are** expected to override this method in
+your own extension classes.
+
+#### transform.\_transform(chunk, encoding, callback)
+
+* `chunk` {Buffer|String} The chunk to be transformed. Will **always**
+ be a buffer unless the `decodeStrings` option was set to `false`.
+* `encoding` {String} If the chunk is a string, then this is the
+ encoding type. If chunk is a buffer, then this is the special
+ value - 'buffer', ignore it in this case.
+* `callback` {Function} Call this function (optionally with an error
+ argument and data) when you are done processing the supplied chunk.
+
+Note: **This function MUST NOT be called directly.** It should be
+implemented by child classes, and called by the internal Transform
+class methods only.
+
+All Transform stream implementations must provide a `_transform()`
+method to accept input and produce output.
+
+`_transform()` should do whatever has to be done in this specific
+Transform class, to handle the bytes being written, and pass them off
+to the readable portion of the interface. Do asynchronous I/O,
+process things, and so on.
+
+Call `transform.push(outputChunk)` 0 or more times to generate output
+from this input chunk, depending on how much data you want to output
+as a result of this chunk.
+
+Call the callback function only when the current chunk is completely
+consumed. Note that there may or may not be output as a result of any
+particular input chunk. If you supply a second argument to the callback
+it will be passed to the push method. In other words the following are
+equivalent:
+
+```js
+transform.prototype._transform = function (data, encoding, callback) {
+ this.push(data);
+ callback();
+};
+
+transform.prototype._transform = function (data, encoding, callback) {
+ callback(null, data);
+};
+```
+
+This method is prefixed with an underscore because it is internal to
+the class that defines it, and should not be called directly by user
+programs. However, you **are** expected to override this method in
+your own extension classes.
+
+#### Example: `SimpleProtocol` parser v2
+
+The example [here](#stream_example_simpleprotocol_v1_sub_optimal) of a simple
+protocol parser can be implemented simply by using the higher level
+[Transform][] stream class, similar to the `parseHeader` and `SimpleProtocol
+v1` examples.
+
+In this example, rather than providing the input as an argument, it
+would be piped into the parser, which is a more idiomatic Node.js stream
+approach.
+
+```javascript
+const util = require('util');
+const Transform = require('stream').Transform;
+util.inherits(SimpleProtocol, Transform);
+
+function SimpleProtocol(options) {
+ if (!(this instanceof SimpleProtocol))
+ return new SimpleProtocol(options);
+
+ Transform.call(this, options);
+ this._inBody = false;
+ this._sawFirstCr = false;
+ this._rawHeader = [];
+ this.header = null;
+}
+
+SimpleProtocol.prototype._transform = function(chunk, encoding, done) {
+ if (!this._inBody) {
+ // check if the chunk has a \n\n
+ var split = -1;
+ for (var i = 0; i < chunk.length; i++) {
+ if (chunk[i] === 10) { // '\n'
+ if (this._sawFirstCr) {
+ split = i;
+ break;
+ } else {
+ this._sawFirstCr = true;
+ }
+ } else {
+ this._sawFirstCr = false;
+ }
+ }
+
+ if (split === -1) {
+ // still waiting for the \n\n
+ // stash the chunk, and try again.
+ this._rawHeader.push(chunk);
+ } else {
+ this._inBody = true;
+ var h = chunk.slice(0, split);
+ this._rawHeader.push(h);
+ var header = Buffer.concat(this._rawHeader).toString();
+ try {
+ this.header = JSON.parse(header);
+ } catch (er) {
+ this.emit('error', new Error('invalid simple protocol data'));
+ return;
+ }
+ // and let them know that we are done parsing the header.
+ this.emit('header', this.header);
+
+ // now, because we got some extra data, emit this first.
+ this.push(chunk.slice(split));
+ }
+ } else {
+ // from there on, just provide the data to our consumer as-is.
+ this.push(chunk);
+ }
+ done();
+};
+
+// Usage:
+// var parser = new SimpleProtocol();
+// source.pipe(parser)
+// Now parser is a readable stream that will emit 'header'
+// with the parsed header data.
+```
+
+### Class: stream.Writable
+
+
+
+`stream.Writable` is an abstract class designed to be extended with an
+underlying implementation of the
+[`stream._write(chunk, encoding, callback)`][stream-_write] method.
+
+Please see [API for Stream Consumers][] for how to consume
+writable streams in your programs. What follows is an explanation of
+how to implement Writable streams in your programs.
+
+#### new stream.Writable([options])
+
+* `options` {Object}
+ * `highWaterMark` {Number} Buffer level when
+ [`stream.write()`][stream-write] starts returning `false`. Default = `16384`
+ (16kb), or `16` for `objectMode` streams.
+ * `decodeStrings` {Boolean} Whether or not to decode strings into
+ Buffers before passing them to [`stream._write()`][stream-_write].
+ Default = `true`
+ * `objectMode` {Boolean} Whether or not the
+ [`stream.write(anyObj)`][stream-write] is a valid operation. If set you can
+ write arbitrary data instead of only `Buffer` / `String` data.
+ Default = `false`
+ * `write` {Function} Implementation for the
+ [`stream._write()`][stream-_write] method.
+ * `writev` {Function} Implementation for the
+ [`stream._writev()`][stream-_writev] method.
+
+In classes that extend the Writable class, make sure to call the
+constructor so that the buffering settings can be properly
+initialized.
+
+#### writable.\_write(chunk, encoding, callback)
+
+* `chunk` {Buffer|String} The chunk to be written. Will **always**
+ be a buffer unless the `decodeStrings` option was set to `false`.
+* `encoding` {String} If the chunk is a string, then this is the
+ encoding type. If chunk is a buffer, then this is the special
+ value - 'buffer', ignore it in this case.
+* `callback` {Function} Call this function (optionally with an error
+ argument) when you are done processing the supplied chunk.
+
+All Writable stream implementations must provide a
+[`stream._write()`][stream-_write] method to send data to the underlying
+resource.
+
+Note: **This function MUST NOT be called directly.** It should be
+implemented by child classes, and called by the internal Writable
+class methods only.
+
+Call the callback using the standard `callback(error)` pattern to
+signal that the write completed successfully or with an error.
+
+If the `decodeStrings` flag is set in the constructor options, then
+`chunk` may be a string rather than a Buffer, and `encoding` will
+indicate the sort of string that it is. This is to support
+implementations that have an optimized handling for certain string
+data encodings. If you do not explicitly set the `decodeStrings`
+option to `false`, then you can safely ignore the `encoding` argument,
+and assume that `chunk` will always be a Buffer.
+
+This method is prefixed with an underscore because it is internal to
+the class that defines it, and should not be called directly by user
+programs. However, you **are** expected to override this method in
+your own extension classes.
+
+#### writable.\_writev(chunks, callback)
+
+* `chunks` {Array} The chunks to be written. Each chunk has following
+ format: `{ chunk: ..., encoding: ... }`.
+* `callback` {Function} Call this function (optionally with an error
+ argument) when you are done processing the supplied chunks.
+
+Note: **This function MUST NOT be called directly.** It may be
+implemented by child classes, and called by the internal Writable
+class methods only.
+
+This function is completely optional to implement. In most cases it is
+unnecessary. If implemented, it will be called with all the chunks
+that are buffered in the write queue.
+
+
+## Simplified Constructor API
+
+
+
+In simple cases there is now the added benefit of being able to construct a
+stream without inheritance.
+
+This can be done by passing the appropriate methods as constructor options:
+
+Examples:
+
+### Duplex
+
+```js
+var duplex = new stream.Duplex({
+ read: function(n) {
+ // sets this._read under the hood
+
+ // push data onto the read queue, passing null
+ // will signal the end of the stream (EOF)
+ this.push(chunk);
+ },
+ write: function(chunk, encoding, next) {
+ // sets this._write under the hood
+
+ // An optional error can be passed as the first argument
+ next()
+ }
+});
+
+// or
+
+var duplex = new stream.Duplex({
+ read: function(n) {
+ // sets this._read under the hood
+
+ // push data onto the read queue, passing null
+ // will signal the end of the stream (EOF)
+ this.push(chunk);
+ },
+ writev: function(chunks, next) {
+ // sets this._writev under the hood
+
+ // An optional error can be passed as the first argument
+ next()
+ }
+});
+```
+
+### Readable
+
+```js
+var readable = new stream.Readable({
+ read: function(n) {
+ // sets this._read under the hood
+
+ // push data onto the read queue, passing null
+ // will signal the end of the stream (EOF)
+ this.push(chunk);
+ }
+});
+```
+
+### Transform
+
+```js
+var transform = new stream.Transform({
+ transform: function(chunk, encoding, next) {
+ // sets this._transform under the hood
+
+ // generate output as many times as needed
+ // this.push(chunk);
+
+ // call when the current chunk is consumed
+ next();
+ },
+ flush: function(done) {
+ // sets this._flush under the hood
+
+ // generate output as many times as needed
+ // this.push(chunk);
+
+ done();
+ }
+});
+```
+
+### Writable
+
+```js
+var writable = new stream.Writable({
+ write: function(chunk, encoding, next) {
+ // sets this._write under the hood
+
+ // An optional error can be passed as the first argument
+ next()
+ }
+});
+
+// or
+
+var writable = new stream.Writable({
+ writev: function(chunks, next) {
+ // sets this._writev under the hood
+
+ // An optional error can be passed as the first argument
+ next()
+ }
+});
+```
+
+## Streams: Under the Hood
+
+
+
+### Buffering
+
+
+
+Both Writable and Readable streams will buffer data on an internal
+object which can be retrieved from `_writableState.getBuffer()` or
+`_readableState.buffer`, respectively.
+
+The amount of data that will potentially be buffered depends on the
+`highWaterMark` option which is passed into the constructor.
+
+Buffering in Readable streams happens when the implementation calls
+[`stream.push(chunk)`][stream-push]. If the consumer of the Stream does not
+call [`stream.read()`][stream-read], then the data will sit in the internal
+queue until it is consumed.
+
+Buffering in Writable streams happens when the user calls
+[`stream.write(chunk)`][stream-write] repeatedly, even when it returns `false`.
+
+The purpose of streams, especially with the [`stream.pipe()`][] method, is to
+limit the buffering of data to acceptable levels, so that sources and
+destinations of varying speed will not overwhelm the available memory.
+
+### Compatibility with Older Node.js Versions
+
+
+
+In versions of Node.js prior to v0.10, the Readable stream interface was
+simpler, but also less powerful and less useful.
+
+* Rather than waiting for you to call the [`stream.read()`][stream-read] method,
+ [`'data'`][] events would start emitting immediately. If you needed to do
+ some I/O to decide how to handle data, then you had to store the chunks
+ in some kind of buffer so that they would not be lost.
+* The [`stream.pause()`][stream-pause] method was advisory, rather than
+ guaranteed. This meant that you still had to be prepared to receive
+ [`'data'`][] events even when the stream was in a paused state.
+
+In Node.js v0.10, the [Readable][] class was added.
+For backwards compatibility with older Node.js programs, Readable streams
+switch into "flowing mode" when a [`'data'`][] event handler is added, or
+when the [`stream.resume()`][stream-resume] method is called. The effect is
+that, even if you are not using the new [`stream.read()`][stream-read] method
+and [`'readable'`][] event, you no longer have to worry about losing
+[`'data'`][] chunks.
+
+Most programs will continue to function normally. However, this
+introduces an edge case in the following conditions:
+
+* No [`'data'`][] event handler is added.
+* The [`stream.resume()`][stream-resume] method is never called.
+* The stream is not piped to any writable destination.
+
+For example, consider the following code:
+
+```js
+// WARNING! BROKEN!
+net.createServer((socket) => {
+
+ // we add an 'end' method, but never consume the data
+ socket.on('end', () => {
+ // It will never get here.
+ socket.end('I got your message (but didnt read it)\n');
+ });
+
+}).listen(1337);
+```
+
+In versions of Node.js prior to v0.10, the incoming message data would be
+simply discarded. However, in Node.js v0.10 and beyond,
+the socket will remain paused forever.
+
+The workaround in this situation is to call the
+[`stream.resume()`][stream-resume] method to start the flow of data:
+
+```js
+// Workaround
+net.createServer((socket) => {
+
+ socket.on('end', () => {
+ socket.end('I got your message (but didnt read it)\n');
+ });
+
+ // start the flow of data, discarding it.
+ socket.resume();
+
+}).listen(1337);
+```
+
+In addition to new Readable streams switching into flowing mode,
+pre-v0.10 style streams can be wrapped in a Readable class using the
+[`stream.wrap()`][] method.
+
+
+### Object Mode
+
+
+
+Normally, Streams operate on Strings and Buffers exclusively.
+
+Streams that are in **object mode** can emit generic JavaScript values
+other than Buffers and Strings.
+
+A Readable stream in object mode will always return a single item from
+a call to [`stream.read(size)`][stream-read], regardless of what the size
+argument is.
+
+A Writable stream in object mode will always ignore the `encoding`
+argument to [`stream.write(data, encoding)`][stream-write].
+
+The special value `null` still retains its special value for object
+mode streams. That is, for object mode readable streams, `null` as a
+return value from [`stream.read()`][stream-read] indicates that there is no more
+data, and [`stream.push(null)`][stream-push] will signal the end of stream data
+(`EOF`).
+
+No streams in Node.js core are object mode streams. This pattern is only
+used by userland streaming libraries.
+
+You should set `objectMode` in your stream child class constructor on
+the options object. Setting `objectMode` mid-stream is not safe.
+
+For Duplex streams `objectMode` can be set exclusively for readable or
+writable side with `readableObjectMode` and `writableObjectMode`
+respectively. These options can be used to implement parsers and
+serializers with Transform streams.
+
+```js
+const util = require('util');
+const StringDecoder = require('string_decoder').StringDecoder;
+const Transform = require('stream').Transform;
+util.inherits(JSONParseStream, Transform);
+
+// Gets \n-delimited JSON string data, and emits the parsed objects
+function JSONParseStream() {
+ if (!(this instanceof JSONParseStream))
+ return new JSONParseStream();
+
+ Transform.call(this, { readableObjectMode : true });
+
+ this._buffer = '';
+ this._decoder = new StringDecoder('utf8');
+}
+
+JSONParseStream.prototype._transform = function(chunk, encoding, cb) {
+ this._buffer += this._decoder.write(chunk);
+ // split on newlines
+ var lines = this._buffer.split(/\r?\n/);
+ // keep the last partial line buffered
+ this._buffer = lines.pop();
+ for (var l = 0; l < lines.length; l++) {
+ var line = lines[l];
+ try {
+ var obj = JSON.parse(line);
+ } catch (er) {
+ this.emit('error', er);
+ return;
+ }
+ // push the parsed object out to the readable consumer
+ this.push(obj);
+ }
+ cb();
+};
+
+JSONParseStream.prototype._flush = function(cb) {
+ // Just handle any leftover
+ var rem = this._buffer.trim();
+ if (rem) {
+ try {
+ var obj = JSON.parse(rem);
+ } catch (er) {
+ this.emit('error', er);
+ return;
+ }
+ // push the parsed object out to the readable consumer
+ this.push(obj);
+ }
+ cb();
+};
+```
+
+### `stream.read(0)`
+
+There are some cases where you want to trigger a refresh of the
+underlying readable stream mechanisms, without actually consuming any
+data. In that case, you can call `stream.read(0)`, which will always
+return null.
+
+If the internal read buffer is below the `highWaterMark`, and the
+stream is not currently reading, then calling `stream.read(0)` will trigger
+a low-level [`stream._read()`][stream-_read] call.
+
+There is almost never a need to do this. However, you will see some
+cases in Node.js's internals where this is done, particularly in the
+Readable stream class internals.
+
+### `stream.push('')`
+
+Pushing a zero-byte string or Buffer (when not in [Object mode][]) has an
+interesting side effect. Because it *is* a call to
+[`stream.push()`][stream-push], it will end the `reading` process. However, it
+does *not* add any data to the readable buffer, so there's nothing for
+a user to consume.
+
+Very rarely, there are cases where you have no data to provide now,
+but the consumer of your stream (or, perhaps, another bit of your own
+code) will know when to check again, by calling [`stream.read(0)`][stream-read].
+In those cases, you *may* call `stream.push('')`.
+
+So far, the only use case for this functionality is in the
+[`tls.CryptoStream`][] class, which is deprecated in Node.js/io.js v1.0. If you
+find that you have to use `stream.push('')`, please consider another
+approach, because it almost certainly indicates that something is
+horribly wrong.
+
+[`'data'`]: #stream_event_data
+[`'drain'`]: #stream_event_drain
+[`'end'`]: #stream_event_end
+[`'finish'`]: #stream_event_finish
+[`'readable'`]: #stream_event_readable
+[`buf.toString(encoding)`]: https://nodejs.org/docs/v5.8.0/api/buffer.html#buffer_buf_tostring_encoding_start_end
+[`EventEmitter`]: https://nodejs.org/docs/v5.8.0/api/events.html#events_class_eventemitter
+[`process.stderr`]: https://nodejs.org/docs/v5.8.0/api/process.html#process_process_stderr
+[`process.stdin`]: https://nodejs.org/docs/v5.8.0/api/process.html#process_process_stdin
+[`process.stdout`]: https://nodejs.org/docs/v5.8.0/api/process.html#process_process_stdout
+[`stream.cork()`]: #stream_writable_cork
+[`stream.pipe()`]: #stream_readable_pipe_destination_options
+[`stream.uncork()`]: #stream_writable_uncork
+[`stream.unpipe()`]: #stream_readable_unpipe_destination
+[`stream.wrap()`]: #stream_readable_wrap_stream
+[`tls.CryptoStream`]: https://nodejs.org/docs/v5.8.0/api/tls.html#tls_class_cryptostream
+[`util.inherits()`]: https://nodejs.org/docs/v5.8.0/api/util.html#util_util_inherits_constructor_superconstructor
+[API for Stream Consumers]: #stream_api_for_stream_consumers
+[API for Stream Implementors]: #stream_api_for_stream_implementors
+[child process stdin]: https://nodejs.org/docs/v5.8.0/api/child_process.html#child_process_child_stdin
+[child process stdout and stderr]: https://nodejs.org/docs/v5.8.0/api/child_process.html#child_process_child_stdout
+[Compatibility]: #stream_compatibility_with_older_node_js_versions
+[crypto]: crypto.html
+[Duplex]: #stream_class_stream_duplex
+[fs read streams]: https://nodejs.org/docs/v5.8.0/api/fs.html#fs_class_fs_readstream
+[fs write streams]: https://nodejs.org/docs/v5.8.0/api/fs.html#fs_class_fs_writestream
+[HTTP requests, on the client]: https://nodejs.org/docs/v5.8.0/api/http.html#http_class_http_clientrequest
+[HTTP responses, on the server]: https://nodejs.org/docs/v5.8.0/api/http.html#http_class_http_serverresponse
+[http-incoming-message]: https://nodejs.org/docs/v5.8.0/api/http.html#http_class_http_incomingmessage
+[Object mode]: #stream_object_mode
+[Readable]: #stream_class_stream_readable
+[SimpleProtocol v2]: #stream_example_simpleprotocol_parser_v2
+[stream-_flush]: #stream_transform_flush_callback
+[stream-_read]: #stream_readable_read_size_1
+[stream-_transform]: #stream_transform_transform_chunk_encoding_callback
+[stream-_write]: #stream_writable_write_chunk_encoding_callback_1
+[stream-_writev]: #stream_writable_writev_chunks_callback
+[stream-end]: #stream_writable_end_chunk_encoding_callback
+[stream-pause]: #stream_readable_pause
+[stream-push]: #stream_readable_push_chunk_encoding
+[stream-read]: #stream_readable_read_size
+[stream-resume]: #stream_readable_resume
+[stream-write]: #stream_writable_write_chunk_encoding_callback
+[TCP sockets]: https://nodejs.org/docs/v5.8.0/api/net.html#net_class_net_socket
+[Transform]: #stream_class_stream_transform
+[Writable]: #stream_class_stream_writable
+[zlib]: zlib.html
diff --git a/fril/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md b/fril/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md
new file mode 100644
index 0000000..83275f1
--- /dev/null
+++ b/fril/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md
@@ -0,0 +1,60 @@
+# streams WG Meeting 2015-01-30
+
+## Links
+
+* **Google Hangouts Video**: http://www.youtube.com/watch?v=I9nDOSGfwZg
+* **GitHub Issue**: https://github.com/iojs/readable-stream/issues/106
+* **Original Minutes Google Doc**: https://docs.google.com/document/d/17aTgLnjMXIrfjgNaTUnHQO7m3xgzHR2VXBTmi03Qii4/
+
+## Agenda
+
+Extracted from https://github.com/iojs/readable-stream/labels/wg-agenda prior to meeting.
+
+* adopt a charter [#105](https://github.com/iojs/readable-stream/issues/105)
+* release and versioning strategy [#101](https://github.com/iojs/readable-stream/issues/101)
+* simpler stream creation [#102](https://github.com/iojs/readable-stream/issues/102)
+* proposal: deprecate implicit flowing of streams [#99](https://github.com/iojs/readable-stream/issues/99)
+
+## Minutes
+
+### adopt a charter
+
+* group: +1's all around
+
+### What versioning scheme should be adopted?
+* group: +1’s 3.0.0
+* domenic+group: pulling in patches from other sources where appropriate
+* mikeal: version independently, suggesting versions for io.js
+* mikeal+domenic: work with TC to notify in advance of changes
+simpler stream creation
+
+### streamline creation of streams
+* sam: streamline creation of streams
+* domenic: nice simple solution posted
+ but, we lose the opportunity to change the model
+ may not be backwards incompatible (double check keys)
+
+ **action item:** domenic will check
+
+### remove implicit flowing of streams on(‘data’)
+* add isFlowing / isPaused
+* mikeal: worrying that we’re documenting polyfill methods – confuses users
+* domenic: more reflective API is probably good, with warning labels for users
+* new section for mad scientists (reflective stream access)
+* calvin: name the “third state”
+* mikeal: maybe borrow the name from whatwg?
+* domenic: we’re missing the “third state”
+* consensus: kind of difficult to name the third state
+* mikeal: figure out differences in states / compat
+* mathias: always flow on data – eliminates third state
+ * explore what it breaks
+
+**action items:**
+* ask isaac for ability to list packages by what public io.js APIs they use (esp. Stream)
+* ask rod/build for infrastructure
+* **chris**: explore the “flow on data” approach
+* add isPaused/isFlowing
+* add new docs section
+* move isPaused to that section
+
+
diff --git a/fril/node_modules/readable-stream/duplex.js b/fril/node_modules/readable-stream/duplex.js
new file mode 100644
index 0000000..ca807af
--- /dev/null
+++ b/fril/node_modules/readable-stream/duplex.js
@@ -0,0 +1 @@
+module.exports = require("./lib/_stream_duplex.js")
diff --git a/fril/node_modules/readable-stream/lib/_stream_duplex.js b/fril/node_modules/readable-stream/lib/_stream_duplex.js
new file mode 100644
index 0000000..736693b
--- /dev/null
+++ b/fril/node_modules/readable-stream/lib/_stream_duplex.js
@@ -0,0 +1,75 @@
+// a duplex stream is just a stream that is both readable and writable.
+// Since JS doesn't have multiple prototypal inheritance, this class
+// prototypally inherits from Readable, and then parasitically from
+// Writable.
+
+'use strict';
+
+/**/
+
+var objectKeys = Object.keys || function (obj) {
+ var keys = [];
+ for (var key in obj) {
+ keys.push(key);
+ }return keys;
+};
+/**/
+
+module.exports = Duplex;
+
+/**/
+var processNextTick = require('process-nextick-args');
+/**/
+
+/**/
+var util = require('core-util-is');
+util.inherits = require('inherits');
+/**/
+
+var Readable = require('./_stream_readable');
+var Writable = require('./_stream_writable');
+
+util.inherits(Duplex, Readable);
+
+var keys = objectKeys(Writable.prototype);
+for (var v = 0; v < keys.length; v++) {
+ var method = keys[v];
+ if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
+}
+
+function Duplex(options) {
+ if (!(this instanceof Duplex)) return new Duplex(options);
+
+ Readable.call(this, options);
+ Writable.call(this, options);
+
+ if (options && options.readable === false) this.readable = false;
+
+ if (options && options.writable === false) this.writable = false;
+
+ this.allowHalfOpen = true;
+ if (options && options.allowHalfOpen === false) this.allowHalfOpen = false;
+
+ this.once('end', onend);
+}
+
+// the no-half-open enforcer
+function onend() {
+ // if we allow half-open state, or if the writable side ended,
+ // then we're ok.
+ if (this.allowHalfOpen || this._writableState.ended) return;
+
+ // no more data can be written.
+ // But allow more writes to happen in this tick.
+ processNextTick(onEndNT, this);
+}
+
+function onEndNT(self) {
+ self.end();
+}
+
+function forEach(xs, f) {
+ for (var i = 0, l = xs.length; i < l; i++) {
+ f(xs[i], i);
+ }
+}
\ No newline at end of file
diff --git a/fril/node_modules/readable-stream/lib/_stream_passthrough.js b/fril/node_modules/readable-stream/lib/_stream_passthrough.js
new file mode 100644
index 0000000..d06f71f
--- /dev/null
+++ b/fril/node_modules/readable-stream/lib/_stream_passthrough.js
@@ -0,0 +1,26 @@
+// a passthrough stream.
+// basically just the most minimal sort of Transform stream.
+// Every written chunk gets output as-is.
+
+'use strict';
+
+module.exports = PassThrough;
+
+var Transform = require('./_stream_transform');
+
+/**/
+var util = require('core-util-is');
+util.inherits = require('inherits');
+/**/
+
+util.inherits(PassThrough, Transform);
+
+function PassThrough(options) {
+ if (!(this instanceof PassThrough)) return new PassThrough(options);
+
+ Transform.call(this, options);
+}
+
+PassThrough.prototype._transform = function (chunk, encoding, cb) {
+ cb(null, chunk);
+};
\ No newline at end of file
diff --git a/fril/node_modules/readable-stream/lib/_stream_readable.js b/fril/node_modules/readable-stream/lib/_stream_readable.js
new file mode 100644
index 0000000..54a9d5c
--- /dev/null
+++ b/fril/node_modules/readable-stream/lib/_stream_readable.js
@@ -0,0 +1,880 @@
+'use strict';
+
+module.exports = Readable;
+
+/**/
+var processNextTick = require('process-nextick-args');
+/**/
+
+/**/
+var isArray = require('isarray');
+/**/
+
+/**/
+var Buffer = require('buffer').Buffer;
+/**/
+
+Readable.ReadableState = ReadableState;
+
+var EE = require('events');
+
+/**/
+var EElistenerCount = function (emitter, type) {
+ return emitter.listeners(type).length;
+};
+/**/
+
+/**/
+var Stream;
+(function () {
+ try {
+ Stream = require('st' + 'ream');
+ } catch (_) {} finally {
+ if (!Stream) Stream = require('events').EventEmitter;
+ }
+})();
+/**/
+
+var Buffer = require('buffer').Buffer;
+
+/**/
+var util = require('core-util-is');
+util.inherits = require('inherits');
+/**/
+
+/**/
+var debugUtil = require('util');
+var debug = undefined;
+if (debugUtil && debugUtil.debuglog) {
+ debug = debugUtil.debuglog('stream');
+} else {
+ debug = function () {};
+}
+/**/
+
+var StringDecoder;
+
+util.inherits(Readable, Stream);
+
+var Duplex;
+function ReadableState(options, stream) {
+ Duplex = Duplex || require('./_stream_duplex');
+
+ options = options || {};
+
+ // object stream flag. Used to make read(n) ignore n and to
+ // make all the buffer merging and length checks go away
+ this.objectMode = !!options.objectMode;
+
+ if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode;
+
+ // the point at which it stops calling _read() to fill the buffer
+ // Note: 0 is a valid value, means "don't call _read preemptively ever"
+ var hwm = options.highWaterMark;
+ var defaultHwm = this.objectMode ? 16 : 16 * 1024;
+ this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;
+
+ // cast to ints.
+ this.highWaterMark = ~ ~this.highWaterMark;
+
+ this.buffer = [];
+ this.length = 0;
+ this.pipes = null;
+ this.pipesCount = 0;
+ this.flowing = null;
+ this.ended = false;
+ this.endEmitted = false;
+ this.reading = false;
+
+ // a flag to be able to tell if the onwrite cb is called immediately,
+ // or on a later tick. We set this to true at first, because any
+ // actions that shouldn't happen until "later" should generally also
+ // not happen before the first write call.
+ this.sync = true;
+
+ // whenever we return null, then we set a flag to say
+ // that we're awaiting a 'readable' event emission.
+ this.needReadable = false;
+ this.emittedReadable = false;
+ this.readableListening = false;
+ this.resumeScheduled = false;
+
+ // Crypto is kind of old and crusty. Historically, its default string
+ // encoding is 'binary' so we have to make this configurable.
+ // Everything else in the universe uses 'utf8', though.
+ this.defaultEncoding = options.defaultEncoding || 'utf8';
+
+ // when piping, we only care about 'readable' events that happen
+ // after read()ing all the bytes and not getting any pushback.
+ this.ranOut = false;
+
+ // the number of writers that are awaiting a drain event in .pipe()s
+ this.awaitDrain = 0;
+
+ // if true, a maybeReadMore has been scheduled
+ this.readingMore = false;
+
+ this.decoder = null;
+ this.encoding = null;
+ if (options.encoding) {
+ if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;
+ this.decoder = new StringDecoder(options.encoding);
+ this.encoding = options.encoding;
+ }
+}
+
+var Duplex;
+function Readable(options) {
+ Duplex = Duplex || require('./_stream_duplex');
+
+ if (!(this instanceof Readable)) return new Readable(options);
+
+ this._readableState = new ReadableState(options, this);
+
+ // legacy
+ this.readable = true;
+
+ if (options && typeof options.read === 'function') this._read = options.read;
+
+ Stream.call(this);
+}
+
+// Manually shove something into the read() buffer.
+// This returns true if the highWaterMark has not been hit yet,
+// similar to how Writable.write() returns true if you should
+// write() some more.
+Readable.prototype.push = function (chunk, encoding) {
+ var state = this._readableState;
+
+ if (!state.objectMode && typeof chunk === 'string') {
+ encoding = encoding || state.defaultEncoding;
+ if (encoding !== state.encoding) {
+ chunk = new Buffer(chunk, encoding);
+ encoding = '';
+ }
+ }
+
+ return readableAddChunk(this, state, chunk, encoding, false);
+};
+
+// Unshift should *always* be something directly out of read()
+Readable.prototype.unshift = function (chunk) {
+ var state = this._readableState;
+ return readableAddChunk(this, state, chunk, '', true);
+};
+
+Readable.prototype.isPaused = function () {
+ return this._readableState.flowing === false;
+};
+
+function readableAddChunk(stream, state, chunk, encoding, addToFront) {
+ var er = chunkInvalid(state, chunk);
+ if (er) {
+ stream.emit('error', er);
+ } else if (chunk === null) {
+ state.reading = false;
+ onEofChunk(stream, state);
+ } else if (state.objectMode || chunk && chunk.length > 0) {
+ if (state.ended && !addToFront) {
+ var e = new Error('stream.push() after EOF');
+ stream.emit('error', e);
+ } else if (state.endEmitted && addToFront) {
+ var e = new Error('stream.unshift() after end event');
+ stream.emit('error', e);
+ } else {
+ var skipAdd;
+ if (state.decoder && !addToFront && !encoding) {
+ chunk = state.decoder.write(chunk);
+ skipAdd = !state.objectMode && chunk.length === 0;
+ }
+
+ if (!addToFront) state.reading = false;
+
+ // Don't add to the buffer if we've decoded to an empty string chunk and
+ // we're not in object mode
+ if (!skipAdd) {
+ // if we want the data now, just emit it.
+ if (state.flowing && state.length === 0 && !state.sync) {
+ stream.emit('data', chunk);
+ stream.read(0);
+ } else {
+ // update the buffer info.
+ state.length += state.objectMode ? 1 : chunk.length;
+ if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk);
+
+ if (state.needReadable) emitReadable(stream);
+ }
+ }
+
+ maybeReadMore(stream, state);
+ }
+ } else if (!addToFront) {
+ state.reading = false;
+ }
+
+ return needMoreData(state);
+}
+
+// if it's past the high water mark, we can push in some more.
+// Also, if we have no data yet, we can stand some
+// more bytes. This is to work around cases where hwm=0,
+// such as the repl. Also, if the push() triggered a
+// readable event, and the user called read(largeNumber) such that
+// needReadable was set, then we ought to push more, so that another
+// 'readable' event will be triggered.
+function needMoreData(state) {
+ return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0);
+}
+
+// backwards compatibility.
+Readable.prototype.setEncoding = function (enc) {
+ if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;
+ this._readableState.decoder = new StringDecoder(enc);
+ this._readableState.encoding = enc;
+ return this;
+};
+
+// Don't raise the hwm > 8MB
+var MAX_HWM = 0x800000;
+function computeNewHighWaterMark(n) {
+ if (n >= MAX_HWM) {
+ n = MAX_HWM;
+ } else {
+ // Get the next highest power of 2
+ n--;
+ n |= n >>> 1;
+ n |= n >>> 2;
+ n |= n >>> 4;
+ n |= n >>> 8;
+ n |= n >>> 16;
+ n++;
+ }
+ return n;
+}
+
+function howMuchToRead(n, state) {
+ if (state.length === 0 && state.ended) return 0;
+
+ if (state.objectMode) return n === 0 ? 0 : 1;
+
+ if (n === null || isNaN(n)) {
+ // only flow one buffer at a time
+ if (state.flowing && state.buffer.length) return state.buffer[0].length;else return state.length;
+ }
+
+ if (n <= 0) return 0;
+
+ // If we're asking for more than the target buffer level,
+ // then raise the water mark. Bump up to the next highest
+ // power of 2, to prevent increasing it excessively in tiny
+ // amounts.
+ if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n);
+
+ // don't have that much. return null, unless we've ended.
+ if (n > state.length) {
+ if (!state.ended) {
+ state.needReadable = true;
+ return 0;
+ } else {
+ return state.length;
+ }
+ }
+
+ return n;
+}
+
+// you can override either this method, or the async _read(n) below.
+Readable.prototype.read = function (n) {
+ debug('read', n);
+ var state = this._readableState;
+ var nOrig = n;
+
+ if (typeof n !== 'number' || n > 0) state.emittedReadable = false;
+
+ // if we're doing read(0) to trigger a readable event, but we
+ // already have a bunch of data in the buffer, then just trigger
+ // the 'readable' event and move on.
+ if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) {
+ debug('read: emitReadable', state.length, state.ended);
+ if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this);
+ return null;
+ }
+
+ n = howMuchToRead(n, state);
+
+ // if we've ended, and we're now clear, then finish it up.
+ if (n === 0 && state.ended) {
+ if (state.length === 0) endReadable(this);
+ return null;
+ }
+
+ // All the actual chunk generation logic needs to be
+ // *below* the call to _read. The reason is that in certain
+ // synthetic stream cases, such as passthrough streams, _read
+ // may be a completely synchronous operation which may change
+ // the state of the read buffer, providing enough data when
+ // before there was *not* enough.
+ //
+ // So, the steps are:
+ // 1. Figure out what the state of things will be after we do
+ // a read from the buffer.
+ //
+ // 2. If that resulting state will trigger a _read, then call _read.
+ // Note that this may be asynchronous, or synchronous. Yes, it is
+ // deeply ugly to write APIs this way, but that still doesn't mean
+ // that the Readable class should behave improperly, as streams are
+ // designed to be sync/async agnostic.
+ // Take note if the _read call is sync or async (ie, if the read call
+ // has returned yet), so that we know whether or not it's safe to emit
+ // 'readable' etc.
+ //
+ // 3. Actually pull the requested chunks out of the buffer and return.
+
+ // if we need a readable event, then we need to do some reading.
+ var doRead = state.needReadable;
+ debug('need readable', doRead);
+
+ // if we currently have less than the highWaterMark, then also read some
+ if (state.length === 0 || state.length - n < state.highWaterMark) {
+ doRead = true;
+ debug('length less than watermark', doRead);
+ }
+
+ // however, if we've ended, then there's no point, and if we're already
+ // reading, then it's unnecessary.
+ if (state.ended || state.reading) {
+ doRead = false;
+ debug('reading or ended', doRead);
+ }
+
+ if (doRead) {
+ debug('do read');
+ state.reading = true;
+ state.sync = true;
+ // if the length is currently zero, then we *need* a readable event.
+ if (state.length === 0) state.needReadable = true;
+ // call internal read method
+ this._read(state.highWaterMark);
+ state.sync = false;
+ }
+
+ // If _read pushed data synchronously, then `reading` will be false,
+ // and we need to re-evaluate how much data we can return to the user.
+ if (doRead && !state.reading) n = howMuchToRead(nOrig, state);
+
+ var ret;
+ if (n > 0) ret = fromList(n, state);else ret = null;
+
+ if (ret === null) {
+ state.needReadable = true;
+ n = 0;
+ }
+
+ state.length -= n;
+
+ // If we have nothing in the buffer, then we want to know
+ // as soon as we *do* get something into the buffer.
+ if (state.length === 0 && !state.ended) state.needReadable = true;
+
+ // If we tried to read() past the EOF, then emit end on the next tick.
+ if (nOrig !== n && state.ended && state.length === 0) endReadable(this);
+
+ if (ret !== null) this.emit('data', ret);
+
+ return ret;
+};
+
+function chunkInvalid(state, chunk) {
+ var er = null;
+ if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) {
+ er = new TypeError('Invalid non-string/buffer chunk');
+ }
+ return er;
+}
+
+function onEofChunk(stream, state) {
+ if (state.ended) return;
+ if (state.decoder) {
+ var chunk = state.decoder.end();
+ if (chunk && chunk.length) {
+ state.buffer.push(chunk);
+ state.length += state.objectMode ? 1 : chunk.length;
+ }
+ }
+ state.ended = true;
+
+ // emit 'readable' now to make sure it gets picked up.
+ emitReadable(stream);
+}
+
+// Don't emit readable right away in sync mode, because this can trigger
+// another read() call => stack overflow. This way, it might trigger
+// a nextTick recursion warning, but that's not so bad.
+function emitReadable(stream) {
+ var state = stream._readableState;
+ state.needReadable = false;
+ if (!state.emittedReadable) {
+ debug('emitReadable', state.flowing);
+ state.emittedReadable = true;
+ if (state.sync) processNextTick(emitReadable_, stream);else emitReadable_(stream);
+ }
+}
+
+function emitReadable_(stream) {
+ debug('emit readable');
+ stream.emit('readable');
+ flow(stream);
+}
+
+// at this point, the user has presumably seen the 'readable' event,
+// and called read() to consume some data. that may have triggered
+// in turn another _read(n) call, in which case reading = true if
+// it's in progress.
+// However, if we're not ended, or reading, and the length < hwm,
+// then go ahead and try to read some more preemptively.
+function maybeReadMore(stream, state) {
+ if (!state.readingMore) {
+ state.readingMore = true;
+ processNextTick(maybeReadMore_, stream, state);
+ }
+}
+
+function maybeReadMore_(stream, state) {
+ var len = state.length;
+ while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) {
+ debug('maybeReadMore read 0');
+ stream.read(0);
+ if (len === state.length)
+ // didn't get any data, stop spinning.
+ break;else len = state.length;
+ }
+ state.readingMore = false;
+}
+
+// abstract method. to be overridden in specific implementation classes.
+// call cb(er, data) where data is <= n in length.
+// for virtual (non-string, non-buffer) streams, "length" is somewhat
+// arbitrary, and perhaps not very meaningful.
+Readable.prototype._read = function (n) {
+ this.emit('error', new Error('not implemented'));
+};
+
+Readable.prototype.pipe = function (dest, pipeOpts) {
+ var src = this;
+ var state = this._readableState;
+
+ switch (state.pipesCount) {
+ case 0:
+ state.pipes = dest;
+ break;
+ case 1:
+ state.pipes = [state.pipes, dest];
+ break;
+ default:
+ state.pipes.push(dest);
+ break;
+ }
+ state.pipesCount += 1;
+ debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);
+
+ var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr;
+
+ var endFn = doEnd ? onend : cleanup;
+ if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn);
+
+ dest.on('unpipe', onunpipe);
+ function onunpipe(readable) {
+ debug('onunpipe');
+ if (readable === src) {
+ cleanup();
+ }
+ }
+
+ function onend() {
+ debug('onend');
+ dest.end();
+ }
+
+ // when the dest drains, it reduces the awaitDrain counter
+ // on the source. This would be more elegant with a .once()
+ // handler in flow(), but adding and removing repeatedly is
+ // too slow.
+ var ondrain = pipeOnDrain(src);
+ dest.on('drain', ondrain);
+
+ var cleanedUp = false;
+ function cleanup() {
+ debug('cleanup');
+ // cleanup event handlers once the pipe is broken
+ dest.removeListener('close', onclose);
+ dest.removeListener('finish', onfinish);
+ dest.removeListener('drain', ondrain);
+ dest.removeListener('error', onerror);
+ dest.removeListener('unpipe', onunpipe);
+ src.removeListener('end', onend);
+ src.removeListener('end', cleanup);
+ src.removeListener('data', ondata);
+
+ cleanedUp = true;
+
+ // if the reader is waiting for a drain event from this
+ // specific writer, then it would cause it to never start
+ // flowing again.
+ // So, if this is awaiting a drain, then we just call it now.
+ // If we don't know, then assume that we are waiting for one.
+ if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain();
+ }
+
+ src.on('data', ondata);
+ function ondata(chunk) {
+ debug('ondata');
+ var ret = dest.write(chunk);
+ if (false === ret) {
+ // If the user unpiped during `dest.write()`, it is possible
+ // to get stuck in a permanently paused state if that write
+ // also returned false.
+ if (state.pipesCount === 1 && state.pipes[0] === dest && src.listenerCount('data') === 1 && !cleanedUp) {
+ debug('false write response, pause', src._readableState.awaitDrain);
+ src._readableState.awaitDrain++;
+ }
+ src.pause();
+ }
+ }
+
+ // if the dest has an error, then stop piping into it.
+ // however, don't suppress the throwing behavior for this.
+ function onerror(er) {
+ debug('onerror', er);
+ unpipe();
+ dest.removeListener('error', onerror);
+ if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er);
+ }
+ // This is a brutally ugly hack to make sure that our error handler
+ // is attached before any userland ones. NEVER DO THIS.
+ if (!dest._events || !dest._events.error) dest.on('error', onerror);else if (isArray(dest._events.error)) dest._events.error.unshift(onerror);else dest._events.error = [onerror, dest._events.error];
+
+ // Both close and finish should trigger unpipe, but only once.
+ function onclose() {
+ dest.removeListener('finish', onfinish);
+ unpipe();
+ }
+ dest.once('close', onclose);
+ function onfinish() {
+ debug('onfinish');
+ dest.removeListener('close', onclose);
+ unpipe();
+ }
+ dest.once('finish', onfinish);
+
+ function unpipe() {
+ debug('unpipe');
+ src.unpipe(dest);
+ }
+
+ // tell the dest that it's being piped to
+ dest.emit('pipe', src);
+
+ // start the flow if it hasn't been started already.
+ if (!state.flowing) {
+ debug('pipe resume');
+ src.resume();
+ }
+
+ return dest;
+};
+
+function pipeOnDrain(src) {
+ return function () {
+ var state = src._readableState;
+ debug('pipeOnDrain', state.awaitDrain);
+ if (state.awaitDrain) state.awaitDrain--;
+ if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) {
+ state.flowing = true;
+ flow(src);
+ }
+ };
+}
+
+Readable.prototype.unpipe = function (dest) {
+ var state = this._readableState;
+
+ // if we're not piping anywhere, then do nothing.
+ if (state.pipesCount === 0) return this;
+
+ // just one destination. most common case.
+ if (state.pipesCount === 1) {
+ // passed in one, but it's not the right one.
+ if (dest && dest !== state.pipes) return this;
+
+ if (!dest) dest = state.pipes;
+
+ // got a match.
+ state.pipes = null;
+ state.pipesCount = 0;
+ state.flowing = false;
+ if (dest) dest.emit('unpipe', this);
+ return this;
+ }
+
+ // slow case. multiple pipe destinations.
+
+ if (!dest) {
+ // remove all.
+ var dests = state.pipes;
+ var len = state.pipesCount;
+ state.pipes = null;
+ state.pipesCount = 0;
+ state.flowing = false;
+
+ for (var _i = 0; _i < len; _i++) {
+ dests[_i].emit('unpipe', this);
+ }return this;
+ }
+
+ // try to find the right one.
+ var i = indexOf(state.pipes, dest);
+ if (i === -1) return this;
+
+ state.pipes.splice(i, 1);
+ state.pipesCount -= 1;
+ if (state.pipesCount === 1) state.pipes = state.pipes[0];
+
+ dest.emit('unpipe', this);
+
+ return this;
+};
+
+// set up data events if they are asked for
+// Ensure readable listeners eventually get something
+Readable.prototype.on = function (ev, fn) {
+ var res = Stream.prototype.on.call(this, ev, fn);
+
+ // If listening to data, and it has not explicitly been paused,
+ // then call resume to start the flow of data on the next tick.
+ if (ev === 'data' && false !== this._readableState.flowing) {
+ this.resume();
+ }
+
+ if (ev === 'readable' && !this._readableState.endEmitted) {
+ var state = this._readableState;
+ if (!state.readableListening) {
+ state.readableListening = true;
+ state.emittedReadable = false;
+ state.needReadable = true;
+ if (!state.reading) {
+ processNextTick(nReadingNextTick, this);
+ } else if (state.length) {
+ emitReadable(this, state);
+ }
+ }
+ }
+
+ return res;
+};
+Readable.prototype.addListener = Readable.prototype.on;
+
+function nReadingNextTick(self) {
+ debug('readable nexttick read 0');
+ self.read(0);
+}
+
+// pause() and resume() are remnants of the legacy readable stream API
+// If the user uses them, then switch into old mode.
+Readable.prototype.resume = function () {
+ var state = this._readableState;
+ if (!state.flowing) {
+ debug('resume');
+ state.flowing = true;
+ resume(this, state);
+ }
+ return this;
+};
+
+function resume(stream, state) {
+ if (!state.resumeScheduled) {
+ state.resumeScheduled = true;
+ processNextTick(resume_, stream, state);
+ }
+}
+
+function resume_(stream, state) {
+ if (!state.reading) {
+ debug('resume read 0');
+ stream.read(0);
+ }
+
+ state.resumeScheduled = false;
+ stream.emit('resume');
+ flow(stream);
+ if (state.flowing && !state.reading) stream.read(0);
+}
+
+Readable.prototype.pause = function () {
+ debug('call pause flowing=%j', this._readableState.flowing);
+ if (false !== this._readableState.flowing) {
+ debug('pause');
+ this._readableState.flowing = false;
+ this.emit('pause');
+ }
+ return this;
+};
+
+function flow(stream) {
+ var state = stream._readableState;
+ debug('flow', state.flowing);
+ if (state.flowing) {
+ do {
+ var chunk = stream.read();
+ } while (null !== chunk && state.flowing);
+ }
+}
+
+// wrap an old-style stream as the async data source.
+// This is *not* part of the readable stream interface.
+// It is an ugly unfortunate mess of history.
+Readable.prototype.wrap = function (stream) {
+ var state = this._readableState;
+ var paused = false;
+
+ var self = this;
+ stream.on('end', function () {
+ debug('wrapped end');
+ if (state.decoder && !state.ended) {
+ var chunk = state.decoder.end();
+ if (chunk && chunk.length) self.push(chunk);
+ }
+
+ self.push(null);
+ });
+
+ stream.on('data', function (chunk) {
+ debug('wrapped data');
+ if (state.decoder) chunk = state.decoder.write(chunk);
+
+ // don't skip over falsy values in objectMode
+ if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return;
+
+ var ret = self.push(chunk);
+ if (!ret) {
+ paused = true;
+ stream.pause();
+ }
+ });
+
+ // proxy all the other methods.
+ // important when wrapping filters and duplexes.
+ for (var i in stream) {
+ if (this[i] === undefined && typeof stream[i] === 'function') {
+ this[i] = function (method) {
+ return function () {
+ return stream[method].apply(stream, arguments);
+ };
+ }(i);
+ }
+ }
+
+ // proxy certain important events.
+ var events = ['error', 'close', 'destroy', 'pause', 'resume'];
+ forEach(events, function (ev) {
+ stream.on(ev, self.emit.bind(self, ev));
+ });
+
+ // when we try to consume some more bytes, simply unpause the
+ // underlying stream.
+ self._read = function (n) {
+ debug('wrapped _read', n);
+ if (paused) {
+ paused = false;
+ stream.resume();
+ }
+ };
+
+ return self;
+};
+
+// exposed for testing purposes only.
+Readable._fromList = fromList;
+
+// Pluck off n bytes from an array of buffers.
+// Length is the combined lengths of all the buffers in the list.
+function fromList(n, state) {
+ var list = state.buffer;
+ var length = state.length;
+ var stringMode = !!state.decoder;
+ var objectMode = !!state.objectMode;
+ var ret;
+
+ // nothing in the list, definitely empty.
+ if (list.length === 0) return null;
+
+ if (length === 0) ret = null;else if (objectMode) ret = list.shift();else if (!n || n >= length) {
+ // read it all, truncate the array.
+ if (stringMode) ret = list.join('');else if (list.length === 1) ret = list[0];else ret = Buffer.concat(list, length);
+ list.length = 0;
+ } else {
+ // read just some of it.
+ if (n < list[0].length) {
+ // just take a part of the first list item.
+ // slice is the same for buffers and strings.
+ var buf = list[0];
+ ret = buf.slice(0, n);
+ list[0] = buf.slice(n);
+ } else if (n === list[0].length) {
+ // first list is a perfect match
+ ret = list.shift();
+ } else {
+ // complex case.
+ // we have enough to cover it, but it spans past the first buffer.
+ if (stringMode) ret = '';else ret = new Buffer(n);
+
+ var c = 0;
+ for (var i = 0, l = list.length; i < l && c < n; i++) {
+ var buf = list[0];
+ var cpy = Math.min(n - c, buf.length);
+
+ if (stringMode) ret += buf.slice(0, cpy);else buf.copy(ret, c, 0, cpy);
+
+ if (cpy < buf.length) list[0] = buf.slice(cpy);else list.shift();
+
+ c += cpy;
+ }
+ }
+ }
+
+ return ret;
+}
+
+function endReadable(stream) {
+ var state = stream._readableState;
+
+ // If we get here before consuming all the bytes, then that is a
+ // bug in node. Should never happen.
+ if (state.length > 0) throw new Error('endReadable called on non-empty stream');
+
+ if (!state.endEmitted) {
+ state.ended = true;
+ processNextTick(endReadableNT, state, stream);
+ }
+}
+
+function endReadableNT(state, stream) {
+ // Check that we didn't get one last unshift.
+ if (!state.endEmitted && state.length === 0) {
+ state.endEmitted = true;
+ stream.readable = false;
+ stream.emit('end');
+ }
+}
+
+function forEach(xs, f) {
+ for (var i = 0, l = xs.length; i < l; i++) {
+ f(xs[i], i);
+ }
+}
+
+function indexOf(xs, x) {
+ for (var i = 0, l = xs.length; i < l; i++) {
+ if (xs[i] === x) return i;
+ }
+ return -1;
+}
\ No newline at end of file
diff --git a/fril/node_modules/readable-stream/lib/_stream_transform.js b/fril/node_modules/readable-stream/lib/_stream_transform.js
new file mode 100644
index 0000000..625cdc1
--- /dev/null
+++ b/fril/node_modules/readable-stream/lib/_stream_transform.js
@@ -0,0 +1,180 @@
+// a transform stream is a readable/writable stream where you do
+// something with the data. Sometimes it's called a "filter",
+// but that's not a great name for it, since that implies a thing where
+// some bits pass through, and others are simply ignored. (That would
+// be a valid example of a transform, of course.)
+//
+// While the output is causally related to the input, it's not a
+// necessarily symmetric or synchronous transformation. For example,
+// a zlib stream might take multiple plain-text writes(), and then
+// emit a single compressed chunk some time in the future.
+//
+// Here's how this works:
+//
+// The Transform stream has all the aspects of the readable and writable
+// stream classes. When you write(chunk), that calls _write(chunk,cb)
+// internally, and returns false if there's a lot of pending writes
+// buffered up. When you call read(), that calls _read(n) until
+// there's enough pending readable data buffered up.
+//
+// In a transform stream, the written data is placed in a buffer. When
+// _read(n) is called, it transforms the queued up data, calling the
+// buffered _write cb's as it consumes chunks. If consuming a single
+// written chunk would result in multiple output chunks, then the first
+// outputted bit calls the readcb, and subsequent chunks just go into
+// the read buffer, and will cause it to emit 'readable' if necessary.
+//
+// This way, back-pressure is actually determined by the reading side,
+// since _read has to be called to start processing a new chunk. However,
+// a pathological inflate type of transform can cause excessive buffering
+// here. For example, imagine a stream where every byte of input is
+// interpreted as an integer from 0-255, and then results in that many
+// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in
+// 1kb of data being output. In this case, you could write a very small
+// amount of input, and end up with a very large amount of output. In
+// such a pathological inflating mechanism, there'd be no way to tell
+// the system to stop doing the transform. A single 4MB write could
+// cause the system to run out of memory.
+//
+// However, even in such a pathological case, only a single written chunk
+// would be consumed, and then the rest would wait (un-transformed) until
+// the results of the previous transformed chunk were consumed.
+
+'use strict';
+
+module.exports = Transform;
+
+var Duplex = require('./_stream_duplex');
+
+/**/
+var util = require('core-util-is');
+util.inherits = require('inherits');
+/**/
+
+util.inherits(Transform, Duplex);
+
+function TransformState(stream) {
+ this.afterTransform = function (er, data) {
+ return afterTransform(stream, er, data);
+ };
+
+ this.needTransform = false;
+ this.transforming = false;
+ this.writecb = null;
+ this.writechunk = null;
+ this.writeencoding = null;
+}
+
+function afterTransform(stream, er, data) {
+ var ts = stream._transformState;
+ ts.transforming = false;
+
+ var cb = ts.writecb;
+
+ if (!cb) return stream.emit('error', new Error('no writecb in Transform class'));
+
+ ts.writechunk = null;
+ ts.writecb = null;
+
+ if (data !== null && data !== undefined) stream.push(data);
+
+ cb(er);
+
+ var rs = stream._readableState;
+ rs.reading = false;
+ if (rs.needReadable || rs.length < rs.highWaterMark) {
+ stream._read(rs.highWaterMark);
+ }
+}
+
+function Transform(options) {
+ if (!(this instanceof Transform)) return new Transform(options);
+
+ Duplex.call(this, options);
+
+ this._transformState = new TransformState(this);
+
+ // when the writable side finishes, then flush out anything remaining.
+ var stream = this;
+
+ // start out asking for a readable event once data is transformed.
+ this._readableState.needReadable = true;
+
+ // we have implemented the _read method, and done the other things
+ // that Readable wants before the first _read call, so unset the
+ // sync guard flag.
+ this._readableState.sync = false;
+
+ if (options) {
+ if (typeof options.transform === 'function') this._transform = options.transform;
+
+ if (typeof options.flush === 'function') this._flush = options.flush;
+ }
+
+ this.once('prefinish', function () {
+ if (typeof this._flush === 'function') this._flush(function (er) {
+ done(stream, er);
+ });else done(stream);
+ });
+}
+
+Transform.prototype.push = function (chunk, encoding) {
+ this._transformState.needTransform = false;
+ return Duplex.prototype.push.call(this, chunk, encoding);
+};
+
+// This is the part where you do stuff!
+// override this function in implementation classes.
+// 'chunk' is an input chunk.
+//
+// Call `push(newChunk)` to pass along transformed output
+// to the readable side. You may call 'push' zero or more times.
+//
+// Call `cb(err)` when you are done with this chunk. If you pass
+// an error, then that'll put the hurt on the whole operation. If you
+// never call cb(), then you'll never get another chunk.
+Transform.prototype._transform = function (chunk, encoding, cb) {
+ throw new Error('not implemented');
+};
+
+Transform.prototype._write = function (chunk, encoding, cb) {
+ var ts = this._transformState;
+ ts.writecb = cb;
+ ts.writechunk = chunk;
+ ts.writeencoding = encoding;
+ if (!ts.transforming) {
+ var rs = this._readableState;
+ if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark);
+ }
+};
+
+// Doesn't matter what the args are here.
+// _transform does all the work.
+// That we got here means that the readable side wants more data.
+Transform.prototype._read = function (n) {
+ var ts = this._transformState;
+
+ if (ts.writechunk !== null && ts.writecb && !ts.transforming) {
+ ts.transforming = true;
+ this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);
+ } else {
+ // mark that we need a transform, so that any data that comes in
+ // will get processed, now that we've asked for it.
+ ts.needTransform = true;
+ }
+};
+
+function done(stream, er) {
+ if (er) return stream.emit('error', er);
+
+ // if there's nothing in the write buffer, then that means
+ // that nothing more will ever be provided
+ var ws = stream._writableState;
+ var ts = stream._transformState;
+
+ if (ws.length) throw new Error('calling transform done when ws.length != 0');
+
+ if (ts.transforming) throw new Error('calling transform done when still transforming');
+
+ return stream.push(null);
+}
\ No newline at end of file
diff --git a/fril/node_modules/readable-stream/lib/_stream_writable.js b/fril/node_modules/readable-stream/lib/_stream_writable.js
new file mode 100644
index 0000000..95916c9
--- /dev/null
+++ b/fril/node_modules/readable-stream/lib/_stream_writable.js
@@ -0,0 +1,516 @@
+// A bit simpler than readable streams.
+// Implement an async ._write(chunk, encoding, cb), and it'll handle all
+// the drain event emission and buffering.
+
+'use strict';
+
+module.exports = Writable;
+
+/**/
+var processNextTick = require('process-nextick-args');
+/**/
+
+/**/
+var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick;
+/**/
+
+/**/
+var Buffer = require('buffer').Buffer;
+/**/
+
+Writable.WritableState = WritableState;
+
+/**/
+var util = require('core-util-is');
+util.inherits = require('inherits');
+/**/
+
+/**/
+var internalUtil = {
+ deprecate: require('util-deprecate')
+};
+/**/
+
+/**/
+var Stream;
+(function () {
+ try {
+ Stream = require('st' + 'ream');
+ } catch (_) {} finally {
+ if (!Stream) Stream = require('events').EventEmitter;
+ }
+})();
+/**/
+
+var Buffer = require('buffer').Buffer;
+
+util.inherits(Writable, Stream);
+
+function nop() {}
+
+function WriteReq(chunk, encoding, cb) {
+ this.chunk = chunk;
+ this.encoding = encoding;
+ this.callback = cb;
+ this.next = null;
+}
+
+var Duplex;
+function WritableState(options, stream) {
+ Duplex = Duplex || require('./_stream_duplex');
+
+ options = options || {};
+
+ // object stream flag to indicate whether or not this stream
+ // contains buffers or objects.
+ this.objectMode = !!options.objectMode;
+
+ if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode;
+
+ // the point at which write() starts returning false
+ // Note: 0 is a valid value, means that we always return false if
+ // the entire buffer is not flushed immediately on write()
+ var hwm = options.highWaterMark;
+ var defaultHwm = this.objectMode ? 16 : 16 * 1024;
+ this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;
+
+ // cast to ints.
+ this.highWaterMark = ~ ~this.highWaterMark;
+
+ this.needDrain = false;
+ // at the start of calling end()
+ this.ending = false;
+ // when end() has been called, and returned
+ this.ended = false;
+ // when 'finish' is emitted
+ this.finished = false;
+
+ // should we decode strings into buffers before passing to _write?
+ // this is here so that some node-core streams can optimize string
+ // handling at a lower level.
+ var noDecode = options.decodeStrings === false;
+ this.decodeStrings = !noDecode;
+
+ // Crypto is kind of old and crusty. Historically, its default string
+ // encoding is 'binary' so we have to make this configurable.
+ // Everything else in the universe uses 'utf8', though.
+ this.defaultEncoding = options.defaultEncoding || 'utf8';
+
+ // not an actual buffer we keep track of, but a measurement
+ // of how much we're waiting to get pushed to some underlying
+ // socket or file.
+ this.length = 0;
+
+ // a flag to see when we're in the middle of a write.
+ this.writing = false;
+
+ // when true all writes will be buffered until .uncork() call
+ this.corked = 0;
+
+ // a flag to be able to tell if the onwrite cb is called immediately,
+ // or on a later tick. We set this to true at first, because any
+ // actions that shouldn't happen until "later" should generally also
+ // not happen before the first write call.
+ this.sync = true;
+
+ // a flag to know if we're processing previously buffered items, which
+ // may call the _write() callback in the same tick, so that we don't
+ // end up in an overlapped onwrite situation.
+ this.bufferProcessing = false;
+
+ // the callback that's passed to _write(chunk,cb)
+ this.onwrite = function (er) {
+ onwrite(stream, er);
+ };
+
+ // the callback that the user supplies to write(chunk,encoding,cb)
+ this.writecb = null;
+
+ // the amount that is being written when _write is called.
+ this.writelen = 0;
+
+ this.bufferedRequest = null;
+ this.lastBufferedRequest = null;
+
+ // number of pending user-supplied write callbacks
+ // this must be 0 before 'finish' can be emitted
+ this.pendingcb = 0;
+
+ // emit prefinish if the only thing we're waiting for is _write cbs
+ // This is relevant for synchronous Transform streams
+ this.prefinished = false;
+
+ // True if the error was already emitted and should not be thrown again
+ this.errorEmitted = false;
+
+ // count buffered requests
+ this.bufferedRequestCount = 0;
+
+ // create the two objects needed to store the corked requests
+ // they are not a linked list, as no new elements are inserted in there
+ this.corkedRequestsFree = new CorkedRequest(this);
+ this.corkedRequestsFree.next = new CorkedRequest(this);
+}
+
+WritableState.prototype.getBuffer = function writableStateGetBuffer() {
+ var current = this.bufferedRequest;
+ var out = [];
+ while (current) {
+ out.push(current);
+ current = current.next;
+ }
+ return out;
+};
+
+(function () {
+ try {
+ Object.defineProperty(WritableState.prototype, 'buffer', {
+ get: internalUtil.deprecate(function () {
+ return this.getBuffer();
+ }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.')
+ });
+ } catch (_) {}
+})();
+
+var Duplex;
+function Writable(options) {
+ Duplex = Duplex || require('./_stream_duplex');
+
+ // Writable ctor is applied to Duplexes, though they're not
+ // instanceof Writable, they're instanceof Readable.
+ if (!(this instanceof Writable) && !(this instanceof Duplex)) return new Writable(options);
+
+ this._writableState = new WritableState(options, this);
+
+ // legacy.
+ this.writable = true;
+
+ if (options) {
+ if (typeof options.write === 'function') this._write = options.write;
+
+ if (typeof options.writev === 'function') this._writev = options.writev;
+ }
+
+ Stream.call(this);
+}
+
+// Otherwise people can pipe Writable streams, which is just wrong.
+Writable.prototype.pipe = function () {
+ this.emit('error', new Error('Cannot pipe. Not readable.'));
+};
+
+function writeAfterEnd(stream, cb) {
+ var er = new Error('write after end');
+ // TODO: defer error events consistently everywhere, not just the cb
+ stream.emit('error', er);
+ processNextTick(cb, er);
+}
+
+// If we get something that is not a buffer, string, null, or undefined,
+// and we're not in objectMode, then that's an error.
+// Otherwise stream chunks are all considered to be of length=1, and the
+// watermarks determine how many objects to keep in the buffer, rather than
+// how many bytes or characters.
+function validChunk(stream, state, chunk, cb) {
+ var valid = true;
+
+ if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) {
+ var er = new TypeError('Invalid non-string/buffer chunk');
+ stream.emit('error', er);
+ processNextTick(cb, er);
+ valid = false;
+ }
+ return valid;
+}
+
+Writable.prototype.write = function (chunk, encoding, cb) {
+ var state = this._writableState;
+ var ret = false;
+
+ if (typeof encoding === 'function') {
+ cb = encoding;
+ encoding = null;
+ }
+
+ if (Buffer.isBuffer(chunk)) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding;
+
+ if (typeof cb !== 'function') cb = nop;
+
+ if (state.ended) writeAfterEnd(this, cb);else if (validChunk(this, state, chunk, cb)) {
+ state.pendingcb++;
+ ret = writeOrBuffer(this, state, chunk, encoding, cb);
+ }
+
+ return ret;
+};
+
+Writable.prototype.cork = function () {
+ var state = this._writableState;
+
+ state.corked++;
+};
+
+Writable.prototype.uncork = function () {
+ var state = this._writableState;
+
+ if (state.corked) {
+ state.corked--;
+
+ if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);
+ }
+};
+
+Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {
+ // node::ParseEncoding() requires lower case.
+ if (typeof encoding === 'string') encoding = encoding.toLowerCase();
+ if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding);
+ this._writableState.defaultEncoding = encoding;
+};
+
+function decodeChunk(state, chunk, encoding) {
+ if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') {
+ chunk = new Buffer(chunk, encoding);
+ }
+ return chunk;
+}
+
+// if we're already writing something, then just put this
+// in the queue, and wait our turn. Otherwise, call _write
+// If we return false, then we need a drain event, so set that flag.
+function writeOrBuffer(stream, state, chunk, encoding, cb) {
+ chunk = decodeChunk(state, chunk, encoding);
+
+ if (Buffer.isBuffer(chunk)) encoding = 'buffer';
+ var len = state.objectMode ? 1 : chunk.length;
+
+ state.length += len;
+
+ var ret = state.length < state.highWaterMark;
+ // we must ensure that previous needDrain will not be reset to false.
+ if (!ret) state.needDrain = true;
+
+ if (state.writing || state.corked) {
+ var last = state.lastBufferedRequest;
+ state.lastBufferedRequest = new WriteReq(chunk, encoding, cb);
+ if (last) {
+ last.next = state.lastBufferedRequest;
+ } else {
+ state.bufferedRequest = state.lastBufferedRequest;
+ }
+ state.bufferedRequestCount += 1;
+ } else {
+ doWrite(stream, state, false, len, chunk, encoding, cb);
+ }
+
+ return ret;
+}
+
+function doWrite(stream, state, writev, len, chunk, encoding, cb) {
+ state.writelen = len;
+ state.writecb = cb;
+ state.writing = true;
+ state.sync = true;
+ if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite);
+ state.sync = false;
+}
+
+function onwriteError(stream, state, sync, er, cb) {
+ --state.pendingcb;
+ if (sync) processNextTick(cb, er);else cb(er);
+
+ stream._writableState.errorEmitted = true;
+ stream.emit('error', er);
+}
+
+function onwriteStateUpdate(state) {
+ state.writing = false;
+ state.writecb = null;
+ state.length -= state.writelen;
+ state.writelen = 0;
+}
+
+function onwrite(stream, er) {
+ var state = stream._writableState;
+ var sync = state.sync;
+ var cb = state.writecb;
+
+ onwriteStateUpdate(state);
+
+ if (er) onwriteError(stream, state, sync, er, cb);else {
+ // Check if we're actually ready to finish, but don't emit yet
+ var finished = needFinish(state);
+
+ if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) {
+ clearBuffer(stream, state);
+ }
+
+ if (sync) {
+ /**/
+ asyncWrite(afterWrite, stream, state, finished, cb);
+ /**/
+ } else {
+ afterWrite(stream, state, finished, cb);
+ }
+ }
+}
+
+function afterWrite(stream, state, finished, cb) {
+ if (!finished) onwriteDrain(stream, state);
+ state.pendingcb--;
+ cb();
+ finishMaybe(stream, state);
+}
+
+// Must force callback to be called on nextTick, so that we don't
+// emit 'drain' before the write() consumer gets the 'false' return
+// value, and has a chance to attach a 'drain' listener.
+function onwriteDrain(stream, state) {
+ if (state.length === 0 && state.needDrain) {
+ state.needDrain = false;
+ stream.emit('drain');
+ }
+}
+
+// if there's something in the buffer waiting, then process it
+function clearBuffer(stream, state) {
+ state.bufferProcessing = true;
+ var entry = state.bufferedRequest;
+
+ if (stream._writev && entry && entry.next) {
+ // Fast case, write everything using _writev()
+ var l = state.bufferedRequestCount;
+ var buffer = new Array(l);
+ var holder = state.corkedRequestsFree;
+ holder.entry = entry;
+
+ var count = 0;
+ while (entry) {
+ buffer[count] = entry;
+ entry = entry.next;
+ count += 1;
+ }
+
+ doWrite(stream, state, true, state.length, buffer, '', holder.finish);
+
+ // doWrite is always async, defer these to save a bit of time
+ // as the hot path ends with doWrite
+ state.pendingcb++;
+ state.lastBufferedRequest = null;
+ state.corkedRequestsFree = holder.next;
+ holder.next = null;
+ } else {
+ // Slow case, write chunks one-by-one
+ while (entry) {
+ var chunk = entry.chunk;
+ var encoding = entry.encoding;
+ var cb = entry.callback;
+ var len = state.objectMode ? 1 : chunk.length;
+
+ doWrite(stream, state, false, len, chunk, encoding, cb);
+ entry = entry.next;
+ // if we didn't call the onwrite immediately, then
+ // it means that we need to wait until it does.
+ // also, that means that the chunk and cb are currently
+ // being processed, so move the buffer counter past them.
+ if (state.writing) {
+ break;
+ }
+ }
+
+ if (entry === null) state.lastBufferedRequest = null;
+ }
+
+ state.bufferedRequestCount = 0;
+ state.bufferedRequest = entry;
+ state.bufferProcessing = false;
+}
+
+Writable.prototype._write = function (chunk, encoding, cb) {
+ cb(new Error('not implemented'));
+};
+
+Writable.prototype._writev = null;
+
+Writable.prototype.end = function (chunk, encoding, cb) {
+ var state = this._writableState;
+
+ if (typeof chunk === 'function') {
+ cb = chunk;
+ chunk = null;
+ encoding = null;
+ } else if (typeof encoding === 'function') {
+ cb = encoding;
+ encoding = null;
+ }
+
+ if (chunk !== null && chunk !== undefined) this.write(chunk, encoding);
+
+ // .end() fully uncorks
+ if (state.corked) {
+ state.corked = 1;
+ this.uncork();
+ }
+
+ // ignore unnecessary end() calls.
+ if (!state.ending && !state.finished) endWritable(this, state, cb);
+};
+
+function needFinish(state) {
+ return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing;
+}
+
+function prefinish(stream, state) {
+ if (!state.prefinished) {
+ state.prefinished = true;
+ stream.emit('prefinish');
+ }
+}
+
+function finishMaybe(stream, state) {
+ var need = needFinish(state);
+ if (need) {
+ if (state.pendingcb === 0) {
+ prefinish(stream, state);
+ state.finished = true;
+ stream.emit('finish');
+ } else {
+ prefinish(stream, state);
+ }
+ }
+ return need;
+}
+
+function endWritable(stream, state, cb) {
+ state.ending = true;
+ finishMaybe(stream, state);
+ if (cb) {
+ if (state.finished) processNextTick(cb);else stream.once('finish', cb);
+ }
+ state.ended = true;
+ stream.writable = false;
+}
+
+// It seems a linked list but it is not
+// there will be only 2 of these for each stream
+function CorkedRequest(state) {
+ var _this = this;
+
+ this.next = null;
+ this.entry = null;
+
+ this.finish = function (err) {
+ var entry = _this.entry;
+ _this.entry = null;
+ while (entry) {
+ var cb = entry.callback;
+ state.pendingcb--;
+ cb(err);
+ entry = entry.next;
+ }
+ if (state.corkedRequestsFree) {
+ state.corkedRequestsFree.next = _this;
+ } else {
+ state.corkedRequestsFree = _this;
+ }
+ };
+}
\ No newline at end of file
diff --git a/fril/node_modules/readable-stream/package.json b/fril/node_modules/readable-stream/package.json
new file mode 100644
index 0000000..56f445a
--- /dev/null
+++ b/fril/node_modules/readable-stream/package.json
@@ -0,0 +1,113 @@
+{
+ "_args": [
+ [
+ {
+ "raw": "readable-stream@~2.0.0",
+ "scope": null,
+ "escapedName": "readable-stream",
+ "name": "readable-stream",
+ "rawSpec": "~2.0.0",
+ "spec": ">=2.0.0 <2.1.0",
+ "type": "range"
+ },
+ "D:\\Workspace\\Dokument\\Skolarbete\\KTH\\Web & Mobile GIS - AG2417\\Project\\dev\\fril\\node_modules\\concat-stream"
+ ]
+ ],
+ "_from": "readable-stream@>=2.0.0 <2.1.0",
+ "_id": "readable-stream@2.0.6",
+ "_inCache": true,
+ "_location": "/readable-stream",
+ "_nodeVersion": "5.7.0",
+ "_npmOperationalInternal": {
+ "host": "packages-12-west.internal.npmjs.com",
+ "tmp": "tmp/readable-stream-2.0.6.tgz_1457893507709_0.369257491780445"
+ },
+ "_npmUser": {
+ "name": "cwmma",
+ "email": "calvin.metcalf@gmail.com"
+ },
+ "_npmVersion": "3.6.0",
+ "_phantomChildren": {},
+ "_requested": {
+ "raw": "readable-stream@~2.0.0",
+ "scope": null,
+ "escapedName": "readable-stream",
+ "name": "readable-stream",
+ "rawSpec": "~2.0.0",
+ "spec": ">=2.0.0 <2.1.0",
+ "type": "range"
+ },
+ "_requiredBy": [
+ "/concat-stream"
+ ],
+ "_resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz",
+ "_shasum": "8f90341e68a53ccc928788dacfcd11b36eb9b78e",
+ "_shrinkwrap": null,
+ "_spec": "readable-stream@~2.0.0",
+ "_where": "D:\\Workspace\\Dokument\\Skolarbete\\KTH\\Web & Mobile GIS - AG2417\\Project\\dev\\fril\\node_modules\\concat-stream",
+ "browser": {
+ "util": false
+ },
+ "bugs": {
+ "url": "https://github.com/nodejs/readable-stream/issues"
+ },
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~1.0.6",
+ "string_decoder": "~0.10.x",
+ "util-deprecate": "~1.0.1"
+ },
+ "description": "Streams3, a user-land copy of the stream library from Node.js",
+ "devDependencies": {
+ "tap": "~0.2.6",
+ "tape": "~4.5.1",
+ "zuul": "~3.9.0"
+ },
+ "directories": {},
+ "dist": {
+ "shasum": "8f90341e68a53ccc928788dacfcd11b36eb9b78e",
+ "tarball": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz"
+ },
+ "gitHead": "01fb5608a970b42c900b96746cadc13d27dd9d7e",
+ "homepage": "https://github.com/nodejs/readable-stream#readme",
+ "keywords": [
+ "readable",
+ "stream",
+ "pipe"
+ ],
+ "license": "MIT",
+ "main": "readable.js",
+ "maintainers": [
+ {
+ "name": "isaacs",
+ "email": "isaacs@npmjs.com"
+ },
+ {
+ "name": "tootallnate",
+ "email": "nathan@tootallnate.net"
+ },
+ {
+ "name": "rvagg",
+ "email": "rod@vagg.org"
+ },
+ {
+ "name": "cwmma",
+ "email": "calvin.metcalf@gmail.com"
+ }
+ ],
+ "name": "readable-stream",
+ "optionalDependencies": {},
+ "readme": "ERROR: No README data found!",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/nodejs/readable-stream.git"
+ },
+ "scripts": {
+ "browser": "npm run write-zuul && zuul -- test/browser.js",
+ "test": "tap test/parallel/*.js test/ours/*.js",
+ "write-zuul": "printf \"ui: tape\nbrowsers:\n - name: $BROWSER_NAME\n version: $BROWSER_VERSION\n\">.zuul.yml"
+ },
+ "version": "2.0.6"
+}
diff --git a/fril/node_modules/readable-stream/passthrough.js b/fril/node_modules/readable-stream/passthrough.js
new file mode 100644
index 0000000..27e8d8a
--- /dev/null
+++ b/fril/node_modules/readable-stream/passthrough.js
@@ -0,0 +1 @@
+module.exports = require("./lib/_stream_passthrough.js")
diff --git a/fril/node_modules/readable-stream/readable.js b/fril/node_modules/readable-stream/readable.js
new file mode 100644
index 0000000..6222a57
--- /dev/null
+++ b/fril/node_modules/readable-stream/readable.js
@@ -0,0 +1,12 @@
+var Stream = (function (){
+ try {
+ return require('st' + 'ream'); // hack to fix a circular dependency issue when used with browserify
+ } catch(_){}
+}());
+exports = module.exports = require('./lib/_stream_readable.js');
+exports.Stream = Stream || exports;
+exports.Readable = exports;
+exports.Writable = require('./lib/_stream_writable.js');
+exports.Duplex = require('./lib/_stream_duplex.js');
+exports.Transform = require('./lib/_stream_transform.js');
+exports.PassThrough = require('./lib/_stream_passthrough.js');
diff --git a/fril/node_modules/readable-stream/transform.js b/fril/node_modules/readable-stream/transform.js
new file mode 100644
index 0000000..5d482f0
--- /dev/null
+++ b/fril/node_modules/readable-stream/transform.js
@@ -0,0 +1 @@
+module.exports = require("./lib/_stream_transform.js")
diff --git a/fril/node_modules/readable-stream/writable.js b/fril/node_modules/readable-stream/writable.js
new file mode 100644
index 0000000..e1e9efd
--- /dev/null
+++ b/fril/node_modules/readable-stream/writable.js
@@ -0,0 +1 @@
+module.exports = require("./lib/_stream_writable.js")
diff --git a/fril/node_modules/string_decoder/.npmignore b/fril/node_modules/string_decoder/.npmignore
new file mode 100644
index 0000000..206320c
--- /dev/null
+++ b/fril/node_modules/string_decoder/.npmignore
@@ -0,0 +1,2 @@
+build
+test
diff --git a/fril/node_modules/string_decoder/LICENSE b/fril/node_modules/string_decoder/LICENSE
new file mode 100644
index 0000000..6de584a
--- /dev/null
+++ b/fril/node_modules/string_decoder/LICENSE
@@ -0,0 +1,20 @@
+Copyright Joyent, Inc. and other Node contributors.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to permit
+persons to whom the Software is furnished to do so, subject to the
+following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/fril/node_modules/string_decoder/README.md b/fril/node_modules/string_decoder/README.md
new file mode 100644
index 0000000..4d2aa00
--- /dev/null
+++ b/fril/node_modules/string_decoder/README.md
@@ -0,0 +1,7 @@
+**string_decoder.js** (`require('string_decoder')`) from Node.js core
+
+Copyright Joyent, Inc. and other Node contributors. See LICENCE file for details.
+
+Version numbers match the versions found in Node core, e.g. 0.10.24 matches Node 0.10.24, likewise 0.11.10 matches Node 0.11.10. **Prefer the stable version over the unstable.**
+
+The *build/* directory contains a build script that will scrape the source from the [joyent/node](https://github.com/joyent/node) repo given a specific Node version.
\ No newline at end of file
diff --git a/fril/node_modules/string_decoder/index.js b/fril/node_modules/string_decoder/index.js
new file mode 100644
index 0000000..b00e54f
--- /dev/null
+++ b/fril/node_modules/string_decoder/index.js
@@ -0,0 +1,221 @@
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+var Buffer = require('buffer').Buffer;
+
+var isBufferEncoding = Buffer.isEncoding
+ || function(encoding) {
+ switch (encoding && encoding.toLowerCase()) {
+ case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true;
+ default: return false;
+ }
+ }
+
+
+function assertEncoding(encoding) {
+ if (encoding && !isBufferEncoding(encoding)) {
+ throw new Error('Unknown encoding: ' + encoding);
+ }
+}
+
+// StringDecoder provides an interface for efficiently splitting a series of
+// buffers into a series of JS strings without breaking apart multi-byte
+// characters. CESU-8 is handled as part of the UTF-8 encoding.
+//
+// @TODO Handling all encodings inside a single object makes it very difficult
+// to reason about this code, so it should be split up in the future.
+// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code
+// points as used by CESU-8.
+var StringDecoder = exports.StringDecoder = function(encoding) {
+ this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, '');
+ assertEncoding(encoding);
+ switch (this.encoding) {
+ case 'utf8':
+ // CESU-8 represents each of Surrogate Pair by 3-bytes
+ this.surrogateSize = 3;
+ break;
+ case 'ucs2':
+ case 'utf16le':
+ // UTF-16 represents each of Surrogate Pair by 2-bytes
+ this.surrogateSize = 2;
+ this.detectIncompleteChar = utf16DetectIncompleteChar;
+ break;
+ case 'base64':
+ // Base-64 stores 3 bytes in 4 chars, and pads the remainder.
+ this.surrogateSize = 3;
+ this.detectIncompleteChar = base64DetectIncompleteChar;
+ break;
+ default:
+ this.write = passThroughWrite;
+ return;
+ }
+
+ // Enough space to store all bytes of a single character. UTF-8 needs 4
+ // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate).
+ this.charBuffer = new Buffer(6);
+ // Number of bytes received for the current incomplete multi-byte character.
+ this.charReceived = 0;
+ // Number of bytes expected for the current incomplete multi-byte character.
+ this.charLength = 0;
+};
+
+
+// write decodes the given buffer and returns it as JS string that is
+// guaranteed to not contain any partial multi-byte characters. Any partial
+// character found at the end of the buffer is buffered up, and will be
+// returned when calling write again with the remaining bytes.
+//
+// Note: Converting a Buffer containing an orphan surrogate to a String
+// currently works, but converting a String to a Buffer (via `new Buffer`, or
+// Buffer#write) will replace incomplete surrogates with the unicode
+// replacement character. See https://codereview.chromium.org/121173009/ .
+StringDecoder.prototype.write = function(buffer) {
+ var charStr = '';
+ // if our last write ended with an incomplete multibyte character
+ while (this.charLength) {
+ // determine how many remaining bytes this buffer has to offer for this char
+ var available = (buffer.length >= this.charLength - this.charReceived) ?
+ this.charLength - this.charReceived :
+ buffer.length;
+
+ // add the new bytes to the char buffer
+ buffer.copy(this.charBuffer, this.charReceived, 0, available);
+ this.charReceived += available;
+
+ if (this.charReceived < this.charLength) {
+ // still not enough chars in this buffer? wait for more ...
+ return '';
+ }
+
+ // remove bytes belonging to the current character from the buffer
+ buffer = buffer.slice(available, buffer.length);
+
+ // get the character that was split
+ charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding);
+
+ // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character
+ var charCode = charStr.charCodeAt(charStr.length - 1);
+ if (charCode >= 0xD800 && charCode <= 0xDBFF) {
+ this.charLength += this.surrogateSize;
+ charStr = '';
+ continue;
+ }
+ this.charReceived = this.charLength = 0;
+
+ // if there are no more bytes in this buffer, just emit our char
+ if (buffer.length === 0) {
+ return charStr;
+ }
+ break;
+ }
+
+ // determine and set charLength / charReceived
+ this.detectIncompleteChar(buffer);
+
+ var end = buffer.length;
+ if (this.charLength) {
+ // buffer the incomplete character bytes we got
+ buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end);
+ end -= this.charReceived;
+ }
+
+ charStr += buffer.toString(this.encoding, 0, end);
+
+ var end = charStr.length - 1;
+ var charCode = charStr.charCodeAt(end);
+ // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character
+ if (charCode >= 0xD800 && charCode <= 0xDBFF) {
+ var size = this.surrogateSize;
+ this.charLength += size;
+ this.charReceived += size;
+ this.charBuffer.copy(this.charBuffer, size, 0, size);
+ buffer.copy(this.charBuffer, 0, 0, size);
+ return charStr.substring(0, end);
+ }
+
+ // or just emit the charStr
+ return charStr;
+};
+
+// detectIncompleteChar determines if there is an incomplete UTF-8 character at
+// the end of the given buffer. If so, it sets this.charLength to the byte
+// length that character, and sets this.charReceived to the number of bytes
+// that are available for this character.
+StringDecoder.prototype.detectIncompleteChar = function(buffer) {
+ // determine how many bytes we have to check at the end of this buffer
+ var i = (buffer.length >= 3) ? 3 : buffer.length;
+
+ // Figure out if one of the last i bytes of our buffer announces an
+ // incomplete char.
+ for (; i > 0; i--) {
+ var c = buffer[buffer.length - i];
+
+ // See http://en.wikipedia.org/wiki/UTF-8#Description
+
+ // 110XXXXX
+ if (i == 1 && c >> 5 == 0x06) {
+ this.charLength = 2;
+ break;
+ }
+
+ // 1110XXXX
+ if (i <= 2 && c >> 4 == 0x0E) {
+ this.charLength = 3;
+ break;
+ }
+
+ // 11110XXX
+ if (i <= 3 && c >> 3 == 0x1E) {
+ this.charLength = 4;
+ break;
+ }
+ }
+ this.charReceived = i;
+};
+
+StringDecoder.prototype.end = function(buffer) {
+ var res = '';
+ if (buffer && buffer.length)
+ res = this.write(buffer);
+
+ if (this.charReceived) {
+ var cr = this.charReceived;
+ var buf = this.charBuffer;
+ var enc = this.encoding;
+ res += buf.slice(0, cr).toString(enc);
+ }
+
+ return res;
+};
+
+function passThroughWrite(buffer) {
+ return buffer.toString(this.encoding);
+}
+
+function utf16DetectIncompleteChar(buffer) {
+ this.charReceived = buffer.length % 2;
+ this.charLength = this.charReceived ? 2 : 0;
+}
+
+function base64DetectIncompleteChar(buffer) {
+ this.charReceived = buffer.length % 3;
+ this.charLength = this.charReceived ? 3 : 0;
+}
diff --git a/fril/node_modules/string_decoder/package.json b/fril/node_modules/string_decoder/package.json
new file mode 100644
index 0000000..29c5cc8
--- /dev/null
+++ b/fril/node_modules/string_decoder/package.json
@@ -0,0 +1,87 @@
+{
+ "_args": [
+ [
+ {
+ "raw": "string_decoder@~0.10.x",
+ "scope": null,
+ "escapedName": "string_decoder",
+ "name": "string_decoder",
+ "rawSpec": "~0.10.x",
+ "spec": ">=0.10.0 <0.11.0",
+ "type": "range"
+ },
+ "D:\\Workspace\\Dokument\\Skolarbete\\KTH\\Web & Mobile GIS - AG2417\\Project\\dev\\fril\\node_modules\\readable-stream"
+ ]
+ ],
+ "_from": "string_decoder@>=0.10.0 <0.11.0",
+ "_id": "string_decoder@0.10.31",
+ "_inCache": true,
+ "_location": "/string_decoder",
+ "_npmUser": {
+ "name": "rvagg",
+ "email": "rod@vagg.org"
+ },
+ "_npmVersion": "1.4.23",
+ "_phantomChildren": {},
+ "_requested": {
+ "raw": "string_decoder@~0.10.x",
+ "scope": null,
+ "escapedName": "string_decoder",
+ "name": "string_decoder",
+ "rawSpec": "~0.10.x",
+ "spec": ">=0.10.0 <0.11.0",
+ "type": "range"
+ },
+ "_requiredBy": [
+ "/readable-stream"
+ ],
+ "_resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "_shasum": "62e203bc41766c6c28c9fc84301dab1c5310fa94",
+ "_shrinkwrap": null,
+ "_spec": "string_decoder@~0.10.x",
+ "_where": "D:\\Workspace\\Dokument\\Skolarbete\\KTH\\Web & Mobile GIS - AG2417\\Project\\dev\\fril\\node_modules\\readable-stream",
+ "bugs": {
+ "url": "https://github.com/rvagg/string_decoder/issues"
+ },
+ "dependencies": {},
+ "description": "The string_decoder module from Node core",
+ "devDependencies": {
+ "tap": "~0.4.8"
+ },
+ "directories": {},
+ "dist": {
+ "shasum": "62e203bc41766c6c28c9fc84301dab1c5310fa94",
+ "tarball": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz"
+ },
+ "gitHead": "d46d4fd87cf1d06e031c23f1ba170ca7d4ade9a0",
+ "homepage": "https://github.com/rvagg/string_decoder",
+ "keywords": [
+ "string",
+ "decoder",
+ "browser",
+ "browserify"
+ ],
+ "license": "MIT",
+ "main": "index.js",
+ "maintainers": [
+ {
+ "name": "substack",
+ "email": "mail@substack.net"
+ },
+ {
+ "name": "rvagg",
+ "email": "rod@vagg.org"
+ }
+ ],
+ "name": "string_decoder",
+ "optionalDependencies": {},
+ "readme": "ERROR: No README data found!",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/rvagg/string_decoder.git"
+ },
+ "scripts": {
+ "test": "tap test/simple/*.js"
+ },
+ "version": "0.10.31"
+}
diff --git a/fril/node_modules/typedarray/.travis.yml b/fril/node_modules/typedarray/.travis.yml
new file mode 100644
index 0000000..cc4dba2
--- /dev/null
+++ b/fril/node_modules/typedarray/.travis.yml
@@ -0,0 +1,4 @@
+language: node_js
+node_js:
+ - "0.8"
+ - "0.10"
diff --git a/fril/node_modules/typedarray/LICENSE b/fril/node_modules/typedarray/LICENSE
new file mode 100644
index 0000000..11adfae
--- /dev/null
+++ b/fril/node_modules/typedarray/LICENSE
@@ -0,0 +1,35 @@
+/*
+ Copyright (c) 2010, Linden Research, Inc.
+ Copyright (c) 2012, Joshua Bell
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ $/LicenseInfo$
+ */
+
+// Original can be found at:
+// https://bitbucket.org/lindenlab/llsd
+// Modifications by Joshua Bell inexorabletash@gmail.com
+// https://github.com/inexorabletash/polyfill
+
+// ES3/ES5 implementation of the Krhonos Typed Array Specification
+// Ref: http://www.khronos.org/registry/typedarray/specs/latest/
+// Date: 2011-02-01
+//
+// Variations:
+// * Allows typed_array.get/set() as alias for subscripts (typed_array[])
diff --git a/fril/node_modules/typedarray/example/tarray.js b/fril/node_modules/typedarray/example/tarray.js
new file mode 100644
index 0000000..8423d7c
--- /dev/null
+++ b/fril/node_modules/typedarray/example/tarray.js
@@ -0,0 +1,4 @@
+var Uint8Array = require('../').Uint8Array;
+var ua = new Uint8Array(5);
+ua[1] = 256 + 55;
+console.log(ua[1]);
diff --git a/fril/node_modules/typedarray/index.js b/fril/node_modules/typedarray/index.js
new file mode 100644
index 0000000..5e54084
--- /dev/null
+++ b/fril/node_modules/typedarray/index.js
@@ -0,0 +1,630 @@
+var undefined = (void 0); // Paranoia
+
+// Beyond this value, index getters/setters (i.e. array[0], array[1]) are so slow to
+// create, and consume so much memory, that the browser appears frozen.
+var MAX_ARRAY_LENGTH = 1e5;
+
+// Approximations of internal ECMAScript conversion functions
+var ECMAScript = (function() {
+ // Stash a copy in case other scripts modify these
+ var opts = Object.prototype.toString,
+ ophop = Object.prototype.hasOwnProperty;
+
+ return {
+ // Class returns internal [[Class]] property, used to avoid cross-frame instanceof issues:
+ Class: function(v) { return opts.call(v).replace(/^\[object *|\]$/g, ''); },
+ HasProperty: function(o, p) { return p in o; },
+ HasOwnProperty: function(o, p) { return ophop.call(o, p); },
+ IsCallable: function(o) { return typeof o === 'function'; },
+ ToInt32: function(v) { return v >> 0; },
+ ToUint32: function(v) { return v >>> 0; }
+ };
+}());
+
+// Snapshot intrinsics
+var LN2 = Math.LN2,
+ abs = Math.abs,
+ floor = Math.floor,
+ log = Math.log,
+ min = Math.min,
+ pow = Math.pow,
+ round = Math.round;
+
+// ES5: lock down object properties
+function configureProperties(obj) {
+ if (getOwnPropNames && defineProp) {
+ var props = getOwnPropNames(obj), i;
+ for (i = 0; i < props.length; i += 1) {
+ defineProp(obj, props[i], {
+ value: obj[props[i]],
+ writable: false,
+ enumerable: false,
+ configurable: false
+ });
+ }
+ }
+}
+
+// emulate ES5 getter/setter API using legacy APIs
+// http://blogs.msdn.com/b/ie/archive/2010/09/07/transitioning-existing-code-to-the-es5-getter-setter-apis.aspx
+// (second clause tests for Object.defineProperty() in IE<9 that only supports extending DOM prototypes, but
+// note that IE<9 does not support __defineGetter__ or __defineSetter__ so it just renders the method harmless)
+var defineProp
+if (Object.defineProperty && (function() {
+ try {
+ Object.defineProperty({}, 'x', {});
+ return true;
+ } catch (e) {
+ return false;
+ }
+ })()) {
+ defineProp = Object.defineProperty;
+} else {
+ defineProp = function(o, p, desc) {
+ if (!o === Object(o)) throw new TypeError("Object.defineProperty called on non-object");
+ if (ECMAScript.HasProperty(desc, 'get') && Object.prototype.__defineGetter__) { Object.prototype.__defineGetter__.call(o, p, desc.get); }
+ if (ECMAScript.HasProperty(desc, 'set') && Object.prototype.__defineSetter__) { Object.prototype.__defineSetter__.call(o, p, desc.set); }
+ if (ECMAScript.HasProperty(desc, 'value')) { o[p] = desc.value; }
+ return o;
+ };
+}
+
+var getOwnPropNames = Object.getOwnPropertyNames || function (o) {
+ if (o !== Object(o)) throw new TypeError("Object.getOwnPropertyNames called on non-object");
+ var props = [], p;
+ for (p in o) {
+ if (ECMAScript.HasOwnProperty(o, p)) {
+ props.push(p);
+ }
+ }
+ return props;
+};
+
+// ES5: Make obj[index] an alias for obj._getter(index)/obj._setter(index, value)
+// for index in 0 ... obj.length
+function makeArrayAccessors(obj) {
+ if (!defineProp) { return; }
+
+ if (obj.length > MAX_ARRAY_LENGTH) throw new RangeError("Array too large for polyfill");
+
+ function makeArrayAccessor(index) {
+ defineProp(obj, index, {
+ 'get': function() { return obj._getter(index); },
+ 'set': function(v) { obj._setter(index, v); },
+ enumerable: true,
+ configurable: false
+ });
+ }
+
+ var i;
+ for (i = 0; i < obj.length; i += 1) {
+ makeArrayAccessor(i);
+ }
+}
+
+// Internal conversion functions:
+// pack() - take a number (interpreted as Type), output a byte array
+// unpack() - take a byte array, output a Type-like number
+
+function as_signed(value, bits) { var s = 32 - bits; return (value << s) >> s; }
+function as_unsigned(value, bits) { var s = 32 - bits; return (value << s) >>> s; }
+
+function packI8(n) { return [n & 0xff]; }
+function unpackI8(bytes) { return as_signed(bytes[0], 8); }
+
+function packU8(n) { return [n & 0xff]; }
+function unpackU8(bytes) { return as_unsigned(bytes[0], 8); }
+
+function packU8Clamped(n) { n = round(Number(n)); return [n < 0 ? 0 : n > 0xff ? 0xff : n & 0xff]; }
+
+function packI16(n) { return [(n >> 8) & 0xff, n & 0xff]; }
+function unpackI16(bytes) { return as_signed(bytes[0] << 8 | bytes[1], 16); }
+
+function packU16(n) { return [(n >> 8) & 0xff, n & 0xff]; }
+function unpackU16(bytes) { return as_unsigned(bytes[0] << 8 | bytes[1], 16); }
+
+function packI32(n) { return [(n >> 24) & 0xff, (n >> 16) & 0xff, (n >> 8) & 0xff, n & 0xff]; }
+function unpackI32(bytes) { return as_signed(bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3], 32); }
+
+function packU32(n) { return [(n >> 24) & 0xff, (n >> 16) & 0xff, (n >> 8) & 0xff, n & 0xff]; }
+function unpackU32(bytes) { return as_unsigned(bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3], 32); }
+
+function packIEEE754(v, ebits, fbits) {
+
+ var bias = (1 << (ebits - 1)) - 1,
+ s, e, f, ln,
+ i, bits, str, bytes;
+
+ function roundToEven(n) {
+ var w = floor(n), f = n - w;
+ if (f < 0.5)
+ return w;
+ if (f > 0.5)
+ return w + 1;
+ return w % 2 ? w + 1 : w;
+ }
+
+ // Compute sign, exponent, fraction
+ if (v !== v) {
+ // NaN
+ // http://dev.w3.org/2006/webapi/WebIDL/#es-type-mapping
+ e = (1 << ebits) - 1; f = pow(2, fbits - 1); s = 0;
+ } else if (v === Infinity || v === -Infinity) {
+ e = (1 << ebits) - 1; f = 0; s = (v < 0) ? 1 : 0;
+ } else if (v === 0) {
+ e = 0; f = 0; s = (1 / v === -Infinity) ? 1 : 0;
+ } else {
+ s = v < 0;
+ v = abs(v);
+
+ if (v >= pow(2, 1 - bias)) {
+ e = min(floor(log(v) / LN2), 1023);
+ f = roundToEven(v / pow(2, e) * pow(2, fbits));
+ if (f / pow(2, fbits) >= 2) {
+ e = e + 1;
+ f = 1;
+ }
+ if (e > bias) {
+ // Overflow
+ e = (1 << ebits) - 1;
+ f = 0;
+ } else {
+ // Normalized
+ e = e + bias;
+ f = f - pow(2, fbits);
+ }
+ } else {
+ // Denormalized
+ e = 0;
+ f = roundToEven(v / pow(2, 1 - bias - fbits));
+ }
+ }
+
+ // Pack sign, exponent, fraction
+ bits = [];
+ for (i = fbits; i; i -= 1) { bits.push(f % 2 ? 1 : 0); f = floor(f / 2); }
+ for (i = ebits; i; i -= 1) { bits.push(e % 2 ? 1 : 0); e = floor(e / 2); }
+ bits.push(s ? 1 : 0);
+ bits.reverse();
+ str = bits.join('');
+
+ // Bits to bytes
+ bytes = [];
+ while (str.length) {
+ bytes.push(parseInt(str.substring(0, 8), 2));
+ str = str.substring(8);
+ }
+ return bytes;
+}
+
+function unpackIEEE754(bytes, ebits, fbits) {
+
+ // Bytes to bits
+ var bits = [], i, j, b, str,
+ bias, s, e, f;
+
+ for (i = bytes.length; i; i -= 1) {
+ b = bytes[i - 1];
+ for (j = 8; j; j -= 1) {
+ bits.push(b % 2 ? 1 : 0); b = b >> 1;
+ }
+ }
+ bits.reverse();
+ str = bits.join('');
+
+ // Unpack sign, exponent, fraction
+ bias = (1 << (ebits - 1)) - 1;
+ s = parseInt(str.substring(0, 1), 2) ? -1 : 1;
+ e = parseInt(str.substring(1, 1 + ebits), 2);
+ f = parseInt(str.substring(1 + ebits), 2);
+
+ // Produce number
+ if (e === (1 << ebits) - 1) {
+ return f !== 0 ? NaN : s * Infinity;
+ } else if (e > 0) {
+ // Normalized
+ return s * pow(2, e - bias) * (1 + f / pow(2, fbits));
+ } else if (f !== 0) {
+ // Denormalized
+ return s * pow(2, -(bias - 1)) * (f / pow(2, fbits));
+ } else {
+ return s < 0 ? -0 : 0;
+ }
+}
+
+function unpackF64(b) { return unpackIEEE754(b, 11, 52); }
+function packF64(v) { return packIEEE754(v, 11, 52); }
+function unpackF32(b) { return unpackIEEE754(b, 8, 23); }
+function packF32(v) { return packIEEE754(v, 8, 23); }
+
+
+//
+// 3 The ArrayBuffer Type
+//
+
+(function() {
+
+ /** @constructor */
+ var ArrayBuffer = function ArrayBuffer(length) {
+ length = ECMAScript.ToInt32(length);
+ if (length < 0) throw new RangeError('ArrayBuffer size is not a small enough positive integer');
+
+ this.byteLength = length;
+ this._bytes = [];
+ this._bytes.length = length;
+
+ var i;
+ for (i = 0; i < this.byteLength; i += 1) {
+ this._bytes[i] = 0;
+ }
+
+ configureProperties(this);
+ };
+
+ exports.ArrayBuffer = exports.ArrayBuffer || ArrayBuffer;
+
+ //
+ // 4 The ArrayBufferView Type
+ //
+
+ // NOTE: this constructor is not exported
+ /** @constructor */
+ var ArrayBufferView = function ArrayBufferView() {
+ //this.buffer = null;
+ //this.byteOffset = 0;
+ //this.byteLength = 0;
+ };
+
+ //
+ // 5 The Typed Array View Types
+ //
+
+ function makeConstructor(bytesPerElement, pack, unpack) {
+ // Each TypedArray type requires a distinct constructor instance with
+ // identical logic, which this produces.
+
+ var ctor;
+ ctor = function(buffer, byteOffset, length) {
+ var array, sequence, i, s;
+
+ if (!arguments.length || typeof arguments[0] === 'number') {
+ // Constructor(unsigned long length)
+ this.length = ECMAScript.ToInt32(arguments[0]);
+ if (length < 0) throw new RangeError('ArrayBufferView size is not a small enough positive integer');
+
+ this.byteLength = this.length * this.BYTES_PER_ELEMENT;
+ this.buffer = new ArrayBuffer(this.byteLength);
+ this.byteOffset = 0;
+ } else if (typeof arguments[0] === 'object' && arguments[0].constructor === ctor) {
+ // Constructor(TypedArray array)
+ array = arguments[0];
+
+ this.length = array.length;
+ this.byteLength = this.length * this.BYTES_PER_ELEMENT;
+ this.buffer = new ArrayBuffer(this.byteLength);
+ this.byteOffset = 0;
+
+ for (i = 0; i < this.length; i += 1) {
+ this._setter(i, array._getter(i));
+ }
+ } else if (typeof arguments[0] === 'object' &&
+ !(arguments[0] instanceof ArrayBuffer || ECMAScript.Class(arguments[0]) === 'ArrayBuffer')) {
+ // Constructor(sequence array)
+ sequence = arguments[0];
+
+ this.length = ECMAScript.ToUint32(sequence.length);
+ this.byteLength = this.length * this.BYTES_PER_ELEMENT;
+ this.buffer = new ArrayBuffer(this.byteLength);
+ this.byteOffset = 0;
+
+ for (i = 0; i < this.length; i += 1) {
+ s = sequence[i];
+ this._setter(i, Number(s));
+ }
+ } else if (typeof arguments[0] === 'object' &&
+ (arguments[0] instanceof ArrayBuffer || ECMAScript.Class(arguments[0]) === 'ArrayBuffer')) {
+ // Constructor(ArrayBuffer buffer,
+ // optional unsigned long byteOffset, optional unsigned long length)
+ this.buffer = buffer;
+
+ this.byteOffset = ECMAScript.ToUint32(byteOffset);
+ if (this.byteOffset > this.buffer.byteLength) {
+ throw new RangeError("byteOffset out of range");
+ }
+
+ if (this.byteOffset % this.BYTES_PER_ELEMENT) {
+ // The given byteOffset must be a multiple of the element
+ // size of the specific type, otherwise an exception is raised.
+ throw new RangeError("ArrayBuffer length minus the byteOffset is not a multiple of the element size.");
+ }
+
+ if (arguments.length < 3) {
+ this.byteLength = this.buffer.byteLength - this.byteOffset;
+
+ if (this.byteLength % this.BYTES_PER_ELEMENT) {
+ throw new RangeError("length of buffer minus byteOffset not a multiple of the element size");
+ }
+ this.length = this.byteLength / this.BYTES_PER_ELEMENT;
+ } else {
+ this.length = ECMAScript.ToUint32(length);
+ this.byteLength = this.length * this.BYTES_PER_ELEMENT;
+ }
+
+ if ((this.byteOffset + this.byteLength) > this.buffer.byteLength) {
+ throw new RangeError("byteOffset and length reference an area beyond the end of the buffer");
+ }
+ } else {
+ throw new TypeError("Unexpected argument type(s)");
+ }
+
+ this.constructor = ctor;
+
+ configureProperties(this);
+ makeArrayAccessors(this);
+ };
+
+ ctor.prototype = new ArrayBufferView();
+ ctor.prototype.BYTES_PER_ELEMENT = bytesPerElement;
+ ctor.prototype._pack = pack;
+ ctor.prototype._unpack = unpack;
+ ctor.BYTES_PER_ELEMENT = bytesPerElement;
+
+ // getter type (unsigned long index);
+ ctor.prototype._getter = function(index) {
+ if (arguments.length < 1) throw new SyntaxError("Not enough arguments");
+
+ index = ECMAScript.ToUint32(index);
+ if (index >= this.length) {
+ return undefined;
+ }
+
+ var bytes = [], i, o;
+ for (i = 0, o = this.byteOffset + index * this.BYTES_PER_ELEMENT;
+ i < this.BYTES_PER_ELEMENT;
+ i += 1, o += 1) {
+ bytes.push(this.buffer._bytes[o]);
+ }
+ return this._unpack(bytes);
+ };
+
+ // NONSTANDARD: convenience alias for getter: type get(unsigned long index);
+ ctor.prototype.get = ctor.prototype._getter;
+
+ // setter void (unsigned long index, type value);
+ ctor.prototype._setter = function(index, value) {
+ if (arguments.length < 2) throw new SyntaxError("Not enough arguments");
+
+ index = ECMAScript.ToUint32(index);
+ if (index >= this.length) {
+ return undefined;
+ }
+
+ var bytes = this._pack(value), i, o;
+ for (i = 0, o = this.byteOffset + index * this.BYTES_PER_ELEMENT;
+ i < this.BYTES_PER_ELEMENT;
+ i += 1, o += 1) {
+ this.buffer._bytes[o] = bytes[i];
+ }
+ };
+
+ // void set(TypedArray array, optional unsigned long offset);
+ // void set(sequence array, optional unsigned long offset);
+ ctor.prototype.set = function(index, value) {
+ if (arguments.length < 1) throw new SyntaxError("Not enough arguments");
+ var array, sequence, offset, len,
+ i, s, d,
+ byteOffset, byteLength, tmp;
+
+ if (typeof arguments[0] === 'object' && arguments[0].constructor === this.constructor) {
+ // void set(TypedArray array, optional unsigned long offset);
+ array = arguments[0];
+ offset = ECMAScript.ToUint32(arguments[1]);
+
+ if (offset + array.length > this.length) {
+ throw new RangeError("Offset plus length of array is out of range");
+ }
+
+ byteOffset = this.byteOffset + offset * this.BYTES_PER_ELEMENT;
+ byteLength = array.length * this.BYTES_PER_ELEMENT;
+
+ if (array.buffer === this.buffer) {
+ tmp = [];
+ for (i = 0, s = array.byteOffset; i < byteLength; i += 1, s += 1) {
+ tmp[i] = array.buffer._bytes[s];
+ }
+ for (i = 0, d = byteOffset; i < byteLength; i += 1, d += 1) {
+ this.buffer._bytes[d] = tmp[i];
+ }
+ } else {
+ for (i = 0, s = array.byteOffset, d = byteOffset;
+ i < byteLength; i += 1, s += 1, d += 1) {
+ this.buffer._bytes[d] = array.buffer._bytes[s];
+ }
+ }
+ } else if (typeof arguments[0] === 'object' && typeof arguments[0].length !== 'undefined') {
+ // void set(sequence array, optional unsigned long offset);
+ sequence = arguments[0];
+ len = ECMAScript.ToUint32(sequence.length);
+ offset = ECMAScript.ToUint32(arguments[1]);
+
+ if (offset + len > this.length) {
+ throw new RangeError("Offset plus length of array is out of range");
+ }
+
+ for (i = 0; i < len; i += 1) {
+ s = sequence[i];
+ this._setter(offset + i, Number(s));
+ }
+ } else {
+ throw new TypeError("Unexpected argument type(s)");
+ }
+ };
+
+ // TypedArray subarray(long begin, optional long end);
+ ctor.prototype.subarray = function(start, end) {
+ function clamp(v, min, max) { return v < min ? min : v > max ? max : v; }
+
+ start = ECMAScript.ToInt32(start);
+ end = ECMAScript.ToInt32(end);
+
+ if (arguments.length < 1) { start = 0; }
+ if (arguments.length < 2) { end = this.length; }
+
+ if (start < 0) { start = this.length + start; }
+ if (end < 0) { end = this.length + end; }
+
+ start = clamp(start, 0, this.length);
+ end = clamp(end, 0, this.length);
+
+ var len = end - start;
+ if (len < 0) {
+ len = 0;
+ }
+
+ return new this.constructor(
+ this.buffer, this.byteOffset + start * this.BYTES_PER_ELEMENT, len);
+ };
+
+ return ctor;
+ }
+
+ var Int8Array = makeConstructor(1, packI8, unpackI8);
+ var Uint8Array = makeConstructor(1, packU8, unpackU8);
+ var Uint8ClampedArray = makeConstructor(1, packU8Clamped, unpackU8);
+ var Int16Array = makeConstructor(2, packI16, unpackI16);
+ var Uint16Array = makeConstructor(2, packU16, unpackU16);
+ var Int32Array = makeConstructor(4, packI32, unpackI32);
+ var Uint32Array = makeConstructor(4, packU32, unpackU32);
+ var Float32Array = makeConstructor(4, packF32, unpackF32);
+ var Float64Array = makeConstructor(8, packF64, unpackF64);
+
+ exports.Int8Array = exports.Int8Array || Int8Array;
+ exports.Uint8Array = exports.Uint8Array || Uint8Array;
+ exports.Uint8ClampedArray = exports.Uint8ClampedArray || Uint8ClampedArray;
+ exports.Int16Array = exports.Int16Array || Int16Array;
+ exports.Uint16Array = exports.Uint16Array || Uint16Array;
+ exports.Int32Array = exports.Int32Array || Int32Array;
+ exports.Uint32Array = exports.Uint32Array || Uint32Array;
+ exports.Float32Array = exports.Float32Array || Float32Array;
+ exports.Float64Array = exports.Float64Array || Float64Array;
+}());
+
+//
+// 6 The DataView View Type
+//
+
+(function() {
+ function r(array, index) {
+ return ECMAScript.IsCallable(array.get) ? array.get(index) : array[index];
+ }
+
+ var IS_BIG_ENDIAN = (function() {
+ var u16array = new(exports.Uint16Array)([0x1234]),
+ u8array = new(exports.Uint8Array)(u16array.buffer);
+ return r(u8array, 0) === 0x12;
+ }());
+
+ // Constructor(ArrayBuffer buffer,
+ // optional unsigned long byteOffset,
+ // optional unsigned long byteLength)
+ /** @constructor */
+ var DataView = function DataView(buffer, byteOffset, byteLength) {
+ if (arguments.length === 0) {
+ buffer = new exports.ArrayBuffer(0);
+ } else if (!(buffer instanceof exports.ArrayBuffer || ECMAScript.Class(buffer) === 'ArrayBuffer')) {
+ throw new TypeError("TypeError");
+ }
+
+ this.buffer = buffer || new exports.ArrayBuffer(0);
+
+ this.byteOffset = ECMAScript.ToUint32(byteOffset);
+ if (this.byteOffset > this.buffer.byteLength) {
+ throw new RangeError("byteOffset out of range");
+ }
+
+ if (arguments.length < 3) {
+ this.byteLength = this.buffer.byteLength - this.byteOffset;
+ } else {
+ this.byteLength = ECMAScript.ToUint32(byteLength);
+ }
+
+ if ((this.byteOffset + this.byteLength) > this.buffer.byteLength) {
+ throw new RangeError("byteOffset and length reference an area beyond the end of the buffer");
+ }
+
+ configureProperties(this);
+ };
+
+ function makeGetter(arrayType) {
+ return function(byteOffset, littleEndian) {
+
+ byteOffset = ECMAScript.ToUint32(byteOffset);
+
+ if (byteOffset + arrayType.BYTES_PER_ELEMENT > this.byteLength) {
+ throw new RangeError("Array index out of range");
+ }
+ byteOffset += this.byteOffset;
+
+ var uint8Array = new exports.Uint8Array(this.buffer, byteOffset, arrayType.BYTES_PER_ELEMENT),
+ bytes = [], i;
+ for (i = 0; i < arrayType.BYTES_PER_ELEMENT; i += 1) {
+ bytes.push(r(uint8Array, i));
+ }
+
+ if (Boolean(littleEndian) === Boolean(IS_BIG_ENDIAN)) {
+ bytes.reverse();
+ }
+
+ return r(new arrayType(new exports.Uint8Array(bytes).buffer), 0);
+ };
+ }
+
+ DataView.prototype.getUint8 = makeGetter(exports.Uint8Array);
+ DataView.prototype.getInt8 = makeGetter(exports.Int8Array);
+ DataView.prototype.getUint16 = makeGetter(exports.Uint16Array);
+ DataView.prototype.getInt16 = makeGetter(exports.Int16Array);
+ DataView.prototype.getUint32 = makeGetter(exports.Uint32Array);
+ DataView.prototype.getInt32 = makeGetter(exports.Int32Array);
+ DataView.prototype.getFloat32 = makeGetter(exports.Float32Array);
+ DataView.prototype.getFloat64 = makeGetter(exports.Float64Array);
+
+ function makeSetter(arrayType) {
+ return function(byteOffset, value, littleEndian) {
+
+ byteOffset = ECMAScript.ToUint32(byteOffset);
+ if (byteOffset + arrayType.BYTES_PER_ELEMENT > this.byteLength) {
+ throw new RangeError("Array index out of range");
+ }
+
+ // Get bytes
+ var typeArray = new arrayType([value]),
+ byteArray = new exports.Uint8Array(typeArray.buffer),
+ bytes = [], i, byteView;
+
+ for (i = 0; i < arrayType.BYTES_PER_ELEMENT; i += 1) {
+ bytes.push(r(byteArray, i));
+ }
+
+ // Flip if necessary
+ if (Boolean(littleEndian) === Boolean(IS_BIG_ENDIAN)) {
+ bytes.reverse();
+ }
+
+ // Write them
+ byteView = new exports.Uint8Array(this.buffer, byteOffset, arrayType.BYTES_PER_ELEMENT);
+ byteView.set(bytes);
+ };
+ }
+
+ DataView.prototype.setUint8 = makeSetter(exports.Uint8Array);
+ DataView.prototype.setInt8 = makeSetter(exports.Int8Array);
+ DataView.prototype.setUint16 = makeSetter(exports.Uint16Array);
+ DataView.prototype.setInt16 = makeSetter(exports.Int16Array);
+ DataView.prototype.setUint32 = makeSetter(exports.Uint32Array);
+ DataView.prototype.setInt32 = makeSetter(exports.Int32Array);
+ DataView.prototype.setFloat32 = makeSetter(exports.Float32Array);
+ DataView.prototype.setFloat64 = makeSetter(exports.Float64Array);
+
+ exports.DataView = exports.DataView || DataView;
+
+}());
diff --git a/fril/node_modules/typedarray/package.json b/fril/node_modules/typedarray/package.json
new file mode 100644
index 0000000..732472b
--- /dev/null
+++ b/fril/node_modules/typedarray/package.json
@@ -0,0 +1,113 @@
+{
+ "_args": [
+ [
+ {
+ "raw": "typedarray@~0.0.5",
+ "scope": null,
+ "escapedName": "typedarray",
+ "name": "typedarray",
+ "rawSpec": "~0.0.5",
+ "spec": ">=0.0.5 <0.1.0",
+ "type": "range"
+ },
+ "D:\\Workspace\\Dokument\\Skolarbete\\KTH\\Web & Mobile GIS - AG2417\\Project\\dev\\fril\\node_modules\\concat-stream"
+ ]
+ ],
+ "_from": "typedarray@>=0.0.5 <0.1.0",
+ "_id": "typedarray@0.0.6",
+ "_inCache": true,
+ "_location": "/typedarray",
+ "_npmUser": {
+ "name": "substack",
+ "email": "mail@substack.net"
+ },
+ "_npmVersion": "1.4.3",
+ "_phantomChildren": {},
+ "_requested": {
+ "raw": "typedarray@~0.0.5",
+ "scope": null,
+ "escapedName": "typedarray",
+ "name": "typedarray",
+ "rawSpec": "~0.0.5",
+ "spec": ">=0.0.5 <0.1.0",
+ "type": "range"
+ },
+ "_requiredBy": [
+ "/concat-stream"
+ ],
+ "_resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+ "_shasum": "867ac74e3864187b1d3d47d996a78ec5c8830777",
+ "_shrinkwrap": null,
+ "_spec": "typedarray@~0.0.5",
+ "_where": "D:\\Workspace\\Dokument\\Skolarbete\\KTH\\Web & Mobile GIS - AG2417\\Project\\dev\\fril\\node_modules\\concat-stream",
+ "author": {
+ "name": "James Halliday",
+ "email": "mail@substack.net",
+ "url": "http://substack.net"
+ },
+ "bugs": {
+ "url": "https://github.com/substack/typedarray/issues"
+ },
+ "dependencies": {},
+ "description": "TypedArray polyfill for old browsers",
+ "devDependencies": {
+ "tape": "~2.3.2"
+ },
+ "directories": {},
+ "dist": {
+ "shasum": "867ac74e3864187b1d3d47d996a78ec5c8830777",
+ "tarball": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz"
+ },
+ "homepage": "https://github.com/substack/typedarray",
+ "keywords": [
+ "ArrayBuffer",
+ "DataView",
+ "Float32Array",
+ "Float64Array",
+ "Int8Array",
+ "Int16Array",
+ "Int32Array",
+ "Uint8Array",
+ "Uint8ClampedArray",
+ "Uint16Array",
+ "Uint32Array",
+ "typed",
+ "array",
+ "polyfill"
+ ],
+ "license": "MIT",
+ "main": "index.js",
+ "maintainers": [
+ {
+ "name": "substack",
+ "email": "mail@substack.net"
+ }
+ ],
+ "name": "typedarray",
+ "optionalDependencies": {},
+ "readme": "ERROR: No README data found!",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/substack/typedarray.git"
+ },
+ "scripts": {
+ "test": "tape test/*.js test/server/*.js"
+ },
+ "testling": {
+ "files": "test/*.js",
+ "browsers": [
+ "ie/6..latest",
+ "firefox/16..latest",
+ "firefox/nightly",
+ "chrome/22..latest",
+ "chrome/canary",
+ "opera/12..latest",
+ "opera/next",
+ "safari/5.1..latest",
+ "ipad/6.0..latest",
+ "iphone/6.0..latest",
+ "android-browser/4.2..latest"
+ ]
+ },
+ "version": "0.0.6"
+}
diff --git a/fril/node_modules/typedarray/readme.markdown b/fril/node_modules/typedarray/readme.markdown
new file mode 100644
index 0000000..d18f6f7
--- /dev/null
+++ b/fril/node_modules/typedarray/readme.markdown
@@ -0,0 +1,61 @@
+# typedarray
+
+TypedArray polyfill ripped from [this
+module](https://raw.github.com/inexorabletash/polyfill).
+
+[](http://travis-ci.org/substack/typedarray)
+
+[](https://ci.testling.com/substack/typedarray)
+
+# example
+
+``` js
+var Uint8Array = require('typedarray').Uint8Array;
+var ua = new Uint8Array(5);
+ua[1] = 256 + 55;
+console.log(ua[1]);
+```
+
+output:
+
+```
+55
+```
+
+# methods
+
+``` js
+var TA = require('typedarray')
+```
+
+The `TA` object has the following constructors:
+
+* TA.ArrayBuffer
+* TA.DataView
+* TA.Float32Array
+* TA.Float64Array
+* TA.Int8Array
+* TA.Int16Array
+* TA.Int32Array
+* TA.Uint8Array
+* TA.Uint8ClampedArray
+* TA.Uint16Array
+* TA.Uint32Array
+
+# install
+
+With [npm](https://npmjs.org) do:
+
+```
+npm install typedarray
+```
+
+To use this module in the browser, compile with
+[browserify](http://browserify.org)
+or download a UMD build from browserify CDN:
+
+http://wzrd.in/standalone/typedarray@latest
+
+# license
+
+MIT
diff --git a/fril/node_modules/typedarray/test/server/undef_globals.js b/fril/node_modules/typedarray/test/server/undef_globals.js
new file mode 100644
index 0000000..425950f
--- /dev/null
+++ b/fril/node_modules/typedarray/test/server/undef_globals.js
@@ -0,0 +1,19 @@
+var test = require('tape');
+var vm = require('vm');
+var fs = require('fs');
+var src = fs.readFileSync(__dirname + '/../../index.js', 'utf8');
+
+test('u8a without globals', function (t) {
+ var c = {
+ module: { exports: {} },
+ };
+ c.exports = c.module.exports;
+ vm.runInNewContext(src, c);
+ var TA = c.module.exports;
+ var ua = new(TA.Uint8Array)(5);
+
+ t.equal(ua.length, 5);
+ ua[1] = 256 + 55;
+ t.equal(ua[1], 55);
+ t.end();
+});
diff --git a/fril/node_modules/typedarray/test/tarray.js b/fril/node_modules/typedarray/test/tarray.js
new file mode 100644
index 0000000..df596a3
--- /dev/null
+++ b/fril/node_modules/typedarray/test/tarray.js
@@ -0,0 +1,10 @@
+var TA = require('../');
+var test = require('tape');
+
+test('tiny u8a test', function (t) {
+ var ua = new(TA.Uint8Array)(5);
+ t.equal(ua.length, 5);
+ ua[1] = 256 + 55;
+ t.equal(ua[1], 55);
+ t.end();
+});
diff --git a/fril/node_modules/util-deprecate/History.md b/fril/node_modules/util-deprecate/History.md
new file mode 100644
index 0000000..acc8675
--- /dev/null
+++ b/fril/node_modules/util-deprecate/History.md
@@ -0,0 +1,16 @@
+
+1.0.2 / 2015-10-07
+==================
+
+ * use try/catch when checking `localStorage` (#3, @kumavis)
+
+1.0.1 / 2014-11-25
+==================
+
+ * browser: use `console.warn()` for deprecation calls
+ * browser: more jsdocs
+
+1.0.0 / 2014-04-30
+==================
+
+ * initial commit
diff --git a/fril/node_modules/util-deprecate/LICENSE b/fril/node_modules/util-deprecate/LICENSE
new file mode 100644
index 0000000..6a60e8c
--- /dev/null
+++ b/fril/node_modules/util-deprecate/LICENSE
@@ -0,0 +1,24 @@
+(The MIT License)
+
+Copyright (c) 2014 Nathan Rajlich
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
diff --git a/fril/node_modules/util-deprecate/README.md b/fril/node_modules/util-deprecate/README.md
new file mode 100644
index 0000000..75622fa
--- /dev/null
+++ b/fril/node_modules/util-deprecate/README.md
@@ -0,0 +1,53 @@
+util-deprecate
+==============
+### The Node.js `util.deprecate()` function with browser support
+
+In Node.js, this module simply re-exports the `util.deprecate()` function.
+
+In the web browser (i.e. via browserify), a browser-specific implementation
+of the `util.deprecate()` function is used.
+
+
+## API
+
+A `deprecate()` function is the only thing exposed by this module.
+
+``` javascript
+// setup:
+exports.foo = deprecate(foo, 'foo() is deprecated, use bar() instead');
+
+
+// users see:
+foo();
+// foo() is deprecated, use bar() instead
+foo();
+foo();
+```
+
+
+## License
+
+(The MIT License)
+
+Copyright (c) 2014 Nathan Rajlich
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
diff --git a/fril/node_modules/util-deprecate/browser.js b/fril/node_modules/util-deprecate/browser.js
new file mode 100644
index 0000000..549ae2f
--- /dev/null
+++ b/fril/node_modules/util-deprecate/browser.js
@@ -0,0 +1,67 @@
+
+/**
+ * Module exports.
+ */
+
+module.exports = deprecate;
+
+/**
+ * Mark that a method should not be used.
+ * Returns a modified function which warns once by default.
+ *
+ * If `localStorage.noDeprecation = true` is set, then it is a no-op.
+ *
+ * If `localStorage.throwDeprecation = true` is set, then deprecated functions
+ * will throw an Error when invoked.
+ *
+ * If `localStorage.traceDeprecation = true` is set, then deprecated functions
+ * will invoke `console.trace()` instead of `console.error()`.
+ *
+ * @param {Function} fn - the function to deprecate
+ * @param {String} msg - the string to print to the console when `fn` is invoked
+ * @returns {Function} a new "deprecated" version of `fn`
+ * @api public
+ */
+
+function deprecate (fn, msg) {
+ if (config('noDeprecation')) {
+ return fn;
+ }
+
+ var warned = false;
+ function deprecated() {
+ if (!warned) {
+ if (config('throwDeprecation')) {
+ throw new Error(msg);
+ } else if (config('traceDeprecation')) {
+ console.trace(msg);
+ } else {
+ console.warn(msg);
+ }
+ warned = true;
+ }
+ return fn.apply(this, arguments);
+ }
+
+ return deprecated;
+}
+
+/**
+ * Checks `localStorage` for boolean values for the given `name`.
+ *
+ * @param {String} name
+ * @returns {Boolean}
+ * @api private
+ */
+
+function config (name) {
+ // accessing global.localStorage can trigger a DOMException in sandboxed iframes
+ try {
+ if (!global.localStorage) return false;
+ } catch (_) {
+ return false;
+ }
+ var val = global.localStorage[name];
+ if (null == val) return false;
+ return String(val).toLowerCase() === 'true';
+}
diff --git a/fril/node_modules/util-deprecate/node.js b/fril/node_modules/util-deprecate/node.js
new file mode 100644
index 0000000..5e6fcff
--- /dev/null
+++ b/fril/node_modules/util-deprecate/node.js
@@ -0,0 +1,6 @@
+
+/**
+ * For Node.js, simply re-export the core `util.deprecate` function.
+ */
+
+module.exports = require('util').deprecate;
diff --git a/fril/node_modules/util-deprecate/package.json b/fril/node_modules/util-deprecate/package.json
new file mode 100644
index 0000000..73071e4
--- /dev/null
+++ b/fril/node_modules/util-deprecate/package.json
@@ -0,0 +1,89 @@
+{
+ "_args": [
+ [
+ {
+ "raw": "util-deprecate@~1.0.1",
+ "scope": null,
+ "escapedName": "util-deprecate",
+ "name": "util-deprecate",
+ "rawSpec": "~1.0.1",
+ "spec": ">=1.0.1 <1.1.0",
+ "type": "range"
+ },
+ "D:\\Workspace\\Dokument\\Skolarbete\\KTH\\Web & Mobile GIS - AG2417\\Project\\dev\\fril\\node_modules\\readable-stream"
+ ]
+ ],
+ "_from": "util-deprecate@>=1.0.1 <1.1.0",
+ "_id": "util-deprecate@1.0.2",
+ "_inCache": true,
+ "_location": "/util-deprecate",
+ "_nodeVersion": "4.1.2",
+ "_npmUser": {
+ "name": "tootallnate",
+ "email": "nathan@tootallnate.net"
+ },
+ "_npmVersion": "2.14.4",
+ "_phantomChildren": {},
+ "_requested": {
+ "raw": "util-deprecate@~1.0.1",
+ "scope": null,
+ "escapedName": "util-deprecate",
+ "name": "util-deprecate",
+ "rawSpec": "~1.0.1",
+ "spec": ">=1.0.1 <1.1.0",
+ "type": "range"
+ },
+ "_requiredBy": [
+ "/readable-stream"
+ ],
+ "_resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "_shasum": "450d4dc9fa70de732762fbd2d4a28981419a0ccf",
+ "_shrinkwrap": null,
+ "_spec": "util-deprecate@~1.0.1",
+ "_where": "D:\\Workspace\\Dokument\\Skolarbete\\KTH\\Web & Mobile GIS - AG2417\\Project\\dev\\fril\\node_modules\\readable-stream",
+ "author": {
+ "name": "Nathan Rajlich",
+ "email": "nathan@tootallnate.net",
+ "url": "http://n8.io/"
+ },
+ "browser": "browser.js",
+ "bugs": {
+ "url": "https://github.com/TooTallNate/util-deprecate/issues"
+ },
+ "dependencies": {},
+ "description": "The Node.js `util.deprecate()` function with browser support",
+ "devDependencies": {},
+ "directories": {},
+ "dist": {
+ "shasum": "450d4dc9fa70de732762fbd2d4a28981419a0ccf",
+ "tarball": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
+ },
+ "gitHead": "475fb6857cd23fafff20c1be846c1350abf8e6d4",
+ "homepage": "https://github.com/TooTallNate/util-deprecate",
+ "keywords": [
+ "util",
+ "deprecate",
+ "browserify",
+ "browser",
+ "node"
+ ],
+ "license": "MIT",
+ "main": "node.js",
+ "maintainers": [
+ {
+ "name": "tootallnate",
+ "email": "nathan@tootallnate.net"
+ }
+ ],
+ "name": "util-deprecate",
+ "optionalDependencies": {},
+ "readme": "ERROR: No README data found!",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/TooTallNate/util-deprecate.git"
+ },
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "version": "1.0.2"
+}
diff --git a/fril/public/javascripts/mapOperations.js b/fril/public/javascripts/mapOperations.js
index f88b693..ce5d761 100644
--- a/fril/public/javascripts/mapOperations.js
+++ b/fril/public/javascripts/mapOperations.js
@@ -50,6 +50,31 @@ STYLE_9935 // Stugby
var LAYER_LIST = [];
+var POLYGON_LIST = [];
+
+var LAN_LIST = [
+'Skåne Län',
+'Blekinge Län',
+'Kalmar Län',
+'Kronobergs Län',
+'Hallands Län',
+'Gotlands Län',
+'Jönköpings Län',
+'Östergötlands Län',
+'Västra Götalands Län',
+'Södermanlands Län',
+'Örebro Län',
+'Värmlands Län',
+'Stockholms Län',
+'Uppsala Län',
+'Västmanlands Län',
+'Dalarnas Län',
+'Gävleborgs Län',
+'Västernorrlands Län',
+'Jämtlands Län',
+'Västerbottens Län',
+'Norrbottens Län'];
+
// ##############################################################
// ---------------------- Initialize stuff ----------------------
// ##############################################################
@@ -74,8 +99,8 @@ function initMap() {
}),
view: new ol.View({
- center: ol.proj.fromLonLat([18.00, 59.00]),
- zoom: 7
+ center: ol.proj.fromLonLat([18.00, 63.00]),
+ zoom: 5
})
});
@@ -83,6 +108,21 @@ function initMap() {
for (i = 0; i < LAYERS.length; i++) {
initLayer(LAYERS[i], LAYER_STYLE[i]);
}
+ // Load polygon data
+ initPolygons(1, ''); // Loads nationalparker
+
+ // Create naturreservat layer and store it
+ var vectorLayer = new ol.layer.Vector({
+ source: new ol.source.Vector({})//,
+ // style: vectorStyle
+ });
+ map.addLayer(vectorLayer);
+ POLYGON_LIST[0] = vectorLayer;
+
+ for (i = 0; i < LAN_LIST.length; i++) {
+ // Loads naturreservat one län at a time
+ initPolygons(0, LAN_LIST[i]);
+ }
// Add relevent controls
addMousePosition(map);
@@ -103,6 +143,7 @@ function initMap() {
// Retrun the map
return map;
+ console.log(POLYGON_LIST);
}
function initLayer(kkod, style) {
@@ -122,10 +163,10 @@ function initLayer(kkod, style) {
style: style
});
-
for (i = 0; i < res.length; i++) {
// Location/geometry
var wktGeometry = Terraformer.WKT.parse(res[i].geometry);
+ // console.log(wktGeometry.coordinates);
var geometry = new ol.geom.Point(ol.proj.transform(wktGeometry.coordinates, 'EPSG:4326', 'EPSG:3857'));
var feature = new ol.Feature({});
@@ -145,6 +186,54 @@ function initLayer(kkod, style) {
});
}
+function initPolygons(type, lan, ) {
+ var request = $.ajax({
+ url: "/api/getPolygons",
+ method: "POST",
+ data: {type:type, lan:lan},
+ cache: false
+ });
+
+ request.done(function(res) {
+ var vectorSource;
+ if (type == 0) {
+ vectorSource = POLYGON_LIST[0].getSource();
+ } else {
+ vectorSource = new ol.source.Vector({});
+
+ var vectorLayer = new ol.layer.Vector({
+ source: vectorSource//,
+ // style: vectorStyle
+ });
+
+ map.addLayer(vectorLayer);
+ POLYGON_LIST[1] = vectorLayer;
+ }
+
+ var resultRow;
+ for (i = 0; i < res.length; i++) {
+ resultRow = res[i];
+
+ var coordinates = formatPolyCoords(resultRow.geometry);
+ var geometry = new ol.geom.Polygon([coordinates]);
+ geometry.transform('EPSG:4326', 'EPSG:3857');
+
+ var feature = new ol.Feature({});
+ feature.setGeometry(geometry);
+
+ // Attributes
+ feature.setId(resultRow.nvrid);
+ feature.set('gid', resultRow.gid);
+ feature.set('namn', resultRow.namn);
+ feature.set('skyddstyp', resultRow.skyddstyp);
+ feature.set('lan', resultRow.lan);
+ feature.set('kommun', resultRow.kommun);
+
+ vectorSource.addFeature(feature);
+ }
+ });
+}
+
function initUI() {
initFilterDiv();
initSpatialSearchDiv();
@@ -196,6 +285,26 @@ window.onresize = function() {
setTimeout( function() { map.updateSize();}, 200);
}
+function formatPolyCoords (wktString) {
+ // Formats WKT coordinates from database to desired format with projection for rendering
+ // console.log(wktString);
+ var coordString = wktString.substring(9, wktString.indexOf(")"));
+ var coordString2 = coordString.replace(/ /g, ',');
+ // console.log(coordString2);
+ var coordinates = coordString2.split(',');
+
+
+ var coords2 = [];
+ // var projectedPair;
+ for (j = 0; j < coordinates.length; j += 2) {
+ coords2.push([Number(coordinates[j]), Number(coordinates[j+1])]);
+ }
+ // console.log(coords2);
+
+ // return coordsProjected;
+ return coords2;
+}
+
// ##############################################################
// ---------------------- Interaction ---------------------------
// ##############################################################
diff --git a/fril/routes/index.js b/fril/routes/index.js
index 61f4674..142871e 100644
--- a/fril/routes/index.js
+++ b/fril/routes/index.js
@@ -45,7 +45,7 @@ router.post('/api/getFeature', function(req, res) {
apiClient.query(queryString)
.then(function(results) {
- //console.log(results.rows);
+ //console.log(results.rows);
if (results.rows.length == 0) res.end("incorrect");
else res.json(results.rows);
@@ -54,6 +54,25 @@ router.post('/api/getFeature', function(req, res) {
.catch(e => console.error(e.stack));
});
+router.post('/api/getPolygons', function(req, res) {
+ var data = {type: req.body.type, lan: req.body.lan};
+ var queryAddition = '';
+ var types = ['Naturreservat', 'Nationalpark'];
+
+ if (data.type == 0) queryAddition = " AND lan = '" + data.lan + "'";
+
+ var queryString = "SELECT gid, nvrid, namn, skyddstyp, lan, kommun, geom_text AS geometry " +
+ "FROM naturskydd_polygon WHERE skyddstyp = '" + types[data.type] + "'" + queryAddition;
+
+ apiClient.query(queryString)
+ .then(function(results) {
+ if (results.rows.length == 0) res.end("incorrect");
+ else res.json(results.rows);
+
+ })
+ .catch(e => console.error(e.stack));
+});
+
router.post('/api/rateFeature', function(req, res) {
var data = {gid: req.body.gid, rating: req.body.rating};
var queryString = "INSERT INTO reviews (gid, user_name, grade) VALUES ("+data.gid+", 'noname', "+data.rating+");";
@@ -83,5 +102,4 @@ router.post('/api/getClosestFeature', function(req, res) {
})
.catch(e => console.error(e.stack));
-});
-
+});
\ No newline at end of file