@itrocks/table 0.0.21 → 0.1.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.
package/README.md CHANGED
@@ -8,6 +8,10 @@
8
8
 
9
9
  A lightweight, modular HTML table offering near-spreadsheet features such as edit, freeze, lock, scroll, and more.
10
10
 
11
+ *This documentation was written by an artificial intelligence and may contain errors or approximations.
12
+ It has not yet been fully reviewed by a human. If anything seems unclear or incomplete,
13
+ please feel free to contact the author of this package.*
14
+
11
15
  ## Installation
12
16
 
13
17
  ```bash
@@ -16,4 +20,207 @@ npm i @itrocks/table
16
20
 
17
21
  ## Usage
18
22
 
19
- Check out the [GitHub demo folder](https://github.com/itrocks-ts/table/tree/master/demo) for a complete demonstration.
23
+ `@itrocks/table` is a lightweight, modular JavaScript table component that
24
+ turns a plain HTML `<table>` into a near‑spreadsheet widget: editable
25
+ cells, frozen columns, locked headers, horizontal and vertical scrolling,
26
+ and more.
27
+
28
+ At runtime you create `Table` instances from existing DOM elements.
29
+
30
+ ### Minimal example
31
+
32
+ ```ts
33
+ import { tableBySelector } from '@itrocks/table'
34
+
35
+ // Turn all matching <table> elements into interactive tables
36
+ const tables = tableBySelector('.js-data-table')
37
+
38
+ // Optionally keep a reference to one table
39
+ const table = tables[0]
40
+ ```
41
+
42
+ Make sure the DOM is ready before you call `tableBySelector` (for example
43
+ after `DOMContentLoaded` or in your framework's mounted hook).
44
+
45
+ You can also construct a table directly from an element:
46
+
47
+ ```ts
48
+ import { tableByElement } from '@itrocks/table'
49
+
50
+ const element = document.querySelector('table#users') as HTMLTableElement
51
+ const table = tableByElement(element)
52
+ ```
53
+
54
+ For more advanced usage (plugins, styling, demos), check out the
55
+ [GitHub demo folder](https://github.com/itrocks-ts/table/tree/master/demo).
56
+
57
+ ## API
58
+
59
+ The public API is intentionally small and focuses on a single `Table`
60
+ class plus a few helpers.
61
+
62
+ ### `applyStyleSheets()`
63
+
64
+ ```ts
65
+ import { applyStyleSheets } from '@itrocks/table'
66
+
67
+ applyStyleSheets()
68
+ ```
69
+
70
+ Forces the table module to (re)apply its internal style sheets. In most
71
+ applications you do not need to call this manually: it is handled when
72
+ creating `Table` instances. It can be useful in advanced integration
73
+ scenarios (dynamic theme switch, hot‑reloaded styles, etc.).
74
+
75
+ ### `garbageCollector()`
76
+
77
+ ```ts
78
+ import { garbageCollector } from '@itrocks/table'
79
+
80
+ garbageCollector()
81
+ ```
82
+
83
+ Runs an internal cleanup pass to detach listeners and release resources
84
+ from tables that are no longer present in the DOM. You might call this
85
+ periodically in long‑running pages where tables are created and removed
86
+ dynamically.
87
+
88
+ ### `getTables()`
89
+
90
+ ```ts
91
+ import { getTables } from '@itrocks/table'
92
+
93
+ const tables = getTables()
94
+ ```
95
+
96
+ Returns the list of all `Table` instances currently managed by the
97
+ module. This is mainly useful for debugging or global operations (for
98
+ example applying a plugin to every existing table).
99
+
100
+ ### `type Options = PluginOptions<Table>`
101
+
102
+ Configuration object passed when creating a `Table`. It is based on the
103
+ generic plugin system from
104
+ [`@itrocks/plugin`](https://github.com/itrocks-ts/plugin).
105
+
106
+ Typical usage:
107
+
108
+ ```ts
109
+ import type { Options } from '@itrocks/table'
110
+
111
+ const options: Partial<Options> = {
112
+ // enable / configure plugins here
113
+ }
114
+ ```
115
+
116
+ The exact shape of the options depends on the plugins you enable (edit,
117
+ freeze, reorder, etc.). Refer to each plugin's documentation and the
118
+ demo code for details.
119
+
120
+ ### `class Table extends HasPlugins<Table>`
121
+
122
+ Represents an interactive table instance bound to a single
123
+ `HTMLTableElement`.
124
+
125
+ #### Constructor
126
+
127
+ ```ts
128
+ import { Table } from '@itrocks/table'
129
+
130
+ const table = new Table(element, options)
131
+ ```
132
+
133
+ Parameters:
134
+
135
+ - `element: HTMLTableElement` – the DOM table to enhance.
136
+ - `options?: Partial<Options>` – optional configuration and plugins.
137
+
138
+ #### Properties
139
+
140
+ - `element: HTMLTableElement` – underlying table element.
141
+ - `id: number` – numeric identifier assigned to the table instance.
142
+ - `selector: string` – selector used when the table was created (when
143
+ relevant).
144
+ - `onReset: (() => void)[]` – list of callbacks invoked when the table
145
+ is reset.
146
+ - `styleSheet: string[]` – list of CSS rules associated with this table
147
+ instance.
148
+
149
+ #### Methods
150
+
151
+ ##### `addEventListener(element, type, listener, options?)`
152
+
153
+ Delegates the registration of an event listener through the table
154
+ infrastructure, so it can be properly cleaned up on reset or removal.
155
+
156
+ ```ts
157
+ table.addEventListener(document, 'keydown', event => {
158
+ // react to keyboard shortcuts related to this table
159
+ })
160
+ ```
161
+
162
+ ##### `cellColumnNumber(cell: HTMLTableCellElement): number`
163
+
164
+ Returns the zero‑based column index of the given table cell within its
165
+ row. This is handy when writing plugins that need to know which column a
166
+ cell belongs to.
167
+
168
+ ##### `reset(): Table`
169
+
170
+ Resets the table to its initial state:
171
+
172
+ - clears plugin state,
173
+ - reapplies default configuration,
174
+ - triggers all callbacks registered in `onReset`.
175
+
176
+ ```ts
177
+ table.reset()
178
+ ```
179
+
180
+ ### Helper constructors
181
+
182
+ In addition to the `Table` class, the module exposes convenience
183
+ functions to create tables from different inputs.
184
+
185
+ #### `tableByElement(element, options?)`
186
+
187
+ ```ts
188
+ import { tableByElement } from '@itrocks/table'
189
+
190
+ const table = tableByElement(element, { /* options */ })
191
+ ```
192
+
193
+ Creates (or returns an existing) `Table` instance for the given
194
+ `HTMLTableElement`.
195
+
196
+ #### `tableByElements(elements, options?)`
197
+
198
+ ```ts
199
+ import { tableByElements } from '@itrocks/table'
200
+
201
+ const nodeList = document.querySelectorAll('table.data')
202
+ const tables = tableByElements(nodeList)
203
+ ```
204
+
205
+ Accepts an array or a `NodeListOf<HTMLTableElement>` and returns an
206
+ array of `Table` instances.
207
+
208
+ #### `tableBySelector(selector, options?)`
209
+
210
+ ```ts
211
+ import { tableBySelector } from '@itrocks/table'
212
+
213
+ const tables = tableBySelector('.js-data-table')
214
+ ```
215
+
216
+ Finds all tables matching the CSS selector and returns the corresponding
217
+ `Table` instances.
218
+
219
+ ## Typical use cases
220
+
221
+ - Enhance existing HTML tables with spreadsheet‑like behaviours (edit,
222
+ freeze, lock, scroll) without rewriting the markup.
223
+ - Build rich back‑office or data‑entry screens where users can edit
224
+ multiple rows directly in a table.
225
+ - Implement custom plugins on top of `HasPlugins<Table>` to add domain‑
226
+ specific features (validation, inline actions, totals rows, etc.).
@@ -1,8 +1,8 @@
1
- import { Plugin } from '../../plugin/plugin.js';
1
+ import { Plugin } from '../plugin/plugin.js';
2
2
  import { HTMLTableFreezeElement } from './freeze.js';
3
3
  import { Table } from './table.js';
4
4
  export declare class TableColumnReorder extends Plugin<Table> {
5
5
  reorderCells: NodeListOf<HTMLTableFreezeElement>;
6
- constructor(table: Table);
6
+ init(): void;
7
7
  protected getReorderCells(): NodeListOf<HTMLTableFreezeElement>;
8
8
  }
package/column-reorder.js CHANGED
@@ -1,13 +1,13 @@
1
1
  import { Plugin } from '../plugin/plugin.js';
2
2
  export class TableColumnReorder extends Plugin {
3
3
  reorderCells;
4
- constructor(table) {
5
- super(table);
4
+ init() {
6
5
  this.reorderCells = this.getReorderCells();
7
6
  let downed;
8
7
  let dragging;
9
8
  let mouse = new DOMRect;
10
9
  let mouseFrom = new DOMRect;
10
+ const table = this.of;
11
11
  for (const cell of Array.from(this.reorderCells)) {
12
12
  table.addEventListener(cell, 'mousedown', event => {
13
13
  console.log('mousedown', event.target);
package/edit/lock.d.ts CHANGED
@@ -1,15 +1,15 @@
1
- import { Plugin } from '../../../plugin/plugin.js';
1
+ import { Plugin } from '../../plugin/plugin.js';
2
+ import { PluginOptions } from '../../plugin/plugin.js';
2
3
  import { Table } from '../table.js';
3
- declare class Options {
4
+ declare class Options extends PluginOptions {
4
5
  nonEditableConditions: {
5
6
  [index: string]: string;
6
7
  };
7
8
  }
8
- export declare class TableEditLock extends Plugin<Table> {
9
- options: Options;
10
- constructor(table: Table, options?: Partial<Options>);
9
+ export declare class TableEditLock extends Plugin<Table, Options> {
11
10
  colCell(cell: HTMLTableCellElement): HTMLTableCellElement | HTMLTableColElement;
12
11
  closestEditableCell(editable?: HTMLTableCellElement): HTMLTableCellElement | undefined;
13
- static defaultOptions(): Options;
12
+ defaultOptions(): Options;
13
+ init(): void;
14
14
  }
15
15
  export {};
package/edit/lock.js CHANGED
@@ -1,19 +1,12 @@
1
1
  import { Plugin } from '../../plugin/plugin.js';
2
- class Options {
2
+ import { PluginOptions } from '../../plugin/plugin.js';
3
+ class Options extends PluginOptions {
3
4
  nonEditableConditions = {
4
5
  'closest': 'tfoot, thead, [data-lock]',
5
6
  'col': '[data-lock]'
6
7
  };
7
8
  }
8
9
  export class TableEditLock extends Plugin {
9
- options = new Options;
10
- constructor(table, options = {}) {
11
- super(table);
12
- Object.assign(this.options, options);
13
- const tableEdit = table.plugins.TableEdit;
14
- const superClosestEditableCell = tableEdit.closestEditableCell;
15
- tableEdit.closestEditableCell = target => this.closestEditableCell(superClosestEditableCell.call(tableEdit, target));
16
- }
17
10
  colCell(cell) {
18
11
  const table = cell.closest('table');
19
12
  const position = this.of.cellColumnNumber(cell);
@@ -61,7 +54,12 @@ export class TableEditLock extends Plugin {
61
54
  }
62
55
  return editable;
63
56
  }
64
- static defaultOptions() {
65
- return new Options;
57
+ defaultOptions() {
58
+ return new Options();
59
+ }
60
+ init() {
61
+ const tableEdit = this.of.plugins.TableEdit;
62
+ const superClosestEditableCell = tableEdit.closestEditableCell;
63
+ tableEdit.closestEditableCell = target => this.closestEditableCell(superClosestEditableCell.call(tableEdit, target));
66
64
  }
67
65
  }
package/edit/move.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { HTMLEditableElement } from '../../../contenteditable/contenteditable.js';
2
- import { Plugin } from '../../../plugin/plugin.js';
1
+ import { HTMLEditableElement } from '../../contenteditable/contenteditable.js';
2
+ import { Plugin } from '../../plugin/plugin.js';
3
3
  import { TableEdit } from '../edit.js';
4
4
  import { Table } from '../table.js';
5
5
  export declare class TableEditMove extends Plugin<Table> {
6
6
  tableEdit: TableEdit;
7
- constructor(table: Table);
7
+ init(): void;
8
8
  selectNextColumn(): void;
9
9
  selectNextRow(): void;
10
10
  selectPreviousColumn(): void;
package/edit/move.js CHANGED
@@ -1,9 +1,8 @@
1
1
  import { Plugin } from '../../plugin/plugin.js';
2
2
  export class TableEditMove extends Plugin {
3
3
  tableEdit;
4
- constructor(table) {
5
- super(table);
6
- this.tableEdit = table.plugins.TableEdit;
4
+ init() {
5
+ this.tableEdit = this.of.plugins.TableEdit;
7
6
  const superCreateEditable = this.tableEdit.createEditable;
8
7
  this.tableEdit.createEditable = (selected, selectedStyle) => this.setEditableKeydownListener(superCreateEditable.call(this.tableEdit, selected, selectedStyle));
9
8
  }
@@ -1,12 +1,12 @@
1
- import { HTMLEditableElement } from '../../../contenteditable/contenteditable.js';
2
- import { Plugin } from '../../../plugin/plugin.js';
1
+ import { HTMLEditableElement } from '../../contenteditable/contenteditable.js';
2
+ import { Plugin } from '../../plugin/plugin.js';
3
3
  import { TableEdit } from '../edit.js';
4
4
  import { TableFreeze } from '../freeze.js';
5
5
  import { Table } from '../table.js';
6
6
  export declare class TableEditFreezeHide extends Plugin<Table> {
7
- readonly tableFreeze: TableFreeze;
8
- readonly tableEdit: TableEdit;
9
- constructor(table: Table);
7
+ tableFreeze: TableFreeze;
8
+ tableEdit: TableEdit;
9
+ init(): void;
10
10
  addEditableEventListeners(editable: HTMLEditableElement): HTMLEditableElement;
11
11
  autoHide(): void;
12
12
  goAhead(): void;
@@ -7,17 +7,16 @@ const zIndex = {
7
7
  export class TableEditFreezeHide extends Plugin {
8
8
  tableFreeze;
9
9
  tableEdit;
10
- constructor(table) {
11
- super(table);
12
- const tableEdit = this.tableEdit = table.plugins.TableEdit;
13
- const tableFreeze = this.tableFreeze = table.plugins.TableFreeze;
14
- const scrollable = this.tableFreeze.closestScrollable(table.element);
10
+ init() {
11
+ const tableEdit = this.tableEdit = this.of.plugins.TableEdit;
12
+ const tableFreeze = this.tableFreeze = this.of.plugins.TableFreeze;
13
+ const scrollable = this.tableFreeze.closestScrollable(this.of.element);
15
14
  if (!scrollable)
16
15
  return;
17
16
  tableFreeze.full = { column: '2', corner: '6', row: '4' };
18
17
  tableEdit.zIndex = '7';
19
- table.addEventListener(scrollable, 'scroll', () => this.autoHide());
20
- table.addEventListener(window, 'resize', () => this.autoHide());
18
+ this.of.addEventListener(scrollable, 'scroll', () => this.autoHide());
19
+ this.of.addEventListener(window, 'resize', () => this.autoHide());
21
20
  const superCreateEditable = tableEdit.createEditable;
22
21
  tableEdit.createEditable = (selected, selectedStyle) => this.addEditableEventListeners(superCreateEditable.call(tableEdit, selected, selectedStyle));
23
22
  }
@@ -1,8 +1,8 @@
1
- import { Plugin } from '../../../plugin/plugin.js';
1
+ import { Plugin } from '../../plugin/plugin.js';
2
2
  import { TableFreeze } from '../freeze.js';
3
3
  import { Table } from '../table.js';
4
4
  export declare class TableEditFreezeScroll extends Plugin<Table> {
5
5
  tableFreeze: TableFreeze;
6
- constructor(table: Table);
6
+ init(): void;
7
7
  scrollToCell(cell: HTMLTableCellElement): HTMLTableCellElement;
8
8
  }
@@ -1,10 +1,9 @@
1
1
  import { Plugin } from '../../plugin/plugin.js';
2
2
  export class TableEditFreezeScroll extends Plugin {
3
3
  tableFreeze;
4
- constructor(table) {
5
- super(table);
6
- this.tableFreeze = table.plugins.TableFreeze;
7
- const tableEdit = table.plugins.TableEdit;
4
+ init() {
5
+ this.tableFreeze = this.of.plugins.TableFreeze;
6
+ const tableEdit = this.of.plugins.TableEdit;
8
7
  const superSetSelectedCell = tableEdit.setSelectedCell;
9
8
  tableEdit.setSelectedCell = cell => superSetSelectedCell.call(tableEdit, this.scrollToCell(cell));
10
9
  }
package/edit.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { HTMLEditableElement } from '../../contenteditable/contenteditable.js';
2
- import { Plugin } from '../../plugin/plugin.js';
1
+ import { HTMLEditableElement } from '../contenteditable/contenteditable.js';
2
+ import { Plugin } from '../plugin/plugin.js';
3
3
  import { Table } from './table.js';
4
4
  export declare class RangeCopy {
5
5
  commonAncestorContainer: Node;
package/feed.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { Plugin } from '../../plugin/plugin.js';
1
+ import { Plugin } from '../plugin/plugin.js';
2
2
  import { Table } from './table.js';
3
3
  export declare class TableFeed extends Plugin<Table> {
4
4
  observer: IntersectionObserver | undefined;
5
- constructor(table: Table);
6
5
  feed(): Promise<void>;
6
+ init(): void;
7
7
  observe(): void;
8
8
  }
package/feed.js CHANGED
@@ -1,10 +1,6 @@
1
1
  import { Plugin } from '../plugin/plugin.js';
2
2
  export class TableFeed extends Plugin {
3
3
  observer = undefined;
4
- constructor(table) {
5
- super(table);
6
- this.observe();
7
- }
8
4
  async feed() {
9
5
  const table = this.of.element;
10
6
  const tbody = table.querySelector(':scope > tbody');
@@ -25,6 +21,9 @@ export class TableFeed extends Plugin {
25
21
  }
26
22
  this.observe();
27
23
  }
24
+ init() {
25
+ this.observe();
26
+ }
28
27
  observe() {
29
28
  const table = this.of.element;
30
29
  const lastCell = table.querySelector(':scope > tbody > tr:last-child')
@@ -1,10 +1,8 @@
1
1
  import { TableFreeze } from '../freeze.js';
2
- import { Table } from '../table';
3
2
  /**
4
3
  * This plugin has no use and no effect if your table has border-collapse: collapse
5
4
  */
6
5
  export declare class TableFreezeInheritBackground extends TableFreeze {
7
6
  tableStyle: CSSStyleDeclaration;
8
- constructor(table: Table);
9
7
  init(): void;
10
8
  }
@@ -4,11 +4,8 @@ import { TableFreeze } from '../freeze.js';
4
4
  */
5
5
  export class TableFreezeInheritBackground extends TableFreeze {
6
6
  tableStyle;
7
- constructor(table) {
8
- super(table);
9
- this.tableStyle = getComputedStyle(table.element);
10
- }
11
7
  init() {
8
+ this.tableStyle = getComputedStyle(this.of.element);
12
9
  if (this.tableStyle.borderCollapse !== 'separate')
13
10
  return;
14
11
  const table = this.of;
@@ -1,14 +1,10 @@
1
- import { Plugin } from '../../../plugin/plugin.js';
2
- import { TableFreeze } from '../freeze.js';
1
+ import { Plugin } from '../../plugin/plugin.js';
3
2
  import { HTMLTableFreezeElement } from '../freeze.js';
4
3
  import { Table } from '../table.js';
5
4
  /**
6
5
  * This plugin has no use and no effect if your table has border-collapse: separate (default)
7
6
  */
8
7
  export declare class TableFreezeInheritBorder extends Plugin<Table> {
9
- tableStyle: CSSStyleDeclaration;
10
- tableFreeze: TableFreeze;
11
- constructor(table: Table);
12
8
  init(): void;
13
9
  position(position: number, counter: number, colCell: HTMLTableFreezeElement, side: 'bottom' | 'left' | 'right' | 'top'): number;
14
10
  }
@@ -3,21 +3,15 @@ import { Plugin } from '../../plugin/plugin.js';
3
3
  * This plugin has no use and no effect if your table has border-collapse: separate (default)
4
4
  */
5
5
  export class TableFreezeInheritBorder extends Plugin {
6
- tableStyle;
7
- tableFreeze;
8
- constructor(table) {
9
- super(table);
10
- this.tableFreeze = table.plugins.TableFreeze;
11
- this.tableStyle = getComputedStyle(table.element);
12
- if (this.tableStyle.borderCollapse !== 'collapse')
13
- return;
14
- const superPosition = this.tableFreeze.position;
15
- this.tableFreeze.position = (position, counter, colCell, side) => superPosition.call(this.of.plugins.TableFreeze, this.position(position, counter, colCell, side), counter, colCell, side);
16
- }
17
6
  init() {
18
- if (this.tableStyle.borderCollapse !== 'collapse')
7
+ const tableFreeze = this.of.plugins.TableFreeze;
8
+ const tableStyle = getComputedStyle(this.of.element);
9
+ if (tableStyle.borderCollapse !== 'collapse')
10
+ return;
11
+ const superPosition = tableFreeze.position;
12
+ tableFreeze.position = (position, counter, colCell, side) => superPosition.call(this.of.plugins.TableFreeze, this.position(position, counter, colCell, side), counter, colCell, side);
13
+ if (tableStyle.borderCollapse !== 'collapse')
19
14
  return;
20
- const tableFreeze = this.tableFreeze;
21
15
  const table = this.of;
22
16
  // table
23
17
  table.styleSheet.push(`
