Add baseRest.

This commit is contained in:
John-David Dalton
2016-07-17 17:14:36 -07:00
parent 90d73143e1
commit ec4ae5978b

153
lodash.js
View File

@@ -3664,6 +3664,40 @@
return result; return result;
} }
/**
* The base implementation of `_.rest` which doesn't validate or coerce arguments.
*
* @private
* @param {Function} func The function to apply a rest parameter to.
* @param {number} [start=func.length-1] The start position of the rest parameter.
* @returns {Function} Returns the new function.
*/
function baseRest(func, start) {
start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
return function() {
var args = arguments,
index = -1,
length = nativeMax(args.length - start, 0),
array = Array(length);
while (++index < length) {
array[index] = args[start + index];
}
switch (start) {
case 0: return func.call(this, array);
case 1: return func.call(this, args[0], array);
case 2: return func.call(this, args[0], args[1], array);
}
var otherArgs = Array(start + 1);
index = -1;
while (++index < start) {
otherArgs[index] = args[index];
}
otherArgs[start] = array;
return apply(func, this, otherArgs);
};
}
/** /**
* The base implementation of `_.set`. * The base implementation of `_.set`.
* *
@@ -4487,7 +4521,7 @@
* @returns {Function} Returns the new assigner function. * @returns {Function} Returns the new assigner function.
*/ */
function createAssigner(assigner) { function createAssigner(assigner) {
return rest(function(object, sources) { return baseRest(function(object, sources) {
var index = -1, var index = -1,
length = sources.length, length = sources.length,
customizer = length > 1 ? sources[length - 1] : undefined, customizer = length > 1 ? sources[length - 1] : undefined,
@@ -4724,7 +4758,7 @@
* @returns {Function} Returns the new flow function. * @returns {Function} Returns the new flow function.
*/ */
function createFlow(fromRight) { function createFlow(fromRight) {
return rest(function(funcs) { return baseRest(function(funcs) {
funcs = baseFlatten(funcs, 1); funcs = baseFlatten(funcs, 1);
var length = funcs.length, var length = funcs.length,
@@ -4909,12 +4943,12 @@
* @returns {Function} Returns the new over function. * @returns {Function} Returns the new over function.
*/ */
function createOver(arrayFunc) { function createOver(arrayFunc) {
return rest(function(iteratees) { return baseRest(function(iteratees) {
iteratees = (iteratees.length == 1 && isArray(iteratees[0])) iteratees = (iteratees.length == 1 && isArray(iteratees[0]))
? arrayMap(iteratees[0], baseUnary(getIteratee())) ? arrayMap(iteratees[0], baseUnary(getIteratee()))
: arrayMap(baseFlatten(iteratees, 1), baseUnary(getIteratee())); : arrayMap(baseFlatten(iteratees, 1), baseUnary(getIteratee()));
return rest(function(args) { return baseRest(function(args) {
var thisArg = this; var thisArg = this;
return arrayFunc(iteratees, function(iteratee) { return arrayFunc(iteratees, function(iteratee) {
return apply(iteratee, thisArg, args); return apply(iteratee, thisArg, args);
@@ -6406,7 +6440,7 @@
* _.difference([2, 1], [2, 3]); * _.difference([2, 1], [2, 3]);
* // => [1] * // => [1]
*/ */
var difference = rest(function(array, values) { var difference = baseRest(function(array, values) {
return isArrayLikeObject(array) return isArrayLikeObject(array)
? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true)) ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
: []; : [];
@@ -6437,7 +6471,7 @@
* _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x'); * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
* // => [{ 'x': 2 }] * // => [{ 'x': 2 }]
*/ */
var differenceBy = rest(function(array, values) { var differenceBy = baseRest(function(array, values) {
var iteratee = last(values); var iteratee = last(values);
if (isArrayLikeObject(iteratee)) { if (isArrayLikeObject(iteratee)) {
iteratee = undefined; iteratee = undefined;
@@ -6470,7 +6504,7 @@
* _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual); * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
* // => [{ 'x': 2, 'y': 1 }] * // => [{ 'x': 2, 'y': 1 }]
*/ */
var differenceWith = rest(function(array, values) { var differenceWith = baseRest(function(array, values) {
var comparator = last(values); var comparator = last(values);
if (isArrayLikeObject(comparator)) { if (isArrayLikeObject(comparator)) {
comparator = undefined; comparator = undefined;
@@ -6958,7 +6992,7 @@
* _.intersection([2, 1], [2, 3]); * _.intersection([2, 1], [2, 3]);
* // => [2] * // => [2]
*/ */
var intersection = rest(function(arrays) { var intersection = baseRest(function(arrays) {
var mapped = arrayMap(arrays, castArrayLikeObject); var mapped = arrayMap(arrays, castArrayLikeObject);
return (mapped.length && mapped[0] === arrays[0]) return (mapped.length && mapped[0] === arrays[0])
? baseIntersection(mapped) ? baseIntersection(mapped)
@@ -6987,7 +7021,7 @@
* _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
* // => [{ 'x': 1 }] * // => [{ 'x': 1 }]
*/ */
var intersectionBy = rest(function(arrays) { var intersectionBy = baseRest(function(arrays) {
var iteratee = last(arrays), var iteratee = last(arrays),
mapped = arrayMap(arrays, castArrayLikeObject); mapped = arrayMap(arrays, castArrayLikeObject);
@@ -7022,7 +7056,7 @@
* _.intersectionWith(objects, others, _.isEqual); * _.intersectionWith(objects, others, _.isEqual);
* // => [{ 'x': 1, 'y': 2 }] * // => [{ 'x': 1, 'y': 2 }]
*/ */
var intersectionWith = rest(function(arrays) { var intersectionWith = baseRest(function(arrays) {
var comparator = last(arrays), var comparator = last(arrays),
mapped = arrayMap(arrays, castArrayLikeObject); mapped = arrayMap(arrays, castArrayLikeObject);
@@ -7168,7 +7202,7 @@
* console.log(array); * console.log(array);
* // => ['b', 'b'] * // => ['b', 'b']
*/ */
var pull = rest(pullAll); var pull = baseRest(pullAll);
/** /**
* This method is like `_.pull` except that it accepts an array of values to remove. * This method is like `_.pull` except that it accepts an array of values to remove.
@@ -7279,7 +7313,7 @@
* console.log(pulled); * console.log(pulled);
* // => ['b', 'd'] * // => ['b', 'd']
*/ */
var pullAt = rest(function(array, indexes) { var pullAt = baseRest(function(array, indexes) {
indexes = baseFlatten(indexes, 1); indexes = baseFlatten(indexes, 1);
var length = array ? array.length : 0, var length = array ? array.length : 0,
@@ -7787,7 +7821,7 @@
* _.union([2], [1, 2]); * _.union([2], [1, 2]);
* // => [2, 1] * // => [2, 1]
*/ */
var union = rest(function(arrays) { var union = baseRest(function(arrays) {
return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true)); return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));
}); });
@@ -7815,7 +7849,7 @@
* _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
* // => [{ 'x': 1 }, { 'x': 2 }] * // => [{ 'x': 1 }, { 'x': 2 }]
*/ */
var unionBy = rest(function(arrays) { var unionBy = baseRest(function(arrays) {
var iteratee = last(arrays); var iteratee = last(arrays);
if (isArrayLikeObject(iteratee)) { if (isArrayLikeObject(iteratee)) {
iteratee = undefined; iteratee = undefined;
@@ -7844,7 +7878,7 @@
* _.unionWith(objects, others, _.isEqual); * _.unionWith(objects, others, _.isEqual);
* // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }] * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
*/ */
var unionWith = rest(function(arrays) { var unionWith = baseRest(function(arrays) {
var comparator = last(arrays); var comparator = last(arrays);
if (isArrayLikeObject(comparator)) { if (isArrayLikeObject(comparator)) {
comparator = undefined; comparator = undefined;
@@ -8017,7 +8051,7 @@
* _.without([2, 1, 2, 3], 1, 2); * _.without([2, 1, 2, 3], 1, 2);
* // => [3] * // => [3]
*/ */
var without = rest(function(array, values) { var without = baseRest(function(array, values) {
return isArrayLikeObject(array) return isArrayLikeObject(array)
? baseDifference(array, values) ? baseDifference(array, values)
: []; : [];
@@ -8041,7 +8075,7 @@
* _.xor([2, 1], [2, 3]); * _.xor([2, 1], [2, 3]);
* // => [1, 3] * // => [1, 3]
*/ */
var xor = rest(function(arrays) { var xor = baseRest(function(arrays) {
return baseXor(arrayFilter(arrays, isArrayLikeObject)); return baseXor(arrayFilter(arrays, isArrayLikeObject));
}); });
@@ -8068,7 +8102,7 @@
* _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
* // => [{ 'x': 2 }] * // => [{ 'x': 2 }]
*/ */
var xorBy = rest(function(arrays) { var xorBy = baseRest(function(arrays) {
var iteratee = last(arrays); var iteratee = last(arrays);
if (isArrayLikeObject(iteratee)) { if (isArrayLikeObject(iteratee)) {
iteratee = undefined; iteratee = undefined;
@@ -8096,7 +8130,7 @@
* _.xorWith(objects, others, _.isEqual); * _.xorWith(objects, others, _.isEqual);
* // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }] * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
*/ */
var xorWith = rest(function(arrays) { var xorWith = baseRest(function(arrays) {
var comparator = last(arrays); var comparator = last(arrays);
if (isArrayLikeObject(comparator)) { if (isArrayLikeObject(comparator)) {
comparator = undefined; comparator = undefined;
@@ -8120,7 +8154,7 @@
* _.zip(['a', 'b'], [1, 2], [true, false]); * _.zip(['a', 'b'], [1, 2], [true, false]);
* // => [['a', 1, true], ['b', 2, false]] * // => [['a', 1, true], ['b', 2, false]]
*/ */
var zip = rest(unzip); var zip = baseRest(unzip);
/** /**
* This method is like `_.fromPairs` except that it accepts two arrays, * This method is like `_.fromPairs` except that it accepts two arrays,
@@ -8180,7 +8214,7 @@
* }); * });
* // => [111, 222] * // => [111, 222]
*/ */
var zipWith = rest(function(arrays) { var zipWith = baseRest(function(arrays) {
var length = arrays.length, var length = arrays.length,
iteratee = length > 1 ? arrays[length - 1] : undefined; iteratee = length > 1 ? arrays[length - 1] : undefined;
@@ -8296,7 +8330,7 @@
* _(object).at(['a[0].b.c', 'a[1]']).value(); * _(object).at(['a[0].b.c', 'a[1]']).value();
* // => [3, 4] * // => [3, 4]
*/ */
var wrapperAt = rest(function(paths) { var wrapperAt = baseRest(function(paths) {
paths = baseFlatten(paths, 1); paths = baseFlatten(paths, 1);
var length = paths.length, var length = paths.length,
start = length ? paths[0] : 0, start = length ? paths[0] : 0,
@@ -8950,7 +8984,7 @@
* _.invokeMap([123, 456], String.prototype.split, ''); * _.invokeMap([123, 456], String.prototype.split, '');
* // => [['1', '2', '3'], ['4', '5', '6']] * // => [['1', '2', '3'], ['4', '5', '6']]
*/ */
var invokeMap = rest(function(collection, path, args) { var invokeMap = baseRest(function(collection, path, args) {
var index = -1, var index = -1,
isFunc = typeof path == 'function', isFunc = typeof path == 'function',
isProp = isKey(path), isProp = isKey(path),
@@ -9439,7 +9473,7 @@
* }); * });
* // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]] * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
*/ */
var sortBy = rest(function(collection, iteratees) { var sortBy = baseRest(function(collection, iteratees) {
if (collection == null) { if (collection == null) {
return []; return [];
} }
@@ -9604,7 +9638,7 @@
* bound('hi'); * bound('hi');
* // => 'hi fred!' * // => 'hi fred!'
*/ */
var bind = rest(function(func, thisArg, partials) { var bind = baseRest(function(func, thisArg, partials) {
var bitmask = BIND_FLAG; var bitmask = BIND_FLAG;
if (partials.length) { if (partials.length) {
var holders = replaceHolders(partials, getHolder(bind)); var holders = replaceHolders(partials, getHolder(bind));
@@ -9658,7 +9692,7 @@
* bound('hi'); * bound('hi');
* // => 'hiya fred!' * // => 'hiya fred!'
*/ */
var bindKey = rest(function(object, key, partials) { var bindKey = baseRest(function(object, key, partials) {
var bitmask = BIND_FLAG | BIND_KEY_FLAG; var bitmask = BIND_FLAG | BIND_KEY_FLAG;
if (partials.length) { if (partials.length) {
var holders = replaceHolders(partials, getHolder(bindKey)); var holders = replaceHolders(partials, getHolder(bindKey));
@@ -9950,7 +9984,7 @@
* }, 'deferred'); * }, 'deferred');
* // => Logs 'deferred' after one or more milliseconds. * // => Logs 'deferred' after one or more milliseconds.
*/ */
var defer = rest(function(func, args) { var defer = baseRest(function(func, args) {
return baseDelay(func, 1, args); return baseDelay(func, 1, args);
}); });
@@ -9973,7 +10007,7 @@
* }, 1000, 'later'); * }, 1000, 'later');
* // => Logs 'later' after one second. * // => Logs 'later' after one second.
*/ */
var delay = rest(function(func, wait, args) { var delay = baseRest(function(func, wait, args) {
return baseDelay(func, toNumber(wait) || 0, args); return baseDelay(func, toNumber(wait) || 0, args);
}); });
@@ -10148,13 +10182,13 @@
* func(10, 5); * func(10, 5);
* // => [100, 10] * // => [100, 10]
*/ */
var overArgs = rest(function(func, transforms) { var overArgs = baseRest(function(func, transforms) {
transforms = (transforms.length == 1 && isArray(transforms[0])) transforms = (transforms.length == 1 && isArray(transforms[0]))
? arrayMap(transforms[0], baseUnary(getIteratee())) ? arrayMap(transforms[0], baseUnary(getIteratee()))
: arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee())); : arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee()));
var funcsLength = transforms.length; var funcsLength = transforms.length;
return rest(function(args) { return baseRest(function(args) {
var index = -1, var index = -1,
length = nativeMin(args.length, funcsLength); length = nativeMin(args.length, funcsLength);
@@ -10198,7 +10232,7 @@
* greetFred('hi'); * greetFred('hi');
* // => 'hi fred' * // => 'hi fred'
*/ */
var partial = rest(function(func, partials) { var partial = baseRest(function(func, partials) {
var holders = replaceHolders(partials, getHolder(partial)); var holders = replaceHolders(partials, getHolder(partial));
return createWrap(func, PARTIAL_FLAG, undefined, partials, holders); return createWrap(func, PARTIAL_FLAG, undefined, partials, holders);
}); });
@@ -10235,7 +10269,7 @@
* sayHelloTo('fred'); * sayHelloTo('fred');
* // => 'hello fred' * // => 'hello fred'
*/ */
var partialRight = rest(function(func, partials) { var partialRight = baseRest(function(func, partials) {
var holders = replaceHolders(partials, getHolder(partialRight)); var holders = replaceHolders(partials, getHolder(partialRight));
return createWrap(func, PARTIAL_RIGHT_FLAG, undefined, partials, holders); return createWrap(func, PARTIAL_RIGHT_FLAG, undefined, partials, holders);
}); });
@@ -10262,7 +10296,7 @@
* rearged('b', 'c', 'a') * rearged('b', 'c', 'a')
* // => ['a', 'b', 'c'] * // => ['a', 'b', 'c']
*/ */
var rearg = rest(function(func, indexes) { var rearg = baseRest(function(func, indexes) {
return createWrap(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes, 1)); return createWrap(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes, 1));
}); });
@@ -10295,29 +10329,8 @@
if (typeof func != 'function') { if (typeof func != 'function') {
throw new TypeError(FUNC_ERROR_TEXT); throw new TypeError(FUNC_ERROR_TEXT);
} }
start = nativeMax(start === undefined ? (func.length - 1) : toInteger(start), 0); start = start === undefined ? start : toInteger(start);
return function() { return baseRest(func, start);
var args = arguments,
index = -1,
length = nativeMax(args.length - start, 0),
array = Array(length);
while (++index < length) {
array[index] = args[start + index];
}
switch (start) {
case 0: return func.call(this, array);
case 1: return func.call(this, args[0], array);
case 2: return func.call(this, args[0], args[1], array);
}
var otherArgs = Array(start + 1);
index = -1;
while (++index < start) {
otherArgs[index] = args[index];
}
otherArgs[start] = array;
return apply(func, this, otherArgs);
};
} }
/** /**
@@ -10359,7 +10372,7 @@
throw new TypeError(FUNC_ERROR_TEXT); throw new TypeError(FUNC_ERROR_TEXT);
} }
start = start === undefined ? 0 : nativeMax(toInteger(start), 0); start = start === undefined ? 0 : nativeMax(toInteger(start), 0);
return rest(function(args) { return baseRest(function(args) {
var array = args[start], var array = args[start],
otherArgs = castSlice(args, 0, start); otherArgs = castSlice(args, 0, start);
@@ -12240,7 +12253,7 @@
* _.at(object, ['a[0].b.c', 'a[1]']); * _.at(object, ['a[0].b.c', 'a[1]']);
* // => [3, 4] * // => [3, 4]
*/ */
var at = rest(function(object, paths) { var at = baseRest(function(object, paths) {
return baseAt(object, baseFlatten(paths, 1)); return baseAt(object, baseFlatten(paths, 1));
}); });
@@ -12304,7 +12317,7 @@
* _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
* // => { 'a': 1, 'b': 2 } * // => { 'a': 1, 'b': 2 }
*/ */
var defaults = rest(function(args) { var defaults = baseRest(function(args) {
args.push(undefined, assignInDefaults); args.push(undefined, assignInDefaults);
return apply(assignInWith, undefined, args); return apply(assignInWith, undefined, args);
}); });
@@ -12328,7 +12341,7 @@
* _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } }); * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } });
* // => { 'a': { 'b': 2, 'c': 3 } } * // => { 'a': { 'b': 2, 'c': 3 } }
*/ */
var defaultsDeep = rest(function(args) { var defaultsDeep = baseRest(function(args) {
args.push(undefined, mergeDefaults); args.push(undefined, mergeDefaults);
return apply(mergeWith, undefined, args); return apply(mergeWith, undefined, args);
}); });
@@ -12758,7 +12771,7 @@
* _.invoke(object, 'a[0].b.c.slice', 1, 3); * _.invoke(object, 'a[0].b.c.slice', 1, 3);
* // => [2, 3] * // => [2, 3]
*/ */
var invoke = rest(baseInvoke); var invoke = baseRest(baseInvoke);
/** /**
* Creates an array of the own enumerable property names of `object`. * Creates an array of the own enumerable property names of `object`.
@@ -13009,7 +13022,7 @@
* _.omit(object, ['a', 'c']); * _.omit(object, ['a', 'c']);
* // => { 'b': '2' } * // => { 'b': '2' }
*/ */
var omit = rest(function(object, props) { var omit = baseRest(function(object, props) {
if (object == null) { if (object == null) {
return {}; return {};
} }
@@ -13061,7 +13074,7 @@
* _.pick(object, ['a', 'c']); * _.pick(object, ['a', 'c']);
* // => { 'a': 1, 'c': 3 } * // => { 'a': 1, 'c': 3 }
*/ */
var pick = rest(function(object, props) { var pick = baseRest(function(object, props) {
return object == null ? {} : basePick(object, arrayMap(baseFlatten(props, 1), toKey)); return object == null ? {} : basePick(object, arrayMap(baseFlatten(props, 1), toKey));
}); });
@@ -14741,7 +14754,7 @@
* elements = []; * elements = [];
* } * }
*/ */
var attempt = rest(function(func, args) { var attempt = baseRest(function(func, args) {
try { try {
return apply(func, undefined, args); return apply(func, undefined, args);
} catch (e) { } catch (e) {
@@ -14775,7 +14788,7 @@
* jQuery(element).on('click', view.click); * jQuery(element).on('click', view.click);
* // => Logs 'clicked docs' when clicked. * // => Logs 'clicked docs' when clicked.
*/ */
var bindAll = rest(function(object, methodNames) { var bindAll = baseRest(function(object, methodNames) {
arrayEach(baseFlatten(methodNames, 1), function(key) { arrayEach(baseFlatten(methodNames, 1), function(key) {
key = toKey(key); key = toKey(key);
object[key] = bind(object[key], object); object[key] = bind(object[key], object);
@@ -14823,7 +14836,7 @@
return [toIteratee(pair[0]), pair[1]]; return [toIteratee(pair[0]), pair[1]];
}); });
return rest(function(args) { return baseRest(function(args) {
var index = -1; var index = -1;
while (++index < length) { while (++index < length) {
var pair = pairs[index]; var pair = pairs[index];
@@ -15101,7 +15114,7 @@
* _.map(objects, _.method(['a', 'b'])); * _.map(objects, _.method(['a', 'b']));
* // => [2, 1] * // => [2, 1]
*/ */
var method = rest(function(path, args) { var method = baseRest(function(path, args) {
return function(object) { return function(object) {
return baseInvoke(object, path, args); return baseInvoke(object, path, args);
}; };
@@ -15130,7 +15143,7 @@
* _.map([['a', '2'], ['c', '0']], _.methodOf(object)); * _.map([['a', '2'], ['c', '0']], _.methodOf(object));
* // => [2, 0] * // => [2, 0]
*/ */
var methodOf = rest(function(object, args) { var methodOf = baseRest(function(object, args) {
return function(path) { return function(path) {
return baseInvoke(object, path, args); return baseInvoke(object, path, args);
}; };
@@ -15266,7 +15279,7 @@
*/ */
function nthArg(n) { function nthArg(n) {
n = toInteger(n); n = toInteger(n);
return rest(function(args) { return baseRest(function(args) {
return baseNth(args, n); return baseNth(args, n);
}); });
} }
@@ -16420,7 +16433,7 @@
return this.reverse().find(predicate); return this.reverse().find(predicate);
}; };
LazyWrapper.prototype.invokeMap = rest(function(path, args) { LazyWrapper.prototype.invokeMap = baseRest(function(path, args) {
if (typeof path == 'function') { if (typeof path == 'function') {
return new LazyWrapper(this); return new LazyWrapper(this);
} }