@nyris/nyris-webapp 0.3.22 → 0.3.24

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.
Files changed (95) hide show
  1. package/README.md +1 -1
  2. package/build/asset-manifest.json +12 -18
  3. package/build/index.html +1 -1
  4. package/build/{precache-manifest.6f6124db008881782a26c64db1f10264.js → precache-manifest.982b135daeb2c083ccf4eeeddf132bf3.js} +11 -35
  5. package/build/service-worker.js +1 -1
  6. package/build/static/css/{main.c956b74c.chunk.css → main.1e43a778.chunk.css} +2 -2
  7. package/build/static/css/main.1e43a778.chunk.css.map +1 -0
  8. package/build/static/js/2.fe9108d5.chunk.js +3 -0
  9. package/build/static/js/{2.a2732c2b.chunk.js.LICENSE.txt → 2.fe9108d5.chunk.js.LICENSE.txt} +0 -15
  10. package/build/static/js/2.fe9108d5.chunk.js.map +1 -0
  11. package/build/static/js/main.83cb88a3.chunk.js +3 -0
  12. package/build/static/js/main.83cb88a3.chunk.js.map +1 -0
  13. package/package.json +3 -3
  14. package/src/App.tsx +6 -14
  15. package/src/Router.tsx +6 -41
  16. package/src/Store/Store.ts +14 -23
  17. package/src/components/DetailItem.tsx +33 -22
  18. package/src/components/FooterMobile.tsx +3 -51
  19. package/src/components/FooterResult.tsx +1 -1
  20. package/src/components/HeaderMobile.tsx +13 -20
  21. package/src/components/HeaderNewVersion.tsx +5 -83
  22. package/src/components/Layout.tsx +3 -19
  23. package/src/components/PanelResult/index.tsx +1 -1
  24. package/src/components/clear-refinements/clear-refinements.tsx +1 -1
  25. package/src/components/drawer/cameraCustom.tsx +6 -12
  26. package/src/components/input/inputSearch.tsx +3 -3
  27. package/src/components/pre-filter/desktop/index.tsx +2 -2
  28. package/src/components/results/ItemResult.tsx +8 -8
  29. package/src/defaults.ts +19 -35
  30. package/src/helpers/CommonHelper.ts +10 -6
  31. package/src/hooks/useVisualSearch.tsx +1 -1
  32. package/src/index.css +13 -0
  33. package/src/index.tsx +0 -20
  34. package/src/modules/LandingPage/AppMD.tsx +59 -386
  35. package/src/modules/LandingPage/AppMobile.tsx +1 -1
  36. package/src/modules/LandingPage/propsType.ts +35 -37
  37. package/src/page/result/index.tsx +2 -2
  38. package/src/services/Feedback.ts +48 -71
  39. package/src/services/filter.tsx +1 -1
  40. package/src/services/types.ts +30 -39
  41. package/src/types.ts +8 -63
  42. package/build/js/test.js +0 -84
  43. package/build/static/css/main.c956b74c.chunk.css.map +0 -1
  44. package/build/static/js/2.a2732c2b.chunk.js +0 -3
  45. package/build/static/js/2.a2732c2b.chunk.js.map +0 -1
  46. package/build/static/js/main.93b05e17.chunk.js +0 -3
  47. package/build/static/js/main.93b05e17.chunk.js.map +0 -1
  48. package/build/static/media/Rectangle.4dd8b747.png +0 -0
  49. package/build/static/media/icon_company.2b2a0a61.svg +0 -3
  50. package/build/static/media/icon_email.132d632b.svg +0 -3
  51. package/build/static/media/icon_phone.09335da9.svg +0 -3
  52. package/build/static/media/icon_textArea.f6d78b61.svg +0 -3
  53. package/build/static/media/icon_users.2013c76e.svg +0 -3
  54. package/public/js/test.js +0 -84
  55. package/src/App.css +0 -65
  56. package/src/components/AppContainer.tsx +0 -126
  57. package/src/components/CategoryFilter.tsx +0 -17
  58. package/src/components/Codes.tsx +0 -20
  59. package/src/components/CustomHits/index.tsx +0 -47
  60. package/src/components/Footer.tsx +0 -96
  61. package/src/components/FooterMD.tsx +0 -54
  62. package/src/components/HeaderMd.tsx +0 -38
  63. package/src/components/Navigation.tsx +0 -34
  64. package/src/components/PredictedCategories.tsx +0 -14
  65. package/src/components/Refine.tsx +0 -28
  66. package/src/components/RelevantSort.tsx +0 -12
  67. package/src/components/Result.tsx +0 -210
  68. package/src/components/Saved/AllItem.tsx +0 -32
  69. package/src/components/Saved/Category.tsx +0 -16
  70. package/src/components/auto-complete/basic.tsx +0 -153
  71. package/src/components/autocomplete/plugins/popular-searches/popular-searches.css +0 -3
  72. package/src/components/autocomplete/plugins/popular-searches/popular-searches.tsx +0 -75
  73. package/src/components/button/clear-fillter.tsx +0 -30
  74. package/src/components/camera/screenshot.tsx +0 -33
  75. package/src/components/count/count.tsx +0 -20
  76. package/src/components/hitItem/hits.tsx +0 -50
  77. package/src/components/hitItem/infinitiHits.tsx +0 -33
  78. package/src/components/icon/icon.tsx +0 -13
  79. package/src/components/icon_textArea.svg +0 -3
  80. package/src/components/refinement-list/index.tsx +0 -42
  81. package/src/components/results/pagination.tsx +0 -34
  82. package/src/components/search/ListSearch.tsx +0 -209
  83. package/src/modules/LandingPage/App.tsx +0 -318
  84. package/src/modules/LandingPage/index.tsx +0 -186
  85. package/src/modules/LandingPage/indexNewVersion.tsx +0 -72
  86. package/src/page/Auth/login.tsx +0 -7
  87. package/src/page/Exception/404.tsx +0 -11
  88. package/src/page/History/index.tsx +0 -76
  89. package/src/page/Profile/index.tsx +0 -140
  90. package/src/page/ResultMobile/index.tsx +0 -12
  91. package/src/page/Saved/MockData.ts +0 -223
  92. package/src/page/Saved/index.tsx +0 -166
  93. package/src/page/Support/MockData.ts +0 -45
  94. package/src/page/Support/index.tsx +0 -492
  95. /package/build/static/js/{main.93b05e17.chunk.js.LICENSE.txt → main.83cb88a3.chunk.js.LICENSE.txt} +0 -0
