sirius-common-utils 1.0.0

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.
@@ -0,0 +1,433 @@
1
+ import _ from 'lodash';
2
+
3
+ import CfgUtils from "./CfgUtils";
4
+ import LoginUserUtils from "./LoginUserUtils";
5
+
6
+ let axios = null;
7
+ let urlContext = null; //URL路径前缀
8
+
9
+ let RESULT = {
10
+ SUCCESS: 200,
11
+ };
12
+
13
+
14
+ let EXCEPTION_CODE = {
15
+ AUTHENTICATION_FAILED_COMMON: 901,
16
+ NETWORK_ISSUE_CLIENT: 911,
17
+ SYS_UNKNOWN_ISSUE: 999,
18
+ }
19
+
20
+ let globalDialogUtilsInstance;
21
+ let globalSpinHandlerInstance;
22
+ let loginServiceInstance;
23
+
24
+ function init(pAxios, pSpinHandlerInstance, pDialogUtilsInstance, pLoginServiceInstance) {
25
+ axios = pAxios;
26
+
27
+ // axios.defaults.baseURL = getPath("/xms-test");
28
+ axios.defaults.baseURL = getPath(process.env.REACT_APP_AXIOS_CONTEXT);
29
+ axios.defaults.timeout = CfgUtils.ajax.timeout;
30
+
31
+ globalDialogUtilsInstance = pDialogUtilsInstance;
32
+ globalSpinHandlerInstance = pSpinHandlerInstance;
33
+ loginServiceInstance = pLoginServiceInstance;
34
+ }
35
+
36
+ /**
37
+ *
38
+ */
39
+ function loadParamFromLocationSearch(paramKey) {
40
+ var paramsStr = window.location.search;
41
+ if (paramsStr.indexOf('?') === 0) {
42
+ paramsStr = paramsStr.substring(1);
43
+ }
44
+ var entryParams = paramsStr.split('&');
45
+ var entryParamStr = _.find(entryParams, function (param) {
46
+ return param.indexOf(paramKey) === 0;
47
+ });
48
+ if (!entryParamStr) {
49
+ return null;
50
+ }
51
+ var param = entryParamStr.split('=');
52
+ if (!param[1]) {
53
+ return null;
54
+ }
55
+ return param[1];
56
+ }
57
+
58
+ /**
59
+ * get the entire url path
60
+ * @param path start with '/'
61
+ * @returns {string|*}
62
+ */
63
+ function getPath(path) {
64
+ if (_.startsWith(path, "http")) {
65
+ return path;
66
+ }
67
+
68
+ if (urlContext == null) {
69
+ urlContext = window.document.location.href;
70
+ let lastIdx = urlContext.indexOf('.htm');
71
+ if (lastIdx > -1) {
72
+ urlContext = urlContext.substring(0, urlContext.lastIndexOf('/', lastIdx));
73
+ } else {
74
+ lastIdx = urlContext.indexOf('/#');
75
+ if (lastIdx > -1) {
76
+ urlContext = urlContext.substring(0, lastIdx);
77
+ } else {
78
+ lastIdx = urlContext.indexOf('#');
79
+ if (lastIdx > -1) {
80
+ urlContext = urlContext.substring(0, lastIdx);
81
+ } else {
82
+ console.log(`Could not identify URL path ${urlContext}`);
83
+ }
84
+ }
85
+ }
86
+ //http://localhost:3000/index.html/#/index/highTriggerWiggleRoomValue -> http://localhost:3000
87
+ }
88
+
89
+ return urlContext + path;
90
+ }
91
+
92
+ /**
93
+ * Download excel from server
94
+ */
95
+ function downloadExcelData(url, data, headers, options = {}) {
96
+ return new Promise(async function (resolve, reject) {
97
+ headers = headers || {};
98
+ if (headers['Content-Type'] == null) {
99
+ headers['Content-Type'] = 'application/json';
100
+ }
101
+
102
+ await buildUserAccessToken(headers);
103
+
104
+ try {
105
+ let response = await axios({
106
+ method: 'post',
107
+ url: url,
108
+ data: data,
109
+ headers: headers,
110
+ responseType: 'blob'
111
+ });
112
+ if (response.data) {
113
+ if (response.data.errorCode && response.data.errorCode !== RESULT.SUCCESS) {
114
+ let errorResult = await handlerError(url, data, response);
115
+ resolve(errorResult);
116
+ return;
117
+ }
118
+ }
119
+
120
+ const link = document.createElement('a')
121
+ let blob = new Blob([response.data], {type: 'application/vnd.ms-excel'});
122
+ let contentDisposition = response.headers["content-disposition"];
123
+
124
+ if (contentDisposition == null) {
125
+ let errorResult = await handlerError(url, data, {
126
+ data: {
127
+ errorCode: EXCEPTION_CODE.SYS_UNKNOWN_ISSUE,
128
+ error: "System Error",
129
+ }
130
+ });
131
+ resolve(errorResult);
132
+ return;
133
+ }
134
+
135
+ let temp = contentDisposition.split(";")[1].split("ilename=")[1];
136
+ var fileName = decodeURIComponent(temp);
137
+ console.log(fileName)
138
+ link.style.display = 'none'
139
+ link.href = URL.createObjectURL(blob);
140
+ link.setAttribute('download', fileName);
141
+ document.body.appendChild(link);
142
+ link.click();
143
+ document.body.removeChild(link);
144
+
145
+ resolve(true);
146
+ } catch (e) {
147
+ let errorResult = await handlerError(url, {}, e);
148
+ resolve(errorResult);
149
+ }
150
+ });
151
+ }
152
+
153
+ /**
154
+ *
155
+ */
156
+ function downloadServerData(url) {
157
+ return new Promise(function (resolve, reject) {
158
+
159
+ const hyperlink = document.createElement('a');
160
+ hyperlink.style.display = 'none';//隐藏,没必要展示出来
161
+ hyperlink.href = url;
162
+ hyperlink.target = "_blank";
163
+ document.body.appendChild(hyperlink);
164
+ hyperlink.click();
165
+ URL.revokeObjectURL(hyperlink.href); // 释放URL 对象
166
+ document.body.removeChild(hyperlink);//下载
167
+
168
+ resolve(true);
169
+ });
170
+ }
171
+
172
+ /**
173
+ * upload file to server
174
+ * TODO Joey need check with FormData scenario
175
+ */
176
+ function uploadFile(url, file, headers, onUploadProgress, customizedOptions) {
177
+ headers = headers || {};
178
+
179
+ let formdata = new FormData();
180
+ if (_.isArray(file)) {
181
+ formdata.append("files", file);
182
+ } else {
183
+ formdata.append("file", file)
184
+ }
185
+
186
+ customizedOptions = customizedOptions || {};
187
+ return execute("POST", url, formdata, headers, onUploadProgress, customizedOptions)
188
+ }
189
+
190
+ /**
191
+ * getStaticTextFile
192
+ */
193
+ function getStaticTextFile(url) {
194
+ return new Promise(async function (resolve, reject) {
195
+ axios.get(url).then((res) => {
196
+ resolve(res);
197
+ }, (error) => {
198
+ resolve(null);
199
+ });
200
+ });
201
+ }
202
+
203
+ /**
204
+ * build form-data from param object
205
+ */
206
+ function getUrlParam(params) {
207
+ if (params) {
208
+ var param = '';
209
+ _.each(params, function (i, val) {
210
+ if (i != null) {
211
+ param += val + '=' + encodeURIComponent(i) + '&';
212
+ } else {
213
+ param += val + '=&';
214
+ }
215
+ });
216
+ param = param.substring(0, param.length - 1);
217
+ return param;
218
+ } else {
219
+ return '';
220
+ }
221
+ }
222
+
223
+ function getFormData(url, headers, customizedOptions) {
224
+ headers = headers || {};
225
+ if (headers['Content-Type'] == null) {
226
+ headers['Content-Type'] = 'application/x-www-form-urlencoded';
227
+ }
228
+
229
+ customizedOptions = customizedOptions || {};
230
+
231
+ return execute("GET", url, null, headers, null, customizedOptions)
232
+ }
233
+
234
+ function postFormData(url, dataObject, headers, customizedOptions) {
235
+ let formdata = null;
236
+ if (dataObject) {
237
+ formdata = getUrlParam(dataObject);
238
+ }
239
+
240
+ headers = headers || {};
241
+ if (headers['Content-Type'] == null) {
242
+ headers['Content-Type'] = 'application/x-www-form-urlencoded';
243
+ }
244
+
245
+ customizedOptions = customizedOptions || {};
246
+
247
+ return execute("POST", url, formdata, headers, null, customizedOptions)
248
+ }
249
+
250
+ function getJsonData(url, headers, customizedOptions) {
251
+ headers = headers || {};
252
+ if (headers['Content-Type'] == null) {
253
+ headers['Content-Type'] = 'application/json';
254
+ }
255
+
256
+ return execute("GET", url, null, headers, null, customizedOptions)
257
+ }
258
+
259
+ function postJsonData(url, dataObject, headers, customizedOptions) {
260
+ headers = headers || {};
261
+ if (headers['Content-Type'] == null) {
262
+ headers['Content-Type'] = 'application/json';
263
+ }
264
+
265
+ return execute("POST", url, dataObject, headers, null, customizedOptions)
266
+ }
267
+
268
+ /**
269
+ * General Axios Data request
270
+ *
271
+ * @param method
272
+ * @param url
273
+ * @param data
274
+ * @param headers
275
+ * @param customizedOptions: { }customizedErrorHandlerFlag: false }
276
+ */
277
+ function execute(method, url, data, headers, onUploadProgress, customizedOptions = {}) {
278
+ return new Promise(function (resolve, reject) {
279
+ //check and set User AccessToken in the request header
280
+ buildUserAccessToken(headers).then(
281
+ function () {
282
+ //AccessToken is valid
283
+ axios({
284
+ method: method,
285
+ url: url,
286
+ data: data,
287
+ headers: headers,
288
+ onUploadProgress: onUploadProgress,
289
+ })
290
+ .then((response) => {
291
+ if (response.data) {
292
+ if (response.data.errorCode && response.data.errorCode !== RESULT.SUCCESS) {
293
+ if (customizedOptions.customizedErrorHandlerFlag) {
294
+ resolve(response.data);
295
+ } else {
296
+ handlerError(url, data, response).then((result) => {
297
+ resolve(result);
298
+ });
299
+ }
300
+ } else {
301
+ resolve(response.data);
302
+ }
303
+ } else {
304
+ resolve(response.data);
305
+ }
306
+ }, (error) => {
307
+ if (customizedOptions.customizedErrorHandlerFlag) {
308
+ resolve(error);
309
+ } else {
310
+ handlerError(url, data, error).then((result) => {
311
+ resolve(result);
312
+ });
313
+ }
314
+ });
315
+ },
316
+ (error) => {
317
+ //AccessToken is invalid
318
+ handlerError(url, data, error).then((result) => {
319
+ resolve(result);
320
+ });
321
+ });
322
+
323
+ });
324
+ }
325
+
326
+ async function buildUserAccessToken(headers) {
327
+ let currUserInfo = await LoginUserUtils.getCurrUserInfo();
328
+ if (currUserInfo && currUserInfo.accessToken) {
329
+ if (headers['ENOS_ACCESS_TOKEN'] == null) {
330
+ headers['ENOS_ACCESS_TOKEN'] = currUserInfo.accessToken;
331
+ }
332
+ }
333
+ }
334
+
335
+
336
+ /**
337
+ * build error message base on errorCode
338
+ */
339
+ function getErrorMsgByCode(errorCode, errorMsg) {
340
+ return errorMsg;
341
+ }
342
+
343
+ /**
344
+ * request error handler
345
+ * if multiple ajax error happened. just process the first one.
346
+ */
347
+ var reqErrorInProcessing = false;
348
+
349
+ async function handlerError(url, reqData, responseOrAxiosError) {
350
+ if (reqErrorInProcessing === true) {
351
+ return;
352
+ }
353
+
354
+ reqErrorInProcessing = true;
355
+ await handlerErrorLogic(url, reqData, responseOrAxiosError);
356
+ reqErrorInProcessing = false;
357
+ }
358
+
359
+ async function showErrorMessage(errorCode, heading = "System Error", message) {
360
+ globalSpinHandlerInstance.complete();
361
+ await globalDialogUtilsInstance.showAppErrorDialog(heading, message);
362
+ }
363
+
364
+ async function handlerErrorLogic(url, reqData, responseOrAxiosError) {
365
+ let errorCode = _.get(responseOrAxiosError, 'data.errorCode');
366
+ let error = _.get(responseOrAxiosError, 'data.error');
367
+
368
+ if (!errorCode && _.get(responseOrAxiosError, 'code')) {
369
+ let axiosErrorStatus = _.get(responseOrAxiosError, 'response.status');
370
+ let axiosErrorStatusText = _.get(responseOrAxiosError, 'response.statusText');
371
+
372
+ if (_.includes([502, 504], axiosErrorStatus)) {
373
+ errorCode = EXCEPTION_CODE.NETWORK_ISSUE_CLIENT;
374
+ error = axiosErrorStatusText;
375
+ } else if (_.includes([400], axiosErrorStatus)) {
376
+ errorCode = EXCEPTION_CODE.SYS_UNKNOWN_ISSUE;
377
+ error = axiosErrorStatusText;
378
+ } else if (_.includes([404], axiosErrorStatus)) {
379
+ errorCode = EXCEPTION_CODE.SYS_UNKNOWN_ISSUE;
380
+ error = axiosErrorStatusText;
381
+ }
382
+ }
383
+
384
+ //session timeout
385
+ var sessionTimeoutErrorCodes = [
386
+ EXCEPTION_CODE.AUTHENTICATION_FAILED_COMMON
387
+ ]
388
+
389
+ if (_.includes(sessionTimeoutErrorCodes, errorCode)) {
390
+ await appSessionExit(errorCode, true);
391
+ return;
392
+ }
393
+
394
+ if (EXCEPTION_CODE.NETWORK_ISSUE_CLIENT === errorCode) {
395
+ await showErrorMessage(errorCode, "Network issue", error);
396
+ return;
397
+ }
398
+
399
+ await showErrorMessage(errorCode, null, getErrorMsgByCode(errorCode, error));
400
+ }
401
+
402
+ /**
403
+ * application exit handler
404
+ */
405
+ async function appSessionExit(resultCode, forceCloseFlag) {
406
+ if(loginServiceInstance && loginServiceInstance.logout){
407
+ await loginServiceInstance.logout();
408
+ }else {
409
+ await globalDialogUtilsInstance.showAppErrorDialog("Session Timeout", "Please login again");
410
+ }
411
+ }
412
+
413
+ const AxiosUtils = {
414
+ init: init,
415
+ loadParamFromLocationSearch: loadParamFromLocationSearch,
416
+ getPath: getPath,
417
+ getUrlParam: getUrlParam,
418
+ getFormData: getFormData,
419
+ postFormData: postFormData,
420
+ getJsonData: getJsonData,
421
+ postJsonData: postJsonData,
422
+ downloadExcelData: downloadExcelData,
423
+ downloadServerData: downloadServerData,
424
+ uploadFile: uploadFile,
425
+ getStaticTextFile: getStaticTextFile,
426
+ appSessionExit: appSessionExit,
427
+ handlerError: handlerError,
428
+ getErrorMsgByCode: getErrorMsgByCode,
429
+
430
+ RESULT: RESULT,
431
+ };
432
+
433
+ export default AxiosUtils;
@@ -0,0 +1,15 @@
1
+ export default {
2
+ //Application Configuration
3
+ appInfo: {
4
+ appName: 'XMS', //application name
5
+
6
+ needFrontEndExceptionStatisticsFlag: true, //need trace front-end logs
7
+ },
8
+ //Ajax Configuration
9
+ ajax:{
10
+ timeOut: 60000, //Timeout
11
+ },
12
+ sysCfg: {
13
+ ibmsEnabled: true,
14
+ }
15
+ };
@@ -0,0 +1,223 @@
1
+ import dayjs from "dayjs";
2
+
3
+ const FORMAT_DATE = "DD-MM-YYYY";
4
+ const FORMAT_DATETIME = "DD-MM-YYYY HH:mm:ss";
5
+ const FORMAT_YEARMONTH = "YYYY-MMMM";
6
+ const FORMAT_YEARWEEK = "YYYY-WW";
7
+ const FORMAT_DAYOFMONTH = "DD";
8
+ const FORMAT_YEAR = "YYYY";
9
+ const FORMAT_TIME = "HH:mm:ss";
10
+
11
+ function getCurrentMoment(){
12
+ return dayjs();
13
+ }
14
+
15
+ function getCurrentDateText(){
16
+ return convertMomentToDateText(getCurrentMoment());
17
+ }
18
+
19
+ function getCurrentDateTimeText(){
20
+ return convertMomentToDateTimeText(getCurrentMoment());
21
+ }
22
+
23
+ function getCurrentDate(){
24
+ return getCurrentMoment().toDate();
25
+ }
26
+
27
+ function convertMomentToTimestamp(moment) {
28
+ if (moment) {
29
+ return moment.toDate().getTime();
30
+ } else {
31
+ return null;
32
+ }
33
+ }
34
+
35
+ function convertMomentToDateText(moment) {
36
+ if (moment) {
37
+ return moment.format(FORMAT_DATE);
38
+ } else {
39
+ return '';
40
+ }
41
+ }
42
+
43
+ function convertTimestampToMoment(timestamp) {
44
+ if (timestamp && timestamp > 0) {
45
+ return dayjs(timestamp);
46
+ } else {
47
+ return null;
48
+ }
49
+ }
50
+
51
+ function convertMomentToDateTimeText(moment) {
52
+ if (moment) {
53
+ return moment.format(FORMAT_DATETIME);
54
+ } else {
55
+ return "";
56
+ }
57
+ }
58
+
59
+ function convertMomentToYearText(moment) {
60
+ if (moment) {
61
+ return moment.format(FORMAT_YEAR);
62
+ } else {
63
+ return "";
64
+ }
65
+ }
66
+
67
+ function convertMomentToYearMonthText(moment) {
68
+ if (moment) {
69
+ return moment.format(FORMAT_YEARMONTH);
70
+ } else {
71
+ return "";
72
+ }
73
+ }
74
+
75
+ function convertMomentToDayOfMonthText(moment) {
76
+ if (moment) {
77
+ return moment.format(FORMAT_DAYOFMONTH);
78
+ } else {
79
+ return "";
80
+ }
81
+ }
82
+
83
+
84
+
85
+ function convertMomentToTimeText(moment) {
86
+ if (moment) {
87
+ return moment.format(FORMAT_TIME);
88
+ } else {
89
+ return "";
90
+ }
91
+ }
92
+
93
+ function convertDateTimeTextToMoment(dateTimeText) {
94
+ if (dateTimeText) {
95
+ return dayjs(dateTimeText, FORMAT_DATETIME);
96
+ } else {
97
+ return null;
98
+ }
99
+ }
100
+
101
+ function convertYearMonthTextToMoment(yearMonthText) {
102
+ if (yearMonthText) {
103
+ return dayjs(yearMonthText, FORMAT_YEARMONTH);
104
+ } else {
105
+ return null;
106
+ }
107
+ }
108
+
109
+ function convertDateTextToMoment(dateText) {
110
+ if (dateText) {
111
+ return dayjs(dateText, FORMAT_DATE);
112
+ } else {
113
+ return null;
114
+ }
115
+ }
116
+
117
+ function convertTimeTextToMoment(dateTimeText) {
118
+ if (dateTimeText) {
119
+ return dayjs(dateTimeText, FORMAT_TIME);
120
+ } else {
121
+ return null;
122
+ }
123
+ }
124
+
125
+ function convertDateTextToDate(dateText) {
126
+ if (dateText) {
127
+ return dayjs(dateText, FORMAT_DATE).toDate();
128
+ } else {
129
+ return null;
130
+ }
131
+ }
132
+
133
+ function convertDateTimeTextToDate(dateTimeText) {
134
+ if (dateTimeText) {
135
+ let moment = dayjs(dateTimeText, FORMAT_DATETIME);
136
+ return dayjs(dateTimeText, FORMAT_DATETIME).toDate();
137
+ } else {
138
+ return null;
139
+ }
140
+ }
141
+
142
+ function convertTimestampToDateText(timestamp) {
143
+ let moments = convertTimestampToMoment(timestamp);
144
+ let text = convertMomentToDateText(moments);
145
+ return text;
146
+ }
147
+
148
+ function convertTimestampToDateTimeText(timestamp) {
149
+ let moments = convertTimestampToMoment(timestamp);
150
+ let text = convertMomentToDateTimeText(moments);
151
+ return text;
152
+ }
153
+
154
+ function convertDateToMoment(date) {
155
+ if(!date){
156
+ return null;
157
+ }
158
+ return dayjs(date);
159
+ }
160
+
161
+ function convertDateToDateText(date) {
162
+ let moments = convertDateToMoment(date);
163
+ let text = convertMomentToDateText(moments);
164
+ return text;
165
+ }
166
+
167
+ function convertDateToDateTimeText(date) {
168
+ let moments = convertDateToMoment(date);
169
+ let text = convertMomentToDateTimeText(moments);
170
+ return text;
171
+ }
172
+
173
+
174
+ function buildDateRange(from, to){
175
+ return from+" ~ "+to;
176
+ }
177
+
178
+ function getFormatTextOfMMM(mthNumber){
179
+ let moment = getCurrentMoment();
180
+ moment = moment.month(mthNumber-1);
181
+ return moment.format('MMM');
182
+ }
183
+
184
+ export default {
185
+ FORMAT_DATE: FORMAT_DATE,
186
+ FORMAT_DATETIME: FORMAT_DATETIME,
187
+ FORMAT_YEARMONTH: FORMAT_YEARMONTH,
188
+ FORMAT_YEARWEEK: FORMAT_YEARWEEK,
189
+ FORMAT_TIME: FORMAT_TIME,
190
+
191
+ getCurrentMoment: getCurrentMoment,
192
+ getCurrentDateTimeText: getCurrentDateTimeText,
193
+ getCurrentDateText: getCurrentDateText,
194
+ getCurrentDate: getCurrentDate,
195
+
196
+ convertMomentToTimestamp: convertMomentToTimestamp,
197
+ convertMomentToDateText: convertMomentToDateText,
198
+ convertMomentToDateTimeText: convertMomentToDateTimeText,
199
+ convertMomentToYearText: convertMomentToYearText,
200
+ convertMomentToYearMonthText: convertMomentToYearMonthText,
201
+ convertMomentToDayOfMonthText: convertMomentToDayOfMonthText,
202
+ convertMomentToTimeText: convertMomentToTimeText,
203
+
204
+ convertTimestampToMoment: convertTimestampToMoment,
205
+ convertTimestampToDateText: convertTimestampToDateText,
206
+ convertTimestampToDateTimeText: convertTimestampToDateTimeText,
207
+
208
+ convertDateToMoment: convertDateToMoment,
209
+ convertDateToDateText: convertDateToDateText,
210
+ convertDateToDateTimeText: convertDateToDateTimeText,
211
+
212
+ convertYearMonthTextToMoment: convertYearMonthTextToMoment,
213
+ convertDateTextToMoment: convertDateTextToMoment,
214
+ convertDateTimeTextToMoment: convertDateTimeTextToMoment,
215
+ convertTimeTextToMoment: convertTimeTextToMoment,
216
+
217
+ convertDateTextToDate: convertDateTextToDate,
218
+ convertDateTimeTextToDate: convertDateTimeTextToDate,
219
+
220
+ buildDateRange:buildDateRange,
221
+
222
+ getFormatTextOfMMM: getFormatTextOfMMM,
223
+ };
@@ -0,0 +1,48 @@
1
+ import _ from "lodash";
2
+
3
+ function resetBodyScroll(){
4
+ document.querySelector("body").style.position="initial";
5
+ }
6
+
7
+ function forbidBodyScroll(){
8
+ document.querySelector("body").style.position="fixed";
9
+ }
10
+
11
+ function syncDomAnimation() {
12
+ setTimeout(() => {
13
+ //sync all animation be the same
14
+ _.each(document.getAnimations(), (item) => {
15
+ item.startTime = 0;
16
+ });
17
+ }, 200);
18
+ }
19
+
20
+ /**
21
+ * find the closet parent element by className
22
+ *
23
+ * @param elem
24
+ * @param className
25
+ */
26
+ function closetByClassName(elem, classNameList) {
27
+ let classList = elem.classList;
28
+ if (classList) {
29
+ if (_.intersection(classList, classNameList).length > 0) {
30
+ return elem;
31
+ }
32
+ }
33
+
34
+ let parentElement = elem.parentElement;
35
+ if (parentElement) {
36
+ return closetByClassName(parentElement, classNameList);
37
+ } else {
38
+ return null;
39
+ }
40
+ }
41
+
42
+ export default {
43
+ resetBodyScroll: resetBodyScroll,
44
+ forbidBodyScroll: forbidBodyScroll,
45
+
46
+ syncDomAnimation: syncDomAnimation,
47
+ closetByClassName: closetByClassName,
48
+ };