Skip to content

Instantly share code, notes, and snippets.

@dsklopp
Created August 8, 2016 20:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dsklopp/cfd9d69ecd0c255e736c23151d186de9 to your computer and use it in GitHub Desktop.
Save dsklopp/cfd9d69ecd0c255e736c23151d186de9 to your computer and use it in GitHub Desktop.
New Relic POC Browserify Doesn't Work
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
/**
* Feel free to explore, or check out the full documentation
* https://docs.newrelic.com/docs/synthetics/new-relic-synthetics/scripting-monitors/writing-api-tests
* for details.
*/
var dns = require("native-dns");
var util = require("util");
function resultant(response) {
console.log(response.answer + " : " + response.time);
}
function dns_query(name, server, callback) {
transport = 'udp';
timeout = 1000;
var question = dns.Question({
name: name,
type: 'A'
});
var req = dns.Request({
question: question,
server: { address: server, port: 53, type: transport },
timeout: timeout
});
var start;
req.on('message', function (err, answer) {
answer.answer.forEach(function (a) {
var response = {
time: Date.now() - start,
answer: a.address
};
callback(response);
});
});
start = Date.now();
req.send();
}
dns_query('www.google.com', '8.8.8.8', resultant);
},{"native-dns":16,"util":15}],2:[function(require,module,exports){
},{}],3:[function(require,module,exports){
// http://wiki.commonjs.org/wiki/Unit_Testing/1.0
//
// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8!
//
// Originally from narwhal.js (http://narwhaljs.org)
// Copyright (c) 2009 Thomas Robinson <280north.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 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.
// when used in node, this will actually load the util module we depend on
// versus loading the builtin util module as happens otherwise
// this is a bug in node module loading as far as I am concerned
var util = require('util/');
var pSlice = Array.prototype.slice;
var hasOwn = Object.prototype.hasOwnProperty;
// 1. The assert module provides functions that throw
// AssertionError's when particular conditions are not met. The
// assert module must conform to the following interface.
var assert = module.exports = ok;
// 2. The AssertionError is defined in assert.
// new assert.AssertionError({ message: message,
// actual: actual,
// expected: expected })
assert.AssertionError = function AssertionError(options) {
this.name = 'AssertionError';
this.actual = options.actual;
this.expected = options.expected;
this.operator = options.operator;
if (options.message) {
this.message = options.message;
this.generatedMessage = false;
} else {
this.message = getMessage(this);
this.generatedMessage = true;
}
var stackStartFunction = options.stackStartFunction || fail;
if (Error.captureStackTrace) {
Error.captureStackTrace(this, stackStartFunction);
}
else {
// non v8 browsers so we can have a stacktrace
var err = new Error();
if (err.stack) {
var out = err.stack;
// try to strip useless frames
var fn_name = stackStartFunction.name;
var idx = out.indexOf('\n' + fn_name);
if (idx >= 0) {
// once we have located the function frame
// we need to strip out everything before it (and its line)
var next_line = out.indexOf('\n', idx + 1);
out = out.substring(next_line + 1);
}
this.stack = out;
}
}
};
// assert.AssertionError instanceof Error
util.inherits(assert.AssertionError, Error);
function replacer(key, value) {
if (util.isUndefined(value)) {
return '' + value;
}
if (util.isNumber(value) && !isFinite(value)) {
return value.toString();
}
if (util.isFunction(value) || util.isRegExp(value)) {
return value.toString();
}
return value;
}
function truncate(s, n) {
if (util.isString(s)) {
return s.length < n ? s : s.slice(0, n);
} else {
return s;
}
}
function getMessage(self) {
return truncate(JSON.stringify(self.actual, replacer), 128) + ' ' +
self.operator + ' ' +
truncate(JSON.stringify(self.expected, replacer), 128);
}
// At present only the three keys mentioned above are used and
// understood by the spec. Implementations or sub modules can pass
// other keys to the AssertionError's constructor - they will be
// ignored.
// 3. All of the following functions must throw an AssertionError
// when a corresponding condition is not met, with a message that
// may be undefined if not provided. All assertion methods provide
// both the actual and expected values to the assertion error for
// display purposes.
function fail(actual, expected, message, operator, stackStartFunction) {
throw new assert.AssertionError({
message: message,
actual: actual,
expected: expected,
operator: operator,
stackStartFunction: stackStartFunction
});
}
// EXTENSION! allows for well behaved errors defined elsewhere.
assert.fail = fail;
// 4. Pure assertion tests whether a value is truthy, as determined
// by !!guard.
// assert.ok(guard, message_opt);
// This statement is equivalent to assert.equal(true, !!guard,
// message_opt);. To test strictly for the value true, use
// assert.strictEqual(true, guard, message_opt);.
function ok(value, message) {
if (!value) fail(value, true, message, '==', assert.ok);
}
assert.ok = ok;
// 5. The equality assertion tests shallow, coercive equality with
// ==.
// assert.equal(actual, expected, message_opt);
assert.equal = function equal(actual, expected, message) {
if (actual != expected) fail(actual, expected, message, '==', assert.equal);
};
// 6. The non-equality assertion tests for whether two objects are not equal
// with != assert.notEqual(actual, expected, message_opt);
assert.notEqual = function notEqual(actual, expected, message) {
if (actual == expected) {
fail(actual, expected, message, '!=', assert.notEqual);
}
};
// 7. The equivalence assertion tests a deep equality relation.
// assert.deepEqual(actual, expected, message_opt);
assert.deepEqual = function deepEqual(actual, expected, message) {
if (!_deepEqual(actual, expected)) {
fail(actual, expected, message, 'deepEqual', assert.deepEqual);
}
};
function _deepEqual(actual, expected) {
// 7.1. All identical values are equivalent, as determined by ===.
if (actual === expected) {
return true;
} else if (util.isBuffer(actual) && util.isBuffer(expected)) {
if (actual.length != expected.length) return false;
for (var i = 0; i < actual.length; i++) {
if (actual[i] !== expected[i]) return false;
}
return true;
// 7.2. If the expected value is a Date object, the actual value is
// equivalent if it is also a Date object that refers to the same time.
} else if (util.isDate(actual) && util.isDate(expected)) {
return actual.getTime() === expected.getTime();
// 7.3 If the expected value is a RegExp object, the actual value is
// equivalent if it is also a RegExp object with the same source and
// properties (`global`, `multiline`, `lastIndex`, `ignoreCase`).
} else if (util.isRegExp(actual) && util.isRegExp(expected)) {
return actual.source === expected.source &&
actual.global === expected.global &&
actual.multiline === expected.multiline &&
actual.lastIndex === expected.lastIndex &&
actual.ignoreCase === expected.ignoreCase;
// 7.4. Other pairs that do not both pass typeof value == 'object',
// equivalence is determined by ==.
} else if (!util.isObject(actual) && !util.isObject(expected)) {
return actual == expected;
// 7.5 For all other Object pairs, including Array objects, equivalence is
// determined by having the same number of owned properties (as verified
// with Object.prototype.hasOwnProperty.call), the same set of keys
// (although not necessarily the same order), equivalent values for every
// corresponding key, and an identical 'prototype' property. Note: this
// accounts for both named and indexed properties on Arrays.
} else {
return objEquiv(actual, expected);
}
}
function isArguments(object) {
return Object.prototype.toString.call(object) == '[object Arguments]';
}
function objEquiv(a, b) {
if (util.isNullOrUndefined(a) || util.isNullOrUndefined(b))
return false;
// an identical 'prototype' property.
if (a.prototype !== b.prototype) return false;
// if one is a primitive, the other must be same
if (util.isPrimitive(a) || util.isPrimitive(b)) {
return a === b;
}
var aIsArgs = isArguments(a),
bIsArgs = isArguments(b);
if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs))
return false;
if (aIsArgs) {
a = pSlice.call(a);
b = pSlice.call(b);
return _deepEqual(a, b);
}
var ka = objectKeys(a),
kb = objectKeys(b),
key, i;
// having the same number of owned properties (keys incorporates
// hasOwnProperty)
if (ka.length != kb.length)
return false;
//the same set of keys (although not necessarily the same order),
ka.sort();
kb.sort();
//~~~cheap key test
for (i = ka.length - 1; i >= 0; i--) {
if (ka[i] != kb[i])
return false;
}
//equivalent values for every corresponding key, and
//~~~possibly expensive deep test
for (i = ka.length - 1; i >= 0; i--) {
key = ka[i];
if (!_deepEqual(a[key], b[key])) return false;
}
return true;
}
// 8. The non-equivalence assertion tests for any deep inequality.
// assert.notDeepEqual(actual, expected, message_opt);
assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
if (_deepEqual(actual, expected)) {
fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual);
}
};
// 9. The strict equality assertion tests strict equality, as determined by ===.
// assert.strictEqual(actual, expected, message_opt);
assert.strictEqual = function strictEqual(actual, expected, message) {
if (actual !== expected) {
fail(actual, expected, message, '===', assert.strictEqual);
}
};
// 10. The strict non-equality assertion tests for strict inequality, as
// determined by !==. assert.notStrictEqual(actual, expected, message_opt);
assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
if (actual === expected) {
fail(actual, expected, message, '!==', assert.notStrictEqual);
}
};
function expectedException(actual, expected) {
if (!actual || !expected) {
return false;
}
if (Object.prototype.toString.call(expected) == '[object RegExp]') {
return expected.test(actual);
} else if (actual instanceof expected) {
return true;
} else if (expected.call({}, actual) === true) {
return true;
}
return false;
}
function _throws(shouldThrow, block, expected, message) {
var actual;
if (util.isString(expected)) {
message = expected;
expected = null;
}
try {
block();
} catch (e) {
actual = e;
}
message = (expected && expected.name ? ' (' + expected.name + ').' : '.') +
(message ? ' ' + message : '.');
if (shouldThrow && !actual) {
fail(actual, expected, 'Missing expected exception' + message);
}
if (!shouldThrow && expectedException(actual, expected)) {
fail(actual, expected, 'Got unwanted exception' + message);
}
if ((shouldThrow && actual && expected &&
!expectedException(actual, expected)) || (!shouldThrow && actual)) {
throw actual;
}
}
// 11. Expected to throw an error:
// assert.throws(block, Error_opt, message_opt);
assert.throws = function(block, /*optional*/error, /*optional*/message) {
_throws.apply(this, [true].concat(pSlice.call(arguments)));
};
// EXTENSION! This is annoying to write outside this module.
assert.doesNotThrow = function(block, /*optional*/message) {
_throws.apply(this, [false].concat(pSlice.call(arguments)));
};
assert.ifError = function(err) { if (err) {throw err;}};
var objectKeys = Object.keys || function (obj) {
var keys = [];
for (var key in obj) {
if (hasOwn.call(obj, key)) keys.push(key);
}
return keys;
};
},{"util/":15}],4:[function(require,module,exports){
(function (global){
/*!
* The buffer module from node.js, for the browser.
*
* @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
* @license MIT
*/
/* eslint-disable no-proto */
'use strict'
var base64 = require('base64-js')
var ieee754 = require('ieee754')
var isArray = require('isarray')
exports.Buffer = Buffer
exports.SlowBuffer = SlowBuffer
exports.INSPECT_MAX_BYTES = 50
/**
* If `Buffer.TYPED_ARRAY_SUPPORT`:
* === true Use Uint8Array implementation (fastest)
* === false Use Object implementation (most compatible, even IE6)
*
* Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
* Opera 11.6+, iOS 4.2+.
*
* Due to various browser bugs, sometimes the Object implementation will be used even
* when the browser supports typed arrays.
*
* Note:
*
* - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,
* See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.
*
* - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.
*
* - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of
* incorrect length in some situations.
* We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they
* get the Object implementation, which is slower but behaves correctly.
*/
Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined
? global.TYPED_ARRAY_SUPPORT
: typedArraySupport()
/*
* Export kMaxLength after typed array support is determined.
*/
exports.kMaxLength = kMaxLength()
function typedArraySupport () {
try {
var arr = new Uint8Array(1)
arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}
return arr.foo() === 42 && // typed array instances can be augmented
typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`
arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`
} catch (e) {
return false
}
}
function kMaxLength () {
return Buffer.TYPED_ARRAY_SUPPORT
? 0x7fffffff
: 0x3fffffff
}
function createBuffer (that, length) {
if (kMaxLength() < length) {
throw new RangeError('Invalid typed array length')
}
if (Buffer.TYPED_ARRAY_SUPPORT) {
// Return an augmented `Uint8Array` instance, for best performance
that = new Uint8Array(length)
that.__proto__ = Buffer.prototype
} else {
// Fallback: Return an object instance of the Buffer class
if (that === null) {
that = new Buffer(length)
}
that.length = length
}
return that
}
/**
* The Buffer constructor returns instances of `Uint8Array` that have their
* prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of
* `Uint8Array`, so the returned instances will have all the node `Buffer` methods
* and the `Uint8Array` methods. Square bracket notation works as expected -- it
* returns a single octet.
*
* The `Uint8Array` prototype remains unmodified.
*/
function Buffer (arg, encodingOrOffset, length) {
if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {
return new Buffer(arg, encodingOrOffset, length)
}
// Common case.
if (typeof arg === 'number') {
if (typeof encodingOrOffset === 'string') {
throw new Error(
'If encoding is specified then the first argument must be a string'
)
}
return allocUnsafe(this, arg)
}
return from(this, arg, encodingOrOffset, length)
}
Buffer.poolSize = 8192 // not used by this implementation
// TODO: Legacy, not needed anymore. Remove in next major version.
Buffer._augment = function (arr) {
arr.__proto__ = Buffer.prototype
return arr
}
function from (that, value, encodingOrOffset, length) {
if (typeof value === 'number') {
throw new TypeError('"value" argument must not be a number')
}
if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {
return fromArrayBuffer(that, value, encodingOrOffset, length)
}
if (typeof value === 'string') {
return fromString(that, value, encodingOrOffset)
}
return fromObject(that, value)
}
/**
* Functionally equivalent to Buffer(arg, encoding) but throws a TypeError
* if value is a number.
* Buffer.from(str[, encoding])
* Buffer.from(array)
* Buffer.from(buffer)
* Buffer.from(arrayBuffer[, byteOffset[, length]])
**/
Buffer.from = function (value, encodingOrOffset, length) {
return from(null, value, encodingOrOffset, length)
}
if (Buffer.TYPED_ARRAY_SUPPORT) {
Buffer.prototype.__proto__ = Uint8Array.prototype
Buffer.__proto__ = Uint8Array
if (typeof Symbol !== 'undefined' && Symbol.species &&
Buffer[Symbol.species] === Buffer) {
// Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97
Object.defineProperty(Buffer, Symbol.species, {
value: null,
configurable: true
})
}
}
function assertSize (size) {
if (typeof size !== 'number') {
throw new TypeError('"size" argument must be a number')
}
}
function alloc (that, size, fill, encoding) {
assertSize(size)
if (size <= 0) {
return createBuffer(that, size)
}
if (fill !== undefined) {
// Only pay attention to encoding if it's a string. This
// prevents accidentally sending in a number that would
// be interpretted as a start offset.
return typeof encoding === 'string'
? createBuffer(that, size).fill(fill, encoding)
: createBuffer(that, size).fill(fill)
}
return createBuffer(that, size)
}
/**
* Creates a new filled Buffer instance.
* alloc(size[, fill[, encoding]])
**/
Buffer.alloc = function (size, fill, encoding) {
return alloc(null, size, fill, encoding)
}
function allocUnsafe (that, size) {
assertSize(size)
that = createBuffer(that, size < 0 ? 0 : checked(size) | 0)
if (!Buffer.TYPED_ARRAY_SUPPORT) {
for (var i = 0; i < size; ++i) {
that[i] = 0
}
}
return that
}
/**
* Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.
* */
Buffer.allocUnsafe = function (size) {
return allocUnsafe(null, size)
}
/**
* Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.
*/
Buffer.allocUnsafeSlow = function (size) {
return allocUnsafe(null, size)
}
function fromString (that, string, encoding) {
if (typeof encoding !== 'string' || encoding === '') {
encoding = 'utf8'
}
if (!Buffer.isEncoding(encoding)) {
throw new TypeError('"encoding" must be a valid string encoding')
}
var length = byteLength(string, encoding) | 0
that = createBuffer(that, length)
that.write(string, encoding)
return that
}
function fromArrayLike (that, array) {
var length = checked(array.length) | 0
that = createBuffer(that, length)
for (var i = 0; i < length; i += 1) {
that[i] = array[i] & 255
}
return that
}
function fromArrayBuffer (that, array, byteOffset, length) {
array.byteLength // this throws if `array` is not a valid ArrayBuffer
if (byteOffset < 0 || array.byteLength < byteOffset) {
throw new RangeError('\'offset\' is out of bounds')
}
if (array.byteLength < byteOffset + (length || 0)) {
throw new RangeError('\'length\' is out of bounds')
}
if (byteOffset === undefined && length === undefined) {
array = new Uint8Array(array)
} else if (length === undefined) {
array = new Uint8Array(array, byteOffset)
} else {
array = new Uint8Array(array, byteOffset, length)
}
if (Buffer.TYPED_ARRAY_SUPPORT) {
// Return an augmented `Uint8Array` instance, for best performance
that = array
that.__proto__ = Buffer.prototype
} else {
// Fallback: Return an object instance of the Buffer class
that = fromArrayLike(that, array)
}
return that
}
function fromObject (that, obj) {
if (Buffer.isBuffer(obj)) {
var len = checked(obj.length) | 0
that = createBuffer(that, len)
if (that.length === 0) {
return that
}
obj.copy(that, 0, 0, len)
return that
}
if (obj) {
if ((typeof ArrayBuffer !== 'undefined' &&
obj.buffer instanceof ArrayBuffer) || 'length' in obj) {
if (typeof obj.length !== 'number' || isnan(obj.length)) {
return createBuffer(that, 0)
}
return fromArrayLike(that, obj)
}
if (obj.type === 'Buffer' && isArray(obj.data)) {
return fromArrayLike(that, obj.data)
}
}
throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')
}
function checked (length) {
// Note: cannot use `length < kMaxLength` here because that fails when
// length is NaN (which is otherwise coerced to zero.)
if (length >= kMaxLength()) {
throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
'size: 0x' + kMaxLength().toString(16) + ' bytes')
}
return length | 0
}
function SlowBuffer (length) {
if (+length != length) { // eslint-disable-line eqeqeq
length = 0
}
return Buffer.alloc(+length)
}
Buffer.isBuffer = function isBuffer (b) {
return !!(b != null && b._isBuffer)
}
Buffer.compare = function compare (a, b) {
if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
throw new TypeError('Arguments must be Buffers')
}
if (a === b) return 0
var x = a.length
var y = b.length
for (var i = 0, len = Math.min(x, y); i < len; ++i) {
if (a[i] !== b[i]) {
x = a[i]
y = b[i]
break
}
}
if (x < y) return -1
if (y < x) return 1
return 0
}
Buffer.isEncoding = function isEncoding (encoding) {
switch (String(encoding).toLowerCase()) {
case 'hex':
case 'utf8':
case 'utf-8':
case 'ascii':
case 'binary':
case 'base64':
case 'raw':
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return true
default:
return false
}
}
Buffer.concat = function concat (list, length) {
if (!isArray(list)) {
throw new TypeError('"list" argument must be an Array of Buffers')
}
if (list.length === 0) {
return Buffer.alloc(0)
}
var i
if (length === undefined) {
length = 0
for (i = 0; i < list.length; ++i) {
length += list[i].length
}
}
var buffer = Buffer.allocUnsafe(length)
var pos = 0
for (i = 0; i < list.length; ++i) {
var buf = list[i]
if (!Buffer.isBuffer(buf)) {
throw new TypeError('"list" argument must be an Array of Buffers')
}
buf.copy(buffer, pos)
pos += buf.length
}
return buffer
}
function byteLength (string, encoding) {
if (Buffer.isBuffer(string)) {
return string.length
}
if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&
(ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {
return string.byteLength
}
if (typeof string !== 'string') {
string = '' + string
}
var len = string.length
if (len === 0) return 0
// Use a for loop to avoid recursion
var loweredCase = false
for (;;) {
switch (encoding) {
case 'ascii':
case 'binary':
case 'raw':
case 'raws':
return len
case 'utf8':
case 'utf-8':
case undefined:
return utf8ToBytes(string).length
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return len * 2
case 'hex':
return len >>> 1
case 'base64':
return base64ToBytes(string).length
default:
if (loweredCase) return utf8ToBytes(string).length // assume utf8
encoding = ('' + encoding).toLowerCase()
loweredCase = true
}
}
}
Buffer.byteLength = byteLength
function slowToString (encoding, start, end) {
var loweredCase = false
// No need to verify that "this.length <= MAX_UINT32" since it's a read-only
// property of a typed array.
// This behaves neither like String nor Uint8Array in that we set start/end
// to their upper/lower bounds if the value passed is out of range.
// undefined is handled specially as per ECMA-262 6th Edition,
// Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.
if (start === undefined || start < 0) {
start = 0
}
// Return early if start > this.length. Done here to prevent potential uint32
// coercion fail below.
if (start > this.length) {
return ''
}
if (end === undefined || end > this.length) {
end = this.length
}
if (end <= 0) {
return ''
}
// Force coersion to uint32. This will also coerce falsey/NaN values to 0.
end >>>= 0
start >>>= 0
if (end <= start) {
return ''
}
if (!encoding) encoding = 'utf8'
while (true) {
switch (encoding) {
case 'hex':
return hexSlice(this, start, end)
case 'utf8':
case 'utf-8':
return utf8Slice(this, start, end)
case 'ascii':
return asciiSlice(this, start, end)
case 'binary':
return binarySlice(this, start, end)
case 'base64':
return base64Slice(this, start, end)
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return utf16leSlice(this, start, end)
default:
if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
encoding = (encoding + '').toLowerCase()
loweredCase = true
}
}
}
// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect
// Buffer instances.
Buffer.prototype._isBuffer = true
function swap (b, n, m) {
var i = b[n]
b[n] = b[m]
b[m] = i
}
Buffer.prototype.swap16 = function swap16 () {
var len = this.length
if (len % 2 !== 0) {
throw new RangeError('Buffer size must be a multiple of 16-bits')
}
for (var i = 0; i < len; i += 2) {
swap(this, i, i + 1)
}
return this
}
Buffer.prototype.swap32 = function swap32 () {
var len = this.length
if (len % 4 !== 0) {
throw new RangeError('Buffer size must be a multiple of 32-bits')
}
for (var i = 0; i < len; i += 4) {
swap(this, i, i + 3)
swap(this, i + 1, i + 2)
}
return this
}
Buffer.prototype.toString = function toString () {
var length = this.length | 0
if (length === 0) return ''
if (arguments.length === 0) return utf8Slice(this, 0, length)
return slowToString.apply(this, arguments)
}
Buffer.prototype.equals = function equals (b) {
if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
if (this === b) return true
return Buffer.compare(this, b) === 0
}
Buffer.prototype.inspect = function inspect () {
var str = ''
var max = exports.INSPECT_MAX_BYTES
if (this.length > 0) {
str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')
if (this.length > max) str += ' ... '
}
return '<Buffer ' + str + '>'
}
Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {
if (!Buffer.isBuffer(target)) {
throw new TypeError('Argument must be a Buffer')
}
if (start === undefined) {
start = 0
}
if (end === undefined) {
end = target ? target.length : 0
}
if (thisStart === undefined) {
thisStart = 0
}
if (thisEnd === undefined) {
thisEnd = this.length
}
if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {
throw new RangeError('out of range index')
}
if (thisStart >= thisEnd && start >= end) {
return 0
}
if (thisStart >= thisEnd) {
return -1
}
if (start >= end) {
return 1
}
start >>>= 0
end >>>= 0
thisStart >>>= 0
thisEnd >>>= 0
if (this === target) return 0
var x = thisEnd - thisStart
var y = end - start
var len = Math.min(x, y)
var thisCopy = this.slice(thisStart, thisEnd)
var targetCopy = target.slice(start, end)
for (var i = 0; i < len; ++i) {
if (thisCopy[i] !== targetCopy[i]) {
x = thisCopy[i]
y = targetCopy[i]
break
}
}
if (x < y) return -1
if (y < x) return 1
return 0
}
function arrayIndexOf (arr, val, byteOffset, encoding) {
var indexSize = 1
var arrLength = arr.length
var valLength = val.length
if (encoding !== undefined) {
encoding = String(encoding).toLowerCase()
if (encoding === 'ucs2' || encoding === 'ucs-2' ||
encoding === 'utf16le' || encoding === 'utf-16le') {
if (arr.length < 2 || val.length < 2) {
return -1
}
indexSize = 2
arrLength /= 2
valLength /= 2
byteOffset /= 2
}
}
function read (buf, i) {
if (indexSize === 1) {
return buf[i]
} else {
return buf.readUInt16BE(i * indexSize)
}
}
var foundIndex = -1
for (var i = byteOffset; i < arrLength; ++i) {
if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {
if (foundIndex === -1) foundIndex = i
if (i - foundIndex + 1 === valLength) return foundIndex * indexSize
} else {
if (foundIndex !== -1) i -= i - foundIndex
foundIndex = -1
}
}
return -1
}
Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {
if (typeof byteOffset === 'string') {
encoding = byteOffset
byteOffset = 0
} else if (byteOffset > 0x7fffffff) {
byteOffset = 0x7fffffff
} else if (byteOffset < -0x80000000) {
byteOffset = -0x80000000
}
byteOffset >>= 0
if (this.length === 0) return -1
if (byteOffset >= this.length) return -1
// Negative offsets start from the end of the buffer
if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0)
if (typeof val === 'string') {
val = Buffer.from(val, encoding)
}
if (Buffer.isBuffer(val)) {
// special case: looking for empty string/buffer always fails
if (val.length === 0) {
return -1
}
return arrayIndexOf(this, val, byteOffset, encoding)
}
if (typeof val === 'number') {
if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') {
return Uint8Array.prototype.indexOf.call(this, val, byteOffset)
}
return arrayIndexOf(this, [ val ], byteOffset, encoding)
}
throw new TypeError('val must be string, number or Buffer')
}
Buffer.prototype.includes = function includes (val, byteOffset, encoding) {
return this.indexOf(val, byteOffset, encoding) !== -1
}
function hexWrite (buf, string, offset, length) {
offset = Number(offset) || 0
var remaining = buf.length - offset
if (!length) {
length = remaining
} else {
length = Number(length)
if (length > remaining) {
length = remaining
}
}
// must be an even number of digits
var strLen = string.length
if (strLen % 2 !== 0) throw new Error('Invalid hex string')
if (length > strLen / 2) {
length = strLen / 2
}
for (var i = 0; i < length; ++i) {
var parsed = parseInt(string.substr(i * 2, 2), 16)
if (isNaN(parsed)) return i
buf[offset + i] = parsed
}
return i
}
function utf8Write (buf, string, offset, length) {
return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
}
function asciiWrite (buf, string, offset, length) {
return blitBuffer(asciiToBytes(string), buf, offset, length)
}
function binaryWrite (buf, string, offset, length) {
return asciiWrite(buf, string, offset, length)
}
function base64Write (buf, string, offset, length) {
return blitBuffer(base64ToBytes(string), buf, offset, length)
}
function ucs2Write (buf, string, offset, length) {
return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
}
Buffer.prototype.write = function write (string, offset, length, encoding) {
// Buffer#write(string)
if (offset === undefined) {
encoding = 'utf8'
length = this.length
offset = 0
// Buffer#write(string, encoding)
} else if (length === undefined && typeof offset === 'string') {
encoding = offset
length = this.length
offset = 0
// Buffer#write(string, offset[, length][, encoding])
} else if (isFinite(offset)) {
offset = offset | 0
if (isFinite(length)) {
length = length | 0
if (encoding === undefined) encoding = 'utf8'
} else {
encoding = length
length = undefined
}
// legacy write(string, encoding, offset, length) - remove in v0.13
} else {
throw new Error(
'Buffer.write(string, encoding, offset[, length]) is no longer supported'
)
}
var remaining = this.length - offset
if (length === undefined || length > remaining) length = remaining
if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
throw new RangeError('Attempt to write outside buffer bounds')
}
if (!encoding) encoding = 'utf8'
var loweredCase = false
for (;;) {
switch (encoding) {
case 'hex':
return hexWrite(this, string, offset, length)
case 'utf8':
case 'utf-8':
return utf8Write(this, string, offset, length)
case 'ascii':
return asciiWrite(this, string, offset, length)
case 'binary':
return binaryWrite(this, string, offset, length)
case 'base64':
// Warning: maxLength not taken into account in base64Write
return base64Write(this, string, offset, length)
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return ucs2Write(this, string, offset, length)
default:
if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
encoding = ('' + encoding).toLowerCase()
loweredCase = true
}
}
}
Buffer.prototype.toJSON = function toJSON () {
return {
type: 'Buffer',
data: Array.prototype.slice.call(this._arr || this, 0)
}
}
function base64Slice (buf, start, end) {
if (start === 0 && end === buf.length) {
return base64.fromByteArray(buf)
} else {
return base64.fromByteArray(buf.slice(start, end))
}
}
function utf8Slice (buf, start, end) {
end = Math.min(buf.length, end)
var res = []
var i = start
while (i < end) {
var firstByte = buf[i]
var codePoint = null
var bytesPerSequence = (firstByte > 0xEF) ? 4
: (firstByte > 0xDF) ? 3
: (firstByte > 0xBF) ? 2
: 1
if (i + bytesPerSequence <= end) {
var secondByte, thirdByte, fourthByte, tempCodePoint
switch (bytesPerSequence) {
case 1:
if (firstByte < 0x80) {
codePoint = firstByte
}
break
case 2:
secondByte = buf[i + 1]
if ((secondByte & 0xC0) === 0x80) {
tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
if (tempCodePoint > 0x7F) {
codePoint = tempCodePoint
}
}
break
case 3:
secondByte = buf[i + 1]
thirdByte = buf[i + 2]
if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
codePoint = tempCodePoint
}
}
break
case 4:
secondByte = buf[i + 1]
thirdByte = buf[i + 2]
fourthByte = buf[i + 3]
if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
codePoint = tempCodePoint
}
}
}
}
if (codePoint === null) {
// we did not generate a valid codePoint so insert a
// replacement char (U+FFFD) and advance only 1 byte
codePoint = 0xFFFD
bytesPerSequence = 1
} else if (codePoint > 0xFFFF) {
// encode to utf16 (surrogate pair dance)
codePoint -= 0x10000
res.push(codePoint >>> 10 & 0x3FF | 0xD800)
codePoint = 0xDC00 | codePoint & 0x3FF
}
res.push(codePoint)
i += bytesPerSequence
}
return decodeCodePointsArray(res)
}
// Based on http://stackoverflow.com/a/22747272/680742, the browser with
// the lowest limit is Chrome, with 0x10000 args.
// We go 1 magnitude less, for safety
var MAX_ARGUMENTS_LENGTH = 0x1000
function decodeCodePointsArray (codePoints) {
var len = codePoints.length
if (len <= MAX_ARGUMENTS_LENGTH) {
return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
}
// Decode in chunks to avoid "call stack size exceeded".
var res = ''
var i = 0
while (i < len) {
res += String.fromCharCode.apply(
String,
codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
)
}
return res
}
function asciiSlice (buf, start, end) {
var ret = ''
end = Math.min(buf.length, end)
for (var i = start; i < end; ++i) {
ret += String.fromCharCode(buf[i] & 0x7F)
}
return ret
}
function binarySlice (buf, start, end) {
var ret = ''
end = Math.min(buf.length, end)
for (var i = start; i < end; ++i) {
ret += String.fromCharCode(buf[i])
}
return ret
}
function hexSlice (buf, start, end) {
var len = buf.length
if (!start || start < 0) start = 0
if (!end || end < 0 || end > len) end = len
var out = ''
for (var i = start; i < end; ++i) {
out += toHex(buf[i])
}
return out
}
function utf16leSlice (buf, start, end) {
var bytes = buf.slice(start, end)
var res = ''
for (var i = 0; i < bytes.length; i += 2) {
res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)
}
return res
}
Buffer.prototype.slice = function slice (start, end) {
var len = this.length
start = ~~start
end = end === undefined ? len : ~~end
if (start < 0) {
start += len
if (start < 0) start = 0
} else if (start > len) {
start = len
}
if (end < 0) {
end += len
if (end < 0) end = 0
} else if (end > len) {
end = len
}
if (end < start) end = start
var newBuf
if (Buffer.TYPED_ARRAY_SUPPORT) {
newBuf = this.subarray(start, end)
newBuf.__proto__ = Buffer.prototype
} else {
var sliceLen = end - start
newBuf = new Buffer(sliceLen, undefined)
for (var i = 0; i < sliceLen; ++i) {
newBuf[i] = this[i + start]
}
}
return newBuf
}
/*
* Need to make sure that buffer isn't trying to write out of bounds.
*/
function checkOffset (offset, ext, length) {
if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
}
Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) checkOffset(offset, byteLength, this.length)
var val = this[offset]
var mul = 1
var i = 0
while (++i < byteLength && (mul *= 0x100)) {
val += this[offset + i] * mul
}
return val
}
Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) {
checkOffset(offset, byteLength, this.length)
}
var val = this[offset + --byteLength]
var mul = 1
while (byteLength > 0 && (mul *= 0x100)) {
val += this[offset + --byteLength] * mul
}
return val
}
Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
if (!noAssert) checkOffset(offset, 1, this.length)
return this[offset]
}
Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 2, this.length)
return this[offset] | (this[offset + 1] << 8)
}
Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 2, this.length)
return (this[offset] << 8) | this[offset + 1]
}
Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return ((this[offset]) |
(this[offset + 1] << 8) |
(this[offset + 2] << 16)) +
(this[offset + 3] * 0x1000000)
}
Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return (this[offset] * 0x1000000) +
((this[offset + 1] << 16) |
(this[offset + 2] << 8) |
this[offset + 3])
}
Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) checkOffset(offset, byteLength, this.length)
var val = this[offset]
var mul = 1
var i = 0
while (++i < byteLength && (mul *= 0x100)) {
val += this[offset + i] * mul
}
mul *= 0x80
if (val >= mul) val -= Math.pow(2, 8 * byteLength)
return val
}
Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) checkOffset(offset, byteLength, this.length)
var i = byteLength
var mul = 1
var val = this[offset + --i]
while (i > 0 && (mul *= 0x100)) {
val += this[offset + --i] * mul
}
mul *= 0x80
if (val >= mul) val -= Math.pow(2, 8 * byteLength)
return val
}
Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
if (!noAssert) checkOffset(offset, 1, this.length)
if (!(this[offset] & 0x80)) return (this[offset])
return ((0xff - this[offset] + 1) * -1)
}
Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 2, this.length)
var val = this[offset] | (this[offset + 1] << 8)
return (val & 0x8000) ? val | 0xFFFF0000 : val
}
Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 2, this.length)
var val = this[offset + 1] | (this[offset] << 8)
return (val & 0x8000) ? val | 0xFFFF0000 : val
}
Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return (this[offset]) |
(this[offset + 1] << 8) |
(this[offset + 2] << 16) |
(this[offset + 3] << 24)
}
Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return (this[offset] << 24) |
(this[offset + 1] << 16) |
(this[offset + 2] << 8) |
(this[offset + 3])
}
Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return ieee754.read(this, offset, true, 23, 4)
}
Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return ieee754.read(this, offset, false, 23, 4)
}
Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 8, this.length)
return ieee754.read(this, offset, true, 52, 8)
}
Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 8, this.length)
return ieee754.read(this, offset, false, 52, 8)
}
function checkInt (buf, value, offset, ext, max, min) {
if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance')
if (value > max || value < min) throw new RangeError('"value" argument is out of bounds')
if (offset + ext > buf.length) throw new RangeError('Index out of range')
}
Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
value = +value
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) {
var maxBytes = Math.pow(2, 8 * byteLength) - 1
checkInt(this, value, offset, byteLength, maxBytes, 0)
}
var mul = 1
var i = 0
this[offset] = value & 0xFF
while (++i < byteLength && (mul *= 0x100)) {
this[offset + i] = (value / mul) & 0xFF
}
return offset + byteLength
}
Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
value = +value
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) {
var maxBytes = Math.pow(2, 8 * byteLength) - 1
checkInt(this, value, offset, byteLength, maxBytes, 0)
}
var i = byteLength - 1
var mul = 1
this[offset + i] = value & 0xFF
while (--i >= 0 && (mul *= 0x100)) {
this[offset + i] = (value / mul) & 0xFF
}
return offset + byteLength
}
Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
this[offset] = (value & 0xff)
return offset + 1
}
function objectWriteUInt16 (buf, value, offset, littleEndian) {
if (value < 0) value = 0xffff + value + 1
for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) {
buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>
(littleEndian ? i : 1 - i) * 8
}
}
Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value & 0xff)
this[offset + 1] = (value >>> 8)
} else {
objectWriteUInt16(this, value, offset, true)
}
return offset + 2
}
Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value >>> 8)
this[offset + 1] = (value & 0xff)
} else {
objectWriteUInt16(this, value, offset, false)
}
return offset + 2
}
function objectWriteUInt32 (buf, value, offset, littleEndian) {
if (value < 0) value = 0xffffffff + value + 1
for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) {
buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff
}
}
Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset + 3] = (value >>> 24)
this[offset + 2] = (value >>> 16)
this[offset + 1] = (value >>> 8)
this[offset] = (value & 0xff)
} else {
objectWriteUInt32(this, value, offset, true)
}
return offset + 4
}
Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value >>> 24)
this[offset + 1] = (value >>> 16)
this[offset + 2] = (value >>> 8)
this[offset + 3] = (value & 0xff)
} else {
objectWriteUInt32(this, value, offset, false)
}
return offset + 4
}
Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) {
var limit = Math.pow(2, 8 * byteLength - 1)
checkInt(this, value, offset, byteLength, limit - 1, -limit)
}
var i = 0
var mul = 1
var sub = 0
this[offset] = value & 0xFF
while (++i < byteLength && (mul *= 0x100)) {
if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {
sub = 1
}
this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
}
return offset + byteLength
}
Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) {
var limit = Math.pow(2, 8 * byteLength - 1)
checkInt(this, value, offset, byteLength, limit - 1, -limit)
}
var i = byteLength - 1
var mul = 1
var sub = 0
this[offset + i] = value & 0xFF
while (--i >= 0 && (mul *= 0x100)) {
if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {
sub = 1
}
this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
}
return offset + byteLength
}
Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
if (value < 0) value = 0xff + value + 1
this[offset] = (value & 0xff)
return offset + 1
}
Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value & 0xff)
this[offset + 1] = (value >>> 8)
} else {
objectWriteUInt16(this, value, offset, true)
}
return offset + 2
}
Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value >>> 8)
this[offset + 1] = (value & 0xff)
} else {
objectWriteUInt16(this, value, offset, false)
}
return offset + 2
}
Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value & 0xff)
this[offset + 1] = (value >>> 8)
this[offset + 2] = (value >>> 16)
this[offset + 3] = (value >>> 24)
} else {
objectWriteUInt32(this, value, offset, true)
}
return offset + 4
}
Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
if (value < 0) value = 0xffffffff + value + 1
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value >>> 24)
this[offset + 1] = (value >>> 16)
this[offset + 2] = (value >>> 8)
this[offset + 3] = (value & 0xff)
} else {
objectWriteUInt32(this, value, offset, false)
}
return offset + 4
}
function checkIEEE754 (buf, value, offset, ext, max, min) {
if (offset + ext > buf.length) throw new RangeError('Index out of range')
if (offset < 0) throw new RangeError('Index out of range')
}
function writeFloat (buf, value, offset, littleEndian, noAssert) {
if (!noAssert) {
checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
}
ieee754.write(buf, value, offset, littleEndian, 23, 4)
return offset + 4
}
Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
return writeFloat(this, value, offset, true, noAssert)
}
Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
return writeFloat(this, value, offset, false, noAssert)
}
function writeDouble (buf, value, offset, littleEndian, noAssert) {
if (!noAssert) {
checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
}
ieee754.write(buf, value, offset, littleEndian, 52, 8)
return offset + 8
}
Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
return writeDouble(this, value, offset, true, noAssert)
}
Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
return writeDouble(this, value, offset, false, noAssert)
}
// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
Buffer.prototype.copy = function copy (target, targetStart, start, end) {
if (!start) start = 0
if (!end && end !== 0) end = this.length
if (targetStart >= target.length) targetStart = target.length
if (!targetStart) targetStart = 0
if (end > 0 && end < start) end = start
// Copy 0 bytes; we're done
if (end === start) return 0
if (target.length === 0 || this.length === 0) return 0
// Fatal error conditions
if (targetStart < 0) {
throw new RangeError('targetStart out of bounds')
}
if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')
if (end < 0) throw new RangeError('sourceEnd out of bounds')
// Are we oob?
if (end > this.length) end = this.length
if (target.length - targetStart < end - start) {
end = target.length - targetStart + start
}
var len = end - start
var i
if (this === target && start < targetStart && targetStart < end) {
// descending copy from end
for (i = len - 1; i >= 0; --i) {
target[i + targetStart] = this[i + start]
}
} else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {
// ascending copy from start
for (i = 0; i < len; ++i) {
target[i + targetStart] = this[i + start]
}
} else {
Uint8Array.prototype.set.call(
target,
this.subarray(start, start + len),
targetStart
)
}
return len
}
// Usage:
// buffer.fill(number[, offset[, end]])
// buffer.fill(buffer[, offset[, end]])
// buffer.fill(string[, offset[, end]][, encoding])
Buffer.prototype.fill = function fill (val, start, end, encoding) {
// Handle string cases:
if (typeof val === 'string') {
if (typeof start === 'string') {
encoding = start
start = 0
end = this.length
} else if (typeof end === 'string') {
encoding = end
end = this.length
}
if (val.length === 1) {
var code = val.charCodeAt(0)
if (code < 256) {
val = code
}
}
if (encoding !== undefined && typeof encoding !== 'string') {
throw new TypeError('encoding must be a string')
}
if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {
throw new TypeError('Unknown encoding: ' + encoding)
}
} else if (typeof val === 'number') {
val = val & 255
}
// Invalid ranges are not set to a default, so can range check early.
if (start < 0 || this.length < start || this.length < end) {
throw new RangeError('Out of range index')
}
if (end <= start) {
return this
}
start = start >>> 0
end = end === undefined ? this.length : end >>> 0
if (!val) val = 0
var i
if (typeof val === 'number') {
for (i = start; i < end; ++i) {
this[i] = val
}
} else {
var bytes = Buffer.isBuffer(val)
? val
: utf8ToBytes(new Buffer(val, encoding).toString())
var len = bytes.length
for (i = 0; i < end - start; ++i) {
this[i + start] = bytes[i % len]
}
}
return this
}
// HELPER FUNCTIONS
// ================
var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g
function base64clean (str) {
// Node strips out invalid characters like \n and \t from the string, base64-js does not
str = stringtrim(str).replace(INVALID_BASE64_RE, '')
// Node converts strings with length < 2 to ''
if (str.length < 2) return ''
// Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
while (str.length % 4 !== 0) {
str = str + '='
}
return str
}
function stringtrim (str) {
if (str.trim) return str.trim()
return str.replace(/^\s+|\s+$/g, '')
}
function toHex (n) {
if (n < 16) return '0' + n.toString(16)
return n.toString(16)
}
function utf8ToBytes (string, units) {
units = units || Infinity
var codePoint
var length = string.length
var leadSurrogate = null
var bytes = []
for (var i = 0; i < length; ++i) {
codePoint = string.charCodeAt(i)
// is surrogate component
if (codePoint > 0xD7FF && codePoint < 0xE000) {
// last char was a lead
if (!leadSurrogate) {
// no lead yet
if (codePoint > 0xDBFF) {
// unexpected trail
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
continue
} else if (i + 1 === length) {
// unpaired lead
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
continue
}
// valid lead
leadSurrogate = codePoint
continue
}
// 2 leads in a row
if (codePoint < 0xDC00) {
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
leadSurrogate = codePoint
continue
}
// valid surrogate pair
codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000
} else if (leadSurrogate) {
// valid bmp char, but last char was a lead
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
}
leadSurrogate = null
// encode utf8
if (codePoint < 0x80) {
if ((units -= 1) < 0) break
bytes.push(codePoint)
} else if (codePoint < 0x800) {
if ((units -= 2) < 0) break
bytes.push(
codePoint >> 0x6 | 0xC0,
codePoint & 0x3F | 0x80
)
} else if (codePoint < 0x10000) {
if ((units -= 3) < 0) break
bytes.push(
codePoint >> 0xC | 0xE0,
codePoint >> 0x6 & 0x3F | 0x80,
codePoint & 0x3F | 0x80
)
} else if (codePoint < 0x110000) {
if ((units -= 4) < 0) break
bytes.push(
codePoint >> 0x12 | 0xF0,
codePoint >> 0xC & 0x3F | 0x80,
codePoint >> 0x6 & 0x3F | 0x80,
codePoint & 0x3F | 0x80
)
} else {
throw new Error('Invalid code point')
}
}
return bytes
}
function asciiToBytes (str) {
var byteArray = []
for (var i = 0; i < str.length; ++i) {
// Node's code seems to be doing this and not & 0x7F..
byteArray.push(str.charCodeAt(i) & 0xFF)
}
return byteArray
}
function utf16leToBytes (str, units) {
var c, hi, lo
var byteArray = []
for (var i = 0; i < str.length; ++i) {
if ((units -= 2) < 0) break
c = str.charCodeAt(i)
hi = c >> 8
lo = c % 256
byteArray.push(lo)
byteArray.push(hi)
}
return byteArray
}
function base64ToBytes (str) {
return base64.toByteArray(base64clean(str))
}
function blitBuffer (src, dst, offset, length) {
for (var i = 0; i < length; ++i) {
if ((i + offset >= dst.length) || (i >= src.length)) break
dst[i + offset] = src[i]
}
return i
}
function isnan (val) {
return val !== val // eslint-disable-line no-self-compare
}
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"base64-js":5,"ieee754":6,"isarray":7}],5:[function(require,module,exports){
'use strict'
exports.toByteArray = toByteArray
exports.fromByteArray = fromByteArray
var lookup = []
var revLookup = []
var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array
function init () {
var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
for (var i = 0, len = code.length; i < len; ++i) {
lookup[i] = code[i]
revLookup[code.charCodeAt(i)] = i
}
revLookup['-'.charCodeAt(0)] = 62
revLookup['_'.charCodeAt(0)] = 63
}
init()
function toByteArray (b64) {
var i, j, l, tmp, placeHolders, arr
var len = b64.length
if (len % 4 > 0) {
throw new Error('Invalid string. Length must be a multiple of 4')
}
// the number of equal signs (place holders)
// if there are two placeholders, than the two characters before it
// represent one byte
// if there is only one, then the three characters before it represent 2 bytes
// this is just a cheap hack to not do indexOf twice
placeHolders = b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0
// base64 is 4/3 + up to two characters of the original data
arr = new Arr(len * 3 / 4 - placeHolders)
// if there are placeholders, only get up to the last complete 4 chars
l = placeHolders > 0 ? len - 4 : len
var L = 0
for (i = 0, j = 0; i < l; i += 4, j += 3) {
tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)]
arr[L++] = (tmp >> 16) & 0xFF
arr[L++] = (tmp >> 8) & 0xFF
arr[L++] = tmp & 0xFF
}
if (placeHolders === 2) {
tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4)
arr[L++] = tmp & 0xFF
} else if (placeHolders === 1) {
tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2)
arr[L++] = (tmp >> 8) & 0xFF
arr[L++] = tmp & 0xFF
}
return arr
}
function tripletToBase64 (num) {
return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F]
}
function encodeChunk (uint8, start, end) {
var tmp
var output = []
for (var i = start; i < end; i += 3) {
tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])
output.push(tripletToBase64(tmp))
}
return output.join('')
}
function fromByteArray (uint8) {
var tmp
var len = uint8.length
var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
var output = ''
var parts = []
var maxChunkLength = 16383 // must be multiple of 3
// go through the array every three bytes, we'll deal with trailing stuff later
for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))
}
// pad the end with zeros, but make sure to not forget the extra bytes
if (extraBytes === 1) {
tmp = uint8[len - 1]
output += lookup[tmp >> 2]
output += lookup[(tmp << 4) & 0x3F]
output += '=='
} else if (extraBytes === 2) {
tmp = (uint8[len - 2] << 8) + (uint8[len - 1])
output += lookup[tmp >> 10]
output += lookup[(tmp >> 4) & 0x3F]
output += lookup[(tmp << 2) & 0x3F]
output += '='
}
parts.push(output)
return parts.join('')
}
},{}],6:[function(require,module,exports){
exports.read = function (buffer, offset, isLE, mLen, nBytes) {
var e, m
var eLen = nBytes * 8 - mLen - 1
var eMax = (1 << eLen) - 1
var eBias = eMax >> 1
var nBits = -7
var i = isLE ? (nBytes - 1) : 0
var d = isLE ? -1 : 1
var s = buffer[offset + i]
i += d
e = s & ((1 << (-nBits)) - 1)
s >>= (-nBits)
nBits += eLen
for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}
m = e & ((1 << (-nBits)) - 1)
e >>= (-nBits)
nBits += mLen
for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}
if (e === 0) {
e = 1 - eBias
} else if (e === eMax) {
return m ? NaN : ((s ? -1 : 1) * Infinity)
} else {
m = m + Math.pow(2, mLen)
e = e - eBias
}
return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
}
exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
var e, m, c
var eLen = nBytes * 8 - mLen - 1
var eMax = (1 << eLen) - 1
var eBias = eMax >> 1
var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
var i = isLE ? 0 : (nBytes - 1)
var d = isLE ? 1 : -1
var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0
value = Math.abs(value)
if (isNaN(value) || value === Infinity) {
m = isNaN(value) ? 1 : 0
e = eMax
} else {
e = Math.floor(Math.log(value) / Math.LN2)
if (value * (c = Math.pow(2, -e)) < 1) {
e--
c *= 2
}
if (e + eBias >= 1) {
value += rt / c
} else {
value += rt * Math.pow(2, 1 - eBias)
}
if (value * c >= 2) {
e++
c /= 2
}
if (e + eBias >= eMax) {
m = 0
e = eMax
} else if (e + eBias >= 1) {
m = (value * c - 1) * Math.pow(2, mLen)
e = e + eBias
} else {
m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
e = 0
}
}
for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
e = (e << mLen) | m
eLen += mLen
for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
buffer[offset + i - d] |= s * 128
}
},{}],7:[function(require,module,exports){
var toString = {}.toString;
module.exports = Array.isArray || function (arr) {
return toString.call(arr) == '[object Array]';
};
},{}],8:[function(require,module,exports){
// 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.
function EventEmitter() {
this._events = this._events || {};
this._maxListeners = this._maxListeners || undefined;
}
module.exports = EventEmitter;
// Backwards-compat with node 0.10.x
EventEmitter.EventEmitter = EventEmitter;
EventEmitter.prototype._events = undefined;
EventEmitter.prototype._maxListeners = undefined;
// By default EventEmitters will print a warning if more than 10 listeners are
// added to it. This is a useful default which helps finding memory leaks.
EventEmitter.defaultMaxListeners = 10;
// Obviously not all Emitters should be limited to 10. This function allows
// that to be increased. Set to zero for unlimited.
EventEmitter.prototype.setMaxListeners = function(n) {
if (!isNumber(n) || n < 0 || isNaN(n))
throw TypeError('n must be a positive number');
this._maxListeners = n;
return this;
};
EventEmitter.prototype.emit = function(type) {
var er, handler, len, args, i, listeners;
if (!this._events)
this._events = {};
// If there is no 'error' event listener then throw.
if (type === 'error') {
if (!this._events.error ||
(isObject(this._events.error) && !this._events.error.length)) {
er = arguments[1];
if (er instanceof Error) {
throw er; // Unhandled 'error' event
} else {
// At least give some kind of context to the user
var err = new Error('Uncaught, unspecified "error" event. (' + er + ')');
err.context = er;
throw err;
}
}
}
handler = this._events[type];
if (isUndefined(handler))
return false;
if (isFunction(handler)) {
switch (arguments.length) {
// fast cases
case 1:
handler.call(this);
break;
case 2:
handler.call(this, arguments[1]);
break;
case 3:
handler.call(this, arguments[1], arguments[2]);
break;
// slower
default:
args = Array.prototype.slice.call(arguments, 1);
handler.apply(this, args);
}
} else if (isObject(handler)) {
args = Array.prototype.slice.call(arguments, 1);
listeners = handler.slice();
len = listeners.length;
for (i = 0; i < len; i++)
listeners[i].apply(this, args);
}
return true;
};
EventEmitter.prototype.addListener = function(type, listener) {
var m;
if (!isFunction(listener))
throw TypeError('listener must be a function');
if (!this._events)
this._events = {};
// To avoid recursion in the case that type === "newListener"! Before
// adding it to the listeners, first emit "newListener".
if (this._events.newListener)
this.emit('newListener', type,
isFunction(listener.listener) ?
listener.listener : listener);
if (!this._events[type])
// Optimize the case of one listener. Don't need the extra array object.
this._events[type] = listener;
else if (isObject(this._events[type]))
// If we've already got an array, just append.
this._events[type].push(listener);
else
// Adding the second element, need to change to array.
this._events[type] = [this._events[type], listener];
// Check for listener leak
if (isObject(this._events[type]) && !this._events[type].warned) {
if (!isUndefined(this._maxListeners)) {
m = this._maxListeners;
} else {
m = EventEmitter.defaultMaxListeners;
}
if (m && m > 0 && this._events[type].length > m) {
this._events[type].warned = true;
console.error('(node) warning: possible EventEmitter memory ' +
'leak detected. %d listeners added. ' +
'Use emitter.setMaxListeners() to increase limit.',
this._events[type].length);
if (typeof console.trace === 'function') {
// not supported in IE 10
console.trace();
}
}
}
return this;
};
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
EventEmitter.prototype.once = function(type, listener) {
if (!isFunction(listener))
throw TypeError('listener must be a function');
var fired = false;
function g() {
this.removeListener(type, g);
if (!fired) {
fired = true;
listener.apply(this, arguments);
}
}
g.listener = listener;
this.on(type, g);
return this;
};
// emits a 'removeListener' event iff the listener was removed
EventEmitter.prototype.removeListener = function(type, listener) {
var list, position, length, i;
if (!isFunction(listener))
throw TypeError('listener must be a function');
if (!this._events || !this._events[type])
return this;
list = this._events[type];
length = list.length;
position = -1;
if (list === listener ||
(isFunction(list.listener) && list.listener === listener)) {
delete this._events[type];
if (this._events.removeListener)
this.emit('removeListener', type, listener);
} else if (isObject(list)) {
for (i = length; i-- > 0;) {
if (list[i] === listener ||
(list[i].listener && list[i].listener === listener)) {
position = i;
break;
}
}
if (position < 0)
return this;
if (list.length === 1) {
list.length = 0;
delete this._events[type];
} else {
list.splice(position, 1);
}
if (this._events.removeListener)
this.emit('removeListener', type, listener);
}
return this;
};
EventEmitter.prototype.removeAllListeners = function(type) {
var key, listeners;
if (!this._events)
return this;
// not listening for removeListener, no need to emit
if (!this._events.removeListener) {
if (arguments.length === 0)
this._events = {};
else if (this._events[type])
delete this._events[type];
return this;
}
// emit removeListener for all listeners on all events
if (arguments.length === 0) {
for (key in this._events) {
if (key === 'removeListener') continue;
this.removeAllListeners(key);
}
this.removeAllListeners('removeListener');
this._events = {};
return this;
}
listeners = this._events[type];
if (isFunction(listeners)) {
this.removeListener(type, listeners);
} else if (listeners) {
// LIFO order
while (listeners.length)
this.removeListener(type, listeners[listeners.length - 1]);
}
delete this._events[type];
return this;
};
EventEmitter.prototype.listeners = function(type) {
var ret;
if (!this._events || !this._events[type])
ret = [];
else if (isFunction(this._events[type]))
ret = [this._events[type]];
else
ret = this._events[type].slice();
return ret;
};
EventEmitter.prototype.listenerCount = function(type) {
if (this._events) {
var evlistener = this._events[type];
if (isFunction(evlistener))
return 1;
else if (evlistener)
return evlistener.length;
}
return 0;
};
EventEmitter.listenerCount = function(emitter, type) {
return emitter.listenerCount(type);
};
function isFunction(arg) {
return typeof arg === 'function';
}
function isNumber(arg) {
return typeof arg === 'number';
}
function isObject(arg) {
return typeof arg === 'object' && arg !== null;
}
function isUndefined(arg) {
return arg === void 0;
}
},{}],9:[function(require,module,exports){
if (typeof Object.create === 'function') {
// implementation from standard node.js 'util' module
module.exports = function inherits(ctor, superCtor) {
ctor.super_ = superCtor
ctor.prototype = Object.create(superCtor.prototype, {
constructor: {
value: ctor,
enumerable: false,
writable: true,
configurable: true
}
});
};
} else {
// old school shim for old browsers
module.exports = function inherits(ctor, superCtor) {
ctor.super_ = superCtor
var TempCtor = function () {}
TempCtor.prototype = superCtor.prototype
ctor.prototype = new TempCtor()
ctor.prototype.constructor = ctor
}
}
},{}],10:[function(require,module,exports){
/**
* Determine if an object is Buffer
*
* Author: Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
* License: MIT
*
* `npm install is-buffer`
*/
module.exports = function (obj) {
return !!(obj != null &&
(obj._isBuffer || // For Safari 5-7 (missing Object.prototype.constructor)
(obj.constructor &&
typeof obj.constructor.isBuffer === 'function' &&
obj.constructor.isBuffer(obj))
))
}
},{}],11:[function(require,module,exports){
exports.endianness = function () { return 'LE' };
exports.hostname = function () {
if (typeof location !== 'undefined') {
return location.hostname
}
else return '';
};
exports.loadavg = function () { return [] };
exports.uptime = function () { return 0 };
exports.freemem = function () {
return Number.MAX_VALUE;
};
exports.totalmem = function () {
return Number.MAX_VALUE;
};
exports.cpus = function () { return [] };
exports.type = function () { return 'Browser' };
exports.release = function () {
if (typeof navigator !== 'undefined') {
return navigator.appVersion;
}
return '';
};
exports.networkInterfaces
= exports.getNetworkInterfaces
= function () { return {} };
exports.arch = function () { return 'javascript' };
exports.platform = function () { return 'browser' };
exports.tmpdir = exports.tmpDir = function () {
return '/tmp';
};
exports.EOL = '\n';
},{}],12:[function(require,module,exports){
(function (process){
// 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.
// resolves . and .. elements in a path array with directory names there
// must be no slashes, empty elements, or device names (c:\) in the array
// (so also no leading and trailing slashes - it does not distinguish
// relative and absolute paths)
function normalizeArray(parts, allowAboveRoot) {
// if the path tries to go above the root, `up` ends up > 0
var up = 0;
for (var i = parts.length - 1; i >= 0; i--) {
var last = parts[i];
if (last === '.') {
parts.splice(i, 1);
} else if (last === '..') {
parts.splice(i, 1);
up++;
} else if (up) {
parts.splice(i, 1);
up--;
}
}
// if the path is allowed to go above the root, restore leading ..s
if (allowAboveRoot) {
for (; up--; up) {
parts.unshift('..');
}
}
return parts;
}
// Split a filename into [root, dir, basename, ext], unix version
// 'root' is just a slash, or nothing.
var splitPathRe =
/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
var splitPath = function(filename) {
return splitPathRe.exec(filename).slice(1);
};
// path.resolve([from ...], to)
// posix version
exports.resolve = function() {
var resolvedPath = '',
resolvedAbsolute = false;
for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
var path = (i >= 0) ? arguments[i] : process.cwd();
// Skip empty and invalid entries
if (typeof path !== 'string') {
throw new TypeError('Arguments to path.resolve must be strings');
} else if (!path) {
continue;
}
resolvedPath = path + '/' + resolvedPath;
resolvedAbsolute = path.charAt(0) === '/';
}
// At this point the path should be resolved to a full absolute path, but
// handle relative paths to be safe (might happen when process.cwd() fails)
// Normalize the path
resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {
return !!p;
}), !resolvedAbsolute).join('/');
return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
};
// path.normalize(path)
// posix version
exports.normalize = function(path) {
var isAbsolute = exports.isAbsolute(path),
trailingSlash = substr(path, -1) === '/';
// Normalize the path
path = normalizeArray(filter(path.split('/'), function(p) {
return !!p;
}), !isAbsolute).join('/');
if (!path && !isAbsolute) {
path = '.';
}
if (path && trailingSlash) {
path += '/';
}
return (isAbsolute ? '/' : '') + path;
};
// posix version
exports.isAbsolute = function(path) {
return path.charAt(0) === '/';
};
// posix version
exports.join = function() {
var paths = Array.prototype.slice.call(arguments, 0);
return exports.normalize(filter(paths, function(p, index) {
if (typeof p !== 'string') {
throw new TypeError('Arguments to path.join must be strings');
}
return p;
}).join('/'));
};
// path.relative(from, to)
// posix version
exports.relative = function(from, to) {
from = exports.resolve(from).substr(1);
to = exports.resolve(to).substr(1);
function trim(arr) {
var start = 0;
for (; start < arr.length; start++) {
if (arr[start] !== '') break;
}
var end = arr.length - 1;
for (; end >= 0; end--) {
if (arr[end] !== '') break;
}
if (start > end) return [];
return arr.slice(start, end - start + 1);
}
var fromParts = trim(from.split('/'));
var toParts = trim(to.split('/'));
var length = Math.min(fromParts.length, toParts.length);
var samePartsLength = length;
for (var i = 0; i < length; i++) {
if (fromParts[i] !== toParts[i]) {
samePartsLength = i;
break;
}
}
var outputParts = [];
for (var i = samePartsLength; i < fromParts.length; i++) {
outputParts.push('..');
}
outputParts = outputParts.concat(toParts.slice(samePartsLength));
return outputParts.join('/');
};
exports.sep = '/';
exports.delimiter = ':';
exports.dirname = function(path) {
var result = splitPath(path),
root = result[0],
dir = result[1];
if (!root && !dir) {
// No dirname whatsoever
return '.';
}
if (dir) {
// It has a dirname, strip trailing slash
dir = dir.substr(0, dir.length - 1);
}
return root + dir;
};
exports.basename = function(path, ext) {
var f = splitPath(path)[2];
// TODO: make this comparison case-insensitive on windows?
if (ext && f.substr(-1 * ext.length) === ext) {
f = f.substr(0, f.length - ext.length);
}
return f;
};
exports.extname = function(path) {
return splitPath(path)[3];
};
function filter (xs, f) {
if (xs.filter) return xs.filter(f);
var res = [];
for (var i = 0; i < xs.length; i++) {
if (f(xs[i], i, xs)) res.push(xs[i]);
}
return res;
}
// String.prototype.substr - negative index don't work in IE8
var substr = 'ab'.substr(-1) === 'b'
? function (str, start, len) { return str.substr(start, len) }
: function (str, start, len) {
if (start < 0) start = str.length + start;
return str.substr(start, len);
}
;
}).call(this,require('_process'))
},{"_process":13}],13:[function(require,module,exports){
// shim for using process in browser
var process = module.exports = {};
// cached from whatever global is present so that test runners that stub it
// don't break things. But we need to wrap it in a try catch in case it is
// wrapped in strict mode code which doesn't define any globals. It's inside a
// function because try/catches deoptimize in certain engines.
var cachedSetTimeout;
var cachedClearTimeout;
(function () {
try {
cachedSetTimeout = setTimeout;
} catch (e) {
cachedSetTimeout = function () {
throw new Error('setTimeout is not defined');
}
}
try {
cachedClearTimeout = clearTimeout;
} catch (e) {
cachedClearTimeout = function () {
throw new Error('clearTimeout is not defined');
}
}
} ())
function runTimeout(fun) {
if (cachedSetTimeout === setTimeout) {
return setTimeout(fun, 0);
} else {
return cachedSetTimeout.call(null, fun, 0);
}
}
function runClearTimeout(marker) {
if (cachedClearTimeout === clearTimeout) {
clearTimeout(marker);
} else {
cachedClearTimeout.call(null, marker);
}
}
var queue = [];
var draining = false;
var currentQueue;
var queueIndex = -1;
function cleanUpNextTick() {
if (!draining || !currentQueue) {
return;
}
draining = false;
if (currentQueue.length) {
queue = currentQueue.concat(queue);
} else {
queueIndex = -1;
}
if (queue.length) {
drainQueue();
}
}
function drainQueue() {
if (draining) {
return;
}
var timeout = runTimeout(cleanUpNextTick);
draining = true;
var len = queue.length;
while(len) {
currentQueue = queue;
queue = [];
while (++queueIndex < len) {
if (currentQueue) {
currentQueue[queueIndex].run();
}
}
queueIndex = -1;
len = queue.length;
}
currentQueue = null;
draining = false;
runClearTimeout(timeout);
}
process.nextTick = function (fun) {
var args = new Array(arguments.length - 1);
if (arguments.length > 1) {
for (var i = 1; i < arguments.length; i++) {
args[i - 1] = arguments[i];
}
}
queue.push(new Item(fun, args));
if (queue.length === 1 && !draining) {
runTimeout(drainQueue);
}
};
// v8 likes predictible objects
function Item(fun, array) {
this.fun = fun;
this.array = array;
}
Item.prototype.run = function () {
this.fun.apply(null, this.array);
};
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
process.version = ''; // empty string to avoid regexp issues
process.versions = {};
function noop() {}
process.on = noop;
process.addListener = noop;
process.once = noop;
process.off = noop;
process.removeListener = noop;
process.removeAllListeners = noop;
process.emit = noop;
process.binding = function (name) {
throw new Error('process.binding is not supported');
};
process.cwd = function () { return '/' };
process.chdir = function (dir) {
throw new Error('process.chdir is not supported');
};
process.umask = function() { return 0; };
},{}],14:[function(require,module,exports){
module.exports = function isBuffer(arg) {
return arg && typeof arg === 'object'
&& typeof arg.copy === 'function'
&& typeof arg.fill === 'function'
&& typeof arg.readUInt8 === 'function';
}
},{}],15:[function(require,module,exports){
(function (process,global){
// 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 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);
}
// IE doesn't make error fields non-enumerable
// http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
if (isError(value)
&& (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
return formatError(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))
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) {
return Array.isArray(ar);
}
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 isObject(re) && objectToString(re) === '[object RegExp]';
}
exports.isRegExp = isRegExp;
function isObject(arg) {
return typeof arg === 'object' && arg !== null;
}
exports.isObject = isObject;
function isDate(d) {
return isObject(d) && objectToString(d) === '[object Date]';
}
exports.isDate = isDate;
function isError(e) {
return isObject(e) &&
(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 = require('./support/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 = require('inherits');
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);
}
}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"./support/isBuffer":14,"_process":13,"inherits":9}],16:[function(require,module,exports){
// Copyright 2011 Timothy J Fontaine <tjfontaine@gmail.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
"use strict";
exports.platform = require('./lib/platform');
exports.createServer = require('./lib/server').createServer;
exports.createUDPServer = require('./lib/server').createUDPServer;
exports.createTCPServer = require('./lib/server').createTCPServer;
var client = require('./lib/client');
exports.lookup = client.lookup;
exports.resolve = client.resolve;
exports.resolve4 = client.resolve4;
exports.resolve6 = client.resolve6;
exports.resolveMx = client.resolveMx;
exports.resolveTxt = client.resolveTxt;
exports.resolveSrv = client.resolveSrv;
exports.resolveNs = client.resolveNs;
exports.resolveCname = client.resolveCname;
exports.reverse = client.reverse;
var consts = require('native-dns-packet').consts;
exports.BADNAME = consts.BADNAME;
exports.BADRESP = consts.BADRESP;
exports.CONNREFUSED = consts.CONNREFUSED;
exports.DESTRUCTION = consts.DESTRUCTION;
exports.REFUSED = consts.REFUSED;
exports.FORMERR = consts.FORMERR;
exports.NODATA = consts.NODATA;
exports.NOMEM = consts.NOMEM;
exports.NOTFOUND = consts.NOTFOUND;
exports.NOTIMP = consts.NOTIMP;
exports.SERVFAIL = consts.SERVFAIL;
exports.TIMEOUT = consts.TIMEOUT;
exports.consts = consts;
var definedTypes = [
'A',
'AAAA',
'NS',
'CNAME',
'PTR',
'NAPTR',
'TXT',
'MX',
'SRV',
'SOA',
'TLSA',
].forEach(function (type) {
exports[type] = function (opts) {
var obj = {};
opts = opts || {};
obj.type = consts.nameToQtype(type);
obj.class = consts.NAME_TO_QCLASS.IN;
Object.keys(opts).forEach(function (k) {
if (opts.hasOwnProperty(k) && ['type', 'class'].indexOf(k) == -1) {
obj[k] = opts[k];
}
});
return obj;
};
});
exports.Question = function (opts) {
var q = {}, qtype;
opts = opts || {};
q.name = opts.name;
qtype = opts.type || consts.NAME_TO_QTYPE.A;
if (typeof(qtype) === 'string' || qtype instanceof String)
qtype = consts.nameToQtype(qtype.toUpperCase());
if (!qtype || typeof(qtype) !== 'number')
throw new Error("Question type must be defined and be valid");
q.type = qtype;
q.class = opts.class || consts.NAME_TO_QCLASS.IN;
return q;
};
exports.Request = client.Request;
},{"./lib/client":17,"./lib/platform":20,"./lib/server":21,"native-dns-packet":30}],17:[function(require,module,exports){
(function (process){
// Copyright 2011 Timothy J Fontaine <tjfontaine@gmail.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
'use strict';
var ipaddr = require('ipaddr.js'),
net = require('net'),
util = require('util'),
EventEmitter = require('events').EventEmitter,
PendingRequests = require('./pending'),
Packet = require('./packet'),
consts = require('native-dns-packet').consts,
utils = require('./utils'),
platform = require('./platform');
var A = consts.NAME_TO_QTYPE.A,
AAAA = consts.NAME_TO_QTYPE.AAAA,
MX = consts.NAME_TO_QTYPE.MX,
TXT = consts.NAME_TO_QTYPE.TXT,
NS = consts.NAME_TO_QTYPE.NS,
CNAME = consts.NAME_TO_QTYPE.CNAME,
SRV = consts.NAME_TO_QTYPE.SRV,
PTR = consts.NAME_TO_QTYPE.PTR,
TLSA = consts.NAME_TO_QTYPE.TLSA;
var debug = function() {};
if (process.env.NODE_DEBUG && process.env.NODE_DEBUG.match(/dns/)) {
debug = function debug() {
var args = Array.prototype.slice.call(arguments);
console.error.apply(this, ['client', Date.now().toString()].concat(args));
};
}
var Request = exports.Request = function(opts) {
if (!(this instanceof Request)) return new Request(opts);
this.question = opts.question;
this.server = opts.server;
if (typeof(this.server) === 'string' || this.server instanceof String)
this.server = { address: this.server, port: 53, type: 'udp'};
if (!this.server || !this.server.address || !net.isIP(this.server.address))
throw new Error('Server object must be supplied with at least address');
if (!this.server.type || ['udp', 'tcp'].indexOf(this.server.type) === -1)
this.server.type = 'udp';
if (!this.server.port)
this.server.port = 53;
this.timeout = opts.timeout || 4 * 1000;
this.try_edns = opts.try_edns || false;
this.fired = false;
this.id = undefined;
if (opts.cache || opts.cache === false) {
this.cache = opts.cache;
} else {
this.cache = platform.cache;
}
debug('request created', this.question);
};
util.inherits(Request, EventEmitter);
Request.prototype.handle = function(err, answer, cached) {
if (!this.fired) {
debug('request handled', this.id, this.question);
if (!cached && this.cache && this.cache.store && answer) {
this.cache.store(answer);
}
this.emit('message', err, answer);
this.done();
}
};
Request.prototype.done = function() {
debug('request finished', this.id, this.question);
this.fired = true;
clearTimeout(this.timer_);
PendingRequests.remove(this);
this.emit('end');
this.id = undefined;
};
Request.prototype.handleTimeout = function() {
if (!this.fired) {
debug('request timedout', this.id, this.question);
this.emit('timeout');
this.done();
}
};
Request.prototype.error = function(err) {
if (!this.fired) {
debug('request error', err, this.id, this.question);
this.emit('error', err);
this.done();
}
};
Request.prototype.send = function() {
debug('request starting', this.question);
var self = this;
if (this.cache && this.cache.lookup) {
this.cache.lookup(this.question, function(results) {
var packet;
if (!results) {
self._send();
} else {
packet = new Packet();
packet.answer = results.slice();
self.handle(null, packet, true);
}
});
} else {
this._send();
}
};
Request.prototype._send = function() {
debug('request not in cache', this.question);
var self = this;
this.timer_ = setTimeout(function() {
self.handleTimeout();
}, this.timeout);
PendingRequests.send(self);
};
Request.prototype.cancel = function() {
debug('request cancelled', this.id, this.question);
this.emit('cancelled');
this.done();
};
var _queue = [];
var sendQueued = function() {
debug('platform ready sending queued requests');
_queue.forEach(function(request) {
request.start();
});
_queue = [];
};
platform.on('ready', function() {
sendQueued();
});
if (platform.ready) {
sendQueued();
}
var Resolve = function Resolve(opts, cb) {
if (!(this instanceof Resolve)) return new Resolve(opts, cb);
this.opts = util._extend({
retryOnTruncate: true,
}, opts);
this._domain = opts.domain;
this._rrtype = opts.rrtype;
this._buildQuestion(this._domain);
this._started = false;
this._current_server = undefined;
this._server_list = [];
if (opts.remote) {
this._server_list.push({
address: opts.remote,
port: 53,
type: 'tcp',
});
this._server_list.push({
address: opts.remote,
port: 53,
type: 'udp',
});
}
this._request = undefined;
this._type = 'getHostByName';
this._cb = cb;
if (!platform.ready) {
_queue.push(this);
} else {
this.start();
}
};
util.inherits(Resolve, EventEmitter);
Resolve.prototype.cancel = function() {
if (this._request) {
this._request.cancel();
}
};
Resolve.prototype._buildQuestion = function(name) {
debug('building question', name);
this.question = {
type: this._rrtype,
class: consts.NAME_TO_QCLASS.IN,
name: name
};
};
exports.Resolve = Resolve;
Resolve.prototype._emit = function(err, answer) {
debug('resolve end', this._domain);
var self = this;
process.nextTick(function() {
if (err) {
err.syscall = self._type;
}
self._cb(err, answer);
});
};
Resolve.prototype._fillServers = function() {
debug('resolve filling servers', this._domain);
var tries = 0, s, t, u, slist;
slist = platform.name_servers;
while (this._server_list.length < platform.attempts) {
s = slist[tries % slist.length];
u = {
address: s.address,
port: s.port,
type: 'udp'
};
t = {
address: s.address,
port: s.port,
type: 'tcp'
};
this._server_list.push(u);
this._server_list.push(t);
tries += 1;
}
this._server_list.reverse();
};
Resolve.prototype._popServer = function() {
debug('resolve pop server', this._current_server, this._domain);
this._server_list.splice(0, 1, this._current_server);
};
Resolve.prototype._preStart = function() {
if (!this._started) {
this._started = new Date().getTime();
this.try_edns = platform.edns;
if (!this._server_list.length)
this._fillServers();
}
};
Resolve.prototype._shouldContinue = function() {
debug('resolve should continue', this._server_list.length, this._domain);
return this._server_list.length;
};
Resolve.prototype._nextQuestion = function() {
debug('resolve next question', this._domain);
};
Resolve.prototype.start = function() {
if (!this._started) {
this._preStart();
}
if (this._server_list.length === 0) {
debug('resolve no more servers', this._domain);
this.handleTimeout();
} else {
this._current_server = this._server_list.pop();
debug('resolve start', this._current_server, this._domain);
this._request = Request({
question: this.question,
server: this._current_server,
timeout: platform.timeout,
try_edns: this.try_edns
});
this._request.on('timeout', this._handleTimeout.bind(this));
this._request.on('message', this._handle.bind(this));
this._request.on('error', this._handle.bind(this));
this._request.send();
}
};
var NOERROR = consts.NAME_TO_RCODE.NOERROR,
SERVFAIL = consts.NAME_TO_RCODE.SERVFAIL,
NOTFOUND = consts.NAME_TO_RCODE.NOTFOUND,
FORMERR = consts.NAME_TO_RCODE.FORMERR;
Resolve.prototype._handle = function(err, answer) {
var rcode, errno;
if (answer) {
rcode = answer.header.rcode;
}
debug('resolve handle', rcode, this._domain);
switch (rcode) {
case NOERROR:
// answer trucated retry with tcp
//console.log(answer);
if (answer.header.tc &&
this.opts.retryOnTruncate &&
this._shouldContinue()) {
debug('truncated', this._domain, answer);
this.emit('truncated', err, answer);
// remove udp servers
this._server_list = this._server_list.filter(function(server) {
return server.type === 'tcp';
});
answer = undefined;
}
break;
case SERVFAIL:
if (this._shouldContinue()) {
this._nextQuestion();
//this._popServer();
} else {
errno = consts.SERVFAIL;
}
answer = undefined;
break;
case NOTFOUND:
if (this._shouldContinue()) {
this._nextQuestion();
} else {
errno = consts.NOTFOUND;
}
answer = undefined;
break;
case FORMERR:
if (this.try_edns) {
this.try_edns = false;
//this._popServer();
} else {
errno = consts.FORMERR;
}
answer = undefined;
break;
default:
if (!err) {
errno = consts.RCODE_TO_NAME[rcode];
answer = undefined;
} else {
errno = consts.NOTFOUND;
}
break;
}
if (errno || answer) {
if (errno) {
err = new Error(this._type + ' ' + errno);
err.errno = err.code = errno;
}
this._emit(err, answer);
} else {
this.start();
}
};
Resolve.prototype._handleTimeout = function() {
var err;
if (this._server_list.length === 0) {
debug('resolve timeout no more servers', this._domain);
err = new Error(this._type + ' ' + consts.TIMEOUT);
err.errno = consts.TIMEOUT;
this._emit(err, undefined);
} else {
debug('resolve timeout continue', this._domain);
this.start();
}
};
var resolve = function(domain, rrtype, ip, callback) {
var res;
if (!callback) {
callback = ip;
ip = undefined;
}
if (!callback) {
callback = rrtype;
rrtype = undefined;
}
rrtype = consts.NAME_TO_QTYPE[rrtype || 'A'];
if (rrtype === PTR) {
return reverse(domain, callback);
}
var opts = {
domain: domain,
rrtype: rrtype,
remote: ip,
};
res = new Resolve(opts);
res._cb = function(err, response) {
var ret = [], i, a;
if (err) {
callback(err, response);
return;
}
for (i = 0; i < response.answer.length; i++) {
a = response.answer[i];
if (a.type === rrtype) {
switch (rrtype) {
case A:
case AAAA:
ret.push(a.address);
break;
case consts.NAME_TO_QTYPE.MX:
ret.push({
priority: a.priority,
exchange: a.exchange
});
break;
case TXT:
case NS:
case CNAME:
case PTR:
ret.push(a.data);
break;
case SRV:
ret.push({
priority: a.priority,
weight: a.weight,
port: a.port,
name: a.target
});
break;
default:
ret.push(a);
break;
}
}
}
if (ret.length === 0) {
ret = undefined;
}
callback(err, ret);
};
return res;
};
exports.resolve = resolve;
var resolve4 = function(domain, callback) {
return resolve(domain, 'A', function(err, results) {
callback(err, results);
});
};
exports.resolve4 = resolve4;
var resolve6 = function(domain, callback) {
return resolve(domain, 'AAAA', function(err, results) {
callback(err, results);
});
};
exports.resolve6 = resolve6;
var resolveMx = function(domain, callback) {
return resolve(domain, 'MX', function(err, results) {
callback(err, results);
});
};
exports.resolveMx = resolveMx;
var resolveTxt = function(domain, callback) {
return resolve(domain, 'TXT', function(err, results) {
callback(err, results);
});
};
exports.resolveTxt = resolveTxt;
var resolveSrv = function(domain, callback) {
return resolve(domain, 'SRV', function(err, results) {
callback(err, results);
});
};
exports.resolveSrv = resolveSrv;
var resolveNs = function(domain, callback) {
return resolve(domain, 'NS', function(err, results) {
callback(err, results);
});
};
exports.resolveNs = resolveNs;
var resolveCname = function(domain, callback) {
return resolve(domain, 'CNAME', function(err, results) {
callback(err, results);
});
};
exports.resolveCname = resolveCname;
var resolveTlsa = function(domain, callback) {
return resolve(domain, 'TLSA', function(err, results) {
callback(err, results);
});
};
exports.resolveTlsa = resolveTlsa;
var reverse = function(ip, callback) {
var error, opts, res;
if (!net.isIP(ip)) {
error = new Error('getHostByAddr ENOTIMP');
error.errno = error.code = 'ENOTIMP';
throw error;
}
opts = {
domain: utils.reverseIP(ip),
rrtype: PTR
};
res = new Lookup(opts);
res._cb = function(err, response) {
var results = [];
if (response) {
response.answer.forEach(function(a) {
if (a.type === PTR) {
results.push(a.data);
}
});
}
if (results.length === 0) {
results = undefined;
}
callback(err, results);
};
return res;
};
exports.reverse = reverse;
var Lookup = function(opts) {
Resolve.call(this, opts);
this._type = 'getaddrinfo';
};
util.inherits(Lookup, Resolve);
Lookup.prototype.start = function() {
var self = this;
if (!this._started) {
this._search_path = platform.search_path.slice(0);
this._preStart();
}
platform.hosts.lookup(this.question, function(results) {
var packet;
if (results && results.length) {
debug('Lookup in hosts', results);
packet = new Packet();
packet.answer = results.slice();
self._emit(null, packet);
} else {
debug('Lookup not in hosts');
Resolve.prototype.start.call(self);
}
});
};
Lookup.prototype._shouldContinue = function() {
debug('Lookup should continue', this._server_list.length,
this._search_path.length);
return this._server_list.length && this._search_path.length;
};
Lookup.prototype._nextQuestion = function() {
debug('Lookup next question');
this._buildQuestion([this._domain, this._search_path.pop()].join('.'));
};
var lookup = function(domain, family, callback) {
var rrtype, revip, res;
if (!callback) {
callback = family;
family = undefined;
}
if (!family) {
family = 4;
}
revip = net.isIP(domain);
if (revip === 4 || revip === 6) {
process.nextTick(function() {
callback(null, domain, revip);
});
return {};
}
if (!domain) {
process.nextTick(function() {
callback(null, null, family);
});
return {};
}
rrtype = consts.FAMILY_TO_QTYPE[family];
var opts = {
domain: domain,
rrtype: rrtype
};
res = new Lookup(opts);
res._cb = function(err, response) {
var i, afamily, address, a, all;
if (err) {
callback(err, undefined, undefined);
return;
}
all = response.answer.concat(response.additional);
for (i = 0; i < all.length; i++) {
a = all[i];
if (a.type === A || a.type === AAAA) {
afamily = consts.QTYPE_TO_FAMILY[a.type];
address = a.address;
break;
}
}
callback(err, address, afamily);
};
return res;
};
exports.lookup = lookup;
}).call(this,require('_process'))
},{"./packet":18,"./pending":19,"./platform":20,"./utils":22,"_process":13,"events":8,"ipaddr.js":23,"native-dns-packet":30,"net":2,"util":15}],18:[function(require,module,exports){
// Copyright 2011 Timothy J Fontaine <tjfontaine@gmail.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
'use strict';
var NDP = require('native-dns-packet'),
util = require('util');
var Packet = module.exports = function(socket) {
NDP.call(this);
this.address = undefined;
this._socket = socket;
};
util.inherits(Packet, NDP);
Packet.prototype.send = function() {
var buff, len, size;
if (typeof(this.edns_version) !== 'undefined') {
size = 4096;
}
this.payload = size = size || this._socket.base_size;
buff = this._socket.buffer(size);
len = Packet.write(buff, this);
this._socket.send(len);
};
Packet.parse = function (msg, socket) {
var p = NDP.parse(msg);
p._socket = socket;
return p;
};
Packet.write = NDP.write;
},{"native-dns-packet":30,"util":15}],19:[function(require,module,exports){
// Copyright 2012 Timothy J Fontaine <tjfontaine@gmail.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
'use strict';
var net = require('net'),
util = require('util'),
EventEmitter = require('events').EventEmitter,
Packet = require('./packet'),
consts = require('native-dns-packet').consts,
UDPSocket = require('./utils').UDPSocket,
TCPSocket = require('./utils').TCPSocket;
var debug = function() {
//var args = Array.prototype.slice.call(arguments);
//console.log.apply(this, ['pending', Date.now().toString()].concat(args));
};
var SocketQueue = function(socket, server) {
this._active = {};
this._active_count = 0;
this._pending = [];
debug('created', server);
this._server = server;
this._socket = socket;
this._socket.on('ready', this._onlisten.bind(this));
this._socket.on('message', this._onmessage.bind(this));
this._socket.on('close', this._onclose.bind(this));
this._socket.bind(server);
this._refd = true;
};
util.inherits(SocketQueue, EventEmitter);
SocketQueue.prototype.send = function(request) {
debug('added', request.question);
this._pending.push(request);
this._fill();
};
SocketQueue.prototype.remove = function(request) {
var req = this._active[request.id];
var idx = this._pending.indexOf(request);
if (req) {
delete this._active[request.id];
this._active_count -= 1;
this._fill();
}
if (idx > -1)
this._pending.splice(idx, 1);
this._unref();
};
SocketQueue.prototype.close = function() {
debug('closing', this._server);
this._socket.close();
this._socket = undefined;
this.emit('close');
};
SocketQueue.prototype._fill = function() {
debug('pre fill, active:', this._active_count, 'pending:',
this._pending.length);
while (this._listening && this._pending.length &&
this._active_count < 100) {
this._dequeue();
}
debug('post fill, active:', this._active_count, 'pending:',
this._pending.length);
};
var random_integer = function() {
return Math.floor(Math.random() * 50000 + 1);
};
SocketQueue.prototype._dequeue = function() {
var req = this._pending.pop();
var id, packet, dnssocket;
if (req) {
id = random_integer();
while (this._active[id])
id = random_integer();
debug('sending', req.question, id);
req.id = id;
this._active[id] = req;
this._active_count += 1;
try {
packet = new Packet(this._socket.remote(req.server));
packet.header.id = id;
packet.header.rd = 1;
if (req.try_edns) {
packet.edns_version = 0;
//TODO when we support dnssec
//packet.do = 1
}
packet.question.push(req.question);
packet.send();
this._ref();
} catch (e) {
req.error(e);
}
}
};
SocketQueue.prototype._onmessage = function(msg, remote) {
var req, packet;
debug('got a message', this._server);
try {
packet = Packet.parse(msg, remote);
req = this._active[packet.header.id];
debug('associated message', packet.header.id);
} catch (e) {
debug('error parsing packet', e);
}
if (req) {
delete this._active[packet.header.id];
this._active_count -= 1;
req.handle(null, packet);
this._fill();
}
this._unref();
};
SocketQueue.prototype._unref = function() {
var self = this;
this._refd = false;
if (this._active_count <= 0) {
if (this._socket.unref) {
debug('unrefd socket');
this._socket.unref();
} else if (!this._timer) {
this._timer = setTimeout(function() {
self.close();
}, 300);
}
}
};
SocketQueue.prototype._ref = function() {
this._refd = true;
if (this._socket.ref) {
debug('refd socket');
this._socket.ref();
} else if (this._timer) {
clearTimeout(this._timer);
this._timer = null;
}
};
SocketQueue.prototype._onlisten = function() {
this._unref();
this._listening = true;
this._fill();
};
SocketQueue.prototype._onclose = function() {
var req, err, self = this;
debug('socket closed', this);
this._listening = false;
err = new Error('getHostByName ' + consts.TIMEOUT);
err.errno = consts.TIMEOUT;
while (this._pending.length) {
req = this._pending.pop();
req.error(err);
}
Object.keys(this._active).forEach(function(key) {
var req = self._active[key];
req.error(err);
delete self._active[key];
self._active_count -= 1;
});
};
var serverHash = function(server) {
if (server.type === 'tcp')
return server.address + ':' + server.port;
else
return 'udp' + net.isIP(server.address);
};
var _sockets = {};
exports.send = function(request) {
var hash = serverHash(request.server);
var socket = _sockets[hash];
if (!socket) {
switch (hash) {
case 'udp4':
case 'udp6':
socket = new SocketQueue(new UDPSocket(), hash);
break;
default:
socket = new SocketQueue(new TCPSocket(), request.server);
break;
}
socket.on('close', function() {
delete _sockets[hash];
});
_sockets[hash] = socket;
}
socket.send(request);
};
exports.remove = function(request) {
var hash = serverHash(request.server);
var socket = _sockets[hash];
if (socket) {
socket.remove(request);
}
};
},{"./packet":18,"./utils":22,"events":8,"native-dns-packet":30,"net":2,"util":15}],20:[function(require,module,exports){
(function (process){
// Copyright 2011 Timothy J Fontaine <tjfontaine@gmail.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
'use strict';
var fs = require('fs'),
EventEmitter = require('events').EventEmitter,
net = require('net'),
os = require('os'),
util = require('util'),
Cache = require('native-dns-cache'),
consts = require('native-dns-packet').consts,
path = require('path'),
utils = require('./utils');
var A = consts.NAME_TO_QTYPE.A,
AAAA = consts.NAME_TO_QTYPE.AAAA,
PTR = consts.NAME_TO_QTYPE.PTR;
var Platform = function() {
this._nsReady = false;
this._hostsReady = false;
Object.defineProperty(this, 'ready', {
get: function() {
return this._nsReady && this._hostsReady;
}
});
this._watches = {};
Object.defineProperty(this, 'watching', {
get: function() {
return Object.keys(this._watches).length > 0;
},
set: function(value) {
var k;
if (value)
this._watchFiles();
else {
for (k in this._watches) {
this._watches[k].close();
delete this._watches[k];
}
}
}
});
this.hosts = new Cache();
this._initNameServers();
this._initHostsFile();
this._populate();
this.cache = false; //new Cache();
};
util.inherits(Platform, EventEmitter);
Platform.prototype.reload = function() {
this.emit('unready');
this._initNameServers();
this._initHostsFile();
this._populate();
};
Platform.prototype._initNameServers = function() {
this._nsReady = false;
this.name_servers = [];
this.search_path = [];
this.timeout = 5 * 1000;
this.attempts = 5;
this.edns = false;
};
Platform.prototype._initHostsFile = function() {
this._hostsReady = false;
this.hosts.purge();
};
Platform.prototype._populate = function() {
var hostsfile, self = this;
switch (os.platform()) {
case 'win32':
this.name_servers = [
{
address: '8.8.8.8',
port: 53
},
{
address: '8.8.4.4',
port: 53
}
];
self._nsReady = true;
hostsfile = path.join(process.env.SystemRoot,
'\\System32\\drivers\\etc\\hosts');
break;
default:
this.parseResolv();
hostsfile = '/etc/hosts';
break;
}
this._parseHosts(hostsfile);
};
Platform.prototype._watchFiles = function() {
var self = this, watchParams;
watchParams = {persistent: false};
switch (os.platform()) {
case 'win32':
//TODO XXX FIXME: it would be nice if this existed
break;
default:
this._watches.resolve = fs.watch('/etc/resolv.conf', watchParams,
function(event, filename) {
if (event === 'change') {
self.emit('unready');
self._initNameServers();
self.parseResolv();
}
});
this._watches.hosts = fs.watch('/etc/hosts', watchParams,
function(event, filename) {
if (event === 'change') {
self.emit('unready');
self._initHostsFile();
self._parseHosts(hostsfile);
}
});
break;
}
};
Platform.prototype._checkReady = function() {
if (this.ready) {
this.emit('ready');
}
};
Platform.prototype.parseResolv = function() {
var self = this;
fs.readFile('/etc/resolv.conf', 'ascii', function(err, file) {
if (err) {
throw err;
}
file.split(/\n/).forEach(function(line) {
var i, parts, subparts;
line = line.replace(/^\s+|\s+$/g, '');
if (!line.match(/^#/)) {
parts = line.split(/\s+/);
switch (parts[0]) {
case 'nameserver':
self.name_servers.push({
address: parts[1],
port: 53
});
break;
case 'domain':
self.search_path = [parts[1]];
break;
case 'search':
self.search_path = [parts.slice(1)];
break;
case 'options':
for (i = 1; i < parts.length; i++) {
subparts = parts[i].split(/:/);
switch (subparts[0]) {
case 'timeout':
self.timeout = parseInt(subparts[1], 10) * 1000;
break;
case 'attempts':
self.attempts = parseInt(subparts[1], 10);
break;
case 'edns0':
self.edns = true;
break;
}
}
break;
}
}
});
self._nsReady = true;
self._checkReady();
});
};
Platform.prototype._parseHosts = function(hostsfile) {
var self = this;
fs.readFile(hostsfile, 'ascii', function(err, file) {
var toStore = {};
if (err) {
throw err;
}
file.split(/\n/).forEach(function(line) {
var i, parts, ip, revip, kind;
line = line.replace(/^\s+|\s+$/g, '');
if (!line.match(/^#/)) {
parts = line.split(/\s+/);
ip = parts[0];
parts = parts.slice(1);
kind = net.isIP(ip);
if (parts.length && ip && kind) {
/* IP -> Domain */
revip = utils.reverseIP(ip);
parts.forEach(function(domain) {
var r = toStore[revip];
if (!r)
r = toStore[revip] = {};
var t = r[PTR];
if (!t)
t = r[PTR] = [];
t.push({
type: PTR,
class: 1,
name: revip,
data: domain,
ttl: Infinity
});
});
/* Domain -> IP */
parts.forEach(function(domain) {
var r = toStore[domain.toLowerCase()];
if (!r) {
r = toStore[domain.toLowerCase()] = {};
}
var type = kind === 4 ? A : AAAA;
var t = r[type];
if (!t)
t = r[type] = [];
t.push({
type: type,
name: domain.toLowerCase(),
address: ip,
ttl: Infinity
});
});
}
}
});
Object.keys(toStore).forEach(function (key) {
self.hosts._store.set(self.hosts._zone, key, toStore[key]);
});
self._hostsReady = true;
self._checkReady();
});
};
module.exports = new Platform();
}).call(this,require('_process'))
},{"./utils":22,"_process":13,"events":8,"fs":2,"native-dns-cache":25,"native-dns-packet":30,"net":2,"os":11,"path":12,"util":15}],21:[function(require,module,exports){
// Copyright 2011 Timothy J Fontaine <tjfontaine@gmail.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
'use strict';
var dgram = require('dgram'),
EventEmitter = require('events').EventEmitter,
net = require('net'),
util = require('util'),
UDPSocket = require('./utils').UDPSocket,
TCPSocket = require('./utils').TCPSocket,
Packet = require('./packet');
var Server = function(opts) {
var self = this;
this._socket.on('listening', function() {
self.emit('listening');
});
this._socket.on('close', function() {
self.emit('close');
});
this._socket.on('error', function(err) {
self.emit('socketError', err, self._socket);
});
};
util.inherits(Server, EventEmitter);
Server.prototype.close = function() {
this._socket.close();
};
Server.prototype.address = function() {
return this._socket.address();
};
Server.prototype.handleMessage = function(msg, remote, address) {
var request, response = new Packet(remote);
try {
request = Packet.parse(msg, remote);
request.address = address;
response.header.id = request.header.id;
response.header.qr = 1;
response.question = request.question;
this.emit('request', request, response);
} catch (e) {
this.emit('error', e, msg, response);
}
};
var UDPServer = function(opts) {
var self = this;
this._socket = dgram.createSocket(opts.dgram_type || 'udp4');
this._socket.on('message', function(msg, remote) {
self.handleMessage(msg, new UDPSocket(self._socket, remote), remote);
});
Server.call(this, opts);
};
util.inherits(UDPServer, Server);
UDPServer.prototype.serve = function(port, address) {
this._socket.bind(port, address);
};
var TCPServer = function(opts) {
var self = this;
this._socket = net.createServer(function(client) {
var tcp = new TCPSocket(client);
var address = client.address();
tcp.on('message', function(msg, remote) {
self.handleMessage(msg, tcp, address);
});
tcp.catchMessages();
});
Server.call(this, opts);
};
util.inherits(TCPServer, Server);
TCPServer.prototype.serve = function(port, address) {
this._socket.listen(port, address);
};
exports.createServer = function(opts) {
return new UDPServer(opts || {});
};
exports.createUDPServer = function(opts) {
return exports.createServer(opts);
};
exports.createTCPServer = function(opts) {
return new TCPServer(opts || {});
};
},{"./packet":18,"./utils":22,"dgram":2,"events":8,"net":2,"util":15}],22:[function(require,module,exports){
(function (Buffer){
// Copyright 2012 Timothy J Fontaine <tjfontaine@gmail.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
var dgram = require('dgram'),
EventEmitter = require('events').EventEmitter,
ipaddr = require('ipaddr.js'),
net = require('net'),
util = require('util');
var UDPSocket = exports.UDPSocket = function(socket, remote) {
this._socket = socket;
this._remote = remote;
this._buff = undefined;
this.base_size = 512;
this.bound = false;
this.unref = undefined;
this.ref = undefined;
};
util.inherits(UDPSocket, EventEmitter);
UDPSocket.prototype.buffer = function(size) {
this._buff = new Buffer(size);
return this._buff;
};
UDPSocket.prototype.send = function(len) {
this._socket.send(this._buff, 0, len, this._remote.port,
this._remote.address);
};
UDPSocket.prototype.bind = function(type) {
var self = this;
if (this.bound) {
this.emit('ready');
} else {
this._socket = dgram.createSocket(type);
this._socket.on('listening', function() {
self.bound = true;
if (self._socket.unref) {
self.unref = function() {
self._socket.unref();
}
self.ref = function() {
self._socket.ref();
}
}
self.emit('ready');
});
this._socket.on('message', this.emit.bind(this, 'message'));
this._socket.on('close', function() {
self.bound = false;
self.emit('close');
});
this._socket.bind();
}
};
UDPSocket.prototype.close = function() {
this._socket.close();
};
UDPSocket.prototype.remote = function(remote) {
return new UDPSocket(this._socket, remote);
};
var TCPSocket = exports.TCPSocket = function(socket) {
UDPSocket.call(this, socket);
this.base_size = 4096;
this._rest = undefined;
};
util.inherits(TCPSocket, UDPSocket);
TCPSocket.prototype.buffer = function(size) {
this._buff = new Buffer(size + 2);
return this._buff.slice(2);
};
TCPSocket.prototype.send = function(len) {
this._buff.writeUInt16BE(len, 0);
this._socket.write(this._buff.slice(0, len + 2));
};
TCPSocket.prototype.bind = function(server) {
var self = this;
if (this.bound) {
this.emit('ready');
} else {
this._socket = net.connect(server.port, server.address);
this._socket.on('connect', function() {
self.bound = true;
if (self._socket.unref) {
self.unref = function() {
self._socket.unref();
}
self.ref = function() {
self._socket.ref();
}
}
self.emit('ready');
});
this._socket.on('timeout', function() {
self.bound = false;
self.emit('close');
});
this._socket.on('close', function() {
self.bound = false;
self.emit('close');
});
this.catchMessages();
}
};
TCPSocket.prototype.catchMessages = function() {
var self = this;
this._socket.on('data', function(data) {
var len, tmp;
if (!self._rest) {
self._rest = data;
} else {
tmp = new Buffer(self._rest.length + data.length);
self._rest.copy(tmp, 0);
data.copy(tmp, self._rest.length);
self._rest = tmp;
}
while (self._rest && self._rest.length > 2) {
len = self._rest.readUInt16BE(0);
if (self._rest.length >= len + 2) {
self.emit('message', self._rest.slice(2, len + 2), self);
self._rest = self._rest.slice(len + 2);
} else {
break;
}
}
});
};
TCPSocket.prototype.close = function() {
this._socket.end();
};
TCPSocket.prototype.remote = function() {
return this;
};
exports.reverseIP = function(ip) {
var address, kind, reverseip, parts;
address = ipaddr.parse(ip.split(/%/)[0]);
kind = address.kind();
switch (kind) {
case 'ipv4':
address = address.toByteArray();
address.reverse();
reverseip = address.join('.') + '.IN-ADDR.ARPA';
break;
case 'ipv6':
parts = [];
address.toNormalizedString().split(':').forEach(function(part) {
var i, pad = 4 - part.length;
for (i = 0; i < pad; i++) {
part = '0' + part;
}
part.split('').forEach(function(p) {
parts.push(p);
});
});
parts.reverse();
reverseip = parts.join('.') + '.IP6.ARPA';
break;
}
return reverseip;
};
}).call(this,require("buffer").Buffer)
},{"buffer":4,"dgram":2,"events":8,"ipaddr.js":23,"net":2,"util":15}],23:[function(require,module,exports){
(function() {
var expandIPv6, ipaddr, ipv4Part, ipv4Regexes, ipv6Part, ipv6Regexes, matchCIDR, root;
ipaddr = {};
root = this;
if ((typeof module !== "undefined" && module !== null) && module.exports) {
module.exports = ipaddr;
} else {
root['ipaddr'] = ipaddr;
}
matchCIDR = function(first, second, partSize, cidrBits) {
var part, shift;
if (first.length !== second.length) {
throw new Error("ipaddr: cannot match CIDR for objects with different lengths");
}
part = 0;
while (cidrBits > 0) {
shift = partSize - cidrBits;
if (shift < 0) {
shift = 0;
}
if (first[part] >> shift !== second[part] >> shift) {
return false;
}
cidrBits -= partSize;
part += 1;
}
return true;
};
ipaddr.subnetMatch = function(address, rangeList, defaultName) {
var rangeName, rangeSubnets, subnet, _i, _len;
if (defaultName == null) {
defaultName = 'unicast';
}
for (rangeName in rangeList) {
rangeSubnets = rangeList[rangeName];
if (toString.call(rangeSubnets[0]) !== '[object Array]') {
rangeSubnets = [rangeSubnets];
}
for (_i = 0, _len = rangeSubnets.length; _i < _len; _i++) {
subnet = rangeSubnets[_i];
if (address.match.apply(address, subnet)) {
return rangeName;
}
}
}
return defaultName;
};
ipaddr.IPv4 = (function() {
function IPv4(octets) {
var octet, _i, _len;
if (octets.length !== 4) {
throw new Error("ipaddr: ipv4 octet count should be 4");
}
for (_i = 0, _len = octets.length; _i < _len; _i++) {
octet = octets[_i];
if (!((0 <= octet && octet <= 255))) {
throw new Error("ipaddr: ipv4 octet is a byte");
}
}
this.octets = octets;
}
IPv4.prototype.kind = function() {
return 'ipv4';
};
IPv4.prototype.toString = function() {
return this.octets.join(".");
};
IPv4.prototype.toByteArray = function() {
return this.octets.slice(0);
};
IPv4.prototype.match = function(other, cidrRange) {
if (other.kind() !== 'ipv4') {
throw new Error("ipaddr: cannot match ipv4 address with non-ipv4 one");
}
return matchCIDR(this.octets, other.octets, 8, cidrRange);
};
IPv4.prototype.SpecialRanges = {
unspecified: [[new IPv4([0, 0, 0, 0]), 8]],
broadcast: [[new IPv4([255, 255, 255, 255]), 32]],
multicast: [[new IPv4([224, 0, 0, 0]), 4]],
linkLocal: [[new IPv4([169, 254, 0, 0]), 16]],
loopback: [[new IPv4([127, 0, 0, 0]), 8]],
"private": [[new IPv4([10, 0, 0, 0]), 8], [new IPv4([172, 16, 0, 0]), 12], [new IPv4([192, 168, 0, 0]), 16]],
reserved: [[new IPv4([192, 0, 0, 0]), 24], [new IPv4([192, 0, 2, 0]), 24], [new IPv4([192, 88, 99, 0]), 24], [new IPv4([198, 51, 100, 0]), 24], [new IPv4([203, 0, 113, 0]), 24], [new IPv4([240, 0, 0, 0]), 4]]
};
IPv4.prototype.range = function() {
return ipaddr.subnetMatch(this, this.SpecialRanges);
};
IPv4.prototype.toIPv4MappedAddress = function() {
return ipaddr.IPv6.parse("::ffff:" + (this.toString()));
};
return IPv4;
})();
ipv4Part = "(0?\\d+|0x[a-f0-9]+)";
ipv4Regexes = {
fourOctet: new RegExp("^" + ipv4Part + "\\." + ipv4Part + "\\." + ipv4Part + "\\." + ipv4Part + "$", 'i'),
longValue: new RegExp("^" + ipv4Part + "$", 'i')
};
ipaddr.IPv4.parser = function(string) {
var match, parseIntAuto, part, shift, value;
parseIntAuto = function(string) {
if (string[0] === "0" && string[1] !== "x") {
return parseInt(string, 8);
} else {
return parseInt(string);
}
};
if (match = string.match(ipv4Regexes.fourOctet)) {
return (function() {
var _i, _len, _ref, _results;
_ref = match.slice(1, 6);
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
part = _ref[_i];
_results.push(parseIntAuto(part));
}
return _results;
})();
} else if (match = string.match(ipv4Regexes.longValue)) {
value = parseIntAuto(match[1]);
if (value > 0xffffffff || value < 0) {
throw new Error("ipaddr: address outside defined range");
}
return ((function() {
var _i, _results;
_results = [];
for (shift = _i = 0; _i <= 24; shift = _i += 8) {
_results.push((value >> shift) & 0xff);
}
return _results;
})()).reverse();
} else {
return null;
}
};
ipaddr.IPv6 = (function() {
function IPv6(parts) {
var part, _i, _len;
if (parts.length !== 8) {
throw new Error("ipaddr: ipv6 part count should be 8");
}
for (_i = 0, _len = parts.length; _i < _len; _i++) {
part = parts[_i];
if (!((0 <= part && part <= 0xffff))) {
throw new Error("ipaddr: ipv6 part should fit to two octets");
}
}
this.parts = parts;
}
IPv6.prototype.kind = function() {
return 'ipv6';
};
IPv6.prototype.toString = function() {
var compactStringParts, part, pushPart, state, stringParts, _i, _len;
stringParts = (function() {
var _i, _len, _ref, _results;
_ref = this.parts;
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
part = _ref[_i];
_results.push(part.toString(16));
}
return _results;
}).call(this);
compactStringParts = [];
pushPart = function(part) {
return compactStringParts.push(part);
};
state = 0;
for (_i = 0, _len = stringParts.length; _i < _len; _i++) {
part = stringParts[_i];
switch (state) {
case 0:
if (part === '0') {
pushPart('');
} else {
pushPart(part);
}
state = 1;
break;
case 1:
if (part === '0') {
state = 2;
} else {
pushPart(part);
}
break;
case 2:
if (part !== '0') {
pushPart('');
pushPart(part);
state = 3;
}
break;
case 3:
pushPart(part);
}
}
if (state === 2) {
pushPart('');
pushPart('');
}
return compactStringParts.join(":");
};
IPv6.prototype.toByteArray = function() {
var bytes, part, _i, _len, _ref;
bytes = [];
_ref = this.parts;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
part = _ref[_i];
bytes.push(part >> 8);
bytes.push(part & 0xff);
}
return bytes;
};
IPv6.prototype.toNormalizedString = function() {
var part;
return ((function() {
var _i, _len, _ref, _results;
_ref = this.parts;
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
part = _ref[_i];
_results.push(part.toString(16));
}
return _results;
}).call(this)).join(":");
};
IPv6.prototype.match = function(other, cidrRange) {
if (other.kind() !== 'ipv6') {
throw new Error("ipaddr: cannot match ipv6 address with non-ipv6 one");
}
return matchCIDR(this.parts, other.parts, 16, cidrRange);
};
IPv6.prototype.SpecialRanges = {
unspecified: [new IPv6([0, 0, 0, 0, 0, 0, 0, 0]), 128],
linkLocal: [new IPv6([0xfe80, 0, 0, 0, 0, 0, 0, 0]), 10],
multicast: [new IPv6([0xff00, 0, 0, 0, 0, 0, 0, 0]), 8],
loopback: [new IPv6([0, 0, 0, 0, 0, 0, 0, 1]), 128],
uniqueLocal: [new IPv6([0xfc00, 0, 0, 0, 0, 0, 0, 0]), 7],
ipv4Mapped: [new IPv6([0, 0, 0, 0, 0, 0xffff, 0, 0]), 96],
rfc6145: [new IPv6([0, 0, 0, 0, 0xffff, 0, 0, 0]), 96],
rfc6052: [new IPv6([0x64, 0xff9b, 0, 0, 0, 0, 0, 0]), 96],
'6to4': [new IPv6([0x2002, 0, 0, 0, 0, 0, 0, 0]), 16],
teredo: [new IPv6([0x2001, 0, 0, 0, 0, 0, 0, 0]), 32],
reserved: [[new IPv6([0x2001, 0xdb8, 0, 0, 0, 0, 0, 0]), 32]]
};
IPv6.prototype.range = function() {
return ipaddr.subnetMatch(this, this.SpecialRanges);
};
IPv6.prototype.isIPv4MappedAddress = function() {
return this.range() === 'ipv4Mapped';
};
IPv6.prototype.toIPv4Address = function() {
var high, low, _ref;
if (!this.isIPv4MappedAddress()) {
throw new Error("ipaddr: trying to convert a generic ipv6 address to ipv4");
}
_ref = this.parts.slice(-2), high = _ref[0], low = _ref[1];
return new ipaddr.IPv4([high >> 8, high & 0xff, low >> 8, low & 0xff]);
};
return IPv6;
})();
ipv6Part = "(?:[0-9a-f]+::?)+";
ipv6Regexes = {
"native": new RegExp("^(::)?(" + ipv6Part + ")?([0-9a-f]+)?(::)?$", 'i'),
transitional: new RegExp(("^((?:" + ipv6Part + ")|(?:::)(?:" + ipv6Part + ")?)") + ("" + ipv4Part + "\\." + ipv4Part + "\\." + ipv4Part + "\\." + ipv4Part + "$"), 'i')
};
expandIPv6 = function(string, parts) {
var colonCount, lastColon, part, replacement, replacementCount;
if (string.indexOf('::') !== string.lastIndexOf('::')) {
return null;
}
colonCount = 0;
lastColon = -1;
while ((lastColon = string.indexOf(':', lastColon + 1)) >= 0) {
colonCount++;
}
if (string[0] === ':') {
colonCount--;
}
if (string[string.length - 1] === ':') {
colonCount--;
}
if (colonCount > parts) {
return null;
}
replacementCount = parts - colonCount;
replacement = ':';
while (replacementCount--) {
replacement += '0:';
}
string = string.replace('::', replacement);
if (string[0] === ':') {
string = string.slice(1);
}
if (string[string.length - 1] === ':') {
string = string.slice(0, -1);
}
return (function() {
var _i, _len, _ref, _results;
_ref = string.split(":");
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
part = _ref[_i];
_results.push(parseInt(part, 16));
}
return _results;
})();
};
ipaddr.IPv6.parser = function(string) {
var match, parts;
if (string.match(ipv6Regexes['native'])) {
return expandIPv6(string, 8);
} else if (match = string.match(ipv6Regexes['transitional'])) {
parts = expandIPv6(match[1].slice(0, -1), 6);
if (parts) {
parts.push(parseInt(match[2]) << 8 | parseInt(match[3]));
parts.push(parseInt(match[4]) << 8 | parseInt(match[5]));
return parts;
}
}
return null;
};
ipaddr.IPv4.isIPv4 = ipaddr.IPv6.isIPv6 = function(string) {
return this.parser(string) !== null;
};
ipaddr.IPv4.isValid = ipaddr.IPv6.isValid = function(string) {
var e;
try {
new this(this.parser(string));
return true;
} catch (_error) {
e = _error;
return false;
}
};
ipaddr.IPv4.parse = ipaddr.IPv6.parse = function(string) {
var parts;
parts = this.parser(string);
if (parts === null) {
throw new Error("ipaddr: string is not formatted like ip address");
}
return new this(parts);
};
ipaddr.isValid = function(string) {
return ipaddr.IPv6.isValid(string) || ipaddr.IPv4.isValid(string);
};
ipaddr.parse = function(string) {
if (ipaddr.IPv6.isValid(string)) {
return ipaddr.IPv6.parse(string);
} else if (ipaddr.IPv4.isValid(string)) {
return ipaddr.IPv4.parse(string);
} else {
throw new Error("ipaddr: the address has neither IPv6 nor IPv4 format");
}
};
ipaddr.process = function(string) {
var addr;
addr = this.parse(string);
if (addr.kind() === 'ipv6' && addr.isIPv4MappedAddress()) {
return addr.toIPv4Address();
} else {
return addr;
}
};
}).call(this);
},{}],24:[function(require,module,exports){
// Copyright 2012 Timothy J Fontaine <tjfontaine@gmail.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
'use strict';
var MemoryStore = require('./memory').MemoryStore;
var utils = require('./lookup');
var Lookup = utils.Lookup;
var util = require('util');
var Heap = require('binaryheap');
var MemoryStoreExpire = function (store, zone, opts) {
opts = opts || {};
this._store = store;
this._zone = zone;
this._max_keys = opts.max_keys;
this._ttl = new Heap(true);
};
MemoryStoreExpire.prototype.get = function (domain, key, cb) {
var self = this;
this._store.get(domain, key, function (err, results) {
var i, j, type, record;
var nresults = {};
var now = Date.now();
for (i in results) {
type = results[i];
for (j in type) {
record = type[j];
record.ttl = Math.round((record._ttl_expires - now) / 1000)
if (record.ttl > 0) {
if (!nresults[i]) {
nresults[i] = [];
}
nresults[i].push(record);
} else {
self._ttl.remove(record);
self._store.delete(self._zone, record.name, record.type, function () {});
}
}
}
cb(err, nresults);
});
};
MemoryStoreExpire.prototype.set = function (domain, key, data, cb) {
var i, j, type, record, expires;
var self = this;
var now = Date.now();
key = utils.ensure_absolute(key);
for (i in data) {
type = data[i];
for (j in type) {
record = type[j];
expires = (record.ttl * 1000) + now;
record._ttl_expires = expires;
self._ttl.insert(record, expires);
}
}
while (this._ttl.length > this._max_keys) {
var record = this._ttl.pop();
this._store.delete(this._zone, record.name, record.type);
}
this._store.set(domain, key, data, function (err, results) {
if (cb)
cb(err, results);
});
};
MemoryStoreExpire.prototype.delete = function (domain, key, type, cb) {
if (!cb) {
cb = type;
type = undefined;
}
var self = this;
this._store.get(domain, utils.ensure_absolute(key), function (gerr, gresults) {
var i, j, ktype, record;
for (i in gresults) {
ktype = gresults[i];
for (j in ktype) {
record = ktype[j];
self._ttl.remove(record);
}
}
if (!gresults) {
if (cb)
cb(gerr, gresults);
return;
}
self._store.delete(domain, key, type, function (err, results) {
if (cb)
cb(err, results);
});
});
};
var Cache = module.exports = function (opts) {
opts = opts || {};
this._zone = '.' || opts.zone;
this._store = undefined;
this.purge = function () {
this._store = new MemoryStoreExpire(opts.store || new MemoryStore(), this._zone, opts);
}
this.purge();
};
Cache.prototype.store = function (packet) {
var self = this;
var c = {};
function each(record) {
var r = c[record.name.toLowerCase()];
var t;
if (!r)
r = c[record.name.toLowerCase()] = {};
t = r[record.type];
if (!t)
t = r[record.type] = [];
t.push(record);
}
packet.answer.forEach(each);
packet.authority.forEach(each);
packet.additional.forEach(each);
Object.keys(c).forEach(function (key) {
self._store.set(self._zone, utils.ensure_absolute(key), c[key]);
});
};
Cache.prototype.lookup = function (question, cb) {
var self = this;
Lookup(this._store, this._zone, question, function (err, results) {
var i, record, found = false;
for (i in results) {
record = results[i];
if (record.type == question.type) {
found = true;
break;
}
}
if (results && !found) {
self._store.delete(self._zone, utils.ensure_absolute(question.name));
results.forEach(function (rr) {
self._store.delete(self._zone, utils.ensure_absolute(rr.name));
});
results = null;
}
cb(results);
});
};
},{"./lookup":26,"./memory":27,"binaryheap":28,"util":15}],25:[function(require,module,exports){
module.exports = require('./cache');
module.exports.MemoryStore = require('./memory').MemoryStore;
module.exports.Lookup = require('./lookup').Lookup;
module.exports.is_absolute = require('./lookup').is_absolute;
module.exports.ensure_absolute = require('./lookup').ensure_absolute;
},{"./cache":24,"./lookup":26,"./memory":27}],26:[function(require,module,exports){
// Copyright 2012 Timothy J Fontaine <tjfontaine@gmail.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
var dgram = require('dgram'),
EventEmitter = require('events').EventEmitter,
net = require('net'),
util = require('util');
var is_absolute = exports.is_absolute = function (f) {
return f && /\.$/.test(f);
};
var ensure_absolute = exports.ensure_absolute = function (f) {
if (!is_absolute(f))
return f += '.';
return f;
};
var CNAME = require('native-dns-packet').consts.NAME_TO_QTYPE.CNAME;
var Lookup = exports.Lookup = function (store, zone, question, cb) {
if (!(this instanceof Lookup))
return new Lookup(store, zone, question, cb);
this.store = store;
this.zone = zone;
this.cb = cb;
this.question = question;
this.results = [];
this.wildcard = undefined;
this.name = ensure_absolute(question.name);
this.store.get(this.zone, this.name, this.lookup.bind(this));
};
Lookup.prototype.send = function (err) {
this.cb(err, this.results);
};
Lookup.prototype.lookup = function (err, results) {
var type, ret, name, self = this;
if (err)
return this.send(err);
if (!results) {
if (!this.wildcard)
this.wildcard = this.question.name;
if (this.wildcard.toLowerCase() == this.zone.toLowerCase())
return this.send();
name = this.wildcard = this.wildcard.split('.').splice(1).join('.');
// 'com.'.split('.').splice(1) will return empty string, we're at the end
if (!this.wildcard)
return this.send();
name = '*.' + name;
} else if (results[this.question.type]) {
type = this.question.type;
ret = results;
} else if (results[CNAME]) {
type = CNAME;
ret = results;
this.name = name = results[CNAME][0].data
}
if (ret) {
ret = ret[type];
ret.forEach(function (r) {
var rr, k;
if (self.wildcard && /^\*/.test(r.name)) {
rr = {};
for (k in r) {
rr[k] = r[k];
}
rr.name = self.name;
} else {
rr = r;
}
self.results.push(rr);
});
}
if (name)
this.store.get(this.zone, ensure_absolute(name), this.lookup.bind(this));
else
this.send();
};
},{"dgram":2,"events":8,"native-dns-packet":30,"net":2,"util":15}],27:[function(require,module,exports){
(function (process){
// Copyright 2012 Timothy J Fontaine <tjfontaine@gmail.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
'use strict';
var MemoryStore = exports.MemoryStore = function (opts) {
this._store = {};
};
MemoryStore.prototype.get = function (domain, key, cb) {
var d = domain.toLowerCase();
var k = key.toLowerCase();
var result = this._store[d];
if (result)
result = result[k];
process.nextTick(function () {
cb(null, result);
});
};
MemoryStore.prototype.set = function (domain, key, data, cb) {
var d = domain.toLowerCase();
var k = key.toLowerCase();
var result_domain = this._store[d];
if (!result_domain)
result_domain = this._store[d] = {};
result_domain[k] = data;
if (cb) {
process.nextTick(function () {
cb(null, data);
});
}
};
MemoryStore.prototype.delete = function (domain, key, type, cb) {
var d, k;
if (!cb) {
cb = type;
type = undefined;
}
if (!cb) {
cb = key;
type = undefined;
}
d = this._store[domain.toLowerCase()];
if (d && key)
k = d[key.toLowerCase()];
if (domain && key && type) {
if (d && k) {
delete k[type];
}
} else if (domain && key) {
if (d) {
delete d[k];
}
} else if (domain) {
if (d) {
delete this._store[domain.toLowerCase()];
}
}
if (cb) {
process.nextTick(function () {
cb(null, domain);
});
}
};
}).call(this,require('_process'))
},{"_process":13}],28:[function(require,module,exports){
// Copyright 2012 Timothy J Fontaine <tjfontaine@gmail.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
'use strict';
var assert = require('assert');
var Heap = function(min) {
this.length = 0;
this.root = undefined;
if (min) {
this._comparator = this._smallest;
} else {
this._comparator = this._largest;
}
};
Heap.init = function(obj, key) {
obj._parent = null;
obj._left = null;
obj._right = null;
obj._key = key;
return obj;
};
Heap.prototype.count = function (node) {
if (!node) return 0;
var c = 1;
c += this.count(node._left);
c += this.count(node._right);
return c;
};
Heap.prototype.insert = function(obj, key) {
var insert, node;
this.length += 1;
node = Heap.init(obj, key);
if (!this.root) {
this.root = node;
} else {
insert = this._last();
node._parent = insert;
if (!insert._left)
insert._left = node;
else
insert._right = node;
this._up(node);
}
this._head();
return node;
};
Heap.prototype.pop = function() {
var ret, last;
if (!this.root)
return null;
return this.remove(this.root);
};
Heap.prototype.remove = function(node) {
var ret, last;
ret = node;
last = this._last();
if (last._right)
last = last._right;
else
last = last._left;
this.length -= 1;
if (!last) {
if (ret == this.root)
this.root = null;
return ret;
}
if (ret == last) {
if (ret._parent._left == node)
ret._parent._left = null;
else
ret._parent._right = null;
last = ret._parent;
ret._parent = null;
} else if (!ret._left && !ret._right) {
// we're trying to remove an element without any children and its not the last
// move the last under its parent and heap-up
if (last._parent._left == last) last._parent._left = null;
else last._parent._right = null;
if (ret._parent._left == ret) ret._parent._left = last;
else ret._parent._right = last;
last._parent = ret._parent;
ret._parent = null;
// TODO in this case we shouldn't later also do a down, but it should only visit once
this._up(last);
} else {
this._delete_swap(ret, last);
}
if (ret == this.root)
this.root = last;
this._down(last);
this._head();
return ret;
};
// TODO this probably isn't the most efficient way to ensure that we're always
// at the root of the tree, but it works for now
Heap.prototype._head = function() {
if (!this.root)
return;
var tmp = this.root;
while (tmp._parent) {
tmp = tmp._parent;
}
this.root = tmp;
};
// TODO is there a more efficient way to store this instead of an array?
Heap.prototype._last = function() {
var path, pos, mod, insert;
pos = this.length;
path = [];
while (pos > 1) {
mod = pos % 2;
pos = Math.floor(pos / 2);
path.push(mod);
}
insert = this.root;
while (path.length > 1) {
pos = path.pop();
if (pos === 0)
insert = insert._left;
else
insert = insert._right;
}
return insert;
};
Heap.prototype._swap = function(a, b) {
var cleft, cright, tparent;
cleft = b._left;
cright = b._right;
if (a._parent) {
if (a._parent._left == a) a._parent._left = b;
else a._parent._right = b;
}
b._parent = a._parent;
a._parent = b;
// This assumes direct descendents
if (a._left == b) {
b._left = a;
b._right = a._right;
if (b._right) b._right._parent = b;
} else {
b._right = a;
b._left = a._left;
if (b._left) b._left._parent = b;
}
a._left = cleft;
a._right = cright;
if (a._left) a._left._parent = a;
if (a._right) a._right._parent = a;
assert.notEqual(a._parent, a, "A shouldn't refer to itself");
assert.notEqual(b._parent, b, "B shouldn't refer to itself");
};
Heap.prototype._delete_swap = function(a, b) {
if (a._left != b) b._left = a._left;
if (a._right != b) b._right = a._right;
if (b._parent._left == b) b._parent._left = null;
else b._parent._right = null;
if (a._parent) {
if (a._parent._left == a) a._parent._left = b;
else a._parent._right = b;
}
b._parent = a._parent;
if (b._left) b._left._parent = b;
if (b._right) b._right._parent = b;
a._parent = null;
a._left = null;
a._right = null;
};
Heap.prototype._smallest = function(heap) {
var small = heap;
if (heap._left && heap._key > heap._left._key) {
small = heap._left;
}
if (heap._right && small._key > heap._right._key) {
small = heap._right;
}
return small;
};
Heap.prototype._largest = function(heap) {
var large = heap;
if (heap._left && heap._key < heap._left._key) {
large = heap._left;
}
if (heap._right && large._key < heap._right._key) {
large = heap._right;
}
return large;
};
Heap.prototype._up = function(node) {
if (!node || !node._parent)
return;
var next = this._comparator(node._parent);
if (next != node._parent) {
this._swap(node._parent, node);
this._up(node);
}
};
Heap.prototype._down = function(node) {
if (!node)
return;
var next = this._comparator(node);
if (next != node) {
this._swap(node, next);
this._down(node);
}
};
var util = require('util');
Heap.prototype.print = function(stream) {
stream.write('digraph {\n');
Heap._print(this.root, stream);
stream.write('}\n');
};
Heap._print = function(heap, stream) {
if (!heap) return;
if (heap._left) {
stream.write(util.format('' + heap._key, '->', heap._left._key, '\n'));
Heap._print(heap._left, stream);
}
if (heap._right) {
stream.write(util.format('' + heap._key, '->', heap._right._key, '\n'));
Heap._print(heap._right, stream);
}
};
module.exports = Heap;
},{"assert":3,"util":15}],29:[function(require,module,exports){
// Copyright 2011 Timothy J Fontaine <tjfontaine@gmail.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
'use strict';
function reverse_map(src) {
var dst = {},
k;
for (k in src) {
if (src.hasOwnProperty(k)) {
dst[src[k]] = k;
}
}
return dst;
}
/* http://www.iana.org/assignments/dns-parameters */
var NAME_TO_QTYPE = exports.NAME_TO_QTYPE = {
A: 1,
NS: 2,
MD: 3,
MF: 4,
CNAME: 5,
SOA: 6,
MB: 7,
MG: 8,
MR: 9,
'NULL': 10,
WKS: 11,
PTR: 12,
HINFO: 13,
MINFO: 14,
MX: 15,
TXT: 16,
RP: 17,
AFSDB: 18,
X25: 19,
ISDN: 20,
RT: 21,
NSAP: 22,
'NSAP-PTR': 23,
SIG: 24,
KEY: 25,
PX: 26,
GPOS: 27,
AAAA: 28,
LOC: 29,
NXT: 30,
EID: 31,
NIMLOC: 32,
SRV: 33,
ATMA: 34,
NAPTR: 35,
KX: 36,
CERT: 37,
A6: 38,
DNAME: 39,
SINK: 40,
OPT: 41,
APL: 42,
DS: 43,
SSHFP: 44,
IPSECKEY: 45,
RRSIG: 46,
NSEC: 47,
DNSKEY: 48,
DHCID: 49,
NSEC3: 50,
NSEC3PARAM: 51,
TLSA: 52,
HIP: 55,
NINFO: 56,
RKEY: 57,
TALINK: 58,
CDS: 59,
SPF: 99,
UINFO: 100,
UID: 101,
GID: 102,
UNSPEC: 103,
TKEY: 249,
TSIG: 250,
IXFR: 251,
AXFR: 252,
MAILB: 253,
MAILA: 254,
ANY: 255,
URI: 256,
CAA: 257,
TA: 32768,
DLV: 32769
};
exports.QTYPE_TO_NAME = reverse_map(NAME_TO_QTYPE);
exports.nameToQtype = function(n) {
return NAME_TO_QTYPE[n.toUpperCase()];
};
exports.qtypeToName = function(t) {
return exports.QTYPE_TO_NAME[t];
};
var NAME_TO_QCLASS = exports.NAME_TO_QCLASS = {
IN: 1
};
exports.QCLASS_TO_NAME = reverse_map(NAME_TO_QCLASS);
exports.FAMILY_TO_QTYPE = {
4: NAME_TO_QTYPE.A,
6: NAME_TO_QTYPE.AAAA
};
exports.QTYPE_TO_FAMILY = {};
exports.QTYPE_TO_FAMILY[exports.NAME_TO_QTYPE.A] = 4;
exports.QTYPE_TO_FAMILY[exports.NAME_TO_QTYPE.AAAA] = 6;
exports.NAME_TO_RCODE = {
NOERROR: 0,
FORMERR: 1,
SERVFAIL: 2,
NOTFOUND: 3,
NOTIMP: 4,
REFUSED: 5,
YXDOMAIN: 6, //Name Exists when it should not
YXRRSET: 7, //RR Set Exists when it should not
NXRRSET: 8, //RR Set that should exist does not
NOTAUTH: 9,
NOTZONE: 10,
BADVERS: 16,
BADSIG: 16, // really?
BADKEY: 17,
BADTIME: 18,
BADMODE: 19,
BADNAME: 20,
BADALG: 21,
BADTRUNC: 22
};
exports.RCODE_TO_NAME = reverse_map(exports.NAME_TO_RCODE);
exports.BADNAME = 'EBADNAME';
exports.BADRESP = 'EBADRESP';
exports.CONNREFUSED = 'ECONNREFUSED';
exports.DESTRUCTION = 'EDESTRUCTION';
exports.REFUSED = 'EREFUSED';
exports.FORMERR = 'EFORMERR';
exports.NODATA = 'ENODATA';
exports.NOMEM = 'ENOMEM';
exports.NOTFOUND = 'ENOTFOUND';
exports.NOTIMP = 'ENOTIMP';
exports.SERVFAIL = 'ESERVFAIL';
exports.TIMEOUT = 'ETIMEOUT';
},{}],30:[function(require,module,exports){
module.exports = require('./packet');
module.exports.consts = require('./consts');
},{"./consts":29,"./packet":35}],31:[function(require,module,exports){
// Copyright 2012 Timothy J Fontaine <tjfontaine@gmail.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
var util = require('util');
var VError = require('verror');
var BufferCursor = module.exports = function(buff, noAssert) {
if (!(this instanceof BufferCursor))
return new BufferCursor(buff, noAssert);
this._pos = 0;
this._noAssert = noAssert;
if (this._noAssert === undefined)
this._noAssert = true;
this.buffer = buff;
this.length = buff.length;
};
var BCO = BufferCursor.BufferCursorOverflow = function(length, pos, size) {
this.kind = 'BufferCursorOverflow';
this.length = length;
this.position = pos;
this.size = size;
VError.call(this,
'BufferCursorOverflow: length %d, position %d, size %d',
length,
pos,
size);
};
util.inherits(BCO, VError);
BufferCursor.prototype._move = function(step) {
this._checkWrite(step);
this._pos += step;
};
BufferCursor.prototype._checkWrite = function(size) {
var shouldThrow = false;
var length = this.length;
var pos = this._pos;
if (size > length)
shouldThrow = true;
if (length - pos < size)
shouldThrow = true;
if (shouldThrow) {
var bco = new BCO(length,
pos,
size);
throw bco;
}
}
BufferCursor.prototype.seek = function(pos) {
if (pos < 0)
throw new VError(new RangeError('Cannot seek before start of buffer'),
'Negative seek values not allowed: %d', pos);
if (pos > this.length)
throw new VError(new RangeError('Trying to seek beyond buffer'),
'Requested %d position is beyond length %d',
pos, this.length);
this._pos = pos;
return this;
};
BufferCursor.prototype.eof = function() {
return this._pos == this.length;
};
BufferCursor.prototype.toByteArray = function(method) {
var arr = [], i, part, count;
if (!method) {
method = 'readUInt8';
part = 1;
}
if (method.indexOf('16') > 0)
part = 2;
else if (method.indexOf('32') > 0)
part = 4;
count = this.length / part;
for (i = 0; i < this.buffer.length; i += part) {
arr.push(this.buffer[method](i));
}
return arr;
};
BufferCursor.prototype.tell = function() {
return this._pos;
};
BufferCursor.prototype.slice = function(length) {
var end, b;
if (length === undefined) {
end = this.length;
} else {
end = this._pos + length;
}
b = new BufferCursor(this.buffer.slice(this._pos, end));
this.seek(end);
return b;
};
BufferCursor.prototype.toString = function(encoding, length) {
var end, ret;
if (length === undefined) {
end = this.length;
} else {
end = this._pos + length;
}
if (!encoding) {
encoding = 'utf8';
}
ret = this.buffer.toString(encoding, this._pos, end);
this.seek(end);
return ret;
};
// This method doesn't need to _checkWrite because Buffer implicitly truncates
// to the length of the buffer, it's the only method in Node core that behaves
// this way by default
BufferCursor.prototype.write = function(value, length, encoding) {
var end, ret;
ret = this.buffer.write(value, this._pos, length, encoding);
this._move(ret);
return this;
};
BufferCursor.prototype.fill = function(value, length) {
var end;
if (length === undefined) {
end = this.length;
} else {
end = this._pos + length;
}
this._checkWrite(end - this._pos);
this.buffer.fill(value, this._pos, end);
this.seek(end);
return this;
};
// This prototype is not entirely like the upstream Buffer.copy, instead it
// is the target buffer, and accepts the source buffer -- since the target
// buffer knows its starting position
BufferCursor.prototype.copy = function copy(source, sourceStart, sourceEnd) {
var sBC = source instanceof BufferCursor;
if (isNaN(sourceEnd))
sourceEnd = source.length;
if (isNaN(sourceStart)) {
if (sBC)
sourceStart = source._pos;
else
sourceStart = 0;
}
var length = sourceEnd - sourceStart;
this._checkWrite(length);
var buf = sBC ? source.buffer : source;
buf.copy(this.buffer, this._pos, sourceStart, sourceEnd);
this._move(length);
return this;
};
BufferCursor.prototype.readUInt8 = function() {
var ret = this.buffer.readUInt8(this._pos, this._noAssert);
this._move(1);
return ret;
};
BufferCursor.prototype.readInt8 = function() {
var ret = this.buffer.readInt8(this._pos, this._noAssert);
this._move(1);
return ret;
};
BufferCursor.prototype.readInt16BE = function() {
var ret = this.buffer.readInt16BE(this._pos, this._noAssert);
this._move(2);
return ret;
};
BufferCursor.prototype.readInt16LE = function() {
var ret = this.buffer.readInt16LE(this._pos, this._noAssert);
this._move(2);
return ret;
};
BufferCursor.prototype.readUInt16BE = function() {
var ret = this.buffer.readUInt16BE(this._pos, this._noAssert);
this._move(2);
return ret;
};
BufferCursor.prototype.readUInt16LE = function() {
var ret = this.buffer.readUInt16LE(this._pos, this._noAssert);
this._move(2);
return ret;
};
BufferCursor.prototype.readUInt32LE = function() {
var ret = this.buffer.readUInt32LE(this._pos, this._noAssert);
this._move(4);
return ret;
};
BufferCursor.prototype.readUInt32BE = function() {
var ret = this.buffer.readUInt32BE(this._pos, this._noAssert);
this._move(4);
return ret;
};
BufferCursor.prototype.readInt32LE = function() {
var ret = this.buffer.readInt32LE(this._pos, this._noAssert);
this._move(4);
return ret;
};
BufferCursor.prototype.readInt32BE = function() {
var ret = this.buffer.readInt32BE(this._pos, this._noAssert);
this._move(4);
return ret;
};
BufferCursor.prototype.readFloatBE = function() {
var ret = this.buffer.readFloatBE(this._pos, this._noAssert);
this._move(4);
return ret;
};
BufferCursor.prototype.readFloatLE = function() {
var ret = this.buffer.readFloatLE(this._pos, this._noAssert);
this._move(4);
return ret;
};
BufferCursor.prototype.readDoubleBE = function() {
var ret = this.buffer.readDoubleBE(this._pos, this._noAssert);
this._move(8);
return ret;
};
BufferCursor.prototype.readDoubleLE = function() {
var ret = this.buffer.readDoubleLE(this._pos, this._noAssert);
this._move(8);
return ret;
};
BufferCursor.prototype.writeUInt8 = function(value) {
this._checkWrite(1);
this.buffer.writeUInt8(value, this._pos, this._noAssert);
this._move(1);
return this;
};
BufferCursor.prototype.writeInt8 = function(value) {
this._checkWrite(1);
this.buffer.writeInt8(value, this._pos, this._noAssert);
this._move(1);
return this;
};
BufferCursor.prototype.writeUInt16BE = function(value) {
this._checkWrite(2);
this.buffer.writeUInt16BE(value, this._pos, this._noAssert);
this._move(2);
return this;
};
BufferCursor.prototype.writeUInt16LE = function(value) {
this._checkWrite(2);
this.buffer.writeUInt16LE(value, this._pos, this._noAssert);
this._move(2);
return this;
};
BufferCursor.prototype.writeInt16BE = function(value) {
this._checkWrite(2);
this.buffer.writeInt16BE(value, this._pos, this._noAssert);
this._move(2);
return this;
};
BufferCursor.prototype.writeInt16LE = function(value) {
this._checkWrite(2);
this.buffer.writeInt16LE(value, this._pos, this._noAssert);
this._move(2);
return this;
};
BufferCursor.prototype.writeUInt32BE = function(value) {
this._checkWrite(4);
this.buffer.writeUInt32BE(value, this._pos, this._noAssert);
this._move(4);
return this;
};
BufferCursor.prototype.writeUInt32LE = function(value) {
this._checkWrite(4);
this.buffer.writeUInt32LE(value, this._pos, this._noAssert);
this._move(4);
return this;
};
BufferCursor.prototype.writeInt32BE = function(value) {
this._checkWrite(4);
this.buffer.writeInt32BE(value, this._pos, this._noAssert);
this._move(4);
return this;
};
BufferCursor.prototype.writeInt32LE = function(value) {
this._checkWrite(4);
this.buffer.writeInt32LE(value, this._pos, this._noAssert);
this._move(4);
return this;
};
BufferCursor.prototype.writeFloatBE = function(value) {
this._checkWrite(4);
this.buffer.writeFloatBE(value, this._pos, this._noAssert);
this._move(4);
return this;
};
BufferCursor.prototype.writeFloatLE = function(value) {
this._checkWrite(4);
this.buffer.writeFloatLE(value, this._pos, this._noAssert);
this._move(4);
return this;
};
BufferCursor.prototype.writeDoubleBE = function(value) {
this._checkWrite(8);
this.buffer.writeDoubleBE(value, this._pos, this._noAssert);
this._move(8);
return this;
};
BufferCursor.prototype.writeDoubleLE = function(value) {
this._checkWrite(8);
this.buffer.writeDoubleLE(value, this._pos, this._noAssert);
this._move(8);
return this;
};
},{"util":15,"verror":32}],32:[function(require,module,exports){
/*
* verror.js: richer JavaScript errors
*/
var mod_assert = require('assert');
var mod_util = require('util');
var mod_extsprintf = require('extsprintf');
var mod_isError = require('core-util-is').isError;
/*
* Public interface
*/
/* So you can 'var VError = require('verror')' */
module.exports = VError;
/* For compatibility */
VError.VError = VError;
/* Other exported classes */
VError.SError = SError;
VError.WError = WError;
VError.MultiError = MultiError;
/*
* VError([cause], fmt[, arg...]): Like JavaScript's built-in Error class, but
* supports a "cause" argument (another error) and a printf-style message. The
* cause argument can be null or omitted entirely.
*
* Examples:
*
* CODE MESSAGE
* new VError('something bad happened') "something bad happened"
* new VError('missing file: "%s"', file) "missing file: "/etc/passwd"
* with file = '/etc/passwd'
* new VError(err, 'open failed') "open failed: file not found"
* with err.message = 'file not found'
*/
function VError(options)
{
var args, obj, causedBy, ctor, tailmsg;
/*
* This is a regrettable pattern, but JavaScript's built-in Error class
* is defined to work this way, so we allow the constructor to be called
* without "new".
*/
if (!(this instanceof VError)) {
args = Array.prototype.slice.call(arguments, 0);
obj = Object.create(VError.prototype);
VError.apply(obj, arguments);
return (obj);
}
if (mod_isError(options) || typeof (options) === 'object') {
args = Array.prototype.slice.call(arguments, 1);
} else {
args = Array.prototype.slice.call(arguments, 0);
options = undefined;
}
/*
* extsprintf (which we invoke here with our caller's arguments in order
* to construct this Error's message) is strict in its interpretation of
* values to be processed by the "%s" specifier. The value passed to
* extsprintf must actually be a string or something convertible to a
* String using .toString(). Passing other values (notably "null" and
* "undefined") is considered a programmer error. The assumption is
* that if you actually want to print the string "null" or "undefined",
* then that's easy to do that when you're calling extsprintf; on the
* other hand, if you did NOT want that (i.e., there's actually a bug
* where the program assumes some variable is non-null and tries to
* print it, which might happen when constructing a packet or file in
* some specific format), then it's better to stop immediately than
* produce bogus output.
*
* However, sometimes the bug is only in the code calling VError, and a
* programmer might prefer to have the error message contain "null" or
* "undefined" rather than have the bug in the error path crash the
* program (making the first bug harder to identify). For that reason,
* by default VError converts "null" or "undefined" arguments to their
* string representations and passes those to extsprintf. Programmers
* desiring the strict behavior can use the SError class or pass the
* "strict" option to the VError constructor.
*/
if (!options || !options.strict) {
args = args.map(function (a) {
return (a === null ? 'null' :
a === undefined ? 'undefined' : a);
});
}
tailmsg = args.length > 0 ?
mod_extsprintf.sprintf.apply(null, args) : '';
this.jse_shortmsg = tailmsg;
this.jse_summary = tailmsg;
if (options) {
causedBy = options.cause;
if (!causedBy || !mod_isError(options.cause))
causedBy = options;
if (causedBy && mod_isError(causedBy)) {
this.jse_cause = causedBy;
this.jse_summary += ': ' + causedBy.message;
}
}
this.message = this.jse_summary;
Error.call(this, this.jse_summary);
if (Error.captureStackTrace) {
ctor = options ? options.constructorOpt : undefined;
ctor = ctor || arguments.callee;
Error.captureStackTrace(this, ctor);
}
return (this);
}
mod_util.inherits(VError, Error);
VError.prototype.name = 'VError';
VError.prototype.toString = function ve_toString()
{
var str = (this.hasOwnProperty('name') && this.name ||
this.constructor.name || this.constructor.prototype.name);
if (this.message)
str += ': ' + this.message;
return (str);
};
VError.prototype.cause = function ve_cause()
{
return (this.jse_cause);
};
/*
* SError is like VError, but stricter about types. You cannot pass "null" or
* "undefined" as string arguments to the formatter. Since SError is only a
* different function, not really a different class, we don't set
* SError.prototype.name.
*/
function SError()
{
var fmtargs, opts, key, args;
opts = {};
opts.constructorOpt = SError;
if (mod_isError(arguments[0])) {
opts.cause = arguments[0];
fmtargs = Array.prototype.slice.call(arguments, 1);
} else if (typeof (arguments[0]) == 'object') {
for (key in arguments[0])
opts[key] = arguments[0][key];
fmtargs = Array.prototype.slice.call(arguments, 1);
} else {
fmtargs = Array.prototype.slice.call(arguments, 0);
}
opts.strict = true;
args = [ opts ].concat(fmtargs);
VError.apply(this, args);
}
mod_util.inherits(SError, VError);
/*
* Represents a collection of errors for the purpose of consumers that generally
* only deal with one error. Callers can extract the individual errors
* contained in this object, but may also just treat it as a normal single
* error, in which case a summary message will be printed.
*/
function MultiError(errors)
{
mod_assert.ok(errors.length > 0);
this.ase_errors = errors;
VError.call(this, errors[0], 'first of %d error%s',
errors.length, errors.length == 1 ? '' : 's');
}
mod_util.inherits(MultiError, VError);
/*
* Like JavaScript's built-in Error class, but supports a "cause" argument which
* is wrapped, not "folded in" as with VError. Accepts a printf-style message.
* The cause argument can be null.
*/
function WError(options)
{
Error.call(this);
var args, cause, ctor;
if (typeof (options) === 'object') {
args = Array.prototype.slice.call(arguments, 1);
} else {
args = Array.prototype.slice.call(arguments, 0);
options = undefined;
}
if (args.length > 0) {
this.message = mod_extsprintf.sprintf.apply(null, args);
} else {
this.message = '';
}
if (options) {
if (mod_isError(options)) {
cause = options;
} else {
cause = options.cause;
ctor = options.constructorOpt;
}
}
Error.captureStackTrace(this, ctor || this.constructor);
if (cause)
this.cause(cause);
}
mod_util.inherits(WError, Error);
WError.prototype.name = 'WError';
WError.prototype.toString = function we_toString()
{
var str = (this.hasOwnProperty('name') && this.name ||
this.constructor.name || this.constructor.prototype.name);
if (this.message)
str += ': ' + this.message;
if (this.we_cause && this.we_cause.message)
str += '; caused by ' + this.we_cause.toString();
return (str);
};
WError.prototype.cause = function we_cause(c)
{
if (mod_isError(c))
this.we_cause = c;
return (this.we_cause);
};
},{"assert":3,"core-util-is":33,"extsprintf":34,"util":15}],33:[function(require,module,exports){
(function (Buffer){
// 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);
}
}).call(this,{"isBuffer":require("../../../../../../../../../../grunt-browserify/node_modules/browserify/node_modules/insert-module-globals/node_modules/is-buffer/index.js")})
},{"../../../../../../../../../../grunt-browserify/node_modules/browserify/node_modules/insert-module-globals/node_modules/is-buffer/index.js":10}],34:[function(require,module,exports){
(function (process){
/*
* extsprintf.js: extended POSIX-style sprintf
*/
var mod_assert = require('assert');
var mod_util = require('util');
/*
* Public interface
*/
exports.sprintf = jsSprintf;
exports.printf = jsPrintf;
/*
* Stripped down version of s[n]printf(3c). We make a best effort to throw an
* exception when given a format string we don't understand, rather than
* ignoring it, so that we won't break existing programs if/when we go implement
* the rest of this.
*
* This implementation currently supports specifying
* - field alignment ('-' flag),
* - zero-pad ('0' flag)
* - always show numeric sign ('+' flag),
* - field width
* - conversions for strings, decimal integers, and floats (numbers).
* - argument size specifiers. These are all accepted but ignored, since
* Javascript has no notion of the physical size of an argument.
*
* Everything else is currently unsupported, most notably precision, unsigned
* numbers, non-decimal numbers, and characters.
*/
function jsSprintf(fmt)
{
var regex = [
'([^%]*)', /* normal text */
'%', /* start of format */
'([\'\\-+ #0]*?)', /* flags (optional) */
'([1-9]\\d*)?', /* width (optional) */
'(\\.([1-9]\\d*))?', /* precision (optional) */
'[lhjztL]*?', /* length mods (ignored) */
'([diouxXfFeEgGaAcCsSp%jr])' /* conversion */
].join('');
var re = new RegExp(regex);
var args = Array.prototype.slice.call(arguments, 1);
var flags, width, precision, conversion;
var left, pad, sign, arg, match;
var ret = '';
var argn = 1;
mod_assert.equal('string', typeof (fmt));
while ((match = re.exec(fmt)) !== null) {
ret += match[1];
fmt = fmt.substring(match[0].length);
flags = match[2] || '';
width = match[3] || 0;
precision = match[4] || '';
conversion = match[6];
left = false;
sign = false;
pad = ' ';
if (conversion == '%') {
ret += '%';
continue;
}
if (args.length === 0)
throw (new Error('too few args to sprintf'));
arg = args.shift();
argn++;
if (flags.match(/[\' #]/))
throw (new Error(
'unsupported flags: ' + flags));
if (precision.length > 0)
throw (new Error(
'non-zero precision not supported'));
if (flags.match(/-/))
left = true;
if (flags.match(/0/))
pad = '0';
if (flags.match(/\+/))
sign = true;
switch (conversion) {
case 's':
if (arg === undefined || arg === null)
throw (new Error('argument ' + argn +
': attempted to print undefined or null ' +
'as a string'));
ret += doPad(pad, width, left, arg.toString());
break;
case 'd':
arg = Math.floor(arg);
/*jsl:fallthru*/
case 'f':
sign = sign && arg > 0 ? '+' : '';
ret += sign + doPad(pad, width, left,
arg.toString());
break;
case 'x':
ret += doPad(pad, width, left, arg.toString(16));
break;
case 'j': /* non-standard */
if (width === 0)
width = 10;
ret += mod_util.inspect(arg, false, width);
break;
case 'r': /* non-standard */
ret += dumpException(arg);
break;
default:
throw (new Error('unsupported conversion: ' +
conversion));
}
}
ret += fmt;
return (ret);
}
function jsPrintf() {
process.stdout.write(jsSprintf.apply(this, arguments));
}
function doPad(chr, width, left, str)
{
var ret = str;
while (ret.length < width) {
if (left)
ret += chr;
else
ret = chr + ret;
}
return (ret);
}
/*
* This function dumps long stack traces for exceptions having a cause() method.
* See node-verror for an example.
*/
function dumpException(ex)
{
var ret;
if (!(ex instanceof Error))
throw (new Error(jsSprintf('invalid type for %%r: %j', ex)));
/* Note that V8 prepends "ex.stack" with ex.toString(). */
ret = 'EXCEPTION: ' + ex.constructor.name + ': ' + ex.stack;
if (ex.cause && typeof (ex.cause) === 'function') {
var cex = ex.cause();
if (cex) {
ret += '\nCaused by: ' + dumpException(cex);
}
}
return (ret);
}
}).call(this,require('_process'))
},{"_process":13,"assert":3,"util":15}],35:[function(require,module,exports){
(function (Buffer){
// Copyright 2011 Timothy J Fontaine <tjfontaine@gmail.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
// TODO: change the default UDP packet size that node-dns sends
// from 4096 to conform to these:
// - [requestor's payload size](https://tools.ietf.org/html/rfc6891#section-6.2.3)
// - [responders's payload size](https://tools.ietf.org/html/rfc6891#section-6.2.4)
'use strict';
var consts = require('./consts'),
BufferCursor = require('buffercursor'),
BufferCursorOverflow = BufferCursor.BufferCursorOverflow,
ipaddr = require('ipaddr.js'),
assert = require('assert'),
util = require('util');
function assertUndefined(val, msg) {
assert(typeof val != 'undefined', msg);
}
var Packet = module.exports = function() {
this.header = {
id: 0,
qr: 0,
opcode: 0,
aa: 0,
tc: 0,
rd: 1,
ra: 0,
res1: 0,
res2: 0,
res3: 0,
rcode: 0
};
this.question = [];
this.answer = [];
this.authority = [];
this.additional = [];
this.edns_options = []; // TODO: DEPRECATED! Use `.edns.options` instead!
this.payload = undefined; // TODO: DEPRECATED! Use `.edns.payload` instead!
};
var LABEL_POINTER = 0xC0;
var isPointer = function(len) {
return (len & LABEL_POINTER) === LABEL_POINTER;
};
function nameUnpack(buff) {
var len, comp, end, pos, part, combine = '';
len = buff.readUInt8();
comp = false;
end = buff.tell();
while (len !== 0) {
if (isPointer(len)) {
len -= LABEL_POINTER;
len = len << 8;
pos = len + buff.readUInt8();
if (!comp)
end = buff.tell();
buff.seek(pos);
len = buff.readUInt8();
comp = true;
continue;
}
part = buff.toString('ascii', len);
if (combine.length)
combine = combine + '.' + part;
else
combine = part;
len = buff.readUInt8();
if (!comp)
end = buff.tell();
}
buff.seek(end);
return combine;
}
function namePack(str, buff, index) {
var offset, dot, part;
while (str) {
if (index[str]) {
offset = (LABEL_POINTER << 8) + index[str];
buff.writeUInt16BE(offset);
break;
} else {
index[str] = buff.tell();
dot = str.indexOf('.');
if (dot > -1) {
part = str.slice(0, dot);
str = str.slice(dot + 1);
} else {
part = str;
str = undefined;
}
buff.writeUInt8(part.length);
buff.write(part, part.length, 'ascii');
}
}
if (!str) {
buff.writeUInt8(0);
}
}
var
WRITE_HEADER = 100001,
WRITE_TRUNCATE = 100002,
WRITE_QUESTION = 100003,
WRITE_RESOURCE_RECORD = 100004,
WRITE_RESOURCE_WRITE = 100005,
WRITE_RESOURCE_DONE = 100006,
WRITE_RESOURCE_END = 100007,
WRITE_EDNS = 100008,
WRITE_END = 100009,
WRITE_A = consts.NAME_TO_QTYPE.A,
WRITE_AAAA = consts.NAME_TO_QTYPE.AAAA,
WRITE_NS = consts.NAME_TO_QTYPE.NS,
WRITE_CNAME = consts.NAME_TO_QTYPE.CNAME,
WRITE_PTR = consts.NAME_TO_QTYPE.PTR,
WRITE_SPF = consts.NAME_TO_QTYPE.SPF,
WRITE_MX = consts.NAME_TO_QTYPE.MX,
WRITE_SRV = consts.NAME_TO_QTYPE.SRV,
WRITE_TXT = consts.NAME_TO_QTYPE.TXT,
WRITE_SOA = consts.NAME_TO_QTYPE.SOA,
WRITE_OPT = consts.NAME_TO_QTYPE.OPT,
WRITE_NAPTR = consts.NAME_TO_QTYPE.NAPTR,
WRITE_TLSA = consts.NAME_TO_QTYPE.TLSA;
function writeHeader(buff, packet) {
assert(packet.header, 'Packet requires "header"');
buff.writeUInt16BE(packet.header.id & 0xFFFF);
var val = 0;
val += (packet.header.qr << 15) & 0x8000;
val += (packet.header.opcode << 11) & 0x7800;
val += (packet.header.aa << 10) & 0x400;
val += (packet.header.tc << 9) & 0x200;
val += (packet.header.rd << 8) & 0x100;
val += (packet.header.ra << 7) & 0x80;
val += (packet.header.res1 << 6) & 0x40;
val += (packet.header.res2 << 5) & 0x20;
val += (packet.header.res3 << 4) & 0x10;
val += packet.header.rcode & 0xF;
buff.writeUInt16BE(val & 0xFFFF);
assert(packet.question.length == 1, 'DNS requires one question');
// aren't used
buff.writeUInt16BE(1);
// answer offset 6
buff.writeUInt16BE(packet.answer.length & 0xFFFF);
// authority offset 8
buff.writeUInt16BE(packet.authority.length & 0xFFFF);
// additional offset 10
buff.writeUInt16BE(packet.additional.length & 0xFFFF);
return WRITE_QUESTION;
}
function writeTruncate(buff, packet, section, val) {
// XXX FIXME TODO truncation is currently done wrong.
// Quote rfc2181 section 9
// The TC bit should not be set merely because some extra information
// could have been included, but there was insufficient room. This
// includes the results of additional section processing. In such cases
// the entire RRSet that will not fit in the response should be omitted,
// and the reply sent as is, with the TC bit clear. If the recipient of
// the reply needs the omitted data, it can construct a query for that
// data and send that separately.
//
// TODO IOW only set TC if we hit it in ANSWERS otherwise make sure an
// entire RRSet is removed during a truncation.
var pos;
buff.seek(2);
val = buff.readUInt16BE();
val |= (1 << 9) & 0x200;
buff.seek(2);
buff.writeUInt16BE(val);
switch (section) {
case 'answer':
pos = 6;
// seek to authority and clear it and additional out
buff.seek(8);
buff.writeUInt16BE(0);
buff.writeUInt16BE(0);
break;
case 'authority':
pos = 8;
// seek to additional and clear it out
buff.seek(10);
buff.writeUInt16BE(0);
break;
case 'additional':
pos = 10;
break;
}
buff.seek(pos);
buff.writeUInt16BE(count - 1); // TODO: count not defined!
buff.seek(last_resource); // TODO: last_resource not defined!
return WRITE_END;
}
function writeQuestion(buff, val, label_index) {
assert(val, 'Packet requires a question');
assertUndefined(val.name, 'Question requires a "name"');
assertUndefined(val.type, 'Question requires a "type"');
assertUndefined(val.class, 'Questionn requires a "class"');
namePack(val.name, buff, label_index);
buff.writeUInt16BE(val.type & 0xFFFF);
buff.writeUInt16BE(val.class & 0xFFFF);
return WRITE_RESOURCE_RECORD;
}
function writeResource(buff, val, label_index, rdata) {
assert(val, 'Resource must be defined');
assertUndefined(val.name, 'Resource record requires "name"');
assertUndefined(val.type, 'Resource record requires "type"');
assertUndefined(val.class, 'Resource record requires "class"');
assertUndefined(val.ttl, 'Resource record requires "ttl"');
namePack(val.name, buff, label_index);
buff.writeUInt16BE(val.type & 0xFFFF);
buff.writeUInt16BE(val.class & 0xFFFF);
buff.writeUInt32BE(val.ttl & 0xFFFFFFFF);
rdata.pos = buff.tell();
buff.writeUInt16BE(0); // if there is rdata, then this value will be updated
// to the correct value by 'writeResourceDone'
return val.type;
}
function writeResourceDone(buff, rdata) {
var pos = buff.tell();
buff.seek(rdata.pos);
buff.writeUInt16BE(pos - rdata.pos - 2);
buff.seek(pos);
return WRITE_RESOURCE_RECORD;
}
function writeIp(buff, val) {
//TODO XXX FIXME -- assert that address is of proper type
assertUndefined(val.address, 'A/AAAA record requires "address"');
val = ipaddr.parse(val.address).toByteArray();
val.forEach(function(b) {
buff.writeUInt8(b);
});
return WRITE_RESOURCE_DONE;
}
function writeCname(buff, val, label_index) {
assertUndefined(val.data, 'NS/CNAME/PTR record requires "data"');
namePack(val.data, buff, label_index);
return WRITE_RESOURCE_DONE;
}
// For <character-string> see: http://tools.ietf.org/html/rfc1035#section-3.3
// For TXT: http://tools.ietf.org/html/rfc1035#section-3.3.14
function writeTxt(buff, val) {
//TODO XXX FIXME -- split on max char string and loop
assertUndefined(val.data, 'TXT record requires "data"');
for (var i=0,len=val.data.length; i<len; i++) {
var dataLen = Buffer.byteLength(val.data[i], 'utf8');
buff.writeUInt8(dataLen);
buff.write(val.data[i], dataLen, 'utf8');
}
return WRITE_RESOURCE_DONE;
}
function writeMx(buff, val, label_index) {
assertUndefined(val.priority, 'MX record requires "priority"');
assertUndefined(val.exchange, 'MX record requires "exchange"');
buff.writeUInt16BE(val.priority & 0xFFFF);
namePack(val.exchange, buff, label_index);
return WRITE_RESOURCE_DONE;
}
// SRV: https://tools.ietf.org/html/rfc2782
// TODO: SRV fixture failing for '_xmpp-server._tcp.gmail.com.srv.js'
function writeSrv(buff, val, label_index) {
assertUndefined(val.priority, 'SRV record requires "priority"');
assertUndefined(val.weight, 'SRV record requires "weight"');
assertUndefined(val.port, 'SRV record requires "port"');
assertUndefined(val.target, 'SRV record requires "target"');
buff.writeUInt16BE(val.priority & 0xFFFF);
buff.writeUInt16BE(val.weight & 0xFFFF);
buff.writeUInt16BE(val.port & 0xFFFF);
namePack(val.target, buff, label_index);
return WRITE_RESOURCE_DONE;
}
function writeSoa(buff, val, label_index) {
assertUndefined(val.primary, 'SOA record requires "primary"');
assertUndefined(val.admin, 'SOA record requires "admin"');
assertUndefined(val.serial, 'SOA record requires "serial"');
assertUndefined(val.refresh, 'SOA record requires "refresh"');
assertUndefined(val.retry, 'SOA record requires "retry"');
assertUndefined(val.expiration, 'SOA record requires "expiration"');
assertUndefined(val.minimum, 'SOA record requires "minimum"');
namePack(val.primary, buff, label_index);
namePack(val.admin, buff, label_index);
buff.writeUInt32BE(val.serial & 0xFFFFFFFF);
buff.writeInt32BE(val.refresh & 0xFFFFFFFF);
buff.writeInt32BE(val.retry & 0xFFFFFFFF);
buff.writeInt32BE(val.expiration & 0xFFFFFFFF);
buff.writeInt32BE(val.minimum & 0xFFFFFFFF);
return WRITE_RESOURCE_DONE;
}
// http://tools.ietf.org/html/rfc3403#section-4.1
function writeNaptr(buff, val, label_index) {
assertUndefined(val.order, 'NAPTR record requires "order"');
assertUndefined(val.preference, 'NAPTR record requires "preference"');
assertUndefined(val.flags, 'NAPTR record requires "flags"');
assertUndefined(val.service, 'NAPTR record requires "service"');
assertUndefined(val.regexp, 'NAPTR record requires "regexp"');
assertUndefined(val.replacement, 'NAPTR record requires "replacement"');
buff.writeUInt16BE(val.order & 0xFFFF);
buff.writeUInt16BE(val.preference & 0xFFFF);
buff.writeUInt8(val.flags.length);
buff.write(val.flags, val.flags.length, 'ascii');
buff.writeUInt8(val.service.length);
buff.write(val.service, val.service.length, 'ascii');
buff.writeUInt8(val.regexp.length);
buff.write(val.regexp, val.regexp.length, 'ascii');
namePack(val.replacement, buff, label_index);
return WRITE_RESOURCE_DONE;
}
// https://tools.ietf.org/html/rfc6698
function writeTlsa(buff, val) {
assertUndefined(val.usage, 'TLSA record requires "usage"');
assertUndefined(val.selector, 'TLSA record requires "selector"');
assertUndefined(val.matchingtype, 'TLSA record requires "matchingtype"');
assertUndefined(val.buff, 'TLSA record requires "buff"');
buff.writeUInt8(val.usage);
buff.writeUInt8(val.selector);
buff.writeUInt8(val.matchingtype);
buff.copy(val.buff);
return WRITE_RESOURCE_DONE;
}
function makeEdns(packet) {
packet.edns = {
name: '',
type: consts.NAME_TO_QTYPE.OPT,
class: packet.payload,
options: [],
ttl: 0
};
packet.edns_options = packet.edns.options; // TODO: 'edns_options' is DEPRECATED!
packet.additional.push(packet.edns);
return WRITE_HEADER;
}
function writeOpt(buff, val) {
var opt;
for (var i=0, len=val.options.length; i<len; i++) {
opt = val.options[i];
buff.writeUInt16BE(opt.code);
buff.writeUInt16BE(opt.data.length);
buff.copy(opt.data);
}
return WRITE_RESOURCE_DONE;
}
Packet.write = function(buff, packet) {
var state = WRITE_HEADER,
val,
section,
count,
rdata,
last_resource,
label_index = {};
buff = new BufferCursor(buff);
// the existence of 'edns' in a packet indicates that a proper OPT record exists
// in 'additional' and that all of the other fields in packet (that are parsed by
// 'parseOpt') are properly set. If it does not exist, we assume that the user
// is requesting that we create one for them.
if (typeof packet.edns_version !== 'undefined' && typeof packet.edns === "undefined")
state = makeEdns(packet);
// TODO: this is unnecessarily inefficient. rewrite this using a
// function table instead. (same for Packet.parse too).
while (true) {
try {
switch (state) {
case WRITE_HEADER:
state = writeHeader(buff, packet);
break;
case WRITE_TRUNCATE:
state = writeTruncate(buff, packet, section, last_resource);
break;
case WRITE_QUESTION:
state = writeQuestion(buff, packet.question[0], label_index);
section = 'answer';
count = 0;
break;
case WRITE_RESOURCE_RECORD:
last_resource = buff.tell();
if (packet[section].length == count) {
switch (section) {
case 'answer':
section = 'authority';
state = WRITE_RESOURCE_RECORD;
break;
case 'authority':
section = 'additional';
state = WRITE_RESOURCE_RECORD;
break;
case 'additional':
state = WRITE_END;
break;
}
count = 0;
} else {
state = WRITE_RESOURCE_WRITE;
}
break;
case WRITE_RESOURCE_WRITE:
rdata = {};
val = packet[section][count];
state = writeResource(buff, val, label_index, rdata);
break;
case WRITE_RESOURCE_DONE:
count += 1;
state = writeResourceDone(buff, rdata);
break;
case WRITE_A:
case WRITE_AAAA:
state = writeIp(buff, val);
break;
case WRITE_NS:
case WRITE_CNAME:
case WRITE_PTR:
state = writeCname(buff, val, label_index);
break;
case WRITE_SPF:
case WRITE_TXT:
state = writeTxt(buff, val);
break;
case WRITE_MX:
state = writeMx(buff, val, label_index);
break;
case WRITE_SRV:
state = writeSrv(buff, val, label_index);
break;
case WRITE_SOA:
state = writeSoa(buff, val, label_index);
break;
case WRITE_OPT:
state = writeOpt(buff, val);
break;
case WRITE_NAPTR:
state = writeNaptr(buff, val, label_index);
break;
case WRITE_TLSA:
state = writeTlsa(buff, val);
break;
case WRITE_END:
return buff.tell();
default:
if (typeof val.data !== 'object')
throw new Error('Packet.write Unknown State: ' + state);
// write unhandled RR type
buff.copy(val.data);
state = WRITE_RESOURCE_DONE;
}
} catch (e) {
if (e instanceof BufferCursorOverflow) {
state = WRITE_TRUNCATE;
} else {
throw e;
}
}
}
};
function parseHeader(msg, packet) {
packet.header.id = msg.readUInt16BE();
var val = msg.readUInt16BE();
packet.header.qr = (val & 0x8000) >> 15;
packet.header.opcode = (val & 0x7800) >> 11;
packet.header.aa = (val & 0x400) >> 10;
packet.header.tc = (val & 0x200) >> 9;
packet.header.rd = (val & 0x100) >> 8;
packet.header.ra = (val & 0x80) >> 7;
packet.header.res1 = (val & 0x40) >> 6;
packet.header.res2 = (val & 0x20) >> 5;
packet.header.res3 = (val & 0x10) >> 4;
packet.header.rcode = (val & 0xF);
packet.question = new Array(msg.readUInt16BE());
packet.answer = new Array(msg.readUInt16BE());
packet.authority = new Array(msg.readUInt16BE());
packet.additional = new Array(msg.readUInt16BE());
return PARSE_QUESTION;
}
function parseQuestion(msg, packet) {
var val = {};
val.name = nameUnpack(msg);
val.type = msg.readUInt16BE();
val.class = msg.readUInt16BE();
packet.question[0] = val;
assert(packet.question.length === 1);
// TODO handle qdcount > 1 in practice no one sends this
return PARSE_RESOURCE_RECORD;
}
function parseRR(msg, val, rdata) {
val.name = nameUnpack(msg);
val.type = msg.readUInt16BE();
val.class = msg.readUInt16BE();
val.ttl = msg.readUInt32BE();
rdata.len = msg.readUInt16BE();
return val.type;
}
function parseA(val, msg) {
var address = '' +
msg.readUInt8() +
'.' + msg.readUInt8() +
'.' + msg.readUInt8() +
'.' + msg.readUInt8();
val.address = address;
return PARSE_RESOURCE_DONE;
}
function parseAAAA(val, msg) {
var address = '';
var compressed = false;
for (var i = 0; i < 8; i++) {
if (i > 0) address += ':';
// TODO zero compression
address += msg.readUInt16BE().toString(16);
}
val.address = address;
return PARSE_RESOURCE_DONE;
}
function parseCname(val, msg) {
val.data = nameUnpack(msg);
return PARSE_RESOURCE_DONE;
}
function parseTxt(val, msg, rdata) {
val.data = [];
var end = msg.tell() + rdata.len;
while (msg.tell() != end) {
var len = msg.readUInt8();
val.data.push(msg.toString('utf8', len));
}
return PARSE_RESOURCE_DONE;
}
function parseMx(val, msg, rdata) {
val.priority = msg.readUInt16BE();
val.exchange = nameUnpack(msg);
return PARSE_RESOURCE_DONE;
}
// TODO: SRV fixture failing for '_xmpp-server._tcp.gmail.com.srv.js'
// https://tools.ietf.org/html/rfc2782
function parseSrv(val, msg) {
val.priority = msg.readUInt16BE();
val.weight = msg.readUInt16BE();
val.port = msg.readUInt16BE();
val.target = nameUnpack(msg);
return PARSE_RESOURCE_DONE;
}
function parseSoa(val, msg) {
val.primary = nameUnpack(msg);
val.admin = nameUnpack(msg);
val.serial = msg.readUInt32BE();
val.refresh = msg.readInt32BE();
val.retry = msg.readInt32BE();
val.expiration = msg.readInt32BE();
val.minimum = msg.readInt32BE();
return PARSE_RESOURCE_DONE;
}
// http://tools.ietf.org/html/rfc3403#section-4.1
function parseNaptr(val, msg) {
val.order = msg.readUInt16BE();
val.preference = msg.readUInt16BE();
var len = msg.readUInt8();
val.flags = msg.toString('ascii', len);
len = msg.readUInt8();
val.service = msg.toString('ascii', len);
len = msg.readUInt8();
val.regexp = msg.toString('ascii', len);
val.replacement = nameUnpack(msg);
return PARSE_RESOURCE_DONE;
}
function parseTlsa(val, msg, rdata) {
val.usage = msg.readUInt8();
val.selector = msg.readUInt8();
val.matchingtype = msg.readUInt8();
val.buff = msg.slice(rdata.len - 3).buffer; // 3 because of the 3 UInt8s above.
return PARSE_RESOURCE_DONE;
}
// https://tools.ietf.org/html/rfc6891#section-6.1.2
// https://tools.ietf.org/html/rfc2671#section-4.4
// - [payload size selection](https://tools.ietf.org/html/rfc6891#section-6.2.5)
function parseOpt(val, msg, rdata, packet) {
// assert first entry in additional
rdata.buf = msg.slice(rdata.len);
val.rcode = ((val.ttl & 0xFF000000) >> 20) + packet.header.rcode;
val.version = (val.ttl >> 16) & 0xFF;
val.do = (val.ttl >> 15) & 1;
val.z = val.ttl & 0x7F;
val.options = [];
packet.edns = val;
packet.edns_version = val.version; // TODO: return BADVERS for unsupported version! (Section 6.1.3)
// !! BEGIN DEPRECATION NOTICE !!
// THESE FIELDS MAY BE REMOVED IN THE FUTURE!
packet.edns_options = val.options;
packet.payload = val.class;
// !! END DEPRECATION NOTICE !!
while (!rdata.buf.eof()) {
val.options.push({
code: rdata.buf.readUInt16BE(),
data: rdata.buf.slice(rdata.buf.readUInt16BE()).buffer
});
}
return PARSE_RESOURCE_DONE;
}
var
PARSE_HEADER = 100000,
PARSE_QUESTION = 100001,
PARSE_RESOURCE_RECORD = 100002,
PARSE_RR_UNPACK = 100003,
PARSE_RESOURCE_DONE = 100004,
PARSE_END = 100005,
PARSE_A = consts.NAME_TO_QTYPE.A,
PARSE_NS = consts.NAME_TO_QTYPE.NS,
PARSE_CNAME = consts.NAME_TO_QTYPE.CNAME,
PARSE_SOA = consts.NAME_TO_QTYPE.SOA,
PARSE_PTR = consts.NAME_TO_QTYPE.PTR,
PARSE_MX = consts.NAME_TO_QTYPE.MX,
PARSE_TXT = consts.NAME_TO_QTYPE.TXT,
PARSE_AAAA = consts.NAME_TO_QTYPE.AAAA,
PARSE_SRV = consts.NAME_TO_QTYPE.SRV,
PARSE_NAPTR = consts.NAME_TO_QTYPE.NAPTR,
PARSE_OPT = consts.NAME_TO_QTYPE.OPT,
PARSE_SPF = consts.NAME_TO_QTYPE.SPF,
PARSE_TLSA = consts.NAME_TO_QTYPE.TLSA;
Packet.parse = function(msg) {
var state,
pos,
val,
rdata,
section,
count;
var packet = new Packet();
pos = 0;
state = PARSE_HEADER;
msg = new BufferCursor(msg);
while (true) {
switch (state) {
case PARSE_HEADER:
state = parseHeader(msg, packet);
break;
case PARSE_QUESTION:
state = parseQuestion(msg, packet);
section = 'answer';
count = 0;
break;
case PARSE_RESOURCE_RECORD:
// console.log('PARSE_RESOURCE_RECORD: count = %d, %s.len = %d', count, section, packet[section].length);
if (count === packet[section].length) {
switch (section) {
case 'answer':
section = 'authority';
count = 0;
break;
case 'authority':
section = 'additional';
count = 0;
break;
case 'additional':
state = PARSE_END;
break;
}
} else {
state = PARSE_RR_UNPACK;
}
break;
case PARSE_RR_UNPACK:
val = {};
rdata = {};
state = parseRR(msg, val, rdata);
break;
case PARSE_RESOURCE_DONE:
packet[section][count++] = val;
state = PARSE_RESOURCE_RECORD;
break;
case PARSE_A:
state = parseA(val, msg);
break;
case PARSE_AAAA:
state = parseAAAA(val, msg);
break;
case PARSE_NS:
case PARSE_CNAME:
case PARSE_PTR:
state = parseCname(val, msg);
break;
case PARSE_SPF:
case PARSE_TXT:
state = parseTxt(val, msg, rdata);
break;
case PARSE_MX:
state = parseMx(val, msg);
break;
case PARSE_SRV:
state = parseSrv(val, msg);
break;
case PARSE_SOA:
state = parseSoa(val, msg);
break;
case PARSE_OPT:
state = parseOpt(val, msg, rdata, packet);
break;
case PARSE_NAPTR:
state = parseNaptr(val, msg);
break;
case PARSE_TLSA:
state = parseTlsa(val, msg, rdata);
break;
case PARSE_END:
return packet;
default:
//console.log(state, val);
val.data = msg.slice(rdata.len);
state = PARSE_RESOURCE_DONE;
break;
}
}
};
}).call(this,require("buffer").Buffer)
},{"./consts":29,"assert":3,"buffer":4,"buffercursor":31,"ipaddr.js":23,"util":15}]},{},[1]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment