react-ui-animate 1.4.5 → 2.0.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vscode/settings.json +3 -0
- package/LICENSE +21 -21
- package/README.md +115 -115
- package/dist/animation/animationType.d.ts +15 -0
- package/dist/animation/getInitialConfig.d.ts +3 -3
- package/dist/animation/index.d.ts +5 -4
- package/dist/animation/interpolation.d.ts +3 -11
- package/dist/animation/modules.d.ts +18 -10
- package/dist/animation/useAnimatedValue.d.ts +11 -23
- package/dist/animation/useMountedValue.d.ts +5 -14
- package/dist/gestures/controllers/DragGesture.d.ts +2 -2
- package/dist/index.d.ts +5 -4
- package/dist/index.js +102 -114
- package/dist/index.js.map +1 -1
- package/dist/utils/delay.d.ts +5 -0
- package/dist/utils/index.d.ts +2 -1
- package/package.json +49 -49
- package/rollup.config.js +18 -18
- package/src/animation/animationType.ts +17 -0
- package/src/animation/getInitialConfig.ts +61 -31
- package/src/animation/index.ts +9 -4
- package/src/animation/interpolation.ts +24 -57
- package/src/animation/modules.tsx +105 -105
- package/src/animation/useAnimatedValue.ts +62 -132
- package/src/animation/useMountedValue.ts +66 -82
- package/src/gestures/controllers/DragGesture.ts +177 -176
- package/src/gestures/controllers/Gesture.ts +54 -54
- package/src/gestures/controllers/MouseMoveGesture.ts +111 -111
- package/src/gestures/controllers/ScrollGesture.ts +107 -107
- package/src/gestures/controllers/WheelGesture.ts +123 -123
- package/src/gestures/controllers/index.ts +4 -4
- package/src/gestures/eventAttacher.ts +67 -67
- package/src/gestures/hooks/index.ts +5 -5
- package/src/gestures/hooks/useDrag.ts +14 -14
- package/src/gestures/hooks/useGesture.ts +38 -38
- package/src/gestures/hooks/useMouseMove.ts +11 -11
- package/src/gestures/hooks/useRecognizer.ts +59 -59
- package/src/gestures/hooks/useScroll.ts +11 -11
- package/src/gestures/hooks/useWheel.ts +11 -11
- package/src/gestures/index.ts +2 -2
- package/src/gestures/math.ts +120 -120
- package/src/gestures/types.ts +49 -49
- package/src/gestures/withDefault.ts +3 -3
- package/src/hooks/index.ts +3 -3
- package/src/hooks/useMeasure.ts +133 -133
- package/src/hooks/useOutsideClick.ts +36 -36
- package/src/hooks/useWindowDimension.ts +59 -59
- package/src/index.ts +5 -4
- package/src/utils/delay.ts +9 -0
- package/src/utils/index.ts +2 -1
- package/src/utils/isDefined.ts +4 -4
- package/tsconfig.json +25 -25
package/dist/index.js
CHANGED
|
@@ -4,24 +4,15 @@ var reMotion = require('@raidipesh78/re-motion');
|
|
|
4
4
|
var React = require('react');
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
* @
|
|
9
|
-
* @param inputRange - Array<number>
|
|
10
|
-
* @param outputRange - Array<string | number>
|
|
11
|
-
* @param extrapolateConfig - "clamp" | "identity" | "extend"
|
|
12
|
-
* @returns - number | TransitionValue
|
|
7
|
+
* @param { number } ms - number of milliseconds to delay code execution
|
|
8
|
+
* @returns Promise
|
|
13
9
|
*/
|
|
14
|
-
function
|
|
15
|
-
|
|
16
|
-
return
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
else {
|
|
22
|
-
throw new Error("Error! " + typeof value + " cannot be interpolated");
|
|
23
|
-
}
|
|
24
|
-
}
|
|
10
|
+
function delay(ms) {
|
|
11
|
+
return new Promise(function (resolve) {
|
|
12
|
+
setTimeout(function () { return resolve(null); }, ms);
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
|
|
25
16
|
/**
|
|
26
17
|
* bInterpolate functions maps input range [0, 1] to given [minOutput, maxOutput]
|
|
27
18
|
* sorthand function to interpolate input range [0, 1]
|
|
@@ -32,7 +23,7 @@ function interpolate(value, inputRange, outputRange, extrapolateConfig) {
|
|
|
32
23
|
* @returns - number | TransitionValue
|
|
33
24
|
*/
|
|
34
25
|
function bInterpolate(value, minOutput, maxOutput, extrapolateConfig) {
|
|
35
|
-
return interpolate(value, [0, 1], [minOutput, maxOutput], extrapolateConfig);
|
|
26
|
+
return reMotion.interpolate(value, [0, 1], [minOutput, maxOutput], extrapolateConfig);
|
|
36
27
|
}
|
|
37
28
|
|
|
38
29
|
/*! *****************************************************************************
|
|
@@ -110,86 +101,36 @@ function __spread() {
|
|
|
110
101
|
return ar;
|
|
111
102
|
}
|
|
112
103
|
|
|
113
|
-
var getInitialConfig = function (animationType) {
|
|
114
|
-
switch (animationType) {
|
|
115
|
-
case "elastic":
|
|
116
|
-
return { mass: 1, friction: 18, tension: 250 };
|
|
117
|
-
case "stiff":
|
|
118
|
-
return { mass: 1, friction: 18, tension: 350 };
|
|
119
|
-
case "wooble":
|
|
120
|
-
return { mass: 1, friction: 8, tension: 250 };
|
|
121
|
-
case "bounce":
|
|
122
|
-
return { duration: 500, easing: reMotion.Easing.bounce };
|
|
123
|
-
case "ease":
|
|
124
|
-
default:
|
|
125
|
-
return { mass: 1, friction: 26, tension: 170 };
|
|
126
|
-
}
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* getValue checks for type of initialValue and throws error
|
|
131
|
-
* for type other than AnimatedValueType
|
|
132
|
-
*/
|
|
133
|
-
var getValue = function (value) {
|
|
134
|
-
if (typeof value === "number" || typeof value === "string") {
|
|
135
|
-
return value;
|
|
136
|
-
}
|
|
137
|
-
else {
|
|
138
|
-
throw new Error("Invalid Value! Animated value only accepts string or number.");
|
|
139
|
-
}
|
|
140
|
-
};
|
|
141
104
|
/**
|
|
142
105
|
* useAnimatedValue for animated transitions
|
|
143
106
|
*/
|
|
144
107
|
function useAnimatedValue(initialValue, config) {
|
|
145
|
-
var _a;
|
|
146
|
-
var _isInitial = React.useRef(true);
|
|
147
|
-
var _initialValue = getValue(initialValue);
|
|
148
|
-
var animationType = (_a = config === null || config === void 0 ? void 0 : config.animationType) !== null && _a !== void 0 ? _a : "ease"; // Defines default animation
|
|
149
|
-
var onAnimationEnd = config === null || config === void 0 ? void 0 : config.onAnimationEnd;
|
|
150
|
-
var listener = config === null || config === void 0 ? void 0 : config.listener;
|
|
151
|
-
var _b = __read(reMotion.useTransition(_initialValue, __assign(__assign(__assign({}, getInitialConfig(animationType)), config), { onRest: function (result) {
|
|
152
|
-
if (result.finished) {
|
|
153
|
-
onAnimationEnd && onAnimationEnd(result.value);
|
|
154
|
-
}
|
|
155
|
-
}, onChange: function (value) {
|
|
156
|
-
listener && listener(value);
|
|
157
|
-
} })), 2), animation = _b[0], setAnimation = _b[1];
|
|
158
|
-
// doesn't fire on initial render
|
|
159
|
-
React.useEffect(function () {
|
|
160
|
-
if (!_isInitial.current) {
|
|
161
|
-
setAnimation({ toValue: _initialValue });
|
|
162
|
-
}
|
|
163
|
-
_isInitial.current = false;
|
|
164
|
-
}, [_initialValue]);
|
|
108
|
+
var _a = __read(reMotion.useTransition(initialValue, config), 2), animation = _a[0], setAnimation = _a[1];
|
|
165
109
|
var targetObject = {
|
|
166
110
|
value: animation,
|
|
167
111
|
currentValue: animation.get(),
|
|
168
112
|
};
|
|
169
113
|
return new Proxy(targetObject, {
|
|
170
114
|
set: function (_, key, value) {
|
|
171
|
-
if (key ===
|
|
172
|
-
if (typeof value ===
|
|
115
|
+
if (key === 'value') {
|
|
116
|
+
if (typeof value === 'number' || typeof value === 'string') {
|
|
173
117
|
setAnimation({ toValue: value });
|
|
174
118
|
}
|
|
175
|
-
else if (typeof value ===
|
|
176
|
-
setAnimation(
|
|
177
|
-
toValue: value.toValue,
|
|
178
|
-
config: { immediate: value.immediate },
|
|
179
|
-
});
|
|
119
|
+
else if (typeof value === 'object' || typeof value === 'function') {
|
|
120
|
+
setAnimation(value);
|
|
180
121
|
}
|
|
181
122
|
return true;
|
|
182
123
|
}
|
|
183
|
-
throw new Error(
|
|
124
|
+
throw new Error('You cannot set any other property to animation node.');
|
|
184
125
|
},
|
|
185
126
|
get: function (_, key) {
|
|
186
|
-
if (key ===
|
|
127
|
+
if (key === 'value') {
|
|
187
128
|
return animation;
|
|
188
129
|
}
|
|
189
|
-
if (key ===
|
|
130
|
+
if (key === 'currentValue') {
|
|
190
131
|
return animation.get();
|
|
191
132
|
}
|
|
192
|
-
throw new Error(
|
|
133
|
+
throw new Error('You cannot access any other property from animation node.');
|
|
193
134
|
},
|
|
194
135
|
});
|
|
195
136
|
}
|
|
@@ -198,28 +139,23 @@ function useAnimatedValue(initialValue, config) {
|
|
|
198
139
|
* useMountedValue handles mounting and unmounting of a component
|
|
199
140
|
* @param state - boolean
|
|
200
141
|
* @param config - useTransitionConfig
|
|
201
|
-
* @returns mountedValueFunction with a callback with argument ( animationNode, mounted )
|
|
142
|
+
* @returns mountedValueFunction with a callback with argument ( { value: animationNode }, mounted )
|
|
202
143
|
*/
|
|
203
144
|
function useMountedValue(state, config) {
|
|
204
|
-
var
|
|
205
|
-
var
|
|
206
|
-
var
|
|
207
|
-
var
|
|
208
|
-
var _k = __read(reMotion.useTransition(from, _config), 2), animation = _k[0], setAnimation = _k[1];
|
|
209
|
-
var enterDuration = (_b = (_a = config.config) === null || _a === void 0 ? void 0 : _a.enterDuration) !== null && _b !== void 0 ? _b : (_c = config.config) === null || _c === void 0 ? void 0 : _c.duration;
|
|
210
|
-
var exitDuration = (_e = (_d = config.config) === null || _d === void 0 ? void 0 : _d.exitDuration) !== null && _e !== void 0 ? _e : (_f = config.config) === null || _f === void 0 ? void 0 : _f.exitDuration;
|
|
145
|
+
var initial = React.useRef(true);
|
|
146
|
+
var _a = __read(React.useState(state), 2), mounted = _a[0], setMounted = _a[1];
|
|
147
|
+
var _b = React.useRef(config).current, from = _b.from, enter = _b.enter, exit = _b.exit, innerConfig = _b.config, enterConfig = _b.enterConfig, exitConfig = _b.exitConfig;
|
|
148
|
+
var _c = __read(reMotion.useTransition(from, innerConfig), 2), animation = _c[0], setAnimation = _c[1];
|
|
211
149
|
React.useEffect(function () {
|
|
212
150
|
if (state) {
|
|
213
|
-
|
|
151
|
+
initial.current = true;
|
|
214
152
|
setMounted(true);
|
|
215
153
|
}
|
|
216
154
|
else {
|
|
217
|
-
|
|
155
|
+
initial.current = false;
|
|
218
156
|
setAnimation({
|
|
219
157
|
toValue: exit,
|
|
220
|
-
config:
|
|
221
|
-
duration: exitDuration,
|
|
222
|
-
},
|
|
158
|
+
config: exitConfig,
|
|
223
159
|
}, function (_a) {
|
|
224
160
|
var finished = _a.finished;
|
|
225
161
|
if (finished) {
|
|
@@ -229,17 +165,13 @@ function useMountedValue(state, config) {
|
|
|
229
165
|
}
|
|
230
166
|
}, [state]);
|
|
231
167
|
React.useEffect(function () {
|
|
232
|
-
if (mounted && initial) {
|
|
168
|
+
if (mounted && initial.current) {
|
|
233
169
|
setAnimation({
|
|
234
170
|
toValue: enter,
|
|
235
|
-
config:
|
|
236
|
-
duration: enterDuration,
|
|
237
|
-
},
|
|
238
|
-
}, function () {
|
|
239
|
-
return;
|
|
171
|
+
config: enterConfig,
|
|
240
172
|
});
|
|
241
173
|
}
|
|
242
|
-
}, [mounted, initial]);
|
|
174
|
+
}, [mounted, initial.current]);
|
|
243
175
|
return function (callback) {
|
|
244
176
|
return callback({ value: animation }, mounted);
|
|
245
177
|
};
|
|
@@ -254,15 +186,15 @@ function makeAnimatedComponent(WrappedComponent) {
|
|
|
254
186
|
/**
|
|
255
187
|
* AnimatedBlock : Animated Div
|
|
256
188
|
*/
|
|
257
|
-
var AnimatedBlock = reMotion.makeAnimatedComponent(
|
|
189
|
+
var AnimatedBlock = reMotion.makeAnimatedComponent('div');
|
|
258
190
|
/**
|
|
259
191
|
* AnimatedInline : Animated Span
|
|
260
192
|
*/
|
|
261
|
-
var AnimatedInline = reMotion.makeAnimatedComponent(
|
|
193
|
+
var AnimatedInline = reMotion.makeAnimatedComponent('span');
|
|
262
194
|
/**
|
|
263
195
|
* AnimatedImage : Animated Image
|
|
264
196
|
*/
|
|
265
|
-
var AnimatedImage = reMotion.makeAnimatedComponent(
|
|
197
|
+
var AnimatedImage = reMotion.makeAnimatedComponent('img');
|
|
266
198
|
/**
|
|
267
199
|
* ScrollableBlock
|
|
268
200
|
* Used to animate element when enter into viewport
|
|
@@ -270,7 +202,7 @@ var AnimatedImage = reMotion.makeAnimatedComponent("img");
|
|
|
270
202
|
* animated value goes from 0 to 1 when appear on viewport & vice versa.
|
|
271
203
|
*/
|
|
272
204
|
var ScrollableBlock = function (props) {
|
|
273
|
-
var children = props.children, _a = props.direction, direction = _a === void 0 ?
|
|
205
|
+
var children = props.children, _a = props.direction, direction = _a === void 0 ? 'single' : _a, animationConfig = props.animationConfig, _b = props.threshold, threshold = _b === void 0 ? 0.2 : _b;
|
|
274
206
|
var scrollableBlockRef = React.useRef(null);
|
|
275
207
|
var animation = useAnimatedValue(0, animationConfig); // 0: not intersecting | 1: intersecting
|
|
276
208
|
React.useEffect(function () {
|
|
@@ -282,7 +214,7 @@ var ScrollableBlock = function (props) {
|
|
|
282
214
|
animation.value = 1;
|
|
283
215
|
}
|
|
284
216
|
else {
|
|
285
|
-
if (direction ===
|
|
217
|
+
if (direction === 'both')
|
|
286
218
|
animation.value = 0;
|
|
287
219
|
}
|
|
288
220
|
}, {
|
|
@@ -307,10 +239,58 @@ var ScrollableBlock = function (props) {
|
|
|
307
239
|
*/
|
|
308
240
|
var MountedBlock = function (_a) {
|
|
309
241
|
var state = _a.state, children = _a.children, config = _a.config;
|
|
310
|
-
var open = useMountedValue(state,
|
|
242
|
+
var open = useMountedValue(state, config);
|
|
311
243
|
return React.createElement(React.Fragment, null, open(function (animation, mounted) { return mounted && children(animation); }));
|
|
312
244
|
};
|
|
313
245
|
|
|
246
|
+
var getInitialConfig = function (animationType) {
|
|
247
|
+
switch (animationType) {
|
|
248
|
+
case 'elastic':
|
|
249
|
+
return { mass: 1, friction: 18, tension: 250 };
|
|
250
|
+
case 'stiff':
|
|
251
|
+
return { mass: 1, friction: 18, tension: 350 };
|
|
252
|
+
case 'wooble':
|
|
253
|
+
return { mass: 1, friction: 8, tension: 250 };
|
|
254
|
+
case 'bounce':
|
|
255
|
+
return { duration: 500, easing: reMotion.Easing.bounce };
|
|
256
|
+
case 'power1':
|
|
257
|
+
return { duration: 500, easing: reMotion.Easing.bezier(0.17, 0.42, 0.51, 0.97) };
|
|
258
|
+
case 'power2':
|
|
259
|
+
return { duration: 500, easing: reMotion.Easing.bezier(0.07, 0.11, 0.13, 1) };
|
|
260
|
+
case 'power3':
|
|
261
|
+
return { duration: 500, easing: reMotion.Easing.bezier(0.09, 0.7, 0.16, 1.04) };
|
|
262
|
+
case 'power4':
|
|
263
|
+
return { duration: 500, easing: reMotion.Easing.bezier(0.05, 0.54, 0, 1.03) };
|
|
264
|
+
case 'linear':
|
|
265
|
+
return { duration: 500, easing: reMotion.Easing.linear };
|
|
266
|
+
case 'easein':
|
|
267
|
+
return { duration: 500, easing: reMotion.Easing.in(reMotion.Easing.ease) };
|
|
268
|
+
case 'easeout':
|
|
269
|
+
return { duration: 500, easing: reMotion.Easing.out(reMotion.Easing.ease) };
|
|
270
|
+
case 'easeinout':
|
|
271
|
+
return { duration: 500, easing: reMotion.Easing.inOut(reMotion.Easing.ease) };
|
|
272
|
+
case 'ease':
|
|
273
|
+
default:
|
|
274
|
+
return { mass: 1, friction: 26, tension: 170 };
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
var AnimationConfigUtils = {
|
|
279
|
+
ELASTIC: getInitialConfig('elastic'),
|
|
280
|
+
BOUNCE: getInitialConfig('bounce'),
|
|
281
|
+
EASE: getInitialConfig('ease'),
|
|
282
|
+
STIFF: getInitialConfig('stiff'),
|
|
283
|
+
WOOBLE: getInitialConfig('wooble'),
|
|
284
|
+
EASE_IN: getInitialConfig('easein'),
|
|
285
|
+
EASE_OUT: getInitialConfig('easeout'),
|
|
286
|
+
EASE_IN_OUT: getInitialConfig('easeinout'),
|
|
287
|
+
POWER1: getInitialConfig('power1'),
|
|
288
|
+
POWER2: getInitialConfig('power2'),
|
|
289
|
+
POWER3: getInitialConfig('power3'),
|
|
290
|
+
POWER4: getInitialConfig('power4'),
|
|
291
|
+
LINEAR: getInitialConfig('linear'),
|
|
292
|
+
};
|
|
293
|
+
|
|
314
294
|
/**
|
|
315
295
|
* Attach single document / window event / HTMLElement
|
|
316
296
|
*/
|
|
@@ -509,12 +489,12 @@ var DragGesture = /** @class */ (function (_super) {
|
|
|
509
489
|
DragGesture.prototype._initEvents = function () {
|
|
510
490
|
if (this.targetElement || this.targetElements.length > 0) {
|
|
511
491
|
this._subscribe = attachEvents([window], [
|
|
512
|
-
[
|
|
513
|
-
[
|
|
514
|
-
[
|
|
515
|
-
[
|
|
516
|
-
[
|
|
517
|
-
[
|
|
492
|
+
['mousedown', this.pointerDown.bind(this)],
|
|
493
|
+
['mousemove', this.pointerMove.bind(this)],
|
|
494
|
+
['mouseup', this.pointerUp.bind(this)],
|
|
495
|
+
['touchstart', this.pointerDown.bind(this), { passive: false }],
|
|
496
|
+
['touchmove', this.pointerMove.bind(this), { passive: false }],
|
|
497
|
+
['touchend', this.pointerUp.bind(this)],
|
|
518
498
|
]);
|
|
519
499
|
}
|
|
520
500
|
};
|
|
@@ -523,7 +503,7 @@ var DragGesture = /** @class */ (function (_super) {
|
|
|
523
503
|
// will not be triggered
|
|
524
504
|
DragGesture.prototype._cancelEvents = function () {
|
|
525
505
|
if (this._subscribe) {
|
|
526
|
-
this._subscribe([
|
|
506
|
+
this._subscribe(['mousedown', 'mousemove', 'touchstart', 'touchmove']);
|
|
527
507
|
}
|
|
528
508
|
};
|
|
529
509
|
DragGesture.prototype._handleCallback = function () {
|
|
@@ -550,7 +530,7 @@ var DragGesture = /** @class */ (function (_super) {
|
|
|
550
530
|
};
|
|
551
531
|
DragGesture.prototype.pointerDown = function (e) {
|
|
552
532
|
var _a;
|
|
553
|
-
if (e.type ===
|
|
533
|
+
if (e.type === 'touchstart') {
|
|
554
534
|
this.movementStart = {
|
|
555
535
|
x: e.touches[0].clientX,
|
|
556
536
|
y: e.touches[0].clientY,
|
|
@@ -596,10 +576,10 @@ var DragGesture = /** @class */ (function (_super) {
|
|
|
596
576
|
if (this.isActive) {
|
|
597
577
|
e.preventDefault();
|
|
598
578
|
var now = Date.now();
|
|
599
|
-
var deltaTime =
|
|
579
|
+
var deltaTime = clamp(now - this.lastTimeStamp, 0.1, 64);
|
|
600
580
|
this.lastTimeStamp = now;
|
|
601
581
|
var t = deltaTime / 1000;
|
|
602
|
-
if (e.type ===
|
|
582
|
+
if (e.type === 'touchmove') {
|
|
603
583
|
this.movement = {
|
|
604
584
|
x: this.initialMovement.x +
|
|
605
585
|
(e.touches[0].clientX - this.movementStart.x),
|
|
@@ -632,6 +612,7 @@ var DragGesture = /** @class */ (function (_super) {
|
|
|
632
612
|
if (this.isActive) {
|
|
633
613
|
this.isActive = false;
|
|
634
614
|
this._handleCallback();
|
|
615
|
+
this._cancelEvents();
|
|
635
616
|
this._initEvents();
|
|
636
617
|
}
|
|
637
618
|
};
|
|
@@ -1169,15 +1150,22 @@ Object.defineProperty(exports, 'Easing', {
|
|
|
1169
1150
|
return reMotion.Easing;
|
|
1170
1151
|
}
|
|
1171
1152
|
});
|
|
1153
|
+
Object.defineProperty(exports, 'interpolate', {
|
|
1154
|
+
enumerable: true,
|
|
1155
|
+
get: function () {
|
|
1156
|
+
return reMotion.interpolate;
|
|
1157
|
+
}
|
|
1158
|
+
});
|
|
1172
1159
|
exports.AnimatedBlock = AnimatedBlock;
|
|
1173
1160
|
exports.AnimatedImage = AnimatedImage;
|
|
1174
1161
|
exports.AnimatedInline = AnimatedInline;
|
|
1162
|
+
exports.AnimationConfigUtils = AnimationConfigUtils;
|
|
1175
1163
|
exports.MountedBlock = MountedBlock;
|
|
1176
1164
|
exports.ScrollableBlock = ScrollableBlock;
|
|
1177
1165
|
exports.bInterpolate = bInterpolate;
|
|
1178
1166
|
exports.bin = bin;
|
|
1179
1167
|
exports.clamp = clamp;
|
|
1180
|
-
exports.
|
|
1168
|
+
exports.delay = delay;
|
|
1181
1169
|
exports.makeAnimatedComponent = makeAnimatedComponent;
|
|
1182
1170
|
exports.mix = mix;
|
|
1183
1171
|
exports.move = move;
|