<commit_before>/*
Copyright (c) 2013, Jake Hartz. All rights reserved.
Use of this source code is governed by a BSD-style license
that can be found in the LICENSE.txt file.
*/

function forEach(arr, func) {
    if (typeof arr.forEach == "function") {
        arr.forEach(func);
    } else {
        for (var i = 0; i < arr.length; i++) {
            func(arr[i], i, arr);
        }
    }
}

if (!Array.isArray) {
    // https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/isArray#Compatibility
    Array.isArray = function (vArg) {
        return Object.prototype.toString.call(vArg) === "[object Array]";
    };
}

function inArray(needle, haystack) {
    if (Array.prototype.indexOf) {
        return (Array.prototype.indexOf.call(haystack, needle) != -1);
    } else {
        for (var i = 0; i < haystack.length; i++) {
            if (haystack[i] === needle) return true;
        }
        return false;
    }
}

(function () {
    var filterer = function (startTag, endTag, text, replacement) {
        if (text.indexOf(startTag) != -1 && text.indexOf(endTag) > text.indexOf(startTag)) {
            var startIndex = text.indexOf(startTag),
                endIndex = text.indexOf(endTag);
            var before = text.substring(0, startIndex),
                content = text.substring(startIndex + startTag.length, endIndex),
                after = text.substring(endIndex + endTag.length);
            after = filterer(startTag, endTag, after, replacement);
            text = before + replacement.replace("$1", content) + after;
        }
        return text;
    };

    var makeTagFilter = function (tagname, replacement) {
        return (function (text) {
            return filterer("[[" + tagname + "]]", "[[/" + tagname + "]]", text, replacement);
        });
    };

    var makeBlockTagFilter = function (tagname, replacement) {
        var regex = new RegExp("^\\[\\[" + tagname + "\\]\\]([^\n]*)\\[\\[\\/" + tagname + "\\]\\]$", "gm");
        return [regex, replacement];
    };

    var filters = [
        // Escape HTML
        [/&/g, "&"],
        [/</g, "<"],
        [/>/g, ">"],
        [/\"/g, """],

        // Turn indented newlines into one line
        [/ *\n\t\t[ \t]*/g, " "],

        // Collapse extra spacing
        [/\t+/g, " "],
        [/\xA0/g, " "],
        [/[ ]{2,}/g, " "],

        // Trim leading/trailing whitespace
        [/^ +/gm, ""],
        [/ +$/gm, ""],

        // Trim commands from script
        [/^(anchor|sports)[ 0-9]*:?\s*/igm, ""],

        // Convert our special syntax (the [[...]][[/...]] tags) to HTML
        // (NOTE: Update help text in ebb.html when you update this)
        makeTagFilter("b", "$1"),
        makeTagFilter("i", "$1"),
        makeTagFilter("u", "$1"),
        makeTagFilter("small", '$1');
        makeTagFilter("big", '$1');
        makeBlockTagFilter("center", '
$1
'),
        makeBlockTagFilter("right", '
$1
'),
        makeTagFilter("img", ''),
        makeTagFilter("rightimg", ''),

        // Collapse extra line breaks; convert to

        [/\n\n\n*/g, "\n\n"],
        [/\n/g, "
"]
    ];

    window.filter = function (text) {
        forEach(filters, function (item) {
            if (typeof item == "function") {
                text = item(text);
            } else {
                text = text.replace(item[0], item[1]);
            }
        });
        return text;
    };
})();

function escHTML(html, convertNewlines) {
    if (typeof html != "string") {
        html = html + "";
    }
    html = html.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, "&gt");
    if (convertNewlines) {
        html = html.replace(/\n/g, "
");
    }
    return html;
}

function update(data) {
    forEach(data, function (item) {
        forEach(document.getElementsByClassName(item.className), function (elem) {
            var myelem = item.useParent ? elem.parentNode : elem;
            if (item.html) myelem.innerHTML = item.html;
            if (item.text) myelem.innerHTML = escHTML(item.text);
            if (item.attributes) {
                for (var attr in item.attributes) {
                    if (item.attributes.hasOwnProperty(attr)) {
                        myelem.setAttribute(attr, item.attributes[attr]);
                    }
                }
            }
            if (item.style) {
                for (var attr in item.style) {
                    if (item.style.hasOwnProperty(attr)) {
                        myelem.style[attr] = item.style[attr];
                    }
                }
            }

            while (myelem) {
                if (myelem.classList && myelem.classList.contains("font-is-adjusted")) myelem.classList.remove("font-is-adjusted");
                myelem = myelem.parentNode;
            }
        });
    });
}<commit_msg>Whoops, syntax typo fix<commit_after>/*
Copyright (c) 2013, Jake Hartz. All rights reserved.
Use of this source code is governed by a BSD-style license
that can be found in the LICENSE.txt file.
*/

function forEach(arr, func) {
    if (typeof arr.forEach == "function") {
        arr.forEach(func);
    } else {
        for (var i = 0; i < arr.length; i++) {
            func(arr[i], i, arr);
        }
    }
}

if (!Array.isArray) {
    // https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/isArray#Compatibility
    Array.isArray = function (vArg) {
        return Object.prototype.toString.call(vArg) === "[object Array]";
    };
}

function inArray(needle, haystack) {
    if (Array.prototype.indexOf) {
        return (Array.prototype.indexOf.call(haystack, needle) != -1);
    } else {
        for (var i = 0; i < haystack.length; i++) {
            if (haystack[i] === needle) return true;
        }
        return false;
    }
}

(function () {
    var filterer = function (startTag, endTag, text, replacement) {
        if (text.indexOf(startTag) != -1 && text.indexOf(endTag) > text.indexOf(startTag)) {
            var startIndex = text.indexOf(startTag),
                endIndex = text.indexOf(endTag);
            var before = text.substring(0, startIndex),
                content = text.substring(startIndex + startTag.length, endIndex),
                after = text.substring(endIndex + endTag.length);
            after = filterer(startTag, endTag, after, replacement);
            text = before + replacement.replace("$1", content) + after;
        }
        return text;
    };

    var makeTagFilter = function (tagname, replacement) {
        return (function (text) {
            return filterer("[[" + tagname + "]]", "[[/" + tagname + "]]", text, replacement);
        });
    };

    var makeBlockTagFilter = function (tagname, replacement) {
        var regex = new RegExp("^\\[\\[" + tagname + "\\]\\]([^\n]*)\\[\\[\\/" + tagname + "\\]\\]$", "gm");
        return [regex, replacement];
    };

    var filters = [
        // Escape HTML
        [/&/g, "&"],
        [/</g, "<"],
        [/>/g, ">"],
        [/\"/g, """],

        // Turn indented newlines into one line
        [/ *\n\t\t[ \t]*/g, " "],

        // Collapse extra spacing
        [/\t+/g, " "],
        [/\xA0/g, " "],
        [/[ ]{2,}/g, " "],

        // Trim leading/trailing whitespace
        [/^ +/gm, ""],
        [/ +$/gm, ""],

        // Trim commands from script
        [/^(anchor|sports)[ 0-9]*:?\s*/igm, ""],

        // Convert our special syntax (the [[...]][[/...]] tags) to HTML
        // (NOTE: Update help text in ebb.html when you update this)
        makeTagFilter("b", "$1"),
        makeTagFilter("i", "$1"),
        makeTagFilter("u", "$1"),
        makeTagFilter("small", '$1'),
        makeTagFilter("big", '$1'),
        makeBlockTagFilter("center", '
$1
'),
        makeBlockTagFilter("right", '
$1
'),
        makeTagFilter("img", ''),
        makeTagFilter("rightimg", ''),

        // Collapse extra line breaks; convert to

        [/\n\n\n*/g, "\n\n"],
        [/\n/g, "
"]
    ];

    window.filter = function (text) {
        forEach(filters, function (item) {
            if (typeof item == "function") {
                text = item(text);
            } else {
                text = text.replace(item[0], item[1]);
            }
        });
        return text;
    };
})();

function escHTML(html, convertNewlines) {
    if (typeof html != "string") {
        html = html + "";
    }
    html = html.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, "&gt");
    if (convertNewlines) {
        html = html.replace(/\n/g, "
");
    }
    return html;
}

function update(data) {
    forEach(data, function (item) {
        forEach(document.getElementsByClassName(item.className), function (elem) {
            var myelem = item.useParent ? elem.parentNode : elem;
            if (item.html) myelem.innerHTML = item.html;
            if (item.text) myelem.innerHTML = escHTML(item.text);
            if (item.attributes) {
                for (var attr in item.attributes) {
                    if (item.attributes.hasOwnProperty(attr)) {
                        myelem.setAttribute(attr, item.attributes[attr]);
                    }
                }
            }
            if (item.style) {
                for (var attr in item.style) {
                    if (item.style.hasOwnProperty(attr)) {
                        myelem.style[attr] = item.style[attr];
                    }
                }
            }

            while (myelem) {
                if (myelem.classList && myelem.classList.contains("font-is-adjusted")) myelem.classList.remove("font-is-adjusted");
                myelem = myelem.parentNode;
            }
        });
    });
}<|endoftext|>


<commit_before>var crypto = require('crypto');
var bigint = require('bigint');

var NULL_HASH = exports.NULL_HASH = new Buffer(32).clear();

// How much of Bitcoin's internal integer coin representation makes 1 BTC
var COIN = 100000000;

var sha256 = exports.sha256 = function (data) {
	return new Buffer(crypto.createHash('sha256').update(data).digest('binary'), 'binary');
};

var ripe160 = exports.ripe160 = function (data) {
	return new Buffer(crypto.createHash('rmd160').update(data).digest('binary'), 'binary');
};

var twoSha256 = exports.twoSha256 = function (data) {
	return sha256(sha256(data));
};

var sha256ripe160 = exports.sha256ripe160 = function (data) {
	return ripe160(sha256(data));
};

var formatHash = exports.formatHash = function (hash) {
	// We make a copy of the data we want to display, because a lot of Buffer
	// methods are destructive.
	var hashEnd = new Buffer(10);
	hash.copy(hashEnd, 0, 22, 32);
	return hashEnd.reverse().toHex();
};

var formatBuffer = exports.formatBuffer = function (buffer, maxLen) {
	// Calculate amount of bytes to display
	maxLen = maxLen || 10;
	if (maxLen > buffer.length) maxLen = buffer.length;

	// Copy those bytes into a temporary buffer
	var temp = new Buffer(maxLen);
	buffer.copy(temp, 0, 0, maxLen);

	// Format as string
	var output = temp.toHex();
	if (temp.length < buffer.length) output += "...";
	return output;
};

var formatValue = exports.formatValue = function (valueBuffer) {
	var value = bigint.fromBuffer(valueBuffer, {endian: 'little', size: 8}).toString();
	var integerPart = value.length > 8 ? value.substr(0, value.length-8) : '0';
	var decimalPart = value.length > 8 ? value.substr(value.length-8) : value;
	while (decimalPart.length < 8) decimalPart = "0"+decimalPart;
	decimalPart = decimalPart.replace(/0*$/, '');
	while (decimalPart.length < 2) decimalPart += "0";
	return integerPart+"."+decimalPart;
};
<commit_msg>Added BlockExplorer-style hash formatting.<commit_after>var crypto = require('crypto');
var bigint = require('bigint');

var NULL_HASH = exports.NULL_HASH = new Buffer(32).clear();

// How much of Bitcoin's internal integer coin representation makes 1 BTC
var COIN = 100000000;

var sha256 = exports.sha256 = function (data) {
	return new Buffer(crypto.createHash('sha256').update(data).digest('binary'), 'binary');
};

var ripe160 = exports.ripe160 = function (data) {
	return new Buffer(crypto.createHash('rmd160').update(data).digest('binary'), 'binary');
};

var twoSha256 = exports.twoSha256 = function (data) {
	return sha256(sha256(data));
};

var sha256ripe160 = exports.sha256ripe160 = function (data) {
	return ripe160(sha256(data));
};

var formatHash = exports.formatHash = function (hash) {
	// We make a copy of the data we want to display, because a lot of Buffer
	// methods are destructive.
	var hashEnd = new Buffer(10);
	hash.copy(hashEnd, 0, 22, 32);
	return hashEnd.reverse().toHex();
};

var formatHashAlt = exports.formatHashAlt = function (hash) {
	// We make a copy of the data we want to display, because a lot of Buffer
	// methods are destructive.
	var copy = new Buffer(hash.length);
	hash.copy(copy);
	var hex = copy.reverse().toHex();
	hex = hex.replace(/^0*/, '');
	return hex.substr(0, 10);
};

var formatBuffer = exports.formatBuffer = function (buffer, maxLen) {
	// Calculate amount of bytes to display
	maxLen = maxLen || 10;
	if (maxLen > buffer.length) maxLen = buffer.length;

	// Copy those bytes into a temporary buffer
	var temp = new Buffer(maxLen);
	buffer.copy(temp, 0, 0, maxLen);

	// Format as string
	var output = temp.toHex();
	if (temp.length < buffer.length) output += "...";
	return output;
};

var formatValue = exports.formatValue = function (valueBuffer) {
	var value = bigint.fromBuffer(valueBuffer, {endian: 'little', size: 8}).toString();
	var integerPart = value.length > 8 ? value.substr(0, value.length-8) : '0';
	var decimalPart = value.length > 8 ? value.substr(value.length-8) : value;
	while (decimalPart.length < 8) decimalPart = "0"+decimalPart;
	decimalPart = decimalPart.replace(/0*$/, '');
	while (decimalPart.length < 2) decimalPart += "0";
	return integerPart+"."+decimalPart;
};
<|endoftext|>


<commit_before>/**
 * Created by nuintun on 2015/4/27.
 */

'use strict';

var is = require('is');
var path = require('path');
var join = path.join;
var extname = path.extname;
var dirname = path.dirname;
var basename = path.basename;
var relative = path.relative;
var util = require('util');
var colors = require('colors/safe');
var debug = require('debug')('gulp-cmd');

// variable declaration
var cwd = process.cwd();
var OUTBOUNDRE = /(?:^[\\\/]?)\.\.(?:[\\\/]|$)/;
var PATHS_RE = /^([^/:]+)(\/.+)$/;
var VARS_RE = /{([^{]+)}/g;

// set debug color use 6
debug.color = 6;

/**
 * parse package form vinyl
 * @param vinyl
 * @param wwwroot
 * @returns {object}
 */
function parsePackage(vinyl, wwwroot){
  var relative = vinyl.relative;

  // vinyl not in base dir, user wwwroot
  if (OUTBOUNDRE.test(relative)) {
    relative = path.relative(wwwroot, vinyl.path);
    // vinyl not in wwwroot, throw error
    if (OUTBOUNDRE.test(relative)) {
      throwError('file: %s is out of bound of wwwroot: %s.', normalize(vinyl.path), normalize(wwwroot));
    }

    // reset relative
    relative = path.join('/', relative);
  }

  var dir = normalize(dirname(relative));
  var filename = basename(relative);
  var SPLITRE = /\/((?:\d+\.){2}\d+)(?:\/|$)/;
  var match = dir.split(SPLITRE);

  return {
    name: match[0] || '',
    version: match[1] || '',
    file: match[2] ? match[2] + '/' + filename : filename
  }
}

/**
 * simple template
 * @param format
 * @param data
 * @returns {string}
 * ```
 * var tpl = '{{name}}/{{version}}';
 * util.template(tpl, {name:'base', version: '1.0.0'});
 * ```
 */
function template(format, data){
  if (!is.string(format)) return '';

  return format.replace(/{{([a-z]*)}}/gi, function (all, match){
    return data[match] || '';
  });
}

/**
 * create a plugin
 * @param name
 * @param transport
 * @returns {Function}
 */
function plugin(name, transport){
  return function (vinyl, options){
    // debug
    debug('load plugin: %s', colors.green(name));
    // debug
    debug('read file: %s', colors.magenta(pathFromCwd(vinyl.path)));

    vinyl = transport(vinyl, options);

    // normalize package
    if (!vinyl.package) {
      vinyl.package = {};
    }

    return vinyl;
  };
}

/**
 * parse alias
 * @param id
 * @param alias
 * @returns {String}
 */
function parseAlias(id, alias){
  alias = alias || {};

  return alias && is.string(alias[id]) ? alias[id] : id;
}

/**
 * parse paths
 * @param id
 * @param paths
 * @returns {String}
 */
function parsePaths(id, paths){
  var match;

  paths = paths || {};

  if (paths && (match = id.match(PATHS_RE)) && is.string(paths[match[1]])) {
    id = paths[match[1]] + match[2];
  }

  return id;
}

/**
 * parse vars
 * @param id
 * @param vars
 * @returns {String}
 */
function parseVars(id, vars){
  vars = vars || {};

  if (vars && id.indexOf('{') > -1) {
    id = id.replace(VARS_RE, function (match, key){
      return is.string(vars[key]) ? vars[key] : match;
    });
  }

  return id;
}

/**
 * parse map
 * @param id
 * @param map
 * @returns {String}
 */
function parseMap(id, map){
  var ret = id;

  if (Array.isArray(map)) {
    for (var i = 0, len = map.length; i < len; i++) {
      var rule = map[i];

      // parse map
      if (is.fn(rule)) {
        ret = rule(id);
      } else if (Array.isArray(rule)) {
        ret = id.replace(rule[0], rule[1]);
      }

      // must be string
      if (!ret || !is.string(ret)) {
        ret = id;
      }

      // only apply the first matched rule
      if (ret !== id) break;
    }
  }

  return ret;
}

/**
 * normalize path
 * @param path
 * @returns {string}
 */
function normalize(path){
  path = path.replace(/\\+/g, '/');
  path = path.replace(/([^:/])\/+\//g, '$1/');
  path = path.replace(/(:)?\/{2,}/, '$1//');

  return path;
}

/**
 * resolve a `relative` path base on `base` path
 * @param relative
 * @param vinyl
 * @param wwwroot
 * @returns {string}
 */
function resolve(relative, vinyl, wwwroot){
  var base;
  var absolute;

  // debug
  debug('resolve path: %s', colors.magenta(normalize(relative)));

  // resolve
  if (isRelative(relative)) {
    base = dirname(vinyl.path);
    absolute = join(base, relative);

    // out of base, use wwwroot
    if (isOutBound(absolute, wwwroot)) {
      throwError('file: %s is out of bound of wwwroot: %s.', normalize(absolute), normalize(wwwroot));
    }
  } else if (isAbsolute(relative)) {
    base = wwwroot;
    absolute = join(base, relative.substring(1));
  } else {
    base = join(vinyl.cwd, vinyl.base);
    absolute = join(base, relative);
  }

  // debug
  debug('of base path: %s', colors.magenta(pathFromCwd(base)));
  debug('to: %s', colors.magenta(pathFromCwd(absolute)));

  return absolute;
}

/**
 * add .js if not exists
 * @param path
 * @returns {*}
 */
function addExt(path){
  return extname(path) === '.js' ? path : (path + '.js');
}

/**
 * hide .js if exists
 * @param path
 * @returns {*}
 */
function hideExt(path){
  return extname(path) === '.js' ? path.replace(/\.js$/, '') : path;
}

/**
 * test path is relative path or not
 * @param path
 * @returns {boolean}
 */
function isRelative(path){
  return /^\.{1,2}[\\/]/.test(path);
}

/**
 * test path is absolute path or not
 * @param path
 * @returns {boolean}
 */
function isAbsolute(path){
  return /^[\\/](?:[^\\/]|$)/.test(path);
}

/**
 * test path is local path or not
 * @param path
 * @returns {boolean}
 */
function isLocal(path){
  return !/^https?:\/\/|^\/\//.test(path) && !/^data:/.test(path);
}

/**
 * test path is out of bound of base
 * @param path
 * @param base
 * @returns {boolean}
 */
function isOutBound(path, base){
  return OUTBOUNDRE.test(relative(base, path));
}

/**
 * Get relative path from cwd
 * @param path
 * @returns {string}
 */

function pathFromCwd(path){
  return normalize(relative(cwd, path)) || './';
}

/**
 * plugin error
 */
function throwError(){
  var slice = [].slice;
  var message = util.format
    .apply(null, slice.call(arguments));

  throw new Error(message);
}

/**
 * node extend
 * Copyright 2011, John Resig
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * @fileoverview
 * Port of jQuery.extend that actually works on node.js
 */
function extend(){
  var target = arguments[0] || {};
  var i = 1;
  var length = arguments.length;
  var deep = false;
  var options, name, src, copy, copyIsArray, clone;

  // handle a deep copy situation
  if (is.bool(target)) {
    deep = target;
    target = arguments[1] || {};
    // skip the boolean and the target
    i = 2;
  }

  // handle case when target is a string or something (possible in deep copy)
  if ((typeof target !== 'object' && !is.fn(target)) || target === null) {
    target = {};
  }

  for (; i < length; i++) {
    // only deal with non-null/undefined values
    options = arguments[i];

    if (options !== null) {
      // extend the base object
      for (name in options) {
        if (options.hasOwnProperty(name)) {
          src = target[name];
          copy = options[name];

          // prevent never-ending loop
          if (target === copy) {
            continue;
          }

          // recurse if we're merging plain objects or arrays
          if (deep && copy && (is.hash(copy) || (copyIsArray = Array.isArray(copy)))) {
            if (copyIsArray) {
              copyIsArray = false;
              clone = src && Array.isArray(src) ? src : [];
            } else {
              clone = src && is.hash(src) ? src : {};
            }

            // never move original objects, clone them
            target[name] = extend(deep, clone, copy);

            // don't bring in undefined values
          } else if (typeof copy !== 'undefined') {
            target[name] = copy;
          }
        }
      }
    }
  }

  // return the modified object
  return target;
}

/**
 * wrap module
 * @param id
 * @param deps
 * @param code
 * @returns {string}
 */
function wrapModule(id, deps, code){
  // header and footer template string
  var headerTpl = 'define({{id}}, {{deps}}, function(require, exports, module){';
  var footerTpl = '});\n';

  if (Buffer.isBuffer(code)) code = code.toString();

  // debug
  debug('compile module: %s', colors.magenta(id));

  id = JSON.stringify(id);
  deps = JSON.stringify(deps);

  return template(headerTpl, { id: id, deps: deps })
    + '\n' + code + '\n' + footerTpl;
}

/**
 * print message
 */
function print(){
  var slice = [].slice;
  var message = util.format
    .apply(null, slice.call(arguments));

  process.stdout.write(colors.cyan.bold('  gulp-cmd ') + message + '\n');
}

/**
 * exports module.
 */
module.exports.cwd = cwd;
module.exports.colors = colors;
module.exports.debug = debug;
module.exports.parsePackage = parsePackage;
module.exports.template = template;
module.exports.plugin = plugin;
module.exports.parseAlias = parseAlias;
module.exports.parsePaths = parsePaths;
module.exports.parseVars = parseVars;
module.exports.parseMap = parseMap;
module.exports.normalize = normalize;
module.exports.resolve = resolve;
module.exports.addExt = addExt;
module.exports.hideExt = hideExt;
module.exports.isRelative = isRelative;
module.exports.isAbsolute = isAbsolute;
module.exports.isLocal = isLocal;
module.exports.isOutBound = isOutBound;
module.exports.pathFromCwd = pathFromCwd;
module.exports.throwError = throwError;
module.exports.extend = extend;
module.exports.wrapModule = wrapModule;
module.exports.print = print;
<commit_msg>update files<commit_after>/**
 * Created by nuintun on 2015/4/27.
 */

'use strict';

var is = require('is');
var path = require('path');
var join = path.join;
var extname = path.extname;
var dirname = path.dirname;
var basename = path.basename;
var relative = path.relative;
var util = require('util');
var colors = require('colors/safe');
var debug = require('debug')('gulp-cmd');

// variable declaration
var cwd = process.cwd();
var OUTBOUNDRE = /(?:^[\\\/]?)\.\.(?:[\\\/]|$)/;
var PATHSRE = /^([^/:]+)(\/.+)$/;
var VARSRE = /{([^{]+)}/g;

// set debug color use 6
debug.color = 6;

/**
 * parse package form vinyl
 * @param vinyl
 * @param wwwroot
 * @returns {object}
 */
function parsePackage(vinyl, wwwroot){
  var relative = vinyl.relative;

  // vinyl not in base dir, user wwwroot
  if (OUTBOUNDRE.test(relative)) {
    relative = path.relative(wwwroot, vinyl.path);
    // vinyl not in wwwroot, throw error
    if (OUTBOUNDRE.test(relative)) {
      throwError('file: %s is out of bound of wwwroot: %s.', normalize(vinyl.path), normalize(wwwroot));
    }

    // reset relative
    relative = path.join('/', relative);
  }

  var dir = normalize(dirname(relative));
  var filename = basename(relative);
  var SPLITRE = /\/((?:\d+\.){2}\d+)(?:\/|$)/;
  var match = dir.split(SPLITRE);

  return {
    name: match[0] || '',
    version: match[1] || '',
    file: match[2] ? match[2] + '/' + filename : filename
  }
}

/**
 * simple template
 * @param format
 * @param data
 * @returns {string}
 * ```
 * var tpl = '{{name}}/{{version}}';
 * util.template(tpl, {name:'base', version: '1.0.0'});
 * ```
 */
function template(format, data){
  if (!is.string(format)) return '';

  return format.replace(/{{([a-z]*)}}/gi, function (all, match){
    return data[match] || '';
  });
}

/**
 * create a plugin
 * @param name
 * @param transport
 * @returns {Function}
 */
function plugin(name, transport){
  return function (vinyl, options){
    // debug
    debug('load plugin: %s', colors.green(name));
    // debug
    debug('read file: %s', colors.magenta(pathFromCwd(vinyl.path)));

    vinyl = transport(vinyl, options);

    // normalize package
    if (!vinyl.package) {
      vinyl.package = {};
    }

    return vinyl;
  };
}

/**
 * parse alias
 * @param id
 * @param alias
 * @returns {String}
 */
function parseAlias(id, alias){
  alias = alias || {};

  return alias && is.string(alias[id]) ? alias[id] : id;
}

/**
 * parse paths
 * @param id
 * @param paths
 * @returns {String}
 */
function parsePaths(id, paths){
  var match;

  paths = paths || {};

  if (paths && (match = id.match(PATHSRE)) && is.string(paths[match[1]])) {
    id = paths[match[1]] + match[2];
  }

  return id;
}

/**
 * parse vars
 * @param id
 * @param vars
 * @returns {String}
 */
function parseVars(id, vars){
  vars = vars || {};

  if (vars && id.indexOf('{') > -1) {
    id = id.replace(VARSRE, function (match, key){
      return is.string(vars[key]) ? vars[key] : match;
    });
  }

  return id;
}

/**
 * parse map
 * @param id
 * @param map
 * @returns {String}
 */
function parseMap(id, map){
  var ret = id;

  if (Array.isArray(map)) {
    for (var i = 0, len = map.length; i < len; i++) {
      var rule = map[i];

      // parse map
      if (is.fn(rule)) {
        ret = rule(id);
      } else if (Array.isArray(rule)) {
        ret = id.replace(rule[0], rule[1]);
      }

      // must be string
      if (!ret || !is.string(ret)) {
        ret = id;
      }

      // only apply the first matched rule
      if (ret !== id) break;
    }
  }

  return ret;
}

/**
 * normalize path
 * @param path
 * @returns {string}
 */
function normalize(path){
  path = path.replace(/\\+/g, '/');
  path = path.replace(/([^:/])\/+\//g, '$1/');
  path = path.replace(/(:)?\/{2,}/, '$1//');

  return path;
}

/**
 * resolve a `relative` path base on `base` path
 * @param relative
 * @param vinyl
 * @param wwwroot
 * @returns {string}
 */
function resolve(relative, vinyl, wwwroot){
  var base;
  var absolute;

  // debug
  debug('resolve path: %s', colors.magenta(normalize(relative)));

  // resolve
  if (isRelative(relative)) {
    base = dirname(vinyl.path);
    absolute = join(base, relative);

    // out of base, use wwwroot
    if (isOutBound(absolute, wwwroot)) {
      throwError('file: %s is out of bound of wwwroot: %s.', normalize(absolute), normalize(wwwroot));
    }
  } else if (isAbsolute(relative)) {
    base = wwwroot;
    absolute = join(base, relative.substring(1));
  } else {
    base = join(vinyl.cwd, vinyl.base);
    absolute = join(base, relative);
  }

  // debug
  debug('of base path: %s', colors.magenta(pathFromCwd(base)));
  debug('to: %s', colors.magenta(pathFromCwd(absolute)));

  return absolute;
}

/**
 * add .js if not exists
 * @param path
 * @returns {*}
 */
function addExt(path){
  return extname(path) === '.js' ? path : (path + '.js');
}

/**
 * hide .js if exists
 * @param path
 * @returns {*}
 */
function hideExt(path){
  return extname(path) === '.js' ? path.replace(/\.js$/, '') : path;
}

/**
 * test path is relative path or not
 * @param path
 * @returns {boolean}
 */
function isRelative(path){
  return /^\.{1,2}[\\/]/.test(path);
}

/**
 * test path is absolute path or not
 * @param path
 * @returns {boolean}
 */
function isAbsolute(path){
  return /^[\\/](?:[^\\/]|$)/.test(path);
}

/**
 * test path is local path or not
 * @param path
 * @returns {boolean}
 */
function isLocal(path){
  return !/^\w*?:\/\/|^\/\//.test(path) && !/^data:\w+?\/\w+?[,;]/i.test(path);
}

/**
 * test path is out of bound of base
 * @param path
 * @param base
 * @returns {boolean}
 */
function isOutBound(path, base){
  return OUTBOUNDRE.test(relative(base, path));
}

/**
 * Get relative path from cwd
 * @param path
 * @returns {string}
 */

function pathFromCwd(path){
  return normalize(relative(cwd, path)) || './';
}

/**
 * plugin error
 */
function throwError(){
  var slice = [].slice;
  var message = util.format
    .apply(null, slice.call(arguments));

  throw new Error(message);
}

/**
 * node extend
 * Copyright 2011, John Resig
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * @fileoverview
 * Port of jQuery.extend that actually works on node.js
 */
function extend(){
  var target = arguments[0] || {};
  var i = 1;
  var length = arguments.length;
  var deep = false;
  var options, name, src, copy, copyIsArray, clone;

  // handle a deep copy situation
  if (is.bool(target)) {
    deep = target;
    target = arguments[1] || {};
    // skip the boolean and the target
    i = 2;
  }

  // handle case when target is a string or something (possible in deep copy)
  if ((typeof target !== 'object' && !is.fn(target)) || target === null) {
    target = {};
  }

  for (; i < length; i++) {
    // only deal with non-null/undefined values
    options = arguments[i];

    if (options !== null) {
      // extend the base object
      for (name in options) {
        if (options.hasOwnProperty(name)) {
          src = target[name];
          copy = options[name];

          // prevent never-ending loop
          if (target === copy) {
            continue;
          }

          // recurse if we're merging plain objects or arrays
          if (deep && copy && (is.hash(copy) || (copyIsArray = Array.isArray(copy)))) {
            if (copyIsArray) {
              copyIsArray = false;
              clone = src && Array.isArray(src) ? src : [];
            } else {
              clone = src && is.hash(src) ? src : {};
            }

            // never move original objects, clone them
            target[name] = extend(deep, clone, copy);

            // don't bring in undefined values
          } else if (typeof copy !== 'undefined') {
            target[name] = copy;
          }
        }
      }
    }
  }

  // return the modified object
  return target;
}

/**
 * wrap module
 * @param id
 * @param deps
 * @param code
 * @returns {string}
 */
function wrapModule(id, deps, code){
  // header and footer template string
  var headerTpl = 'define({{id}}, {{deps}}, function(require, exports, module){';
  var footerTpl = '});\n';

  if (Buffer.isBuffer(code)) code = code.toString();

  // debug
  debug('compile module: %s', colors.magenta(id));

  id = JSON.stringify(id);
  deps = JSON.stringify(deps);

  return template(headerTpl, { id: id, deps: deps })
    + '\n' + code + '\n' + footerTpl;
}

/**
 * print message
 */
function print(){
  var slice = [].slice;
  var message = util.format
    .apply(null, slice.call(arguments));

  process.stdout.write(colors.cyan.bold('  gulp-cmd ') + message + '\n');
}

/**
 * exports module.
 */
module.exports.cwd = cwd;
module.exports.colors = colors;
module.exports.debug = debug;
module.exports.parsePackage = parsePackage;
module.exports.template = template;
module.exports.plugin = plugin;
module.exports.parseAlias = parseAlias;
module.exports.parsePaths = parsePaths;
module.exports.parseVars = parseVars;
module.exports.parseMap = parseMap;
module.exports.normalize = normalize;
module.exports.resolve = resolve;
module.exports.addExt = addExt;
module.exports.hideExt = hideExt;
module.exports.isRelative = isRelative;
module.exports.isAbsolute = isAbsolute;
module.exports.isLocal = isLocal;
module.exports.isOutBound = isOutBound;
module.exports.pathFromCwd = pathFromCwd;
module.exports.throwError = throwError;
module.exports.extend = extend;
module.exports.wrapModule = wrapModule;
module.exports.print = print;
<|endoftext|>


<commit_before>/*!
 * util
 * Version: 0.0.1
 * Date: 2016/7/29
 * https://github.com/Nuintun/fengine
 *
 * This is licensed under the MIT License (MIT).
 * For details, see: https://github.com/Nuintun/fengine/blob/master/LICENSE
 */

'use strict';

// prototype method
var toString = Object.prototype.toString;
var getPrototypeOf = Object.getPrototypeOf;
var hasOwnProperty = Object.prototype.hasOwnProperty;
var fnToString = hasOwnProperty.toString;
var objectFunctionString = fnToString.call(Object);

// variable declaration
var BACKSLASH_RE = /\\/g;
var DOT_RE = /\/\.\//g;
var DOUBLE_DOT_RE = /\/[^/]+\/\.\.\//;
var MULTI_SLASH_RE = /([^:/])\/+\//g;
var PROTOCOL_SLASH_RE = /(:)?\/{2,}/;
var REGEXSYMBOLRE = /[\[\]\\.^|()*+$:?!-]/g;

/**
 * is array
 * @type {Function}
 */
var isArray = Array.isArray ? Array.isArray : function (value){
  return type(value) === 'array';
};

/**
 * type
 * @param value
 * @returns {*}
 */
function type(value){
  // get real type
  var type = toString.call(value).toLowerCase();

  type = type.replace(/\[object (.+)]/, '$1').toLowerCase();

  // nan and infinity
  if (type === 'number') {
    // nan
    if (value !== value) {
      return 'nan';
    }

    // infinity
    if (value === Infinity || value === -Infinity) {
      return 'infinity';
    }
  }

  // return type
  return type;
}

/**
 * is function
 * @param value
 * @returns {boolean}
 */
function isFunction(value){
  return type(value) === 'function';
}

/**
 * is plain object
 * @param value
 * @returns {*}
 */
function isPlainObject(value){
  var proto, ctor;

  // detect obvious negatives
  // use toString instead of jQuery.type to catch host objects
  if (!value || type(value) !== 'object') {
    return false;
  }

  // proto
  proto = getPrototypeOf(value);

  // objects with no prototype (e.g., `Object.create( null )`) are plain
  if (!proto) {
    return true;
  }

  // objects with prototype are plain iff they were constructed by a global Object function
  ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;

  return typeof ctor === 'function' && fnToString.call(ctor) === objectFunctionString;
}

/**
 * extend
 * @returns {*}
 */
function extend(){
  var i = 1;
  var deep = false;
  var length = arguments.length;
  var target = arguments[0] || {};
  var options, name, src, copy, copyIsArray, clone;

  // handle a deep copy situation
  if (typeof target === 'boolean') {
    deep = target;
    // skip the boolean and the target
    target = arguments[i++] || {};
  }

  // handle case when target is a string or something (possible in deep copy)
  if (typeof target !== 'object' && !isFunction(target)) {
    target = {};
  }

  for (; i < length; i++) {
    // only deal with non-null/undefined values
    if ((options = arguments[i]) != null) {
      // extend the base object
      for (name in options) {
        // only copy own property
        if (!options.hasOwnProperty(name)) {
          continue;
        }

        src = target[name];
        copy = options[name];

        // prevent never-ending loop
        if (target === copy) {
          continue;
        }

        // recurse if we're merging plain objects or arrays
        if (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) {
          if (copyIsArray) {
            copyIsArray = false;
            clone = src && isArray(src) ? src : [];
          } else {
            clone = src && isPlainObject(src) ? src : {};
          }

          // never move original objects, clone them
          target[name] = extend(deep, clone, copy);
        } else if (copy !== undefined) {
          // don't bring in undefined values
          target[name] = copy;
        }
      }
    }
  }

  // return the modified object
  return target;
}

/**
 * string for regex
 * @param string
 * @returns {void|XML}
 */
function str4regex(string){
  return string.replace(REGEXSYMBOLRE, function (symbol){
    return '\\' + symbol;
  });
}

// exports
module.exports = {
  type: type,
  fn: isFunction,
  extend: extend,
  string: function (value){
    return type(value) === 'string';
  },
  array: isArray,
  number: function (value){
    return type(value) === 'number';
  },
  str4regex: str4regex,
  /**
   * normalize path
   * @param path
   * @returns {string}
   */
  normalize: function (path){
    // \a\b\.\c\.\d ==> /a/b/./c/./d
    path = path.replace(BACKSLASH_RE, '/');

    // :///a/b/c ==> ://a/b/c
    path = path.replace(PROTOCOL_SLASH_RE, '$1//');

    // /a/b/./c/./d ==> /a/b/c/d
    path = path.replace(DOT_RE, '/');

    // @author wh1100717
    // a//b/c ==> a/b/c
    // a///b/////c ==> a/b/c
    // DOUBLE_DOT_RE matches a/b/c//../d path correctly only if replace // with / first
    path = path.replace(MULTI_SLASH_RE, '$1/');

    // a/b/c/../../d  ==>  a/b/../d  ==>  a/d
    while (path.match(DOUBLE_DOT_RE)) {
      path = path.replace(DOUBLE_DOT_RE, '/');
    }

    // get path
    return path;
  }
};
<commit_msg>update deps<commit_after>/*!
 * util
 * Version: 0.0.1
 * Date: 2016/7/29
 * https://github.com/Nuintun/fengine
 *
 * This is licensed under the MIT License (MIT).
 * For details, see: https://github.com/Nuintun/fengine/blob/master/LICENSE
 */

'use strict';

// prototype method
var toString = Object.prototype.toString;
var getPrototypeOf = Object.getPrototypeOf;
var hasOwnProperty = Object.prototype.hasOwnProperty;
var fnToString = hasOwnProperty.toString;
var objectFunctionString = fnToString.call(Object);

// variable declaration
var BACKSLASH_RE = /\\/g;
var DOT_RE = /\/\.\//g;
var DOUBLE_DOT_RE = /\/[^/]+\/\.\.\//;
var MULTI_SLASH_RE = /([^:/])\/+\//g;
var PROTOCOL_SLASH_RE = /(:)?\/{2,}/;
var REGEXSYMBOLRE = /[\[\]\\.^|()*+$:?!-]/g;

/**
 * is array
 * @type {Function}
 */
var isArray = Array.isArray ? Array.isArray : function (value){
  return type(value) === 'array';
};

/**
 * type
 * @param value
 * @returns {*}
 */
function type(value){
  // get real type
  var type = toString.call(value).toLowerCase();

  type = type.replace(/\[object (.+)]/, '$1').toLowerCase();

  // nan and infinity
  if (type === 'number') {
    // nan
    if (value !== value) {
      return 'nan';
    }

    // infinity
    if (value === Infinity || value === -Infinity) {
      return 'infinity';
    }
  }

  // return type
  return type;
}

/**
 * is function
 * @param value
 * @returns {boolean}
 */
function isFunction(value){
  return type(value) === 'function';
}

/**
 * is plain object
 * @param value
 * @returns {*}
 */
function isPlainObject(value){
  var proto, ctor;

  // detect obvious negatives
  // use toString instead of jQuery.type to catch host objects
  if (!value || type(value) !== 'object') {
    return false;
  }

  // proto
  proto = getPrototypeOf(value);

  // objects with no prototype (e.g., `Object.create( null )`) are plain
  if (!proto) {
    return true;
  }

  // objects with prototype are plain iff they were constructed by a global Object function
  ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;

  return typeof ctor === 'function' && fnToString.call(ctor) === objectFunctionString;
}

/**
 * extend
 * @returns {*}
 */
function extend(){
  var i = 1;
  var deep = false;
  var length = arguments.length;
  var target = arguments[0] || {};
  var options, name, src, copy, copyIsArray, clone;

  // handle a deep copy situation
  if (typeof target === 'boolean') {
    deep = target;
    // skip the boolean and the target
    target = arguments[i++] || {};
  }

  // handle case when target is a string or something (possible in deep copy)
  if (typeof target !== 'object' && !isFunction(target)) {
    target = {};
  }

  for (; i < length; i++) {
    // only deal with non-null/undefined values
    if ((options = arguments[i]) != null) {
      // extend the base object
      for (name in options) {
        // only copy own property
        if (!options.hasOwnProperty(name)) {
          continue;
        }

        src = target[name];
        copy = options[name];

        // prevent never-ending loop
        if (target === copy) {
          continue;
        }

        // recurse if we're merging plain objects or arrays
        if (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) {
          if (copyIsArray) {
            copyIsArray = false;
            clone = src && isArray(src) ? src : [];
          } else {
            clone = src && isPlainObject(src) ? src : {};
          }

          // never move original objects, clone them
          target[name] = extend(deep, clone, copy);
        } else if (copy !== undefined) {
          // don't bring in undefined values
          target[name] = copy;
        }
      }
    }
  }

  // return the modified object
  return target;
}

/**
 * string for regex
 * @param string
 * @returns {void|XML}
 */
function str4regex(string){
  return string.replace(REGEXSYMBOLRE, '\\$&');
}

// exports
module.exports = {
  type: type,
  fn: isFunction,
  extend: extend,
  string: function (value){
    return type(value) === 'string';
  },
  array: isArray,
  number: function (value){
    return type(value) === 'number';
  },
  str4regex: str4regex,
  /**
   * normalize path
   * @param path
   * @returns {string}
   */
  normalize: function (path){
    // \a\b\.\c\.\d ==> /a/b/./c/./d
    path = path.replace(BACKSLASH_RE, '/');

    // :///a/b/c ==> ://a/b/c
    path = path.replace(PROTOCOL_SLASH_RE, '$1//');

    // /a/b/./c/./d ==> /a/b/c/d
    path = path.replace(DOT_RE, '/');

    // @author wh1100717
    // a//b/c ==> a/b/c
    // a///b/////c ==> a/b/c
    // DOUBLE_DOT_RE matches a/b/c//../d path correctly only if replace // with / first
    path = path.replace(MULTI_SLASH_RE, '$1/');

    // a/b/c/../../d  ==>  a/b/../d  ==>  a/d
    while (path.match(DOUBLE_DOT_RE)) {
      path = path.replace(DOUBLE_DOT_RE, '/');
    }

    // get path
    return path;
  }
};
<|endoftext|>


<commit_before>(function(scope) {
    'use strict';

    var Scope = scope.window ? window : global;

    /* global rendy */

    if (typeof module === 'object' && module.exports)
        module.exports = new UtilProto();
    else if (!Scope.Util)
        Scope.Util = new UtilProto();

    function UtilProto() {
        var Util = this;

        this.check              = new checkProto();

        function checkProto() {
            /**
             * Check is all arguments with names present
             *
             * @param name
             * @param arg
             * @param type
             */
            var check = function check(args, names) {
                var msg         = '',
                    name        = '',
                    template    = '{{ name }} coud not be empty!',

                    indexOf     = Array.prototype.indexOf,

                    lenNames    = names.length,
                    lenArgs     = args.length,
                    lessArgs    = lenArgs < lenNames,
                    emptyIndex  = indexOf.call(args),
                    isEmpty     = ~emptyIndex && emptyIndex <= lenNames - 1;

                if (lessArgs || isEmpty) {
                    if (lessArgs)
                        name        = names[lenNames - 1];
                    else
                        name        = names[emptyIndex];

                    msg         = rendy(template, {
                        name: name
                    });

                    throw(Error(msg));
                }

                return check;
            };

            check.check = check;

            /**
             * Check is type of arg with name is equal to type
             *
             * @param name
             * @param arg
             * @param type
             */
            check.type  = function(name, arg, type) {
                var is = Util.type(arg) === type;

                if (!is)
                    throw(Error(name + ' should be ' + type));

                return check;
            };

            return check;
        }

        /**
         * Copy properties from from to to
         *
         * @param from
         * @param to
         */
        this.copyObj                = function(to, from) {
            if (!from) {
                from    = to;
                to      = {};
            }

            if (to)
                Object.keys(from).forEach(function(name) {
                    to[name]    = from[name];
                });

            return to;
        };

        /**
         * copy objFrom properties to target
         *
         * @target
         * @objFrom
         */
        this.extend                 = function(target, objFrom) {
            var obj,
                keys,
                proto,
                isFunc  = Util.type.function(objFrom),
                isArray = Util.type.array(objFrom),
                isObj   = Util.type.object(target),
                ret     = isObj ? target : {};

            if (isArray)
                objFrom.forEach(function(item) {
                   ret = Util.extend(target, item);
                });

            else if (objFrom) {
                obj     = isFunc ? new objFrom() : objFrom;
                keys    = Object.keys(obj);

                if (!keys.length) {
                    proto = Object.getPrototypeOf(objFrom);
                    keys  = Object.keys(proto);
                }

                keys.forEach(function(name) {
                    ret[name] = obj[name];
                });
            }

            return ret;
        };

        /**
         * extend proto
         *
         * @obj
         */
        this.extendProto           = function(obj) {
            var ret, F      = function() {};
            F.prototype     = Util.extend({}, obj);
            ret             = new F();

            return ret;
        };

        this.json               = new JsonProto();

        function JsonProto() {
            /**
             * @param str
             */
            this.parse      = function(str) {
                var obj;

                Util.exec.try(function() {
                    obj = JSON.parse(str);
                });

                return obj;
            },

            /**
             * @param obj
             */
            this.stringify  = function(obj) {
                var str;

                Util.exec.try(function() {
                    str = JSON.stringify(obj, null, 4);
                });

                return str;
            };
        }

        this.escapeRegExp = function(str) {
            var isStr   = Util.type.string(str);

            if (isStr)
                str = str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');

            return str;
        };

        /**
         * get regexp from wild card
         */
        this.getRegExp              = function(wildcard) {
            var regExp;

            if (!wildcard)
                wildcard = '*';

            wildcard    = '^' + wildcard /* search from start of line */
                .replace('.', '\\.')
                .replace('*', '.*')
                .replace('?', '.?');

            wildcard    += '$'; /* search to end of line */

            regExp      = new RegExp(wildcard);

            return regExp;
        };

        this.type                   = new TypeProto();

        function TypeProto() {
            /**
             * get type of variable
             *
             * @param variable
             */
            function type(variable) {
                var regExp      = /\s([a-zA-Z]+)/,
                    str         = {}.toString.call(variable),
                    typeBig     = str.match(regExp)[1],
                    result      = typeBig.toLowerCase();

                return result;
            }

            /**
             * functions check is variable is type of name
             *
             * @param variable
             */
            function typeOf(name, variable) {
                return type(variable) === name;
            }

            function typeOfSimple(name, variable) {
                return typeof variable === name;
            }

            ['null', 'arrayBuffer', 'file', 'array', 'object']
                .forEach(function(name) {
                    type[name] = typeOf.bind(null, name);
                });

            ['string', 'undefined', 'boolean', 'number', 'function']
                .forEach(function(name) {
                    type[name] = typeOfSimple.bind(null, name);
                });

            return type;
        }

        this.exec                       = new ExecProto();

        function ExecProto() {
            /**
             * function do save exec of function
             * @param callback
             * @param arg1
             * ...
             * @param argN
             */
            var exec        = function(callback) {
                var ret,
                    isFunc  = Util.type.function(callback),
                    args    = [].slice.call(arguments, 1);

                if (isFunc)
                    ret     = callback.apply(null, args);

                return ret;
            };

            /*
             * return function that calls callback with arguments
             */

            exec.with           =  function(callback) {
                var args        = [].slice.call(arguments, 1);

                return callback.bind(null, args);
            };

             /**
             * return save exec function
             * @param callback
             */
            exec.ret        = function() {
                var result,
                    args        = [].slice.call(arguments);

                args.unshift(exec);
                result          = exec.with.apply(null, args);

                return result;
            };

            /**
             * function do conditional save exec of function
             * @param condition
             * @param callback
             * @param func
             */
            exec.if         = function(condition, callback, func) {
                var ret;

                if (condition)
                    exec(callback);
                else
                    exec(func, callback);

                return ret;
            };

            /**
             * exec function if it exist in object
             *
             * @param obj
             * @param name
             * @param arg
             */
            exec.ifExist                = function(obj, name, arg) {
                var ret,
                    func    = obj && obj[name];

                if (func)
                    func    = func.apply(obj, arg);

                return ret;
            };

            exec.parallel   = function(funcs, callback) {
                var keys        = [],
                    callbackWas = false,
                    arr         = [],
                    obj         = {},
                    count       = 0,
                    countFuncs  = 0,
                    type        = Util.type(funcs);

                Util.check(arguments, ['funcs', 'callback']);

                switch(type) {
                case 'array':
                    countFuncs  = funcs.length;

                    funcs.forEach(function(func, num) {
                        exec(func, function() {
                            checkFunc(num, arguments, arr);
                        });
                    });
                    break;

                case 'object':
                    keys        = Object.keys(funcs);
                    countFuncs  = keys.length;

                    keys.forEach(function(name) {
                        var func    = funcs[name];

                        exec(func, function() {
                            checkFunc(name, arguments, obj);
                        });
                    });
                    break;
                }

                function checkFunc(num, data, all) {
                    var args    = [].slice.call(data, 1),
                        isLast  = false,
                        error   = data[0],
                        length  = args.length;

                    ++count;

                    isLast = count === countFuncs;

                    if (!error)
                        if (length >= 2)
                            all[num] = args;
                        else
                            all[num] = args[0];

                    if (!callbackWas && (error || isLast)) {
                        callbackWas = true;

                        if (type === 'array')
                            callback.apply(null, [error].concat(all));
                        else
                            callback(error, all);
                    }
                }
            };

            /**
             * load functions thrue callbacks one-by-one
             * @param funcs {Array} - array of functions
             */
            exec.series             = function(funcs) {
                var func, callback,
                    isArray     = Util.type.array(funcs);

                if (isArray) {
                    func        = funcs.shift();

                    callback    = function() {
                        return exec.series(funcs);
                    };

                    exec(func, callback);
                }
            };

           /**
             * function execute param function in
             * try...catch block
             *
             * @param callback
             */
            exec.try                = function(callback) {
                var ret;
                try {
                    ret = callback();
                } catch(error) {
                    ret = error;
                }

                return ret;
            };

            return exec;
        }

        /**
         * function gets file extension
         *
         * @param pFileName
         * @return Ext
         */
        this.getExt                     = function(name) {
            var ret     = '',
                dot,
                isStr   = Util.type.string(name);

            if (isStr) {
                dot = name.lastIndexOf('.');

                if (~dot)
                    ret = name.substr(dot);
            }

            return ret;
        };

       /**
         * get values from Object Array name properties
         * or
         * @pObj
         */
        this.getNamesFromObjArray       = function(arr) {
            var ret     = [];

            if (!Array.isArray(arr))
                throw(Error('arr should be array!'));

            ret = arr.map(function(item) {
                return item.name;
            });

            return ret;
        };

        /**
         * find object by name in arrray
         *
         * @param array
         * @param name
         */
        this.findObjByNameInArr         = function(array, name) {
            var ret;

             if (!Array.isArray(array))
                throw(Error('array should be array!'));

            if (typeof name !== 'string')
                throw(Error('name should be string!'));

            array.some(function(item) {
                var is = item.name === name,
                    isArray = Util.type.array(item);

                if (is)
                    ret = item;
                else if (isArray)
                    item.some(function(item) {
                        is = item.name === name;

                        if (is)
                            ret = item.data;

                        return is;
                    });

                return is;
            });

            return ret;
        };

        /**
         * start timer
         * @param name
         */
        this.time                       = function(name) {
            var console     = Scope.console;

            Util.exec.ifExist(console, 'time', [name]);

            return this;
        };

        /**
         * stop timer
         * @param name
         */
        this.timeEnd                   = function(name) {
            var console    = Scope.console;

            Util.exec.ifExist(console, 'timeEnd', [name]);

            return this;
        };
    }

})(this);
<commit_msg>feature(util) exec.with: callback.bind -> bind.apply<commit_after>(function(scope) {
    'use strict';

    var Scope = scope.window ? window : global;

    /* global rendy */

    if (typeof module === 'object' && module.exports)
        module.exports = new UtilProto();
    else if (!Scope.Util)
        Scope.Util = new UtilProto();

    function UtilProto() {
        var Util = this;

        this.check              = new checkProto();

        function checkProto() {
            /**
             * Check is all arguments with names present
             *
             * @param name
             * @param arg
             * @param type
             */
            var check = function check(args, names) {
                var msg         = '',
                    name        = '',
                    template    = '{{ name }} coud not be empty!',

                    indexOf     = Array.prototype.indexOf,

                    lenNames    = names.length,
                    lenArgs     = args.length,
                    lessArgs    = lenArgs < lenNames,
                    emptyIndex  = indexOf.call(args),
                    isEmpty     = ~emptyIndex && emptyIndex <= lenNames - 1;

                if (lessArgs || isEmpty) {
                    if (lessArgs)
                        name        = names[lenNames - 1];
                    else
                        name        = names[emptyIndex];

                    msg         = rendy(template, {
                        name: name
                    });

                    throw(Error(msg));
                }

                return check;
            };

            check.check = check;

            /**
             * Check is type of arg with name is equal to type
             *
             * @param name
             * @param arg
             * @param type
             */
            check.type  = function(name, arg, type) {
                var is = Util.type(arg) === type;

                if (!is)
                    throw(Error(name + ' should be ' + type));

                return check;
            };

            return check;
        }

        /**
         * Copy properties from from to to
         *
         * @param from
         * @param to
         */
        this.copyObj                = function(to, from) {
            if (!from) {
                from    = to;
                to      = {};
            }

            if (to)
                Object.keys(from).forEach(function(name) {
                    to[name]    = from[name];
                });

            return to;
        };

        /**
         * copy objFrom properties to target
         *
         * @target
         * @objFrom
         */
        this.extend                 = function(target, objFrom) {
            var obj,
                keys,
                proto,
                isFunc  = Util.type.function(objFrom),
                isArray = Util.type.array(objFrom),
                isObj   = Util.type.object(target),
                ret     = isObj ? target : {};

            if (isArray)
                objFrom.forEach(function(item) {
                   ret = Util.extend(target, item);
                });

            else if (objFrom) {
                obj     = isFunc ? new objFrom() : objFrom;
                keys    = Object.keys(obj);

                if (!keys.length) {
                    proto = Object.getPrototypeOf(objFrom);
                    keys  = Object.keys(proto);
                }

                keys.forEach(function(name) {
                    ret[name] = obj[name];
                });
            }

            return ret;
        };

        /**
         * extend proto
         *
         * @obj
         */
        this.extendProto           = function(obj) {
            var ret, F      = function() {};
            F.prototype     = Util.extend({}, obj);
            ret             = new F();

            return ret;
        };

        this.json               = new JsonProto();

        function JsonProto() {
            /**
             * @param str
             */
            this.parse      = function(str) {
                var obj;

                Util.exec.try(function() {
                    obj = JSON.parse(str);
                });

                return obj;
            },

            /**
             * @param obj
             */
            this.stringify  = function(obj) {
                var str;

                Util.exec.try(function() {
                    str = JSON.stringify(obj, null, 4);
                });

                return str;
            };
        }

        this.escapeRegExp = function(str) {
            var isStr   = Util.type.string(str);

            if (isStr)
                str = str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');

            return str;
        };

        /**
         * get regexp from wild card
         */
        this.getRegExp              = function(wildcard) {
            var regExp;

            if (!wildcard)
                wildcard = '*';

            wildcard    = '^' + wildcard /* search from start of line */
                .replace('.', '\\.')
                .replace('*', '.*')
                .replace('?', '.?');

            wildcard    += '$'; /* search to end of line */

            regExp      = new RegExp(wildcard);

            return regExp;
        };

        this.type                   = new TypeProto();

        function TypeProto() {
            /**
             * get type of variable
             *
             * @param variable
             */
            function type(variable) {
                var regExp      = /\s([a-zA-Z]+)/,
                    str         = {}.toString.call(variable),
                    typeBig     = str.match(regExp)[1],
                    result      = typeBig.toLowerCase();

                return result;
            }

            /**
             * functions check is variable is type of name
             *
             * @param variable
             */
            function typeOf(name, variable) {
                return type(variable) === name;
            }

            function typeOfSimple(name, variable) {
                return typeof variable === name;
            }

            ['null', 'arrayBuffer', 'file', 'array', 'object']
                .forEach(function(name) {
                    type[name] = typeOf.bind(null, name);
                });

            ['string', 'undefined', 'boolean', 'number', 'function']
                .forEach(function(name) {
                    type[name] = typeOfSimple.bind(null, name);
                });

            return type;
        }

        this.exec                       = new ExecProto();

        function ExecProto() {
            /**
             * function do save exec of function
             * @param callback
             * @param arg1
             * ...
             * @param argN
             */
            var exec        = function(callback) {
                var ret,
                    isFunc  = Util.type.function(callback),
                    args    = [].slice.call(arguments, 1);

                if (isFunc)
                    ret     = callback.apply(null, args);

                return ret;
            };

            /*
             * return function that calls callback with arguments
             */
            exec.with           =  function(callback) {
                var args    = [].slice.call(arguments),
                    bind    = Function.prototype.bind;

                args[0]     = null;

                return  bind.apply(callback, args);
            };

             /**
             * return save exec function
             * @param callback
             */
            exec.ret        = function() {
                var result,
                    args        = [].slice.call(arguments);

                args.unshift(exec);
                result          = exec.with.apply(null, args);

                return result;
            };

            /**
             * function do conditional save exec of function
             * @param condition
             * @param callback
             * @param func
             */
            exec.if         = function(condition, callback, func) {
                var ret;

                if (condition)
                    exec(callback);
                else
                    exec(func, callback);

                return ret;
            };

            /**
             * exec function if it exist in object
             *
             * @param obj
             * @param name
             * @param arg
             */
            exec.ifExist                = function(obj, name, arg) {
                var ret,
                    func    = obj && obj[name];

                if (func)
                    func    = func.apply(obj, arg);

                return ret;
            };

            exec.parallel   = function(funcs, callback) {
                var keys        = [],
                    callbackWas = false,
                    arr         = [],
                    obj         = {},
                    count       = 0,
                    countFuncs  = 0,
                    type        = Util.type(funcs);

                Util.check(arguments, ['funcs', 'callback']);

                switch(type) {
                case 'array':
                    countFuncs  = funcs.length;

                    funcs.forEach(function(func, num) {
                        exec(func, function() {
                            checkFunc(num, arguments, arr);
                        });
                    });
                    break;

                case 'object':
                    keys        = Object.keys(funcs);
                    countFuncs  = keys.length;

                    keys.forEach(function(name) {
                        var func    = funcs[name];

                        exec(func, function() {
                            checkFunc(name, arguments, obj);
                        });
                    });
                    break;
                }

                function checkFunc(num, data, all) {
                    var args    = [].slice.call(data, 1),
                        isLast  = false,
                        error   = data[0],
                        length  = args.length;

                    ++count;

                    isLast = count === countFuncs;

                    if (!error)
                        if (length >= 2)
                            all[num] = args;
                        else
                            all[num] = args[0];

                    if (!callbackWas && (error || isLast)) {
                        callbackWas = true;

                        if (type === 'array')
                            callback.apply(null, [error].concat(all));
                        else
                            callback(error, all);
                    }
                }
            };

            /**
             * load functions thrue callbacks one-by-one
             * @param funcs {Array} - array of functions
             */
            exec.series             = function(funcs) {
                var func, callback,
                    isArray     = Util.type.array(funcs);

                if (isArray) {
                    func        = funcs.shift();

                    callback    = function() {
                        return exec.series(funcs);
                    };

                    exec(func, callback);
                }
            };

           /**
             * function execute param function in
             * try...catch block
             *
             * @param callback
             */
            exec.try                = function(callback) {
                var ret;
                try {
                    ret = callback();
                } catch(error) {
                    ret = error;
                }

                return ret;
            };

            return exec;
        }

        /**
         * function gets file extension
         *
         * @param pFileName
         * @return Ext
         */
        this.getExt                     = function(name) {
            var ret     = '',
                dot,
                isStr   = Util.type.string(name);

            if (isStr) {
                dot = name.lastIndexOf('.');

                if (~dot)
                    ret = name.substr(dot);
            }

            return ret;
        };

       /**
         * get values from Object Array name properties
         * or
         * @pObj
         */
        this.getNamesFromObjArray       = function(arr) {
            var ret     = [];

            if (!Array.isArray(arr))
                throw(Error('arr should be array!'));

            ret = arr.map(function(item) {
                return item.name;
            });

            return ret;
        };

        /**
         * find object by name in arrray
         *
         * @param array
         * @param name
         */
        this.findObjByNameInArr         = function(array, name) {
            var ret;

             if (!Array.isArray(array))
                throw(Error('array should be array!'));

            if (typeof name !== 'string')
                throw(Error('name should be string!'));

            array.some(function(item) {
                var is = item.name === name,
                    isArray = Util.type.array(item);

                if (is)
                    ret = item;
                else if (isArray)
                    item.some(function(item) {
                        is = item.name === name;

                        if (is)
                            ret = item.data;

                        return is;
                    });

                return is;
            });

            return ret;
        };

        /**
         * start timer
         * @param name
         */
        this.time                       = function(name) {
            var console     = Scope.console;

            Util.exec.ifExist(console, 'time', [name]);

            return this;
        };

        /**
         * stop timer
         * @param name
         */
        this.timeEnd                   = function(name) {
            var console    = Scope.console;

            Util.exec.ifExist(console, 'timeEnd', [name]);

            return this;
        };
    }

})(this);
<|endoftext|>