@@ -1,399 +1,72 @@
1
- import { useDropzone } from "react-dropzone";
2
- import {
3
- makeStyles,
4
- Button,
5
- Card,
6
- CardActions,
7
- CardContent,
8
- CardMedia,
9
- CircularProgress,
10
- Container,
11
- CssBaseline,
12
- Fab,
13
- Grid,
14
- Hidden,
15
- Typography,
16
- } from "@material-ui/core";
17
- import { PhotoCamera, ArrowBack, Image } from "@material-ui/icons";
18
- import Icon from "@material-ui/core/Icon";
19
- import { NodeGroup } from "react-move";
20
- import classNames from "classnames";
21
- import {Capture, Preview} from "@nyris/nyris-react-components";
22
- import _ from "lodash";
23
- import {AppProps} from "./propsType";
24
- import React from "react";
1
+ import { Box } from '@material-ui/core';
2
+ import React, { useState } from 'react';
3
+ import './common.scss';
4
+ import { cadExtensions } from '@nyris/nyris-api';
5
+ import algoliasearch from 'algoliasearch/lite';
6
+ import IconSupport from 'common/assets/icons/support3.svg';
7
+ import DragDropFile from 'components/DragDropFile';
8
+ import CustomSearchBox from 'components/input/inputSearch';
9
+ import { connectInfiniteHits } from 'react-instantsearch-dom';
10
+ import { useMediaQuery } from 'react-responsive';
11
+ import { Link } from 'react-router-dom';
12
+ import { useAppSelector } from 'Store/Store';
13
+ import { AlgoliaSettings } from '../../types';
25
14
 
