(function () { "use strict"; function defineFunction(extended, is, args) { var isArray = is.isArray, isObject = is.isObject, isString = is.isString, isFunction = is.isFunction, argsToArray = args.argsToArray; function spreadArgs(f, args, scope) { var ret; switch ((args || []).length) { case 0: ret = f.call(scope); break; case 1: ret = f.call(scope, args[0]); break; case 2: ret = f.call(scope, args[0], args[1]); break; case 3: ret = f.call(scope, args[0], args[1], args[2]); break; default: ret = f.apply(scope, args); } return ret; } function hitch(scope, method, args) { args = argsToArray(arguments, 2); if ((isString(method) && !(method in scope))) { throw new Error(method + " property not defined in scope"); } else if (!isString(method) && !isFunction(method)) { throw new Error(method + " is not a function"); } if (isString(method)) { return function () { var func = scope[method]; if (isFunction(func)) { return spreadArgs(func, args.concat(argsToArray(arguments)), scope); } else { return func; } }; } else { if (args.length) { return function () { return spreadArgs(method, args.concat(argsToArray(arguments)), scope); }; } else { return function () { return spreadArgs(method, arguments, scope); }; } } } function applyFirst(method, args) { args = argsToArray(arguments, 1); if (!isString(method) && !isFunction(method)) { throw new Error(method + " must be the name of a property or function to execute"); } if (isString(method)) { return function () { var scopeArgs = argsToArray(arguments), scope = scopeArgs.shift(); var func = scope[method]; if (isFunction(func)) { scopeArgs = args.concat(scopeArgs); return spreadArgs(func, scopeArgs, scope); } else { return func; } }; } else { return function () { var scopeArgs = argsToArray(arguments), scope = scopeArgs.shift(); scopeArgs = args.concat(scopeArgs); return spreadArgs(method, scopeArgs, scope); }; } } function hitchIgnore(scope, method, args) { args = argsToArray(arguments, 2); if ((isString(method) && !(method in scope))) { throw new Error(method + " property not defined in scope"); } else if (!isString(method) && !isFunction(method)) { throw new Error(method + " is not a function"); } if (isString(method)) { return function () { var func = scope[method]; if (isFunction(func)) { return spreadArgs(func, args, scope); } else { return func; } }; } else { return function () { return spreadArgs(method, args, scope); }; } } function hitchAll(scope) { var funcs = argsToArray(arguments, 1); if (!isObject(scope) && !isFunction(scope)) { throw new TypeError("scope must be an object"); } if (funcs.length === 1 && isArray(funcs[0])) { funcs = funcs[0]; } if (!funcs.length) { funcs = []; for (var k in scope) { if (scope.hasOwnProperty(k) && isFunction(scope[k])) { funcs.push(k); } } } for (var i = 0, l = funcs.length; i < l; i++) { scope[funcs[i]] = hitch(scope, scope[funcs[i]]); } return scope; } function partial(method, args) { args = argsToArray(arguments, 1); if (!isString(method) && !isFunction(method)) { throw new Error(method + " must be the name of a property or function to execute"); } if (isString(method)) { return function () { var func = this[method]; if (isFunction(func)) { var scopeArgs = args.concat(argsToArray(arguments)); return spreadArgs(func, scopeArgs, this); } else { return func; } }; } else { return function () { var scopeArgs = args.concat(argsToArray(arguments)); return spreadArgs(method, scopeArgs, this); }; } } function curryFunc(f, execute) { return function () { var args = argsToArray(arguments); return execute ? spreadArgs(f, arguments, this) : function () { return spreadArgs(f, args.concat(argsToArray(arguments)), this); }; }; } function curry(depth, cb, scope) { var f; if (scope) { f = hitch(scope, cb); } else { f = cb; } if (depth) { var len = depth - 1; for (var i = len; i >= 0; i--) { f = curryFunc(f, i === len); } } return f; } return extended .define(isObject, { bind: hitch, bindAll: hitchAll, bindIgnore: hitchIgnore, curry: function (scope, depth, fn) { return curry(depth, fn, scope); } }) .define(isFunction, { bind: function (fn, obj) { return spreadArgs(hitch, [obj, fn].concat(argsToArray(arguments, 2)), this); }, bindIgnore: function (fn, obj) { return spreadArgs(hitchIgnore, [obj, fn].concat(argsToArray(arguments, 2)), this); }, partial: partial, applyFirst: applyFirst, curry: function (fn, num, scope) { return curry(num, fn, scope); }, noWrap: { f: function () { return this.value(); } } }) .define(isString, { bind: function (str, scope) { return hitch(scope, str); }, bindIgnore: function (str, scope) { return hitchIgnore(scope, str); }, partial: partial, applyFirst: applyFirst, curry: function (fn, depth, scope) { return curry(depth, fn, scope); } }) .expose({ bind: hitch, bindAll: hitchAll, bindIgnore: hitchIgnore, partial: partial, applyFirst: applyFirst, curry: curry }); } if ("undefined" !== typeof exports) { if ("undefined" !== typeof module && module.exports) { module.exports = defineFunction(require("extended"), require("is-extended"), require("arguments-extended")); } } else if ("function" === typeof define && define.amd) { define(["extended", "is-extended", "arguments-extended"], function (extended, is, args) { return defineFunction(extended, is, args); }); } else { this.functionExtended = defineFunction(this.extended, this.isExtended, this.argumentsExtended); } }).call(this);