package/freeze.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Plugin } from '../../plugin/plugin.js';
1
+ import { Plugin } from '../plugin/plugin.js';
2
2
  import { Table } from './table.js';
3
3
  export type HTMLTableFreezeElement = HTMLTableCellElement | HTMLTableColElement;
4
4
  interface FullIndex {
@@ -12,7 +12,6 @@ export declare class TableFreeze extends Plugin<Table> {
12
12
  leftColumnCount: number;
13
13
  rightColumnCount: number;
14
14
  zIndex: string;
15
- constructor(table: Table);
16
15
  init(): void;
17
16
  closestScrollable(element: Element): HTMLElement | (Window & typeof globalThis) | undefined;
18
17
  protected countLeftColumns(): number;
package/freeze.js CHANGED
@@ -5,13 +5,10 @@ export class TableFreeze extends Plugin {
5
5
  leftColumnCount;
6
6
  rightColumnCount;
7
7
  zIndex = '1';
8
- constructor(table) {
9
- super(table);
8
+ init() {
10
9
  this.columns = this.getColumns();
11
10
  this.leftColumnCount = this.countLeftColumns();
12
11
  this.rightColumnCount = this.countRightColumns();
13
- }
14
- init() {
15
12
  this.freezeFootRows();
16
13
  this.freezeHeadRows();
17
14
  this.freezeLeftColumns();
package/package.json CHANGED
@@ -24,18 +24,25 @@
24
24
  ],
25
25
  "homepage": "https://it.rocks",
26
26
  "keywords": [
27
+ "column",
28
+ "columns",
27
29
  "drag",
28
30
  "drop",
29
31
  "edit",
30
32
  "editable",
33
+ "feed",
31
34
  "freeze",
32
35
  "front-end",
33
36
  "frozen",
34
37
  "it.rocks",
35
38
  "lock",
36
39
  "reorder",
40
+ "row",
41
+ "rows",
37
42
  "scroll",
38
- "table"
43
+ "table",
44
+ "UI",
45
+ "UX"
39
46
  ],
40
47
  "license": "LGPL-3.0-or-later",
41
48
  "module": "./table.js",
@@ -49,5 +56,5 @@
49
56
  },
50
57
  "type": "module",
51
58
  "types": "./table.d.ts",
52
- "version": "0.0.21"
59
+ "version": "0.1.0"
53
60
  }
package/table.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { HasPlugins, Options as PluginOptions } from '../../plugin/plugin.js';
1
+ import { HasPlugins, Options as PluginOptions } from '../plugin/plugin.js';
2
2
  export declare function applyStyleSheets(): void;
3
3
  export declare function garbageCollector(): void;
4
4
  export declare function getTables(): Table[];