26
- const useStyles = makeStyles((theme) => ({
27
- icon: {
28
- marginRight: theme.spacing(2),
29
- },
30
- heroContent: {
31
- backgroundColor: theme.palette.background.paper,
32
- padding: theme.spacing(8, 0, 6),
33
- transition: "all 300ms",
34
- overflow: "hidden",
35
- height: 500,
36
- },
37
- heroContentClosed: {
38
- height: 0,
39
- padding: 0,
40
- },
41
- heroButtons: {
42
- marginTop: theme.spacing(4),
43
- },
44
- cardGrid: {
45
- paddingTop: theme.spacing(8),
46
- paddingBottom: theme.spacing(8),
47
- minHeight: 600,
48
- overflow: "hidden",
49
- transition: "all 300ms",
50
- },
51
- cardGridCollapsed: {
52
- height: 0,
53
- opacity: 0,
54
- minHeight: 0,
55
- paddingTop: 0,
56
- paddingBottom: 0,
57
- },
58
- card: {
59
- height: "100%",
60
- display: "flex",
61
- flexDirection: "column",
62
- },
63
- cardMedia: {
64
- paddingTop: "56.25%", // 16:9
65
- backgroundSize: "contain",
66
- },
67
- cardContent: {
68
- flexGrow: 1,
69
- paddingBottom: 0,
70
- },
71
- footer: {
72
- backgroundColor: theme.palette.background.paper,
73
- padding: theme.spacing(6),
74
- },
75
- withElipsis: {
76
- textOverflow: "ellipsis",
77
- overflow: "hidden",
78
- whiteSpace: "nowrap",
79
- },
80
- loading: {
81
- margin: theme.spacing(2),
82
- },
83
- fabContainer: {
84
- position: "fixed",
85
- bottom: theme.spacing(2),
86
- },
87
- fab: {
88
- marginLeft: theme.spacing(2),
89
- },
90
- }));
15
+ interface Props {}
91
16
 
