'use strict';
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								module.exports = {
							 | 
						|
								  copy: copy,
							 | 
						|
								  checkDataType: checkDataType,
							 | 
						|
								  checkDataTypes: checkDataTypes,
							 | 
						|
								  coerceToTypes: coerceToTypes,
							 | 
						|
								  toHash: toHash,
							 | 
						|
								  getProperty: getProperty,
							 | 
						|
								  escapeQuotes: escapeQuotes,
							 | 
						|
								  equal: require('fast-deep-equal'),
							 | 
						|
								  ucs2length: require('./ucs2length'),
							 | 
						|
								  varOccurences: varOccurences,
							 | 
						|
								  varReplace: varReplace,
							 | 
						|
								  schemaHasRules: schemaHasRules,
							 | 
						|
								  schemaHasRulesExcept: schemaHasRulesExcept,
							 | 
						|
								  schemaUnknownRules: schemaUnknownRules,
							 | 
						|
								  toQuotedString: toQuotedString,
							 | 
						|
								  getPathExpr: getPathExpr,
							 | 
						|
								  getPath: getPath,
							 | 
						|
								  getData: getData,
							 | 
						|
								  unescapeFragment: unescapeFragment,
							 | 
						|
								  unescapeJsonPointer: unescapeJsonPointer,
							 | 
						|
								  escapeFragment: escapeFragment,
							 | 
						|
								  escapeJsonPointer: escapeJsonPointer
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								function copy(o, to) {
							 | 
						|
								  to = to || {};
							 | 
						|
								  for (var key in o) to[key] = o[key];
							 | 
						|
								  return to;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								function checkDataType(dataType, data, strictNumbers, negate) {
							 | 
						|
								  var EQUAL = negate ? ' !== ' : ' === '
							 | 
						|
								    , AND = negate ? ' || ' : ' && '
							 | 
						|
								    , OK = negate ? '!' : ''
							 | 
						|
								    , NOT = negate ? '' : '!';
							 | 
						|
								  switch (dataType) {
							 | 
						|
								    case 'null': return data + EQUAL + 'null';
							 | 
						|
								    case 'array': return OK + 'Array.isArray(' + data + ')';
							 | 
						|
								    case 'object': return '(' + OK + data + AND +
							 | 
						|
								                          'typeof ' + data + EQUAL + '"object"' + AND +
							 | 
						|
								                          NOT + 'Array.isArray(' + data + '))';
							 | 
						|
								    case 'integer': return '(typeof ' + data + EQUAL + '"number"' + AND +
							 | 
						|
								                           NOT + '(' + data + ' % 1)' +
							 | 
						|
								                           AND + data + EQUAL + data +
							 | 
						|
								                           (strictNumbers ? (AND + OK + 'isFinite(' + data + ')') : '') + ')';
							 | 
						|
								    case 'number': return '(typeof ' + data + EQUAL + '"' + dataType + '"' +
							 | 
						|
								                          (strictNumbers ? (AND + OK + 'isFinite(' + data + ')') : '') + ')';
							 | 
						|
								    default: return 'typeof ' + data + EQUAL + '"' + dataType + '"';
							 | 
						|
								  }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								function checkDataTypes(dataTypes, data, strictNumbers) {
							 | 
						|
								  switch (dataTypes.length) {
							 | 
						|
								    case 1: return checkDataType(dataTypes[0], data, strictNumbers, true);
							 | 
						|
								    default:
							 | 
						|
								      var code = '';
							 | 
						|
								      var types = toHash(dataTypes);
							 | 
						|
								      if (types.array && types.object) {
							 | 
						|
								        code = types.null ? '(': '(!' + data + ' || ';
							 | 
						|
								        code += 'typeof ' + data + ' !== "object")';
							 | 
						|
								        delete types.null;
							 | 
						|
								        delete types.array;
							 | 
						|
								        delete types.object;
							 | 
						|
								      }
							 | 
						|
								      if (types.number) delete types.integer;
							 | 
						|
								      for (var t in types)
							 | 
						|
								        code += (code ? ' && ' : '' ) + checkDataType(t, data, strictNumbers, true);
							 | 
						|
								
							 | 
						|
								      return code;
							 | 
						|
								  }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								var COERCE_TO_TYPES = toHash([ 'string', 'number', 'integer', 'boolean', 'null' ]);
							 | 
						|
								function coerceToTypes(optionCoerceTypes, dataTypes) {
							 | 
						|
								  if (Array.isArray(dataTypes)) {
							 | 
						|
								    var types = [];
							 | 
						|
								    for (var i=0; i<dataTypes.length; i++) {
							 | 
						|
								      var t = dataTypes[i];
							 | 
						|
								      if (COERCE_TO_TYPES[t]) types[types.length] = t;
							 | 
						|
								      else if (optionCoerceTypes === 'array' && t === 'array') types[types.length] = t;
							 | 
						|
								    }
							 | 
						|
								    if (types.length) return types;
							 | 
						|
								  } else if (COERCE_TO_TYPES[dataTypes]) {
							 | 
						|
								    return [dataTypes];
							 | 
						|
								  } else if (optionCoerceTypes === 'array' && dataTypes === 'array') {
							 | 
						|
								    return ['array'];
							 | 
						|
								  }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								function toHash(arr) {
							 | 
						|
								  var hash = {};
							 | 
						|
								  for (var i=0; i<arr.length; i++) hash[arr[i]] = true;
							 | 
						|
								  return hash;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								var IDENTIFIER = /^[a-z$_][a-z$_0-9]*$/i;
							 | 
						|
								var SINGLE_QUOTE = /'|\\/g;
							 | 
						|
								function getProperty(key) {
							 | 
						|
								  return typeof key == 'number'
							 | 
						|
								          ? '[' + key + ']'
							 | 
						|
								          : IDENTIFIER.test(key)
							 | 
						|
								            ? '.' + key
							 | 
						|
								            : "['" + escapeQuotes(key) + "']";
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								function escapeQuotes(str) {
							 | 
						|
								  return str.replace(SINGLE_QUOTE, '\\$&')
							 | 
						|
								            .replace(/\n/g, '\\n')
							 | 
						|
								            .replace(/\r/g, '\\r')
							 | 
						|
								            .replace(/\f/g, '\\f')
							 | 
						|
								            .replace(/\t/g, '\\t');
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								function varOccurences(str, dataVar) {
							 | 
						|
								  dataVar += '[^0-9]';
							 | 
						|
								  var matches = str.match(new RegExp(dataVar, 'g'));
							 | 
						|
								  return matches ? matches.length : 0;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								function varReplace(str, dataVar, expr) {
							 | 
						|
								  dataVar += '([^0-9])';
							 | 
						|
								  expr = expr.replace(/\$/g, '$$$$');
							 | 
						|
								  return str.replace(new RegExp(dataVar, 'g'), expr + '$1');
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								function schemaHasRules(schema, rules) {
							 | 
						|
								  if (typeof schema == 'boolean') return !schema;
							 | 
						|
								  for (var key in schema) if (rules[key]) return true;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								function schemaHasRulesExcept(schema, rules, exceptKeyword) {
							 | 
						|
								  if (typeof schema == 'boolean') return !schema && exceptKeyword != 'not';
							 | 
						|
								  for (var key in schema) if (key != exceptKeyword && rules[key]) return true;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								function schemaUnknownRules(schema, rules) {
							 | 
						|
								  if (typeof schema == 'boolean') return;
							 | 
						|
								  for (var key in schema) if (!rules[key]) return key;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								function toQuotedString(str) {
							 | 
						|
								  return '\'' + escapeQuotes(str) + '\'';
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								function getPathExpr(currentPath, expr, jsonPointers, isNumber) {
							 | 
						|
								  var path = jsonPointers // false by default
							 | 
						|
								              ? '\'/\' + ' + expr + (isNumber ? '' : '.replace(/~/g, \'~0\').replace(/\\//g, \'~1\')')
							 | 
						|
								              : (isNumber ? '\'[\' + ' + expr + ' + \']\'' : '\'[\\\'\' + ' + expr + ' + \'\\\']\'');
							 | 
						|
								  return joinPaths(currentPath, path);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								function getPath(currentPath, prop, jsonPointers) {
							 | 
						|
								  var path = jsonPointers // false by default
							 | 
						|
								              ? toQuotedString('/' + escapeJsonPointer(prop))
							 | 
						|
								              : toQuotedString(getProperty(prop));
							 | 
						|
								  return joinPaths(currentPath, path);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								var JSON_POINTER = /^\/(?:[^~]|~0|~1)*$/;
							 | 
						|
								var RELATIVE_JSON_POINTER = /^([0-9]+)(#|\/(?:[^~]|~0|~1)*)?$/;
							 | 
						|
								function getData($data, lvl, paths) {
							 | 
						|
								  var up, jsonPointer, data, matches;
							 | 
						|
								  if ($data === '') return 'rootData';
							 | 
						|
								  if ($data[0] == '/') {
							 | 
						|
								    if (!JSON_POINTER.test($data)) throw new Error('Invalid JSON-pointer: ' + $data);
							 | 
						|
								    jsonPointer = $data;
							 | 
						|
								    data = 'rootData';
							 | 
						|
								  } else {
							 | 
						|
								    matches = $data.match(RELATIVE_JSON_POINTER);
							 | 
						|
								    if (!matches) throw new Error('Invalid JSON-pointer: ' + $data);
							 | 
						|
								    up = +matches[1];
							 | 
						|
								    jsonPointer = matches[2];
							 | 
						|
								    if (jsonPointer == '#') {
							 | 
						|
								      if (up >= lvl) throw new Error('Cannot access property/index ' + up + ' levels up, current level is ' + lvl);
							 | 
						|
								      return paths[lvl - up];
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    if (up > lvl) throw new Error('Cannot access data ' + up + ' levels up, current level is ' + lvl);
							 | 
						|
								    data = 'data' + ((lvl - up) || '');
							 | 
						|
								    if (!jsonPointer) return data;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  var expr = data;
							 | 
						|
								  var segments = jsonPointer.split('/');
							 | 
						|
								  for (var i=0; i<segments.length; i++) {
							 | 
						|
								    var segment = segments[i];
							 | 
						|
								    if (segment) {
							 | 
						|
								      data += getProperty(unescapeJsonPointer(segment));
							 | 
						|
								      expr += ' && ' + data;
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								  return expr;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								function joinPaths (a, b) {
							 | 
						|
								  if (a == '""') return b;
							 | 
						|
								  return (a + ' + ' + b).replace(/([^\\])' \+ '/g, '$1');
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								function unescapeFragment(str) {
							 | 
						|
								  return unescapeJsonPointer(decodeURIComponent(str));
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								function escapeFragment(str) {
							 | 
						|
								  return encodeURIComponent(escapeJsonPointer(str));
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								function escapeJsonPointer(str) {
							 | 
						|
								  return str.replace(/~/g, '~0').replace(/\//g, '~1');
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								function unescapeJsonPointer(str) {
							 | 
						|
								  return str.replace(/~1/g, '/').replace(/~0/g, '~');
							 | 
						|
								}
							 |