/**
* isomorph 0.3.0 - https://github.com/insin/isomorph
* MIT Licensed
*/
!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var o;"undefined"!=typeof window?o=window:"undefined"!=typeof global?o=global:"undefined"!=typeof self&&(o=self),o.isomorph=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o.
*/
// Re-usable constructor function used by clone()
function Clone() {}
// Clone objects, skip other types
function clone(target) {
if (typeof target == 'object') {
Clone.prototype = target
return new Clone()
}
else {
return target
}
}
// Shallow Copy
function copy(target) {
var c, property
if (typeof target != 'object') {
// Non-objects have value semantics, so target is already a copy
return target
}
else {
var value = target.valueOf()
if (target == value) {
// The object is a standard object wrapper for a native type, say String.
// we can make a copy by instantiating a new object around the value.
c = new target.constructor(value)
var notString = type(target) != 'string'
// Wrappers can have properties added to them
for (property in target) {
if (hasOwn.call(target, property) && (notString || !stringPropsRE.test(property))) {
c[property] = target[property]
}
}
return c
}
else {
// We have a normal object. If possible, we'll clone the original's
// prototype (not the original) to get an empty object with the same
// prototype chain as the original. If just copy the instance properties.
// Otherwise, we have to copy the whole thing, property-by-property.
if (target instanceof target.constructor && target.constructor !== Object) {
c = clone(target.constructor.prototype)
// Give the copy all the instance properties of target. It has the same
// prototype as target, so inherited properties are already there.
for (property in target) {
if (hasOwn.call(target, property)) {
c[property] = target[property]
}
}
}
else {
c = {}
for (property in target) {
c[property] = target[property]
}
}
return c
}
}
}
// Deep Copy
var deepCopiers = []
function DeepCopier(config) {
for (var key in config) {
this[key] = config[key]
}
}
DeepCopier.prototype = {
constructor: DeepCopier
// Determines if this DeepCopier can handle the given object.
, canCopy: function(source) { return false }
// Starts the deep copying process by creating the copy object. You can
// initialize any properties you want, but you can't call recursively into the
// DeepCopyAlgorithm.
, create: function(source) {}
// Completes the deep copy of the source object by populating any properties
// that need to be recursively deep copied. You can do this by using the
// provided deepCopyAlgorithm instance's deepCopy() method. This will handle
// cyclic references for objects already deepCopied, including the source
// object itself. The "result" passed in is the object returned from create().
, populate: function(deepCopyAlgorithm, source, result) {}
}
function DeepCopyAlgorithm() {
// copiedObjects keeps track of objects already copied by this deepCopy
// operation, so we can correctly handle cyclic references.
this.copiedObjects = []
var thisPass = this
this.recursiveDeepCopy = function(source) {
return thisPass.deepCopy(source)
}
this.depth = 0
}
DeepCopyAlgorithm.prototype = {
constructor: DeepCopyAlgorithm
, maxDepth: 256
// Add an object to the cache. No attempt is made to filter duplicates; we
// always check getCachedResult() before calling it.
, cacheResult: function(source, result) {
this.copiedObjects.push([source, result])
}
// Returns the cached copy of a given object, or undefined if it's an object
// we haven't seen before.
, getCachedResult: function(source) {
var copiedObjects = this.copiedObjects
var length = copiedObjects.length
for ( var i=0; i this.maxDepth) {
throw new Error("Exceeded max recursion depth in deep copy.")
}
// It's now safe to let the deepCopier recursively deep copy its properties
deepCopier.populate(this.recursiveDeepCopy, source, result)
this.depth--
return result
}
}
// Entry point for deep copy.
// source is the object to be deep copied.
// maxDepth is an optional recursion limit. Defaults to 256.
function deepCopy(source, maxDepth) {
var deepCopyAlgorithm = new DeepCopyAlgorithm()
if (maxDepth) {
deepCopyAlgorithm.maxDepth = maxDepth
}
return deepCopyAlgorithm.deepCopy(source)
}
// Publicly expose the DeepCopier class
deepCopy.DeepCopier = DeepCopier
// Publicly expose the list of deepCopiers
deepCopy.deepCopiers = deepCopiers
// Make deepCopy() extensible by allowing others to register their own custom
// DeepCopiers.
deepCopy.register = function(deepCopier) {
if (!(deepCopier instanceof DeepCopier)) {
deepCopier = new DeepCopier(deepCopier)
}
deepCopiers.unshift(deepCopier)
}
// Generic Object copier
// The ultimate fallback DeepCopier, which tries to handle the generic case.
// This should work for base Objects and many user-defined classes.
deepCopy.register({
canCopy: function(source) { return true }
, create: function(source) {
if (source instanceof source.constructor) {
return clone(source.constructor.prototype)
}
else {
return {}
}
}
, populate: function(deepCopy, source, result) {
for (var key in source) {
if (hasOwn.call(source, key)) {
result[key] = deepCopy(source[key])
}
}
return result
}
})
// Standard primitive wrapper copier
deepCopy.register({
canCopy: function(source) {
return primitiveWrapperTypes[type(source)]
}
, create: function(source) {
return new source.constructor(source.valueOf())
}
, populate: function(deepCopy, source, result) {
var notString = type(source) != 'string'
for (var key in source) {
if (hasOwn.call(source, key) && (notString || !stringPropsRE.test(key))) {
result[key] = deepCopy(source[key])
}
}
return result
}
})
// RegExp copier
deepCopy.register({
canCopy: function(source) {
return type(source) == 'regexp'
}
, create: function(source) {
return source
}
})
// Date copier
deepCopy.register({
canCopy: function(source) {
return type(source) == 'date'
}
, create: function(source) {
return new Date(source)
}
})
// Array copier
deepCopy.register({
canCopy: function(source) {
return type(source) == 'array'
}
, create: function(source) {
return new source.constructor()
}
, populate: function(deepCopy, source, result) {
for (var i = 0; i < source.length; i++) {
result.push(deepCopy(source[i]))
}
return result
}
})
module.exports = {
DeepCopyAlgorithm: DeepCopyAlgorithm
, copy: copy
, clone: clone
, deepCopy: deepCopy
}
},{}],4:[function(require,module,exports){
'use strict';
var slice = Array.prototype.slice
, formatRegExp = /%[%s]/g
, formatObjRegExp = /({{?)(\w+)}/g
/**
* Replaces %s placeholders in a string with positional arguments.
*/
function format(s) {
return formatArr(s, slice.call(arguments, 1))
}
/**
* Replaces %s placeholders in a string with array contents.
*/
function formatArr(s, a) {
var i = 0
return s.replace(formatRegExp, function(m) { return m == '%%' ? '%' : a[i++] })
}
/**
* Replaces {propertyName} placeholders in a string with object properties.
*/
function formatObj(s, o) {
return s.replace(formatObjRegExp, function(m, b, p) { return b.length == 2 ? m.slice(1) : o[p] })
}
var units = 'kMGTPEZY'
, stripDecimals = /\.00$|0$/
/**
* Formats bytes as a file size with the appropriately scaled units.
*/
function fileSize(bytes, threshold) {
threshold = Math.min(threshold || 768, 1024)
var i = -1
, unit = 'bytes'
, size = bytes
while (size > threshold && i < units.length) {
size = size / 1024
i++
}
if (i > -1) {
unit = units.charAt(i) + 'B'
}
return size.toFixed(2).replace(stripDecimals, '') + ' ' + unit
}
module.exports = {
format: format
, formatArr: formatArr
, formatObj: formatObj
, fileSize: fileSize
}
},{}],5:[function(require,module,exports){
'use strict';
var slice = Array.prototype.slice
/**
* Binds a function with a call context and (optionally) some partially applied
* arguments.
*/
function bind(fn, ctx) {
var partial = (arguments.length > 2 ? slice.call(arguments, 2) : null)
var f = function() {
var args = (partial ? partial.concat(slice.call(arguments)) : arguments)
return fn.apply(ctx, args)
}
f.__func__ = fn
f.__context__ = ctx
return f
}
module.exports = {
bind: bind
}
},{}],6:[function(require,module,exports){
'use strict';
var toString = Object.prototype.toString
// Type checks
function isArray(o) {
return toString.call(o) == '[object Array]'
}
function isBoolean(o) {
return toString.call(o) == '[object Boolean]'
}
function isDate(o) {
return toString.call(o) == '[object Date]'
}
function isError(o) {
return toString.call(o) == '[object Error]'
}
function isFunction(o) {
return toString.call(o) == '[object Function]'
}
function isNumber(o) {
return toString.call(o) == '[object Number]'
}
function isObject(o) {
return toString.call(o) == '[object Object]'
}
function isRegExp(o) {
return toString.call(o) == '[object RegExp]'
}
function isString(o) {
return toString.call(o) == '[object String]'
}
// Content checks
function isEmpty(o) {
/* jshint ignore:start */
for (var prop in o) {
return false
}
/* jshint ignore:end */
return true
}
module.exports = {
Array: isArray
, Boolean: isBoolean
, Date: isDate
, Empty: isEmpty
, Error: isError
, Function: isFunction
, NaN: isNaN
, Number: isNumber
, Object: isObject
, RegExp: isRegExp
, String: isString
}
},{}],7:[function(require,module,exports){
'use strict';
/**
* Wraps Object.prototype.hasOwnProperty() so it can be called with an object
* and property name.
*/
var hasOwn = (function() {
var hasOwnProperty = Object.prototype.hasOwnProperty
return function(obj, prop) { return hasOwnProperty.call(obj, prop) }
})()
/**
* Returns the type of an object as a lowercase string.
*/
var type = (function() {
var toString = Object.prototype.toString
return function(obj) { return toString.call(obj).slice(8, -1).toLowerCase() }
})()
/**
* Copies own properties from any given objects to a destination object.
*/
function extend(dest) {
for (var i = 1, l = arguments.length, src; i < l; i++) {
src = arguments[i]
if (src) {
for (var prop in src) {
if (hasOwn(src, prop)) {
dest[prop] = src[prop]
}
}
}
}
return dest
}
/**
* Makes a constructor inherit another constructor's prototype without
* having to actually use the constructor.
*/
function inherits(childConstructor, parentConstructor) {
var F = function() {}
F.prototype = parentConstructor.prototype
childConstructor.prototype = new F()
childConstructor.prototype.constructor = childConstructor
return childConstructor
}
/**
* Creates an Array of [property, value] pairs from an Object.
*/
function items(obj) {
var items_ = []
for (var prop in obj) {
if (hasOwn(obj, prop)) {
items_.push([prop, obj[prop]])
}
}
return items_
}
/**
* Creates an Object from an Array of [property, value] pairs.
*/
function fromItems(items) {
var obj = {}
for (var i = 0, l = items.length, item; i < l; i++) {
item = items[i]
obj[item[0]] = item[1]
}
return obj
}
/**
* Creates a lookup Object from an Array, coercing each item to a String.
*/
function lookup(arr) {
var obj = {}
for (var i = 0, l = arr.length; i < l; i++) {
obj[''+arr[i]] = true
}
return obj
}
/**
* If the given object has the given property, returns its value, otherwise
* returns the given default value.
*/
function get(obj, prop, defaultValue) {
return (hasOwn(obj, prop) ? obj[prop] : defaultValue)
}
/**
* Deletes and returns an own property from an object, optionally returning a
* default value if the object didn't have theproperty.
* @throws if given an object which is null (or undefined), or if the property
* doesn't exist and there was no defaultValue given.
*/
function pop(obj, prop, defaultValue) {
if (obj == null) {
throw new Error('pop was given ' + obj)
}
if (hasOwn(obj, prop)) {
var value = obj[prop]
delete obj[prop]
return value
}
else if (arguments.length == 2) {
throw new Error("pop was given an object which didn't have an own '" +
prop + "' property, without a default value to return")
}
return defaultValue
}
/**
* If the prop is in the object, return its value. If not, set the prop to
* defaultValue and return defaultValue.
*/
function setDefault(obj, prop, defaultValue) {
if (obj == null) {
throw new Error('setDefault was given ' + obj)
}
defaultValue = defaultValue || null
if (hasOwn(obj, prop)) {
return obj[prop]
}
else {
obj[prop] = defaultValue
return defaultValue
}
}
module.exports = {
hasOwn: hasOwn
, type: type
, extend: extend
, inherits: inherits
, items: items
, fromItems: fromItems
, lookup: lookup
, get: get
, pop: pop
, setDefault: setDefault
}
},{}],8:[function(require,module,exports){
'use strict';
var is = require('./is')
/**
* Creates an Object from a query string, providing values for names which are
* present more than once as an Array.
*/
function parse(query) {
var obj = {}
if (query.length < 2) {
return obj
}
var params = query.substring(1).split('&')
for (var i = 0, l = params.length; i < l; i++) {
var parts = params[i].split('=')
, name = parts[0]
, value = decodeURIComponent(parts[1])
if (obj.hasOwnProperty(name)) {
if (is.Array(obj[name])) {
obj[name].push(value)
}
else {
obj[name] = [obj[name], value]
}
}
else {
obj[name] = value
}
}
return obj
}
/**
* Creates a query string from an Object, expecting names with multiple values
* to be specified as an Array.
*/
function stringify(obj) {
var params = []
for (var name in obj) {
if (is.Array(obj[name])) {
for (var a = obj[name], i = 0, l = a.length; i < l; i++) {
params.push(name + '=' + encodeURIComponent(a[i]))
}
}
else {
params.push(name + '=' + encodeURIComponent(obj[name]))
}
}
return params.join('&')
}
module.exports = {
parse: parse
, stringify: stringify
}
},{"./is":6}],9:[function(require,module,exports){
'use strict';
var is = require('./is')
/**
* Finds all matches againt a RegExp, returning captured groups if present.
*/
function findAll(re, str, flags) {
if (!is.RegExp(re)) {
re = new RegExp(re, flags)
}
var match = null
, matches = []
while ((match = re.exec(str)) !== null) {
switch (match.length) {
case 1:
matches.push(match[0])
break
case 2:
matches.push(match[1])
break
default:
matches.push(match.slice(1))
}
if (!re.global) {
break
}
}
return matches
}
module.exports = {
findAll: findAll
}
},{"./is":6}],10:[function(require,module,exports){
'use strict';
var is = require('./is')
/**
* Pads a number with a leading zero if necessary.
*/
function pad(number) {
return (number < 10 ? '0' + number : number)
}
/**
* Returns the index of item in list, or -1 if it's not in list.
*/
function indexOf(item, list) {
for (var i = 0, l = list.length; i < l; i++) {
if (item === list[i]) {
return i
}
}
return -1
}
/**
* Maps directive codes to regular expression patterns which will capture the
* data the directive corresponds to, or in the case of locale-dependent
* directives, a function which takes a locale and generates a regular
* expression pattern.
*/
var parserDirectives = {
// Locale's abbreviated month name
'b': function(l) { return '(' + l.b.join('|') + ')' }
// Locale's full month name
, 'B': function(l) { return '(' + l.B.join('|') + ')' }
// Locale's equivalent of either AM or PM.
, 'p': function(l) { return '(' + l.AM + '|' + l.PM + ')' }
, 'd': '(\\d\\d?)' // Day of the month as a decimal number [01,31]
, 'H': '(\\d\\d?)' // Hour (24-hour clock) as a decimal number [00,23]
, 'I': '(\\d\\d?)' // Hour (12-hour clock) as a decimal number [01,12]
, 'm': '(\\d\\d?)' // Month as a decimal number [01,12]
, 'M': '(\\d\\d?)' // Minute as a decimal number [00,59]
, 'S': '(\\d\\d?)' // Second as a decimal number [00,59]
, 'y': '(\\d\\d?)' // Year without century as a decimal number [00,99]
, 'Y': '(\\d{4})' // Year with century as a decimal number
, '%': '%' // A literal '%' character
}
/**
* Maps directive codes to functions which take the date to be formatted and
* locale details (if required), returning an appropriate formatted value.
*/
var formatterDirectives = {
'a': function(d, l) { return l.a[d.getDay()] }
, 'A': function(d, l) { return l.A[d.getDay()] }
, 'b': function(d, l) { return l.b[d.getMonth()] }
, 'B': function(d, l) { return l.B[d.getMonth()] }
, 'd': function(d) { return pad(d.getDate(), 2) }
, 'H': function(d) { return pad(d.getHours(), 2) }
, 'M': function(d) { return pad(d.getMinutes(), 2) }
, 'm': function(d) { return pad(d.getMonth() + 1, 2) }
, 'S': function(d) { return pad(d.getSeconds(), 2) }
, 'w': function(d) { return d.getDay() }
, 'Y': function(d) { return d.getFullYear() }
, '%': function(d) { return '%' }
}
/** Test for hanging percentage symbols. */
var strftimeFormatCheck = /[^%]%$/
/**
* A partial implementation of strptime which parses time details from a string,
* based on a format string.
* @param {String} format
* @param {Object} locale
*/
function TimeParser(format, locale) {
this.format = format
this.locale = locale
var cachedPattern = TimeParser._cache[locale.name + '|' + format]
if (cachedPattern !== undefined) {
this.re = cachedPattern[0]
this.matchOrder = cachedPattern[1]
}
else {
this.compilePattern()
}
}
/**
* Caches RegExps and match orders generated per locale/format string combo.
*/
TimeParser._cache = {}
TimeParser.prototype.compilePattern = function() {
// Normalise whitespace before further processing
var format = this.format.split(/(?:\s|\t|\n)+/).join(' ')
, pattern = []
, matchOrder = []
, c
, directive
for (var i = 0, l = format.length; i < l; i++) {
c = format.charAt(i)
if (c != '%') {
if (c === ' ') {
pattern.push(' +')
}
else {
pattern.push(c)
}
continue
}
if (i == l - 1) {
throw new Error('strptime format ends with raw %')
}
c = format.charAt(++i)
directive = parserDirectives[c]
if (directive === undefined) {
throw new Error('strptime format contains an unknown directive: %' + c)
}
else if (is.Function(directive)) {
pattern.push(directive(this.locale))
}
else {
pattern.push(directive)
}
if (c != '%') {
matchOrder.push(c)
}
}
this.re = new RegExp('^' + pattern.join('') + '$')
this.matchOrder = matchOrder
TimeParser._cache[this.locale.name + '|' + this.format] = [this.re, matchOrder]
}
/**
* Attempts to extract date and time details from the given input.
* @param {string} input
* @return {Array.}
*/
TimeParser.prototype.parse = function(input) {
var matches = this.re.exec(input)
if (matches === null) {
throw new Error('Time data did not match format: data=' + input +
', format=' + this.format)
}
// Default values for when more accurate values cannot be inferred
var time = [1900, 1, 1, 0, 0, 0]
// Matched time data, keyed by directive code
, data = {}
for (var i = 1, l = matches.length; i < l; i++) {
data[this.matchOrder[i - 1]] = matches[i]
}
// Extract year
if (data.hasOwnProperty('Y')) {
time[0] = parseInt(data.Y, 10)
}
else if (data.hasOwnProperty('y')) {
var year = parseInt(data.y, 10)
if (year < 68) {
year = 2000 + year
}
else if (year < 100) {
year = 1900 + year
}
time[0] = year
}
// Extract month
if (data.hasOwnProperty('m')) {
var month = parseInt(data.m, 10)
if (month < 1 || month > 12) {
throw new Error('Month is out of range: ' + month)
}
time[1] = month
}
else if (data.hasOwnProperty('B')) {
time[1] = indexOf(data.B, this.locale.B) + 1
}
else if (data.hasOwnProperty('b')) {
time[1] = indexOf(data.b, this.locale.b) + 1
}
// Extract day of month
if (data.hasOwnProperty('d')) {
var day = parseInt(data.d, 10)
if (day < 1 || day > 31) {
throw new Error('Day is out of range: ' + day)
}
time[2] = day
}
// Extract hour
var hour
if (data.hasOwnProperty('H')) {
hour = parseInt(data.H, 10)
if (hour > 23) {
throw new Error('Hour is out of range: ' + hour)
}
time[3] = hour
}
else if (data.hasOwnProperty('I')) {
hour = parseInt(data.I, 10)
if (hour < 1 || hour > 12) {
throw new Error('Hour is out of range: ' + hour)
}
// If we don't get any more information, we'll assume this time is
// a.m. - 12 a.m. is midnight.
if (hour == 12) {
hour = 0
}
time[3] = hour
if (data.hasOwnProperty('p')) {
if (data.p == this.locale.PM) {
// We've already handled the midnight special case, so it's
// safe to bump the time by 12 hours without further checks.
time[3] = time[3] + 12
}
}
}
// Extract minute
if (data.hasOwnProperty('M')) {
var minute = parseInt(data.M, 10)
if (minute > 59) {
throw new Error('Minute is out of range: ' + minute)
}
time[4] = minute
}
// Extract seconds
if (data.hasOwnProperty('S')) {
var second = parseInt(data.S, 10)
if (second > 59) {
throw new Error('Second is out of range: ' + second)
}
time[5] = second
}
// Validate day of month
day = time[2], month = time[1], year = time[0]
if (((month == 4 || month == 6 || month == 9 || month == 11) &&
day > 30) ||
(month == 2 && day > ((year % 4 === 0 && year % 100 !== 0 ||
year % 400 === 0) ? 29 : 28))) {
throw new Error('Day is out of range: ' + day)
}
return time
}
var time = {
/** Default locale name. */
defaultLocale: 'en'
/** Locale details. */
, locales: {
en: {
name: 'en'
, a: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
, A: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday',
'Friday', 'Saturday']
, AM: 'AM'
, b: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
'Oct', 'Nov', 'Dec']
, B: ['January', 'February', 'March', 'April', 'May', 'June', 'July',
'August', 'September', 'October', 'November', 'December']
, PM: 'PM'
}
}
}
/**
* Retrieves the locale with the given code.
* @param {string} code
* @return {Object}
*/
var getLocale = time.getLocale = function(code) {
if (code) {
if (time.locales.hasOwnProperty(code)) {
return time.locales[code]
}
else if (code.length > 2) {
// If we appear to have more than a language code, try the
// language code on its own.
var languageCode = code.substring(0, 2)
if (time.locales.hasOwnProperty(languageCode)) {
return time.locales[languageCode]
}
}
}
return time.locales[time.defaultLocale]
}
/**
* Parses time details from a string, based on a format string.
* @param {string} input
* @param {string} format
* @param {string=} locale
* @return {Array.}
*/
var strptime = time.strptime = function(input, format, locale) {
return new TimeParser(format, getLocale(locale)).parse(input)
}
/**
* Convenience wrapper around time.strptime which returns a JavaScript Date.
* @param {string} input
* @param {string} format
* @param {string=} locale
* @return {date}
*/
time.strpdate = function(input, format, locale) {
var t = strptime(input, format, locale)
return new Date(t[0], t[1] - 1, t[2], t[3], t[4], t[5])
}
/**
* A partial implementation of strftime
, which formats a date
* according to a format string. An Error will be thrown if an invalid
* format string is given.
* @param {date} date
* @param {string} format
* @param {string=} locale
* @return {string}
*/
time.strftime = function(date, format, locale) {
if (strftimeFormatCheck.test(format)) {
throw new Error('strftime format ends with raw %')
}
locale = getLocale(locale)
return format.replace(/(%.)/g, function(s, f) {
var code = f.charAt(1)
if (typeof formatterDirectives[code] == 'undefined') {
throw new Error('strftime format contains an unknown directive: ' + f)
}
return formatterDirectives[code](date, locale)
})
}
module.exports = time
},{"./is":6}],11:[function(require,module,exports){
'use strict';
// parseUri 1.2.2
// (c) Steven Levithan
// MIT License
function parseUri (str) {
var o = parseUri.options
, m = o.parser[o.strictMode ? "strict" : "loose"].exec(str)
, uri = {}
, i = 14
while (i--) { uri[o.key[i]] = m[i] || "" }
uri[o.q.name] = {};
uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
if ($1) { uri[o.q.name][$1] = $2 }
})
return uri
}
parseUri.options = {
strictMode: false
, key: ['source','protocol','authority','userInfo','user','password','host','port','relative','path','directory','file','query','anchor']
, q: {
name: 'queryKey'
, parser: /(?:^|&)([^&=]*)=?([^&]*)/g
}
, parser: {
strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/
, loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
}
}
// makeURI 1.2.2 - create a URI from an object specification; compatible with
// parseURI (http://blog.stevenlevithan.com/archives/parseuri)
// (c) Niall Smart
// MIT License
function makeUri(u) {
var uri = ''
if (u.protocol) {
uri += u.protocol + '://'
}
if (u.user) {
uri += u.user
}
if (u.password) {
uri += ':' + u.password
}
if (u.user || u.password) {
uri += '@'
}
if (u.host) {
uri += u.host
}
if (u.port) {
uri += ':' + u.port
}
if (u.path) {
uri += u.path
}
var qk = u.queryKey
var qs = []
for (var k in qk) {
if (!qk.hasOwnProperty(k)) {
continue
}
var v = encodeURIComponent(qk[k])
k = encodeURIComponent(k)
if (v) {
qs.push(k + '=' + v)
}
else {
qs.push(k)
}
}
if (qs.length > 0) {
uri += '?' + qs.join('&')
}
if (u.anchor) {
uri += '#' + u.anchor
}
return uri
}
module.exports = {
parseUri: parseUri
, makeUri: makeUri
}
},{}]},{},[1])(1)
});