92
- const makeFileHandler = (action: any) => (e: any) => {
93
- let file = (e.dataTransfer && e.dataTransfer.files[0]) || e.target.files[0];
94
- if (e.target && e.target.value) {
95
- e.target.value = "";
96
- }
17
+ function AppMD(props: Props) {
18
+ const { settings } = useAppSelector(state => state);
19
+ const [isLoading, setLoading] = useState<boolean>(false);
20
+ const { apiKey, appId, indexName } = settings.algolia as AlgoliaSettings;
21
+ const searchClient = algoliasearch(appId, apiKey);
22
+ searchClient.initIndex(indexName);
23
+ const isMobile = useMediaQuery({ query: '(max-width: 776px)' });
97
24
 
98
- if (file) {
99
- action(file);
100
- }
101
- };
25
+ const acceptTypes = ['image/*']
26
+ .concat(settings.cadSearch ? cadExtensions : [])
27
+ .join(',');
102
28
 
103
- const LandingPageAppMD = (props: AppProps) => {
104
- const classes = useStyles();
105
- const {
106
- handlers,
107
- showPart,
108
- acceptTypes,
109
- settings,
110
- search,
111
- loading,
112
- previewImage
113
- } = props;
29
+ const InfiniteHits = ({ hits }: any) => {
30
+ return <div></div>;
31
+ };
114
32
 
115
- const mdSettings = settings.themePage.materialDesign;
116
-
117
- const {
118
- results,
119
- regions,
120
- previewSelection,
121
- } = search;
122
-
123
- const {
124
- onLinkClick,
125
- onFileDropped,
126
- onCaptureComplete,
127
- onCaptureCanceled,
128
- onSelectFile,
129
- onCameraClick,
130
- onShowStart,
131
- onSelectionChange,
132
- } = handlers;
133
-
134
- const { getRootProps, getInputProps, isDragActive } = useDropzone({
135
- onDrop: (fs: File[]) => {
136
- onFileDropped(fs[0]);
137
- },
138
- });
33
+ const onChangeLoading = (value: boolean) => {
34
+ setLoading(value);
35
+ };
139
36
 
37
+ const CustomInfiniteHits = connectInfiniteHits(InfiniteHits);
140
38
 
141
39
  return (
142
- <React.Fragment>
143
- {!_.isEmpty(mdSettings?.resultLinkIcon) && (
144
- <link
145
- rel="stylesheet"
146
- href="https://fonts.googleapis.com/icon?family=Material+Icons"
147
- />
148
- )}
149
- <CssBaseline />
150
- {showPart === "camera" && (
151
- <Capture
152
- onCaptureComplete={onCaptureComplete}
153
- onCaptureCanceled={onCaptureCanceled}
154
- useAppText="Use default camera app"
155
- />
40
+ <Box className={`box-content-main ${isLoading ? 'loading' : ''}`}>
41
+ {isMobile && (
42
+ <Box className="btn-open-support">
43
+ <Link to={'/support'} style={{ color: '#3E36DC' }}>
44
+ <img src={IconSupport} alt="" width={16} height={16} />
45
+ </Link>
46
+ </Box>
156
47
  )}
157
- <main>
158
- <div
159
- className={classNames(
160
- classes.heroContent,
161
- showPart === "results" ? classes.heroContentClosed : null
162
- )}
163
- >
164
- <Container maxWidth="md">
165
- <div>
166
- <Hidden mdUp>
167
- <div style={{ textAlign: "center" }}>
168
- <PhotoCamera style={{ fontSize: "20em", color: "#cccccc" }} />
169
- </div>
170
- <div style={{ textAlign: "center" }}>
171
- <Button
172
- variant={"contained"}
173
- color={"primary"}
174
- onClick={onCameraClick}
175
- >
176
- Take a picture
177
- </Button>
178
- </div>
179
- <div style={{ textAlign: "center" }}>
180
- <Typography>or</Typography>
181
- </div>
182
- <div style={{ textAlign: "center" }}>
183
- <input
184
- accept={acceptTypes}
185
- id="raised-button-file"
186
- type="file"
187
- onChange={makeFileHandler(onSelectFile)}
188
- style={{
189
- width: ".1px",
190
- height: ".1px",
191
- overflow: "hidden",
192
- opacity: 0,
193
- }}
194
- />
195
- <label htmlFor="raised-button-file">
196
- <Button
197
- variant={"contained"}
198
- color={"primary"}
199
- component="span"
200
- >
201
- Select a file
202
- </Button>
203
- </label>
204
- </div>
205
- </Hidden>
206
- <Hidden smDown>
207
- <div
208
- style={{
209
- borderStyle: "dashed",
210
- borderWidth: 5,
211
- borderColor: isDragActive ? "#ccc" : "#eee",
212
- borderRadius: 10,
213
- padding: 10,
214
- paddingBottom: 30,
215
- }}
216
- {...getRootProps({
217
- onClick: (e) => {
218
- e.stopPropagation();
219
- },
220
- })}
221
- >
222
- <div style={{ textAlign: "center" }}>
223
- <Image style={{ fontSize: "20em", color: "#cccccc" }} />
224
- </div>
225
- <div style={{ textAlign: "center" }}>
226
- <Typography variant="body2">DROP AN IMAGE</Typography>
227
- </div>
228
- <div style={{ textAlign: "center" }}>
229
- <Typography variant="subtitle2">or</Typography>
230
- </div>
231
- <div style={{ textAlign: "center" }}>
232
- <input
233
- accept={acceptTypes}
234
- id="raised-button-file"
235
- type="file"
236
- {...getInputProps()}
237
- onChange={makeFileHandler(onSelectFile)}
238
- style={{
239
- width: ".1px",
240
- height: ".1px",
241
- overflow: "hidden",
242
- opacity: 0,
243
- }}
244
- />
245
- <label htmlFor="raised-button-file">
246
- <Button
247
- variant={"contained"}
248
- color={"primary"}
249
- component="span"
250
- >
251
- Select an image
252
- </Button>
253
- </label>
254
- </div>
255
- </div>
256
- </Hidden>
48
+ <Box className="box-content_top">
49
+ <Box className="fw-700 text-f32 text-dark2">
50
+ <h1>{settings.headerText}</h1>
51
+ </Box>
52
+ <div className="box-input">
53
+ <div className="wrap-input-search">
54
+ <div style={{ display: 'none' }}>
55
+ <CustomInfiniteHits />
257
56
  </div>
258
- </Container>
57
+ <CustomSearchBox />
58
+ </div>
259
59
  </div>
260
- <Container
261
- className={classNames(
262
- classes.cardGrid,
263
- showPart !== "results" && classes.cardGridCollapsed
264
- )}
265
- maxWidth="md"
266
- >
267
- {previewImage && (
268
- <Card style={{ marginBottom: "4em" }} raised={true}>
269
- <Preview
270
- key={previewImage?.id}
271
- onSelectionChange={onSelectionChange}
272
- image={previewImage?.canvas}
273
- selection={previewSelection}
274
- regions={regions}
275
- maxWidth={400}
276
- maxHeight={500}
277
- dotColor="#FBD914"
278
- />
279
- </Card>
280
- )}
281
-
282
- {loading && (
283
- <div style={{ textAlign: "center" }}>
284
- <CircularProgress className={classes.loading} />
285
- </div>
286
- )}
287
-
288
- <Grid container spacing={4}>
289
- <NodeGroup
290
- data={results}
291
- keyAccessor={(r) => r.position + r.sku}
292
- start={(r, i) => ({ opacity: 0, translateX: -100 })}
293
- enter={(r, i) => ({
294
- opacity: [1],
295
- translateX: [0],
296
- timing: { delay: i * 100, duration: 300 },
297
- })}
298
- >
299
- {(rs) => (
300
- <>
301
- {rs.map(({ key, data: result, state }) => (
302
- <Grid item key={key} xs={12} sm={4} md={3}>
303
- <Card
304
- className={classes.card}
305
- style={{
306
- opacity: state.opacity,
307
- position: "relative",
308
- transform: `translateX(${state.translateX}%)`,
309
- }}
310
- >
311
- <CardMedia
312
- className={classes.cardMedia}
313
- image={
314
- (result.img && result.img.url) ||
315
- settings.noImageUrl
316
- }
317
- title={result.title}
318
- />
319
- <CardContent className={classes.cardContent}>
320
- <Typography
321
- gutterBottom
322
- variant="subtitle2"
323
- component="h5"
324
- className={classes.withElipsis}
325
- >
326
- {result[mdSettings?.resultFirstRowProperty!!]}
327
- </Typography>
328
- <Typography
329
- variant="body2"
330
- className={classes.withElipsis}
331
- >
332
- {result[mdSettings?.resultSecondRowProperty!!]}
333
- </Typography>
334
- </CardContent>
335
- {result.l && (
336
- <CardActions>
337
- <Button
338
- variant="outlined"
339
- style={{ marginLeft: "auto" }}
340
- size="small"
341
- color="primary"
342
- onClick={
343
- () => {
344
- onLinkClick(
345
- result.position,
346
- result.l
347
- );
348
- }
349
- }
350
- onAuxClick={() => {
351
- onLinkClick(
352
- result.position,
353
- result.l
354
- );
355
- }}
356
- >
357
- {mdSettings?.resultLinkIcon && (
358
- <React.Fragment>
359
- <Icon>{mdSettings.resultLinkIcon}</Icon>{" "}
360
- </React.Fragment>
361
- )}
362
- {mdSettings?.resultLinkText}
363
- </Button>
364
- </CardActions>
365
- )}
366
- </Card>
367
- </Grid>
368
- ))}
369
- </>
370
- )}
371
- </NodeGroup>
372
- </Grid>
373
-
374
- {results.length === 0 && showPart === "results" && !loading && (
375
- <Typography variant="h3" align="center">
376
- We did not find anything
377
- </Typography>
378
- )}
379
- </Container>
380
- {showPart !== "start" && (
381
- <Container maxWidth="lg">
382
- <div className={classes.fabContainer}>
383
- <Fab
384
- aria-label="back"
385
- className={classes.fab}
386
- color="primary"
387
- onClick={onShowStart}
388
- >
389
- <ArrowBack />
390
- </Fab>
391
- </div>
392
- </Container>
393
- )}
394
- </main>
395
- </React.Fragment>
60
+ </Box>
61
+ <Box className="box-content_bottom">
62
+ <DragDropFile
63
+ acceptTypes={acceptTypes}
64
+ isLoading={isLoading}
65
+ onChangeLoading={onChangeLoading}
66
+ />
67
+ </Box>
68
+ </Box>
396
69
  );
397
- };
70
+ }
398
71
 
399
- export default LandingPageAppMD;
72
+ export default AppMD;
@@ -87,7 +87,7 @@ function AppMobile(props: Props): JSX.Element {
87
87
  height: '100%',
88
88
  width: '100%',
89
89
  zIndex: 1,
90
- background: `${settings.themePage.searchSuite?.mobileFooterImageColor}`,
90
+ background: `${settings.theme?.mobileFooterImageColor}`,
91
91
  }}
92
92
  ></div>
93
93
  <Box style={{ position: 'inherit', zIndex: 100 }} className="title-top">
@@ -1,43 +1,41 @@
1
- import {CategoryPrediction, Code, RectCoords, Region} from "@nyris/nyris-api";
2
- import {AppSettings, CanvasWithId, MDSettings} from "../../types";
3
- import {NyrisAppPart, NyrisFeedbackState} from "../../Store/Nyris";
1
+ import { CategoryPrediction, Code, RectCoords, Region } from '@nyris/nyris-api';
2
+ import { AppSettings, CanvasWithId } from '../../types';
3
+ import { NyrisAppPart, NyrisFeedbackState } from '../../Store/Nyris';
4
4
 
5
5
  export interface AppHandlers {
6
- onExampleImageClick: (url: string) => void;
7
- onImageClick: (position: number, url: string) => void;
8
- onLinkClick: (position: number, url: string) => void;
9
- onFileDropped: (file: File) => void;
10
- onCaptureComplete: (image: HTMLCanvasElement) => void;
11
- onCaptureCanceled: () => void;
12
- onSelectFile: (f: File) => void;
13
- onCameraClick: () => void;
14
- onShowStart: () => void;
15
- onSelectionChange: (r: RectCoords) => void;
16
- onPositiveFeedback: () => void;
17
- onNegativeFeedback: () => void;
18
- onCloseFeedback: () => void;
6
+ onExampleImageClick: (url: string) => void;
7
+ onImageClick: (position: number, url: string) => void;
8
+ onLinkClick: (position: number, url: string) => void;
9
+ onFileDropped: (file: File) => void;
10
+ onCaptureComplete: (image: HTMLCanvasElement) => void;
11
+ onCaptureCanceled: () => void;
12
+ onSelectFile: (f: File) => void;
13
+ onCameraClick: () => void;
14
+ onShowStart: () => void;
15
+ onSelectionChange: (r: RectCoords) => void;
16
+ onPositiveFeedback: () => void;
17
+ onNegativeFeedback: () => void;
18
+ onCloseFeedback: () => void;
19
19
  }
20
20
 
21
-
22
21
  export interface AppProps {
23
- search: {
24
- results: any[];
25
- requestId?: string;
26
- duration?: number;
27
- categoryPredictions: CategoryPrediction[];
28
- codes: Code[];
29
- filterOptions: string[];
30
- errorMessage?: string;
31
- regions: Region[];
32
- previewSelection: RectCoords;
33
- toastErrorMessage?: string;
34
- };
35
- acceptTypes: string,
36
- previewImage?: CanvasWithId;
37
- settings: AppSettings;
38
- loading: boolean;
39
- showPart: NyrisAppPart;
40
- feedbackState: NyrisFeedbackState;
41
- handlers: AppHandlers;
42
- mdSettings: MDSettings;
22
+ search: {
23
+ results: any[];
24
+ requestId?: string;
25
+ duration?: number;
26
+ categoryPredictions: CategoryPrediction[];
27
+ codes: Code[];
28
+ filterOptions: string[];
29
+ errorMessage?: string;
30
+ regions: Region[];
31
+ previewSelection: RectCoords;
32
+ toastErrorMessage?: string;
33
+ };
34
+ acceptTypes: string;
35
+ previewImage?: CanvasWithId;
36
+ settings: AppSettings;
37
+ loading: boolean;
38
+ showPart: NyrisAppPart;
39
+ feedbackState: NyrisFeedbackState;
40
+ handlers: AppHandlers;
43
41
  }
@@ -74,7 +74,7 @@ function ResultComponent(props: Props) {
74
74
  async (canvas: any, r?: RectCoords) => {
75
75
  const preFilter = [
76
76
  {
77
- key: settings.filterType,
77
+ key: settings.visualSearchFilterKey,
78
78
  values: [`${keyFilter}`],
79
79
  },
80
80
  ];
@@ -148,7 +148,7 @@ function ResultComponent(props: Props) {
148
148
  }
149
149
  const preFilter = [
150
150
  {
151
- key: settings.filterType,
151
+ key: settings.visualSearchFilterKey,
152
152
  values: [`${keyFilter}`],
153
153
  },
154
154
  ];