nexus site path corrected
[portal.git] / ecomp-portal-FE / client / bower_components / lodash / fp / _baseConvert.js
1 var mapping = require('./_mapping'),
2     mutateMap = mapping.mutate,
3     fallbackHolder = require('./placeholder');
4
5 /**
6  * Creates a function, with an arity of `n`, that invokes `func` with the
7  * arguments it receives.
8  *
9  * @private
10  * @param {Function} func The function to wrap.
11  * @param {number} n The arity of the new function.
12  * @returns {Function} Returns the new function.
13  */
14 function baseArity(func, n) {
15   return n == 2
16     ? function(a, b) { return func.apply(undefined, arguments); }
17     : function(a) { return func.apply(undefined, arguments); };
18 }
19
20 /**
21  * Creates a function that invokes `func`, with up to `n` arguments, ignoring
22  * any additional arguments.
23  *
24  * @private
25  * @param {Function} func The function to cap arguments for.
26  * @param {number} n The arity cap.
27  * @returns {Function} Returns the new function.
28  */
29 function baseAry(func, n) {
30   return n == 2
31     ? function(a, b) { return func(a, b); }
32     : function(a) { return func(a); };
33 }
34
35 /**
36  * Creates a clone of `array`.
37  *
38  * @private
39  * @param {Array} array The array to clone.
40  * @returns {Array} Returns the cloned array.
41  */
42 function cloneArray(array) {
43   var length = array ? array.length : 0,
44       result = Array(length);
45
46   while (length--) {
47     result[length] = array[length];
48   }
49   return result;
50 }
51
52 /**
53  * Creates a function that clones a given object using the assignment `func`.
54  *
55  * @private
56  * @param {Function} func The assignment function.
57  * @returns {Function} Returns the new cloner function.
58  */
59 function createCloner(func) {
60   return function(object) {
61     return func({}, object);
62   };
63 }
64
65 /**
66  * Creates a function that wraps `func` and uses `cloner` to clone the first
67  * argument it receives.
68  *
69  * @private
70  * @param {Function} func The function to wrap.
71  * @param {Function} cloner The function to clone arguments.
72  * @returns {Function} Returns the new immutable function.
73  */
74 function immutWrap(func, cloner) {
75   return function() {
76     var length = arguments.length;
77     if (!length) {
78       return result;
79     }
80     var args = Array(length);
81     while (length--) {
82       args[length] = arguments[length];
83     }
84     var result = args[0] = cloner.apply(undefined, args);
85     func.apply(undefined, args);
86     return result;
87   };
88 }
89
90 /**
91  * The base implementation of `convert` which accepts a `util` object of methods
92  * required to perform conversions.
93  *
94  * @param {Object} util The util object.
95  * @param {string} name The name of the function to convert.
96  * @param {Function} func The function to convert.
97  * @param {Object} [options] The options object.
98  * @param {boolean} [options.cap=true] Specify capping iteratee arguments.
99  * @param {boolean} [options.curry=true] Specify currying.
100  * @param {boolean} [options.fixed=true] Specify fixed arity.
101  * @param {boolean} [options.immutable=true] Specify immutable operations.
102  * @param {boolean} [options.rearg=true] Specify rearranging arguments.
103  * @returns {Function|Object} Returns the converted function or object.
104  */
105 function baseConvert(util, name, func, options) {
106   var setPlaceholder,
107       isLib = typeof name == 'function',
108       isObj = name === Object(name);
109
110   if (isObj) {
111     options = func;
112     func = name;
113     name = undefined;
114   }
115   if (func == null) {
116     throw new TypeError;
117   }
118   options || (options = {});
119
120   var config = {
121     'cap': 'cap' in options ? options.cap : true,
122     'curry': 'curry' in options ? options.curry : true,
123     'fixed': 'fixed' in options ? options.fixed : true,
124     'immutable': 'immutable' in options ? options.immutable : true,
125     'rearg': 'rearg' in options ? options.rearg : true
126   };
127
128   var forceCurry = ('curry' in options) && options.curry,
129       forceFixed = ('fixed' in options) && options.fixed,
130       forceRearg = ('rearg' in options) && options.rearg,
131       placeholder = isLib ? func : fallbackHolder,
132       pristine = isLib ? func.runInContext() : undefined;
133
134   var helpers = isLib ? func : {
135     'ary': util.ary,
136     'assign': util.assign,
137     'clone': util.clone,
138     'curry': util.curry,
139     'forEach': util.forEach,
140     'isArray': util.isArray,
141     'isFunction': util.isFunction,
142     'iteratee': util.iteratee,
143     'keys': util.keys,
144     'rearg': util.rearg,
145     'spread': util.spread,
146     'toPath': util.toPath
147   };
148
149   var ary = helpers.ary,
150       assign = helpers.assign,
151       clone = helpers.clone,
152       curry = helpers.curry,
153       each = helpers.forEach,
154       isArray = helpers.isArray,
155       isFunction = helpers.isFunction,
156       keys = helpers.keys,
157       rearg = helpers.rearg,
158       spread = helpers.spread,
159       toPath = helpers.toPath;
160
161   var aryMethodKeys = keys(mapping.aryMethod);
162
163   var wrappers = {
164     'castArray': function(castArray) {
165       return function() {
166         var value = arguments[0];
167         return isArray(value)
168           ? castArray(cloneArray(value))
169           : castArray.apply(undefined, arguments);
170       };
171     },
172     'iteratee': function(iteratee) {
173       return function() {
174         var func = arguments[0],
175             arity = arguments[1],
176             result = iteratee(func, arity),
177             length = result.length;
178
179         if (config.cap && typeof arity == 'number') {
180           arity = arity > 2 ? (arity - 2) : 1;
181           return (length && length <= arity) ? result : baseAry(result, arity);
182         }
183         return result;
184       };
185     },
186     'mixin': function(mixin) {
187       return function(source) {
188         var func = this;
189         if (!isFunction(func)) {
190           return mixin(func, Object(source));
191         }
192         var pairs = [];
193         each(keys(source), function(key) {
194           if (isFunction(source[key])) {
195             pairs.push([key, func.prototype[key]]);
196           }
197         });
198
199         mixin(func, Object(source));
200
201         each(pairs, function(pair) {
202           var value = pair[1];
203           if (isFunction(value)) {
204             func.prototype[pair[0]] = value;
205           } else {
206             delete func.prototype[pair[0]];
207           }
208         });
209         return func;
210       };
211     },
212     'runInContext': function(runInContext) {
213       return function(context) {
214         return baseConvert(util, runInContext(context), options);
215       };
216     }
217   };
218
219   /*--------------------------------------------------------------------------*/
220
221   /**
222    * Creates a clone of `object` by `path`.
223    *
224    * @private
225    * @param {Object} object The object to clone.
226    * @param {Array|string} path The path to clone by.
227    * @returns {Object} Returns the cloned object.
228    */
229   function cloneByPath(object, path) {
230     path = toPath(path);
231
232     var index = -1,
233         length = path.length,
234         lastIndex = length - 1,
235         result = clone(Object(object)),
236         nested = result;
237
238     while (nested != null && ++index < length) {
239       var key = path[index],
240           value = nested[key];
241
242       if (value != null) {
243         nested[path[index]] = clone(index == lastIndex ? value : Object(value));
244       }
245       nested = nested[key];
246     }
247     return result;
248   }
249
250   /**
251    * Converts `lodash` to an immutable auto-curried iteratee-first data-last
252    * version with conversion `options` applied.
253    *
254    * @param {Object} [options] The options object. See `baseConvert` for more details.
255    * @returns {Function} Returns the converted `lodash`.
256    */
257   function convertLib(options) {
258     return _.runInContext.convert(options)(undefined);
259   }
260
261   /**
262    * Create a converter function for `func` of `name`.
263    *
264    * @param {string} name The name of the function to convert.
265    * @param {Function} func The function to convert.
266    * @returns {Function} Returns the new converter function.
267    */
268   function createConverter(name, func) {
269     var oldOptions = options;
270     return function(options) {
271       var newUtil = isLib ? pristine : helpers,
272           newFunc = isLib ? pristine[name] : func,
273           newOptions = assign(assign({}, oldOptions), options);
274
275       return baseConvert(newUtil, name, newFunc, newOptions);
276     };
277   }
278
279   /**
280    * Creates a function that wraps `func` to invoke its iteratee, with up to `n`
281    * arguments, ignoring any additional arguments.
282    *
283    * @private
284    * @param {Function} func The function to cap iteratee arguments for.
285    * @param {number} n The arity cap.
286    * @returns {Function} Returns the new function.
287    */
288   function iterateeAry(func, n) {
289     return overArg(func, function(func) {
290       return typeof func == 'function' ? baseAry(func, n) : func;
291     });
292   }
293
294   /**
295    * Creates a function that wraps `func` to invoke its iteratee with arguments
296    * arranged according to the specified `indexes` where the argument value at
297    * the first index is provided as the first argument, the argument value at
298    * the second index is provided as the second argument, and so on.
299    *
300    * @private
301    * @param {Function} func The function to rearrange iteratee arguments for.
302    * @param {number[]} indexes The arranged argument indexes.
303    * @returns {Function} Returns the new function.
304    */
305   function iterateeRearg(func, indexes) {
306     return overArg(func, function(func) {
307       var n = indexes.length;
308       return baseArity(rearg(baseAry(func, n), indexes), n);
309     });
310   }
311
312   /**
313    * Creates a function that invokes `func` with its first argument passed
314    * thru `transform`.
315    *
316    * @private
317    * @param {Function} func The function to wrap.
318    * @param {...Function} transform The functions to transform the first argument.
319    * @returns {Function} Returns the new function.
320    */
321   function overArg(func, transform) {
322     return function() {
323       var length = arguments.length;
324       if (!length) {
325         return func();
326       }
327       var args = Array(length);
328       while (length--) {
329         args[length] = arguments[length];
330       }
331       var index = config.rearg ? 0 : (length - 1);
332       args[index] = transform(args[index]);
333       return func.apply(undefined, args);
334     };
335   }
336
337   /**
338    * Creates a function that wraps `func` and applys the conversions
339    * rules by `name`.
340    *
341    * @private
342    * @param {string} name The name of the function to wrap.
343    * @param {Function} func The function to wrap.
344    * @returns {Function} Returns the converted function.
345    */
346   function wrap(name, func) {
347     name = mapping.aliasToReal[name] || name;
348
349     var result,
350         wrapped = func,
351         wrapper = wrappers[name];
352
353     if (wrapper) {
354       wrapped = wrapper(func);
355     }
356     else if (config.immutable) {
357       if (mutateMap.array[name]) {
358         wrapped = immutWrap(func, cloneArray);
359       }
360       else if (mutateMap.object[name]) {
361         wrapped = immutWrap(func, createCloner(func));
362       }
363       else if (mutateMap.set[name]) {
364         wrapped = immutWrap(func, cloneByPath);
365       }
366     }
367     each(aryMethodKeys, function(aryKey) {
368       each(mapping.aryMethod[aryKey], function(otherName) {
369         if (name == otherName) {
370           var aryN = !isLib && mapping.iterateeAry[name],
371               reargIndexes = mapping.iterateeRearg[name],
372               spreadStart = mapping.methodSpread[name];
373
374           result = wrapped;
375           if (config.fixed && (forceFixed || !mapping.skipFixed[name])) {
376             result = spreadStart === undefined
377               ? ary(result, aryKey)
378               : spread(result, spreadStart);
379           }
380           if (config.rearg && aryKey > 1 && (forceRearg || !mapping.skipRearg[name])) {
381             result = rearg(result, mapping.methodRearg[name] || mapping.aryRearg[aryKey]);
382           }
383           if (config.cap) {
384             if (reargIndexes) {
385               result = iterateeRearg(result, reargIndexes);
386             } else if (aryN) {
387               result = iterateeAry(result, aryN);
388             }
389           }
390           if (forceCurry || (config.curry && aryKey > 1)) {
391             forceCurry  && console.log(forceCurry, name);
392             result = curry(result, aryKey);
393           }
394           return false;
395         }
396       });
397       return !result;
398     });
399
400     result || (result = wrapped);
401     if (result == func) {
402       result = forceCurry ? curry(result, 1) : function() {
403         return func.apply(this, arguments);
404       };
405     }
406     result.convert = createConverter(name, func);
407     if (mapping.placeholder[name]) {
408       setPlaceholder = true;
409       result.placeholder = func.placeholder = placeholder;
410     }
411     return result;
412   }
413
414   /*--------------------------------------------------------------------------*/
415
416   if (!isObj) {
417     return wrap(name, func);
418   }
419   var _ = func;
420
421   // Convert methods by ary cap.
422   var pairs = [];
423   each(aryMethodKeys, function(aryKey) {
424     each(mapping.aryMethod[aryKey], function(key) {
425       var func = _[mapping.remap[key] || key];
426       if (func) {
427         pairs.push([key, wrap(key, func)]);
428       }
429     });
430   });
431
432   // Convert remaining methods.
433   each(keys(_), function(key) {
434     var func = _[key];
435     if (typeof func == 'function') {
436       var length = pairs.length;
437       while (length--) {
438         if (pairs[length][0] == key) {
439           return;
440         }
441       }
442       func.convert = createConverter(key, func);
443       pairs.push([key, func]);
444     }
445   });
446
447   // Assign to `_` leaving `_.prototype` unchanged to allow chaining.
448   each(pairs, function(pair) {
449     _[pair[0]] = pair[1];
450   });
451
452   _.convert = convertLib;
453   if (setPlaceholder) {
454     _.placeholder = placeholder;
455   }
456   // Assign aliases.
457   each(keys(_), function(key) {
458     each(mapping.realToAlias[key] || [], function(alias) {
459       _[alias] = _[key];
460     });
461   });
462
463   return _;
464 }
465
466 module.exports = baseConvert;