1 | import _extends from 'babel-runtime/helpers/extends';
|
2 | import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
|
3 | import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
|
4 | import _inherits from 'babel-runtime/helpers/inherits';
|
5 |
|
6 | var _class, _temp;
|
7 |
|
8 | import React, { Component } from 'react';
|
9 | import cx from 'classnames';
|
10 | import PropTypes from 'prop-types';
|
11 | import { polyfill } from 'react-lifecycles-compat';
|
12 |
|
13 | import Icon from '../../icon';
|
14 | import Button from '../../button';
|
15 | import zhCN from '../../locale/zh-cn';
|
16 | import { func, obj } from '../../util';
|
17 | import ConfigProvider from '../../config-provider';
|
18 | import TransferPanel from '../view/transfer-panel';
|
19 |
|
20 | var config = ConfigProvider.config;
|
21 | var bindCtx = func.bindCtx;
|
22 | var pickOthers = obj.pickOthers;
|
23 |
|
24 |
|
25 | var getLeftValue = function getLeftValue(dataSource, rightValue) {
|
26 | return dataSource.map(function (item) {
|
27 | return item.value;
|
28 | }).filter(function (itemValue) {
|
29 | return rightValue.indexOf(itemValue) === -1;
|
30 | });
|
31 | };
|
32 |
|
33 | var filterCheckedValue = function filterCheckedValue(left, right, dataSource) {
|
34 | var result = {
|
35 | left: [],
|
36 | right: []
|
37 | };
|
38 |
|
39 | if (left.length || right.length) {
|
40 | var value = dataSource.map(function (item) {
|
41 | return item.value;
|
42 | });
|
43 | value.forEach(function (itemValue) {
|
44 | if (left.indexOf(itemValue) > -1) {
|
45 | result.left.push(itemValue);
|
46 | } else if (right.indexOf(itemValue) > -1) {
|
47 | result.right.push(itemValue);
|
48 | }
|
49 | });
|
50 | }
|
51 |
|
52 | return result;
|
53 | };
|
54 |
|
55 |
|
56 |
|
57 |
|
58 | var Transfer = (_temp = _class = function (_Component) {
|
59 | _inherits(Transfer, _Component);
|
60 |
|
61 | Transfer.normalizeValue = function normalizeValue(value) {
|
62 | if (value) {
|
63 | if (Array.isArray(value)) {
|
64 | return value;
|
65 | }
|
66 |
|
67 | return [value];
|
68 | }
|
69 |
|
70 | return [];
|
71 | };
|
72 |
|
73 | Transfer.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps, prevState) {
|
74 | var innerUpdate = prevState.innerUpdate,
|
75 | value = prevState.value,
|
76 | leftValue = prevState.leftValue;
|
77 |
|
78 | if (innerUpdate) {
|
79 | return {
|
80 | innerUpdate: false,
|
81 | value: value,
|
82 | leftValue: leftValue
|
83 | };
|
84 | }
|
85 | var st = {};
|
86 |
|
87 | var newValue = void 0;
|
88 | if ('value' in nextProps) {
|
89 | var _value = Transfer.normalizeValue(nextProps.value);
|
90 | st.value = _value;
|
91 | newValue = _value;
|
92 | } else {
|
93 |
|
94 | newValue = prevState.value;
|
95 | }
|
96 | st.leftValue = getLeftValue(nextProps.dataSource, newValue);
|
97 |
|
98 | var _filterCheckedValue = filterCheckedValue(prevState.leftCheckedValue, prevState.rightCheckedValue, nextProps.dataSource),
|
99 | left = _filterCheckedValue.left,
|
100 | right = _filterCheckedValue.right;
|
101 |
|
102 | st.leftCheckedValue = left;
|
103 | st.rightCheckedValue = right;
|
104 |
|
105 | return st;
|
106 | };
|
107 |
|
108 | function Transfer(props, context) {
|
109 | _classCallCheck(this, Transfer);
|
110 |
|
111 | var _this = _possibleConstructorReturn(this, _Component.call(this, props, context));
|
112 |
|
113 | var value = props.value,
|
114 | defaultValue = props.defaultValue,
|
115 | defaultLeftChecked = props.defaultLeftChecked,
|
116 | defaultRightChecked = props.defaultRightChecked,
|
117 | dataSource = props.dataSource,
|
118 | rtl = props.rtl,
|
119 | operations = props.operations;
|
120 |
|
121 | if (operations.length === 0) {
|
122 | operations.push(React.createElement(Icon, { rtl: rtl, type: 'arrow-right' }));
|
123 | operations.push(React.createElement(Icon, { rtl: rtl, type: 'arrow-left' }));
|
124 | }
|
125 |
|
126 | var _filterCheckedValue2 = filterCheckedValue(Transfer.normalizeValue(defaultLeftChecked), Transfer.normalizeValue(defaultRightChecked), dataSource),
|
127 | left = _filterCheckedValue2.left,
|
128 | right = _filterCheckedValue2.right;
|
129 |
|
130 | var stValue = Transfer.normalizeValue('value' in props ? value : defaultValue);
|
131 | _this.state = {
|
132 | value: stValue,
|
133 | leftCheckedValue: left,
|
134 | rightCheckedValue: right,
|
135 | leftValue: getLeftValue(dataSource, stValue)
|
136 | };
|
137 |
|
138 | bindCtx(_this, ['handlePanelChange', 'handlePanelSort', 'handleMoveItem', 'handleSimpleMove', 'handleSimpleMoveAll']);
|
139 | return _this;
|
140 | }
|
141 |
|
142 | Transfer.prototype.groupDatasource = function groupDatasource(value, itemValues, dataSource) {
|
143 | return value.reduce(function (ret, itemValue) {
|
144 | var index = itemValues.indexOf(itemValue);
|
145 | if (index > -1) {
|
146 | ret.push(dataSource[index]);
|
147 | }
|
148 | return ret;
|
149 | }, []);
|
150 | };
|
151 |
|
152 | Transfer.prototype.handlePanelChange = function handlePanelChange(position, value) {
|
153 | var _setState;
|
154 |
|
155 | var _state = this.state,
|
156 | leftCheckedValue = _state.leftCheckedValue,
|
157 | rightCheckedValue = _state.rightCheckedValue;
|
158 | var onSelect = this.props.onSelect;
|
159 |
|
160 | var valuePropName = position === 'left' ? 'leftCheckedValue' : 'rightCheckedValue';
|
161 |
|
162 | this.setState((_setState = {
|
163 | innerUpdate: true
|
164 | }, _setState[valuePropName] = value, _setState));
|
165 | onSelect && onSelect(position === 'left' ? value : leftCheckedValue, position === 'left' ? rightCheckedValue : value, position === 'left' ? 'source' : 'target');
|
166 | };
|
167 |
|
168 | Transfer.prototype.handlePanelSort = function handlePanelSort(position, dragValue, referenceValue, dragGap) {
|
169 | var _this2 = this;
|
170 |
|
171 | var _state2 = this.state,
|
172 | value = _state2.value,
|
173 | leftValue = _state2.leftValue;
|
174 |
|
175 | var newValue = position === 'right' ? value : leftValue;
|
176 | var currentIndex = newValue.indexOf(dragValue);
|
177 | var referenceIndex = newValue.indexOf(referenceValue);
|
178 | var expectIndex = dragGap === 'before' ? referenceIndex : referenceIndex + 1;
|
179 | if (currentIndex === expectIndex) {
|
180 | return;
|
181 | }
|
182 |
|
183 | newValue.splice(currentIndex, 1);
|
184 | if (currentIndex < expectIndex) {
|
185 | expectIndex = expectIndex - 1;
|
186 | }
|
187 | newValue.splice(expectIndex, 0, dragValue);
|
188 | this.setState({
|
189 | innerUpdate: true,
|
190 | value: value,
|
191 | leftValue: leftValue
|
192 | }, function () {
|
193 | _this2.props.onSort(newValue, position);
|
194 | });
|
195 | };
|
196 |
|
197 | Transfer.prototype.handleMoveItem = function handleMoveItem(direction) {
|
198 | var _st;
|
199 |
|
200 | var rightValue = void 0;
|
201 | var newLeftValue = void 0;
|
202 | var movedValue = void 0;
|
203 | var valuePropName = void 0;
|
204 |
|
205 | var _state3 = this.state,
|
206 | value = _state3.value,
|
207 | leftValue = _state3.leftValue,
|
208 | leftCheckedValue = _state3.leftCheckedValue,
|
209 | rightCheckedValue = _state3.rightCheckedValue;
|
210 |
|
211 |
|
212 | if (direction === 'right') {
|
213 | rightValue = leftCheckedValue.concat(value);
|
214 | newLeftValue = leftValue.filter(function (itemValue) {
|
215 | return leftCheckedValue.indexOf(itemValue) === -1;
|
216 | });
|
217 | movedValue = leftCheckedValue;
|
218 | valuePropName = 'leftCheckedValue';
|
219 | } else {
|
220 | rightValue = value.filter(function (itemValue) {
|
221 | return rightCheckedValue.indexOf(itemValue) === -1;
|
222 | });
|
223 | newLeftValue = rightCheckedValue.concat(leftValue);
|
224 | movedValue = rightCheckedValue;
|
225 | valuePropName = 'rightCheckedValue';
|
226 | }
|
227 |
|
228 | var st = (_st = {}, _st[valuePropName] = [], _st);
|
229 |
|
230 | this.setValueState(st, rightValue, newLeftValue, movedValue, direction);
|
231 | };
|
232 |
|
233 | Transfer.prototype.handleSimpleMove = function handleSimpleMove(direction, v) {
|
234 | var rightValue = void 0;
|
235 | var newLeftValue = void 0;
|
236 |
|
237 | var _state4 = this.state,
|
238 | value = _state4.value,
|
239 | leftValue = _state4.leftValue;
|
240 |
|
241 |
|
242 | if (direction === 'right') {
|
243 | rightValue = [v].concat(value);
|
244 | newLeftValue = leftValue.filter(function (itemValue) {
|
245 | return itemValue !== v;
|
246 | });
|
247 | } else {
|
248 | rightValue = value.filter(function (itemValue) {
|
249 | return itemValue !== v;
|
250 | });
|
251 | newLeftValue = [v].concat(leftValue);
|
252 | }
|
253 |
|
254 | this.setValueState({}, rightValue, newLeftValue, [v], direction);
|
255 | };
|
256 |
|
257 | Transfer.prototype.handleSimpleMoveAll = function handleSimpleMoveAll(direction) {
|
258 | var rightValue = void 0;
|
259 | var newLeftValue = void 0;
|
260 | var movedValue = void 0;
|
261 |
|
262 | var dataSource = this.props.dataSource;
|
263 | var _state5 = this.state,
|
264 | value = _state5.value,
|
265 | leftValue = _state5.leftValue;
|
266 |
|
267 | var disabledValue = dataSource.reduce(function (ret, item) {
|
268 | if (item.disabled) {
|
269 | ret.push(item.value);
|
270 | }
|
271 |
|
272 | return ret;
|
273 | }, []);
|
274 |
|
275 | if (direction === 'right') {
|
276 | movedValue = leftValue.filter(function (itemValue) {
|
277 | return disabledValue.indexOf(itemValue) === -1;
|
278 | });
|
279 | rightValue = movedValue.concat(value);
|
280 | newLeftValue = leftValue.filter(function (itemValue) {
|
281 | return disabledValue.indexOf(itemValue) > -1;
|
282 | });
|
283 | } else {
|
284 | movedValue = value.filter(function (itemValue) {
|
285 | return disabledValue.indexOf(itemValue) === -1;
|
286 | });
|
287 | rightValue = value.filter(function (itemValue) {
|
288 | return disabledValue.indexOf(itemValue) > -1;
|
289 | });
|
290 | newLeftValue = movedValue.concat(leftValue);
|
291 | }
|
292 |
|
293 | this.setValueState({}, rightValue, newLeftValue, movedValue, direction);
|
294 | };
|
295 |
|
296 |
|
297 |
|
298 |
|
299 | Transfer.prototype.setValueState = function setValueState(st, rightValue, leftValue, movedValue, direction) {
|
300 | var _this3 = this;
|
301 |
|
302 | var dataSource = this.props.dataSource;
|
303 |
|
304 | var callback = function callback() {
|
305 | if ('onChange' in _this3.props) {
|
306 | var itemValues = dataSource.map(function (item) {
|
307 | return item.value;
|
308 | });
|
309 | var rightData = _this3.groupDatasource(rightValue, itemValues, dataSource);
|
310 | var leftData = _this3.groupDatasource(leftValue, itemValues, dataSource);
|
311 | var movedData = _this3.groupDatasource(movedValue, itemValues, dataSource);
|
312 |
|
313 | _this3.props.onChange(rightValue, rightData, {
|
314 | leftValue: leftValue,
|
315 | leftData: leftData,
|
316 | movedValue: movedValue,
|
317 | movedData: movedData,
|
318 | direction: direction
|
319 | });
|
320 | }
|
321 | };
|
322 |
|
323 | if (!('value' in this.props)) {
|
324 | st.value = rightValue;
|
325 | st.leftValue = leftValue;
|
326 | }
|
327 |
|
328 | if (Object.keys(st).length) {
|
329 | this.setState(st, callback);
|
330 | } else {
|
331 |
|
332 | callback();
|
333 | }
|
334 | };
|
335 |
|
336 | Transfer.prototype.renderCenter = function renderCenter() {
|
337 | var _props = this.props,
|
338 | prefix = _props.prefix,
|
339 | mode = _props.mode,
|
340 | operations = _props.operations,
|
341 | disabled = _props.disabled,
|
342 | leftDisabled = _props.leftDisabled,
|
343 | rightDisabled = _props.rightDisabled,
|
344 | locale = _props.locale;
|
345 | var _state6 = this.state,
|
346 | leftCheckedValue = _state6.leftCheckedValue,
|
347 | rightCheckedValue = _state6.rightCheckedValue;
|
348 |
|
349 | return React.createElement(
|
350 | 'div',
|
351 | { className: prefix + 'transfer-operations' },
|
352 | mode === 'simple' ? React.createElement(Icon, { className: prefix + 'transfer-move', size: 'large', type: 'switch' }) : [React.createElement(
|
353 | Button,
|
354 | {
|
355 | 'aria-label': locale.moveToRight,
|
356 | key: 'l2r',
|
357 | className: prefix + 'transfer-operation',
|
358 | type: leftCheckedValue.length ? 'primary' : 'normal',
|
359 | disabled: leftDisabled || disabled || !leftCheckedValue.length,
|
360 | onClick: this.handleMoveItem.bind(this, 'right')
|
361 | },
|
362 | operations[0]
|
363 | ), React.createElement(
|
364 | Button,
|
365 | {
|
366 | 'aria-label': locale.moveToLeft,
|
367 | key: 'r2l',
|
368 | className: prefix + 'transfer-operation',
|
369 | type: rightCheckedValue.length ? 'primary' : 'normal',
|
370 | disabled: rightDisabled || disabled || !rightCheckedValue.length,
|
371 | onClick: this.handleMoveItem.bind(this, 'left')
|
372 | },
|
373 | operations[1]
|
374 | )]
|
375 | );
|
376 | };
|
377 |
|
378 | Transfer.prototype.render = function render() {
|
379 | var _props2 = this.props,
|
380 | prefix = _props2.prefix,
|
381 | mode = _props2.mode,
|
382 | disabled = _props2.disabled,
|
383 | className = _props2.className,
|
384 | dataSource = _props2.dataSource,
|
385 | locale = _props2.locale,
|
386 | _props2$showSearch = _props2.showSearch,
|
387 | showSearch = _props2$showSearch === undefined ? false : _props2$showSearch,
|
388 | _props2$searchProps = _props2.searchProps,
|
389 | searchProps = _props2$searchProps === undefined ? {} : _props2$searchProps,
|
390 | filter = _props2.filter,
|
391 | onSearch = _props2.onSearch,
|
392 | leftDisabled = _props2.leftDisabled,
|
393 | rightDisabled = _props2.rightDisabled,
|
394 | searchPlaceholder = _props2.searchPlaceholder,
|
395 | notFoundContent = _props2.notFoundContent,
|
396 | titles = _props2.titles,
|
397 | listClassName = _props2.listClassName,
|
398 | listStyle = _props2.listStyle,
|
399 | itemRender = _props2.itemRender,
|
400 | sortable = _props2.sortable,
|
401 | useVirtual = _props2.useVirtual,
|
402 | rtl = _props2.rtl,
|
403 | id = _props2.id,
|
404 | children = _props2.children,
|
405 | showCheckAll = _props2.showCheckAll;
|
406 | var _state7 = this.state,
|
407 | value = _state7.value,
|
408 | leftValue = _state7.leftValue,
|
409 | leftCheckedValue = _state7.leftCheckedValue,
|
410 | rightCheckedValue = _state7.rightCheckedValue;
|
411 |
|
412 | var itemValues = dataSource.map(function (item) {
|
413 | return item.value;
|
414 | });
|
415 | var leftDatasource = this.groupDatasource(leftValue, itemValues, dataSource);
|
416 | var rightDatasource = this.groupDatasource(value, itemValues, dataSource);
|
417 | var panelProps = {
|
418 | prefix: prefix,
|
419 | mode: mode,
|
420 | locale: locale,
|
421 | filter: filter,
|
422 | onSearch: onSearch,
|
423 | searchPlaceholder: searchPlaceholder,
|
424 | listClassName: listClassName,
|
425 | listStyle: listStyle,
|
426 | itemRender: itemRender,
|
427 | onMove: this.handleSimpleMove,
|
428 | onMoveAll: this.handleSimpleMoveAll,
|
429 | onChange: this.handlePanelChange,
|
430 | sortable: sortable,
|
431 | useVirtual: useVirtual,
|
432 | onSort: this.handlePanelSort,
|
433 | baseId: id,
|
434 | customerList: children,
|
435 | showCheckAll: showCheckAll
|
436 | };
|
437 | var others = pickOthers(Object.keys(Transfer.propTypes), this.props);
|
438 |
|
439 | if (rtl) {
|
440 | others.dir = 'rtl';
|
441 | }
|
442 | var _showSearch = Array.isArray(showSearch) ? showSearch : [showSearch, showSearch];
|
443 | var _searchProps = Array.isArray(searchProps) ? searchProps : [searchProps, searchProps];
|
444 | var _notFoundContent = Array.isArray(notFoundContent) ? notFoundContent : [notFoundContent, notFoundContent];
|
445 | return React.createElement(
|
446 | 'div',
|
447 | _extends({ className: cx(prefix + 'transfer', className), id: id }, others),
|
448 | React.createElement(TransferPanel, _extends({}, panelProps, {
|
449 | position: 'left',
|
450 | dataSource: leftDatasource,
|
451 | disabled: leftDisabled || disabled,
|
452 | value: leftCheckedValue,
|
453 | showSearch: _showSearch[0],
|
454 | searchProps: _searchProps[0],
|
455 | notFoundContent: _notFoundContent[0],
|
456 | title: titles[0]
|
457 | })),
|
458 | this.renderCenter(),
|
459 | React.createElement(TransferPanel, _extends({}, panelProps, {
|
460 | position: 'right',
|
461 | dataSource: rightDatasource,
|
462 | disabled: rightDisabled || disabled,
|
463 | value: rightCheckedValue,
|
464 | showSearch: _showSearch[1],
|
465 | searchProps: _searchProps[1],
|
466 | notFoundContent: _notFoundContent[1],
|
467 | title: titles[1]
|
468 | }))
|
469 | );
|
470 | };
|
471 |
|
472 | return Transfer;
|
473 | }(Component), _class.contextTypes = {
|
474 | prefix: PropTypes.string
|
475 | }, _class.propTypes = _extends({}, ConfigProvider.propTypes, {
|
476 | prefix: PropTypes.string,
|
477 | pure: PropTypes.bool,
|
478 | rtl: PropTypes.bool,
|
479 | className: PropTypes.string,
|
480 | |
481 |
|
482 |
|
483 | mode: PropTypes.oneOf(['normal', 'simple']),
|
484 | |
485 |
|
486 |
|
487 | dataSource: PropTypes.arrayOf(PropTypes.object),
|
488 | |
489 |
|
490 |
|
491 | value: PropTypes.arrayOf(PropTypes.string),
|
492 | |
493 |
|
494 |
|
495 | defaultValue: PropTypes.arrayOf(PropTypes.string),
|
496 | |
497 |
|
498 |
|
499 |
|
500 |
|
501 |
|
502 |
|
503 |
|
504 |
|
505 |
|
506 |
|
507 | onChange: PropTypes.func,
|
508 | |
509 |
|
510 |
|
511 |
|
512 |
|
513 |
|
514 | onSelect: PropTypes.func,
|
515 | |
516 |
|
517 |
|
518 | disabled: PropTypes.bool,
|
519 | |
520 |
|
521 |
|
522 | leftDisabled: PropTypes.bool,
|
523 | |
524 |
|
525 |
|
526 | rightDisabled: PropTypes.bool,
|
527 | |
528 |
|
529 |
|
530 |
|
531 |
|
532 | itemRender: PropTypes.func,
|
533 | |
534 |
|
535 |
|
536 |
|
537 |
|
538 |
|
539 |
|
540 | filter: PropTypes.func,
|
541 | |
542 |
|
543 |
|
544 |
|
545 |
|
546 | onSearch: PropTypes.func,
|
547 | |
548 |
|
549 |
|
550 | searchPlaceholder: PropTypes.string,
|
551 | |
552 |
|
553 |
|
554 | showSearch: PropTypes.oneOfType([PropTypes.bool, PropTypes.arrayOf(PropTypes.bool)]),
|
555 | |
556 |
|
557 |
|
558 | searchProps: PropTypes.oneOfType([PropTypes.object, PropTypes.arrayOf(PropTypes.object)]),
|
559 | |
560 |
|
561 |
|
562 | notFoundContent: PropTypes.oneOfType([PropTypes.node, PropTypes.arrayOf(PropTypes.node)]),
|
563 | |
564 |
|
565 |
|
566 | titles: PropTypes.arrayOf(PropTypes.node),
|
567 | |
568 |
|
569 |
|
570 |
|
571 | operations: PropTypes.arrayOf(PropTypes.node),
|
572 | |
573 |
|
574 |
|
575 | defaultLeftChecked: PropTypes.arrayOf(PropTypes.string),
|
576 | |
577 |
|
578 |
|
579 | defaultRightChecked: PropTypes.arrayOf(PropTypes.string),
|
580 | |
581 |
|
582 |
|
583 | listClassName: PropTypes.string,
|
584 | |
585 |
|
586 |
|
587 | listStyle: PropTypes.object,
|
588 | |
589 |
|
590 |
|
591 | sortable: PropTypes.bool,
|
592 | |
593 |
|
594 |
|
595 |
|
596 |
|
597 | onSort: PropTypes.func,
|
598 | |
599 |
|
600 |
|
601 | locale: PropTypes.object,
|
602 | |
603 |
|
604 |
|
605 | id: PropTypes.string,
|
606 | |
607 |
|
608 |
|
609 | children: PropTypes.func,
|
610 | |
611 |
|
612 |
|
613 | useVirtual: PropTypes.bool,
|
614 | |
615 |
|
616 |
|
617 | showCheckAll: PropTypes.bool
|
618 | }), _class.defaultProps = {
|
619 | prefix: 'next-',
|
620 | pure: false,
|
621 | mode: 'normal',
|
622 | dataSource: [],
|
623 | defaultValue: [],
|
624 | disabled: false,
|
625 | leftDisabled: false,
|
626 | rightDisabled: false,
|
627 | showCheckAll: true,
|
628 | itemRender: function itemRender(data) {
|
629 | return data.label;
|
630 | },
|
631 | showSearch: false,
|
632 | filter: function filter(searchedValue, data) {
|
633 | var labelString = '';
|
634 | var loop = function loop(arg) {
|
635 | if (React.isValidElement(arg) && arg.props.children) {
|
636 | React.Children.forEach(arg.props.children, loop);
|
637 | } else if (typeof arg === 'string') {
|
638 | labelString += arg;
|
639 | }
|
640 | };
|
641 | loop(data.label);
|
642 |
|
643 | return labelString.length >= searchedValue.length && labelString.indexOf(searchedValue) > -1;
|
644 | },
|
645 | onSearch: function onSearch() {},
|
646 | notFoundContent: 'Not Found',
|
647 | titles: [],
|
648 | operations: [],
|
649 | defaultLeftChecked: [],
|
650 | defaultRightChecked: [],
|
651 | sortable: false,
|
652 | onSort: function onSort() {},
|
653 | locale: zhCN.Transfer
|
654 | }, _temp);
|
655 | Transfer.displayName = 'Transfer';
|
656 |
|
657 |
|
658 | export default config(polyfill(Transfer)); |
\ | No newline at end of file |