auto-parse
Version:
Automatically convert any value to its best matching JavaScript type. Supports numbers, booleans, objects, arrays, BigInt, Symbol, comma-separated numbers, prefix stripping, allowed type enforcement and a plugin API.
382 lines (360 loc) • 26 kB
JavaScript
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.autoParse = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
module.exports = autoParse
var typpy = require('typpy')
/**
*
* @name stripTrimLower
* @function
* @param {Value} value strip trim & lower case the string
* @return {Value} parsed string
*
*/
function stripTrimLower (value) {
return value.replace(/[""'']/ig, '').trim().toLowerCase()
}
/**
*
* @name toBoolean
* @function
* @param {Value} value parse to boolean
* @return {Boolean} parsed boolean
*
*/
function toBoolean (value) {
return checkBoolean(value) || false
}
/**
*
* @name checkBoolean
* @function
* @param {Value} value is any value
* @return {Boolean} is a boolean value
*
*/
function checkBoolean (value) {
if (!value) {
return false
}
if (typeof value === 'number' || typeof value === 'boolean') {
return !!value
}
value = stripTrimLower(value)
if (value === 'true' || value === '1') return true
if (value === 'false' || value === '0') return false
return null
}
/**
*
* @name parseObject
* @function
* @param {Value} value parse object
* @return {Value} parsed object
*
*/
function parseObject (value) {
if (typpy(value, Array)) {
return value.map(function (n, key) {
return autoParse(n)
})
} else if (typpy(value, Object) || value.constructor === undefined) {
for (var n in value) {
value[n] = autoParse(value[n])
}
return value
}
return {}
}
/**
*
* @name parseFunction
* @function
* @param {Value} value function
* @return {Value} returned value from the called value function
*
*/
function parseFunction (value) {
return autoParse(value())
}
/**
*
* @name parseType
* @function
* @param {Value} value inputed value
* @param {Type} type inputed type
* @return {Value} parsed type
*
*/
function parseType (value, type) {
/**
* Currently they send a string - handle String or Number or Boolean?
*/
if ((value && value.constructor === type) || typpy(value, type)) {
return value
}
var typeName = type
/**
* Convert the constructor into a string
*/
if (type && type.name) {
typeName = type.name.toLowerCase()
}
typeName = stripTrimLower(typeName)
switch (typeName) {
case 'string':
if (typeof value === 'object') return JSON.stringify(value)
return String(value)
case 'function':
if (typpy(value, Function)) {
return value
}
return function (cb) {
if (typeof cb === 'function') {
cb(value)
}
return value
}
case 'date':
return new Date(value)
case 'object':
var jsonParsed
try {
jsonParsed = JSON.parse(value)
} catch (e) {}
if (typpy(jsonParsed, Object) || typpy(jsonParsed, Array)) {
return autoParse(jsonParsed)
} else if (!typpy(jsonParsed, 'undefined')) {
return {}
}
return parseObject(value)
case 'boolean':
return toBoolean(value)
case 'number':
return Number(value)
case 'undefined':
return undefined
case 'null':
return null
case 'array':
return [value]
default:
if (typeof type === 'function') {
return new type(value) // eslint-disable-line
}
throw new Error('Unsupported type.')
}
}
/**
* autoParse
* auto-parse any value you happen to send in
* (String, Number, Boolean, Array, Object, Function, undefined and null).
* You send it we will try to find a way to parse it.
* We now support sending in a string of what type
* (e.g. "boolean") or constructor (e.g. Boolean)
*
* Usage:
*
* ```js
* autoParse({}) // => "object"
* autoParse('42'); // => 42
* autoParse.get('[]'); // => []
* ```
*
* @name autoParse
* @function
* @param {Value} input The input value.
* @param {Constructor|String} target The target type.
* @return {String|Function|Date|Object|Boolean|Number|Undefined|Null|Array}
*/
function autoParse (value, type) {
if (type) {
return parseType(value, type)
}
var orignalValue = value
/**
* PRE RULE - check for null be cause null can be typeof object which can through off parsing
*/
if (value === null) {
return null
}
/**
* TYPEOF SECTION - Use to check and do specific things based off of know the type
* Check against undefined
*/
if (value === void 0) {
return undefined
}
if (value instanceof Date || value instanceof RegExp) {
return value
}
if (typeof value === 'number' || typeof value === 'boolean') {
return value
}
if (typeof value === 'function') {
return parseFunction(value)
}
if (typeof value === 'object') {
return parseObject(value)
}
/**
* STRING SECTION - If we made it this far that means it is a string that we must do something with to parse
*/
if (value === 'NaN') {
return NaN
}
var jsonParsed = null
try {
jsonParsed = JSON.parse(value)
} catch (e) {
try {
jsonParsed = JSON.parse(
value.trim().replace(/(\\\\")|(\\")/gi, '"').replace(/(\\n|\\\\n)/gi, '').replace(/(^"|"$)|(^'|'$)/gi, '')
)
} catch (e) {
try {
jsonParsed = JSON.parse(
value.trim().replace(/'/gi, '"')
)
} catch (e) {}
}
}
if (jsonParsed && typeof jsonParsed === 'object') {
return autoParse(jsonParsed)
}
value = stripTrimLower(value)
if (value === 'undefined' || value === '') {
return undefined
}
if (value === 'null') {
return null
}
/**
* Order Matter because if it is a one or zero boolean will come back with a awnser too. if you want it to be a boolean you must specify
*/
var num = Number(value)
if (typpy(num, Number)) {
return num
}
var boo = checkBoolean(value)
if (typpy(boo, Boolean)) {
return boo
}
/**
* DEFAULT SECTION - bascially if we catch nothing we assume that you just have a string
*/
// if string - convert to ""
return String(orignalValue)
}
},{"typpy":4}],2:[function(require,module,exports){
;
var noop6 = require("noop6");
(function () {
var NAME_FIELD = "name";
if (typeof noop6.name === "string") {
return;
}
try {
Object.defineProperty(Function.prototype, NAME_FIELD, {
get: function get() {
var nameMatch = this.toString().trim().match(/^function\s*([^\s(]+)/);
var name = nameMatch ? nameMatch[1] : "";
Object.defineProperty(this, NAME_FIELD, { value: name });
return name;
}
});
} catch (e) {}
})();
/**
* functionName
* Get the function name.
*
* @name functionName
* @function
* @param {Function} input The input function.
* @returns {String} The function name.
*/
module.exports = function functionName(input) {
return input.name;
};
},{"noop6":3}],3:[function(require,module,exports){
;
module.exports = function () {};
},{}],4:[function(require,module,exports){
;
require("function.name");
/**
* Typpy
* Gets the type of the input value or compares it
* with a provided type.
*
* Usage:
*
* ```js
* Typpy({}) // => "object"
* Typpy(42, Number); // => true
* Typpy.get([], "array"); => true
* ```
*
* @name Typpy
* @function
* @param {Anything} input The input value.
* @param {Constructor|String} target The target type.
* It could be a string (e.g. `"array"`) or a
* constructor (e.g. `Array`).
* @return {String|Boolean} It returns `true` if the
* input has the provided type `target` (if was provided),
* `false` if the input type does *not* have the provided type
* `target` or the stringified type of the input (always lowercase).
*/
function Typpy(input, target) {
if (arguments.length === 2) {
return Typpy.is(input, target);
}
return Typpy.get(input, true);
}
/**
* Typpy.is
* Checks if the input value has a specified type.
*
* @name Typpy.is
* @function
* @param {Anything} input The input value.
* @param {Constructor|String} target The target type.
* It could be a string (e.g. `"array"`) or a
* constructor (e.g. `Array`).
* @return {Boolean} `true`, if the input has the same
* type with the target or `false` otherwise.
*/
Typpy.is = function (input, target) {
return Typpy.get(input, typeof target === "string") === target;
};
/**
* Typpy.get
* Gets the type of the input value. This is used internally.
*
* @name Typpy.get
* @function
* @param {Anything} input The input value.
* @param {Boolean} str A flag to indicate if the return value
* should be a string or not.
* @return {Constructor|String} The input value constructor
* (if any) or the stringified type (always lowercase).
*/
Typpy.get = function (input, str) {
if (typeof input === "string") {
return str ? "string" : String;
}
if (null === input) {
return str ? "null" : null;
}
if (undefined === input) {
return str ? "undefined" : undefined;
}
if (input !== input) {
return str ? "nan" : NaN;
}
return str ? input.constructor.name.toLowerCase() : input.constructor;
};
module.exports = Typpy;
},{"function.name":2}]},{},[1])(1)
});
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJpbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9mdW5jdGlvbi5uYW1lL2xpYi9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9ub29wNi9saWIvaW5kZXguanMiLCJub2RlX21vZHVsZXMvdHlwcHkvbGliL2luZGV4LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xDQTtBQUNBO0FBQ0E7O0FDRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uKCl7ZnVuY3Rpb24gcihlLG4sdCl7ZnVuY3Rpb24gbyhpLGYpe2lmKCFuW2ldKXtpZighZVtpXSl7dmFyIGM9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZTtpZighZiYmYylyZXR1cm4gYyhpLCEwKTtpZih1KXJldHVybiB1KGksITApO3ZhciBhPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIraStcIidcIik7dGhyb3cgYS5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGF9dmFyIHA9bltpXT17ZXhwb3J0czp7fX07ZVtpXVswXS5jYWxsKHAuZXhwb3J0cyxmdW5jdGlvbihyKXt2YXIgbj1lW2ldWzFdW3JdO3JldHVybiBvKG58fHIpfSxwLHAuZXhwb3J0cyxyLGUsbix0KX1yZXR1cm4gbltpXS5leHBvcnRzfWZvcih2YXIgdT1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlLGk9MDtpPHQubGVuZ3RoO2krKylvKHRbaV0pO3JldHVybiBvfXJldHVybiByfSkoKSIsIm1vZHVsZS5leHBvcnRzID0gYXV0b1BhcnNlXG5cbnZhciB0eXBweSA9IHJlcXVpcmUoJ3R5cHB5JylcblxuLyoqXG4gKlxuICogQG5hbWUgc3RyaXBUcmltTG93ZXJcbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtWYWx1ZX0gdmFsdWUgc3RyaXAgdHJpbSAmIGxvd2VyIGNhc2UgdGhlIHN0cmluZ1xuICogQHJldHVybiB7VmFsdWV9IHBhcnNlZCBzdHJpbmdcbiAqXG4gKi9cbmZ1bmN0aW9uIHN0cmlwVHJpbUxvd2VyICh2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUucmVwbGFjZSgvW1wiXCInJ10vaWcsICcnKS50cmltKCkudG9Mb3dlckNhc2UoKVxufVxuLyoqXG4gKlxuICogQG5hbWUgdG9Cb29sZWFuXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7VmFsdWV9IHZhbHVlIHBhcnNlIHRvIGJvb2xlYW5cbiAqIEByZXR1cm4ge0Jvb2xlYW59IHBhcnNlZCBib29sZWFuXG4gKlxuICovXG5mdW5jdGlvbiB0b0Jvb2xlYW4gKHZhbHVlKSB7XG4gIHJldHVybiBjaGVja0Jvb2xlYW4odmFsdWUpIHx8IGZhbHNlXG59XG4vKipcbiAqXG4gKiBAbmFtZSBjaGVja0Jvb2xlYW5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtWYWx1ZX0gdmFsdWUgaXMgYW55IHZhbHVlXG4gKiBAcmV0dXJuIHtCb29sZWFufSBpcyBhIGJvb2xlYW4gdmFsdWVcbiAqXG4gKi9cbmZ1bmN0aW9uIGNoZWNrQm9vbGVhbiAodmFsdWUpIHtcbiAgaWYgKCF2YWx1ZSkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInIHx8IHR5cGVvZiB2YWx1ZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgcmV0dXJuICEhdmFsdWVcbiAgfVxuICB2YWx1ZSA9IHN0cmlwVHJpbUxvd2VyKHZhbHVlKVxuICBpZiAodmFsdWUgPT09ICd0cnVlJyB8fCB2YWx1ZSA9PT0gJzEnKSByZXR1cm4gdHJ1ZVxuICBpZiAodmFsdWUgPT09ICdmYWxzZScgfHwgdmFsdWUgPT09ICcwJykgcmV0dXJuIGZhbHNlXG4gIHJldHVybiBudWxsXG59XG4vKipcbiAqXG4gKiBAbmFtZSBwYXJzZU9iamVjdFxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge1ZhbHVlfSB2YWx1ZSBwYXJzZSBvYmplY3RcbiAqIEByZXR1cm4ge1ZhbHVlfSBwYXJzZWQgb2JqZWN0XG4gKlxuICovXG5mdW5jdGlvbiBwYXJzZU9iamVjdCAodmFsdWUpIHtcbiAgaWYgKHR5cHB5KHZhbHVlLCBBcnJheSkpIHtcbiAgICByZXR1cm4gdmFsdWUubWFwKGZ1bmN0aW9uIChuLCBrZXkpIHtcbiAgICAgIHJldHVybiBhdXRvUGFyc2UobilcbiAgICB9KVxuICB9IGVsc2UgaWYgKHR5cHB5KHZhbHVlLCBPYmplY3QpIHx8IHZhbHVlLmNvbnN0cnVjdG9yID09PSB1bmRlZmluZWQpIHtcbiAgICBmb3IgKHZhciBuIGluIHZhbHVlKSB7XG4gICAgICB2YWx1ZVtuXSA9IGF1dG9QYXJzZSh2YWx1ZVtuXSlcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlXG4gIH1cbiAgcmV0dXJuIHt9XG59XG4vKipcbiAqXG4gKiBAbmFtZSBwYXJzZUZ1bmN0aW9uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7VmFsdWV9IHZhbHVlIGZ1bmN0aW9uXG4gKiBAcmV0dXJuIHtWYWx1ZX0gcmV0dXJuZWQgdmFsdWUgZnJvbSB0aGUgY2FsbGVkIHZhbHVlIGZ1bmN0aW9uXG4gKlxuICovXG5mdW5jdGlvbiBwYXJzZUZ1bmN0aW9uICh2YWx1ZSkge1xuICByZXR1cm4gYXV0b1BhcnNlKHZhbHVlKCkpXG59XG4vKipcbiAqXG4gKiBAbmFtZSBwYXJzZVR5cGVcbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtWYWx1ZX0gdmFsdWUgaW5wdXRlZCB2YWx1ZVxuICogQHBhcmFtIHtUeXBlfSB0eXBlICBpbnB1dGVkIHR5cGVcbiAqIEByZXR1cm4ge1ZhbHVlfSBwYXJzZWQgdHlwZVxuICpcbiAqL1xuZnVuY3Rpb24gcGFyc2VUeXBlICh2YWx1ZSwgdHlwZSkge1xuICAvKipcbiAgICogIEN1cnJlbnRseSB0aGV5IHNlbmQgYSBzdHJpbmcgLSBoYW5kbGUgU3RyaW5nIG9yIE51bWJlciBvciBCb29sZWFuP1xuICAgKi9cbiAgaWYgKCh2YWx1ZSAmJiB2YWx1ZS5jb25zdHJ1Y3RvciA9PT0gdHlwZSkgfHwgdHlwcHkodmFsdWUsIHR5cGUpKSB7XG4gICAgcmV0dXJuIHZhbHVlXG4gIH1cbiAgdmFyIHR5cGVOYW1lID0gdHlwZVxuICAvKipcbiAgICogQ29udmVydCB0aGUgY29uc3RydWN0b3IgaW50byBhIHN0cmluZ1xuICAgKi9cbiAgaWYgKHR5cGUgJiYgdHlwZS5uYW1lKSB7XG4gICAgdHlwZU5hbWUgPSB0eXBlLm5hbWUudG9Mb3dlckNhc2UoKVxuICB9XG5cbiAgdHlwZU5hbWUgPSBzdHJpcFRyaW1Mb3dlcih0eXBlTmFtZSlcbiAgc3dpdGNoICh0eXBlTmFtZSkge1xuICAgIGNhc2UgJ3N0cmluZyc6XG4gICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JykgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHZhbHVlKVxuICAgICAgcmV0dXJuIFN0cmluZyh2YWx1ZSlcbiAgICBjYXNlICdmdW5jdGlvbic6XG4gICAgICBpZiAodHlwcHkodmFsdWUsIEZ1bmN0aW9uKSkge1xuICAgICAgICByZXR1cm4gdmFsdWVcbiAgICAgIH1cbiAgICAgIHJldHVybiBmdW5jdGlvbiAoY2IpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIGNiKHZhbHVlKVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB2YWx1ZVxuICAgICAgfVxuICAgIGNhc2UgJ2RhdGUnOlxuICAgICAgcmV0dXJuIG5ldyBEYXRlKHZhbHVlKVxuICAgIGNhc2UgJ29iamVjdCc6XG4gICAgICB2YXIganNvblBhcnNlZFxuICAgICAgdHJ5IHtcbiAgICAgICAganNvblBhcnNlZCA9IEpTT04ucGFyc2UodmFsdWUpXG4gICAgICB9IGNhdGNoIChlKSB7fVxuICAgICAgaWYgKHR5cHB5KGpzb25QYXJzZWQsIE9iamVjdCkgfHwgdHlwcHkoanNvblBhcnNlZCwgQXJyYXkpKSB7XG4gICAgICAgIHJldHVybiBhdXRvUGFyc2UoanNvblBhcnNlZClcbiAgICAgIH0gZWxzZSBpZiAoIXR5cHB5KGpzb25QYXJzZWQsICd1bmRlZmluZWQnKSkge1xuICAgICAgICByZXR1cm4ge31cbiAgICAgIH1cbiAgICAgIHJldHVybiBwYXJzZU9iamVjdCh2YWx1ZSlcbiAgICBjYXNlICdib29sZWFuJzpcbiAgICAgIHJldHVybiB0b0Jvb2xlYW4odmFsdWUpXG4gICAgY2FzZSAnbnVtYmVyJzpcbiAgICAgIHJldHVybiBOdW1iZXIodmFsdWUpXG4gICAgY2FzZSAndW5kZWZpbmVkJzpcbiAgICAgIHJldHVybiB1bmRlZmluZWRcbiAgICBjYXNlICdudWxsJzpcbiAgICAgIHJldHVybiBudWxsXG4gICAgY2FzZSAnYXJyYXknOlxuICAgICAgcmV0dXJuIFt2YWx1ZV1cbiAgICBkZWZhdWx0OlxuICAgICAgaWYgKHR5cGVvZiB0eXBlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHJldHVybiBuZXcgdHlwZSh2YWx1ZSkgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCB0eXBlLicpXG4gIH1cbn1cbi8qKlxuICogYXV0b1BhcnNlXG4gKiBhdXRvLXBhcnNlIGFueSB2YWx1ZSB5b3UgaGFwcGVuIHRvIHNlbmQgaW5cbiAqIChTdHJpbmcsIE51bWJlciwgQm9vbGVhbiwgQXJyYXksIE9iamVjdCwgRnVuY3Rpb24sIHVuZGVmaW5lZCBhbmQgbnVsbCkuXG4gKiBZb3Ugc2VuZCBpdCB3ZSB3aWxsIHRyeSB0byBmaW5kIGEgd2F5IHRvIHBhcnNlIGl0LlxuICogV2Ugbm93IHN1cHBvcnQgc2VuZGluZyBpbiBhIHN0cmluZyBvZiB3aGF0IHR5cGVcbiAqIChlLmcuIFwiYm9vbGVhblwiKSBvciBjb25zdHJ1Y3RvciAoZS5nLiBCb29sZWFuKVxuICpcbiAqIFVzYWdlOlxuICpcbiAqIGBgYGpzXG4gKiBhdXRvUGFyc2Uoe30pIC8vID0+IFwib2JqZWN0XCJcbiAqIGF1dG9QYXJzZSgnNDInKTsgLy8gPT4gNDJcbiAqIGF1dG9QYXJzZS5nZXQoJ1tdJyk7IC8vID0+IFtdXG4gKiBgYGBcbiAqXG4gKiBAbmFtZSBhdXRvUGFyc2VcbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtWYWx1ZX0gaW5wdXQgVGhlIGlucHV0IHZhbHVlLlxuICogQHBhcmFtIHtDb25zdHJ1Y3RvcnxTdHJpbmd9IHRhcmdldCBUaGUgdGFyZ2V0IHR5cGUuXG4gKiBAcmV0dXJuIHtTdHJpbmd8RnVuY3Rpb258RGF0ZXxPYmplY3R8Qm9vbGVhbnxOdW1iZXJ8VW5kZWZpbmVkfE51bGx8QXJyYXl9XG4gKi9cbmZ1bmN0aW9uIGF1dG9QYXJzZSAodmFsdWUsIHR5cGUpIHtcbiAgaWYgKHR5cGUpIHtcbiAgICByZXR1cm4gcGFyc2VUeXBlKHZhbHVlLCB0eXBlKVxuICB9XG4gIHZhciBvcmlnbmFsVmFsdWUgPSB2YWx1ZVxuICAvKipcbiAgICogIFBSRSBSVUxFIC0gY2hlY2sgZm9yIG51bGwgYmUgY2F1c2UgbnVsbCBjYW4gYmUgdHlwZW9mIG9iamVjdCB3aGljaCBjYW4gIHRocm91Z2ggb2ZmIHBhcnNpbmdcbiAgICovXG4gIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgIHJldHVybiBudWxsXG4gIH1cbiAgLyoqXG4gICAqIFRZUEVPRiBTRUNUSU9OIC0gVXNlIHRvIGNoZWNrIGFuZCBkbyBzcGVjaWZpYyB0aGluZ3MgYmFzZWQgb2ZmIG9mIGtub3cgdGhlIHR5cGVcbiAgICogQ2hlY2sgYWdhaW5zdCB1bmRlZmluZWRcbiAgICovXG4gIGlmICh2YWx1ZSA9PT0gdm9pZCAwKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZFxuICB9XG4gIGlmICh2YWx1ZSBpbnN0YW5jZW9mIERhdGUgfHwgdmFsdWUgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICByZXR1cm4gdmFsdWVcbiAgfVxuICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyB8fCB0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJykge1xuICAgIHJldHVybiB2YWx1ZVxuICB9XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gcGFyc2VGdW5jdGlvbih2YWx1ZSlcbiAgfVxuICBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0Jykge1xuICAgIHJldHVybiBwYXJzZU9iamVjdCh2YWx1ZSlcbiAgfVxuICAvKipcbiAgICogU1RSSU5HIFNFQ1RJT04gLSBJZiB3ZSBtYWRlIGl0IHRoaXMgZmFyIHRoYXQgbWVhbnMgaXQgaXMgYSBzdHJpbmcgdGhhdCB3ZSBtdXN0IGRvIHNvbWV0aGluZyB3aXRoIHRvIHBhcnNlXG4gICAqL1xuICBpZiAodmFsdWUgPT09ICdOYU4nKSB7XG4gICAgcmV0dXJuIE5hTlxuICB9XG4gIHZhciBqc29uUGFyc2VkID0gbnVsbFxuICB0cnkge1xuICAgIGpzb25QYXJzZWQgPSBKU09OLnBhcnNlKHZhbHVlKVxuICB9IGNhdGNoIChlKSB7XG4gICAgdHJ5IHtcbiAgICAgIGpzb25QYXJzZWQgPSBKU09OLnBhcnNlKFxuICAgICAgICB2YWx1ZS50cmltKCkucmVwbGFjZSgvKFxcXFxcXFxcXCIpfChcXFxcXCIpL2dpLCAnXCInKS5yZXBsYWNlKC8oXFxcXG58XFxcXFxcXFxuKS9naSwgJycpLnJlcGxhY2UoLyheXCJ8XCIkKXwoXid8JyQpL2dpLCAnJylcbiAgICAgIClcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0cnkge1xuICAgICAgICBqc29uUGFyc2VkID0gSlNPTi5wYXJzZShcbiAgICAgICAgICB2YWx1ZS50cmltKCkucmVwbGFjZSgvJy9naSwgJ1wiJylcbiAgICAgICAgKVxuICAgICAgfSBjYXRjaCAoZSkge31cbiAgICB9XG4gIH1cbiAgaWYgKGpzb25QYXJzZWQgJiYgdHlwZW9mIGpzb25QYXJzZWQgPT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIGF1dG9QYXJzZShqc29uUGFyc2VkKVxuICB9XG4gIHZhbHVlID0gc3RyaXBUcmltTG93ZXIodmFsdWUpXG4gIGlmICh2YWx1ZSA9PT0gJ3VuZGVmaW5lZCcgfHwgdmFsdWUgPT09ICcnKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZFxuICB9XG4gIGlmICh2YWx1ZSA9PT0gJ251bGwnKSB7XG4gICAgcmV0dXJuIG51bGxcbiAgfVxuICAvKipcbiAgICogT3JkZXIgTWF0dGVyIGJlY2F1c2UgaWYgaXQgaXMgYSBvbmUgb3IgemVybyBib29sZWFuIHdpbGwgY29tZSBiYWNrIHdpdGggYSBhd25zZXIgdG9vLiBpZiB5b3Ugd2FudCBpdCB0byBiZSBhIGJvb2xlYW4geW91IG11c3Qgc3BlY2lmeVxuICAgKi9cbiAgdmFyIG51bSA9IE51bWJlcih2YWx1ZSlcbiAgaWYgKHR5cHB5KG51bSwgTnVtYmVyKSkge1xuICAgIHJldHVybiBudW1cbiAgfVxuICB2YXIgYm9vID0gY2hlY2tCb29sZWFuKHZhbHVlKVxuICBpZiAodHlwcHkoYm9vLCBCb29sZWFuKSkge1xuICAgIHJldHVybiBib29cbiAgfVxuICAvKipcbiAgICogREVGQVVMVCBTRUNUSU9OIC0gYmFzY2lhbGx5IGlmIHdlIGNhdGNoIG5vdGhpbmcgd2UgYXNzdW1lIHRoYXQgeW91IGp1c3QgaGF2ZSBhIHN0cmluZ1xuICAgKi9cbiAgLy8gaWYgc3RyaW5nIC0gY29udmVydCB0byBcIlwiXG4gIHJldHVybiBTdHJpbmcob3JpZ25hbFZhbHVlKVxufVxuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBub29wNiA9IHJlcXVpcmUoXCJub29wNlwiKTtcblxuKGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgTkFNRV9GSUVMRCA9IFwibmFtZVwiO1xuXG4gICAgaWYgKHR5cGVvZiBub29wNi5uYW1lID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoRnVuY3Rpb24ucHJvdG90eXBlLCBOQU1FX0ZJRUxELCB7XG4gICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgICAgICAgICAgICB2YXIgbmFtZU1hdGNoID0gdGhpcy50b1N0cmluZygpLnRyaW0oKS5tYXRjaCgvXmZ1bmN0aW9uXFxzKihbXlxccyhdKykvKTtcbiAgICAgICAgICAgICAgICB2YXIgbmFtZSA9IG5hbWVNYXRjaCA/IG5hbWVNYXRjaFsxXSA6IFwiXCI7XG4gICAgICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIE5BTUVfRklFTEQsIHsgdmFsdWU6IG5hbWUgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5hbWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGUpIHt9XG59KSgpO1xuXG4vKipcbiAqIGZ1bmN0aW9uTmFtZVxuICogR2V0IHRoZSBmdW5jdGlvbiBuYW1lLlxuICpcbiAqIEBuYW1lIGZ1bmN0aW9uTmFtZVxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpbnB1dCBUaGUgaW5wdXQgZnVuY3Rpb24uXG4gKiBAcmV0dXJucyB7U3RyaW5nfSBUaGUgZnVuY3Rpb24gbmFtZS5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBmdW5jdGlvbk5hbWUoaW5wdXQpIHtcbiAgICByZXR1cm4gaW5wdXQubmFtZTtcbn07IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkge307IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbnJlcXVpcmUoXCJmdW5jdGlvbi5uYW1lXCIpO1xuXG4vKipcbiAqIFR5cHB5XG4gKiBHZXRzIHRoZSB0eXBlIG9mIHRoZSBpbnB1dCB2YWx1ZSBvciBjb21wYXJlcyBpdFxuICogd2l0aCBhIHByb3ZpZGVkIHR5cGUuXG4gKlxuICogVXNhZ2U6XG4gKlxuICogYGBganNcbiAqIFR5cHB5KHt9KSAvLyA9PiBcIm9iamVjdFwiXG4gKiBUeXBweSg0MiwgTnVtYmVyKTsgLy8gPT4gdHJ1ZVxuICogVHlwcHkuZ2V0KFtdLCBcImFycmF5XCIpOyA9PiB0cnVlXG4gKiBgYGBcbiAqXG4gKiBAbmFtZSBUeXBweVxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge0FueXRoaW5nfSBpbnB1dCBUaGUgaW5wdXQgdmFsdWUuXG4gKiBAcGFyYW0ge0NvbnN0cnVjdG9yfFN0cmluZ30gdGFyZ2V0IFRoZSB0YXJnZXQgdHlwZS5cbiAqIEl0IGNvdWxkIGJlIGEgc3RyaW5nIChlLmcuIGBcImFycmF5XCJgKSBvciBhXG4gKiBjb25zdHJ1Y3RvciAoZS5nLiBgQXJyYXlgKS5cbiAqIEByZXR1cm4ge1N0cmluZ3xCb29sZWFufSBJdCByZXR1cm5zIGB0cnVlYCBpZiB0aGVcbiAqIGlucHV0IGhhcyB0aGUgcHJvdmlkZWQgdHlwZSBgdGFyZ2V0YCAoaWYgd2FzIHByb3ZpZGVkKSxcbiAqIGBmYWxzZWAgaWYgdGhlIGlucHV0IHR5cGUgZG9lcyAqbm90KiBoYXZlIHRoZSBwcm92aWRlZCB0eXBlXG4gKiBgdGFyZ2V0YCBvciB0aGUgc3RyaW5naWZpZWQgdHlwZSBvZiB0aGUgaW5wdXQgKGFsd2F5cyBsb3dlcmNhc2UpLlxuICovXG5mdW5jdGlvbiBUeXBweShpbnB1dCwgdGFyZ2V0KSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDIpIHtcbiAgICAgICAgcmV0dXJuIFR5cHB5LmlzKGlucHV0LCB0YXJnZXQpO1xuICAgIH1cbiAgICByZXR1cm4gVHlwcHkuZ2V0KGlucHV0LCB0cnVlKTtcbn1cblxuLyoqXG4gKiBUeXBweS5pc1xuICogQ2hlY2tzIGlmIHRoZSBpbnB1dCB2YWx1ZSBoYXMgYSBzcGVjaWZpZWQgdHlwZS5cbiAqXG4gKiBAbmFtZSBUeXBweS5pc1xuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge0FueXRoaW5nfSBpbnB1dCBUaGUgaW5wdXQgdmFsdWUuXG4gKiBAcGFyYW0ge0NvbnN0cnVjdG9yfFN0cmluZ30gdGFyZ2V0IFRoZSB0YXJnZXQgdHlwZS5cbiAqIEl0IGNvdWxkIGJlIGEgc3RyaW5nIChlLmcuIGBcImFycmF5XCJgKSBvciBhXG4gKiBjb25zdHJ1Y3RvciAoZS5nLiBgQXJyYXlgKS5cbiAqIEByZXR1cm4ge0Jvb2xlYW59IGB0cnVlYCwgaWYgdGhlIGlucHV0IGhhcyB0aGUgc2FtZVxuICogdHlwZSB3aXRoIHRoZSB0YXJnZXQgb3IgYGZhbHNlYCBvdGhlcndpc2UuXG4gKi9cblR5cHB5LmlzID0gZnVuY3Rpb24gKGlucHV0LCB0YXJnZXQpIHtcbiAgICByZXR1cm4gVHlwcHkuZ2V0KGlucHV0LCB0eXBlb2YgdGFyZ2V0ID09PSBcInN0cmluZ1wiKSA9PT0gdGFyZ2V0O1xufTtcblxuLyoqXG4gKiBUeXBweS5nZXRcbiAqIEdldHMgdGhlIHR5cGUgb2YgdGhlIGlucHV0IHZhbHVlLiBUaGlzIGlzIHVzZWQgaW50ZXJuYWxseS5cbiAqXG4gKiBAbmFtZSBUeXBweS5nZXRcbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtBbnl0aGluZ30gaW5wdXQgVGhlIGlucHV0IHZhbHVlLlxuICogQHBhcmFtIHtCb29sZWFufSBzdHIgQSBmbGFnIHRvIGluZGljYXRlIGlmIHRoZSByZXR1cm4gdmFsdWVcbiAqIHNob3VsZCBiZSBhIHN0cmluZyBvciBub3QuXG4gKiBAcmV0dXJuIHtDb25zdHJ1Y3RvcnxTdHJpbmd9IFRoZSBpbnB1dCB2YWx1ZSBjb25zdHJ1Y3RvclxuICogKGlmIGFueSkgb3IgdGhlIHN0cmluZ2lmaWVkIHR5cGUgKGFsd2F5cyBsb3dlcmNhc2UpLlxuICovXG5UeXBweS5nZXQgPSBmdW5jdGlvbiAoaW5wdXQsIHN0cikge1xuXG4gICAgaWYgKHR5cGVvZiBpbnB1dCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICByZXR1cm4gc3RyID8gXCJzdHJpbmdcIiA6IFN0cmluZztcbiAgICB9XG5cbiAgICBpZiAobnVsbCA9PT0gaW5wdXQpIHtcbiAgICAgICAgcmV0dXJuIHN0ciA/IFwibnVsbFwiIDogbnVsbDtcbiAgICB9XG5cbiAgICBpZiAodW5kZWZpbmVkID09PSBpbnB1dCkge1xuICAgICAgICByZXR1cm4gc3RyID8gXCJ1bmRlZmluZWRcIiA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBpZiAoaW5wdXQgIT09IGlucHV0KSB7XG4gICAgICAgIHJldHVybiBzdHIgPyBcIm5hblwiIDogTmFOO1xuICAgIH1cblxuICAgIHJldHVybiBzdHIgPyBpbnB1dC5jb25zdHJ1Y3Rvci5uYW1lLnRvTG93ZXJDYXNlKCkgOiBpbnB1dC5jb25zdHJ1Y3Rvcjtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gVHlwcHk7Il19