jquery.dgtable 0.5.59 → 0.6.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,7 @@ This is a table View for jQuery, which is meant to be high-performance, and allo
8
8
  * Resizing columns
9
9
  * Full cell preview when hovering
10
10
  * Native RTL support
11
+ * Variable row height
11
12
 
12
13
  Other features implemented are:
13
14
  * Mix absolute column widths with relative column widths
@@ -18,7 +19,6 @@ Other features implemented are:
18
19
 
19
20
  A few notes:
20
21
  * TODO: Have a simple and accurate API documentation here in the readme
21
- * Currently in virtual table mode - I cannot handle variable height rows.
22
22
 
23
23
  ## Dev environment
24
24
 
@@ -53,55 +53,56 @@ To create a new table, just use `var myTable = new DGTable(INIT_OPTIONS)`.
53
53
  #### `INIT_OPTIONS`
54
54
 
55
55
  * **columns**: `COLUMN_OPTIONS[]` (Array of COLUMN_OPTIONS objects)
56
- * **name**: `String` Name of the column
57
- * **label**: `String=name` Used for the header of this column
58
- * **dataPath**: `String=name` Path to the data to show (Defaults to `name`)
59
- * **comparePath**: `String=name` Path to the data to use for comparison (Defaults to `dataPath`)
60
- * **width**: `Number|String`
56
+ * **name**: `string` Name of the column
57
+ * **label**: `string=name` Used for the header of this column
58
+ * **dataPath**: `string=name` Path to the data to show (Defaults to `name`)
59
+ * **comparePath**: `string=name` Path to the data to use for comparison (Defaults to `dataPath`)
60
+ * **width**: `number|string`
61
61
  * A simple number (i.e `10`, `30`, `50`) will set an absolute width for the column.
62
62
  * A percentage (i.e `'30%'`) or a 0-1 decimal value (i.e `0.2`, `0.7`) will set a relative width for the column, out of the full table's width.
63
63
  * Any other value, like `0`, `null` etc. will set an automatic width mode, base of the header's content length.
64
- * **resizable**: `Boolean=true` Is this column resizable?
65
- * **sortable**: `Boolean=true` Is this column sortable?
66
- * **movable**: `Boolean=true` Is this column movable?
67
- * **visible**: `Boolean=true` Is this column visible?
68
- * **cellClasses**: `String` Classes to add to the DOM element of this cell
69
- * **ignoreMin**: `Boolean=false` Should this column ignore the minimum width specified for the table columns?
70
- * **height**: `Number` Suggested height for the table
64
+ * **resizable**: `boolean=true` Is this column resizable?
65
+ * **sortable**: `boolean=true` Is this column sortable?
66
+ * **movable**: `boolean=true` Is this column movable?
67
+ * **visible**: `boolean=true` Is this column visible?
68
+ * **cellClasses**: `string` Classes to add to the DOM element of this cell
69
+ * **ignoreMin**: `boolean=false` Should this column ignore the minimum width specified for the table columns?
70
+ * **height**: `number` Suggested height for the table
71
71
  * **width**: `DGTable.Width=DGTable.Width.NONE` The way that the width of the table will be handled
72
72
  * `DGTable.Width.NONE`: No special handling
73
73
  * `DGTable.Width.AUTO`: Sets the width automatically
74
74
  * `DGTable.Width.SCROLL`: Creates a horizontal scroll when required
75
- * **virtualTable**: `Boolean=true` When set, the table will work in virtual mode, which means only the visible rows are rendered. Rows must have fixed height in this mode.
76
- * **resizableColumns**: `Boolean=true` Turns on or off the resizable columns globally.
77
- * **movableColumns**: `Boolean=true` Turns on or off the movable columns globally.
78
- * **sortableColumns**: `Number=1` How many columns can you sort by, one after another?
79
- * **adjustColumnWidthForSortArrow**: `Boolean=true` When set, the columns will automatically grow to accommodate for the sort arrow.
80
- * **relativeWidthGrowsToFillWidth**: `Boolean=true` When set, relative width columns automatically grow to fill the table's width.
81
- * **relativeWidthShrinksToFillWidth**: `Boolean=false` When set, relative width columns automatically shrink to fill the table's width.
82
- * **convertColumnWidthsToRelative**: `Boolean=false` When set, auto-width columns are automatically converted to relatives.
83
- * **autoFillTableWidth**: `Boolean=false` When set, columns are stretched proportionally to fill the table width (only if there is space left). Will supersede `relativeWidthGrowsToFillWidth` in the future.
84
- * **cellClasses**: `String` Classes to add to the DOM element of all cells
85
- * **sortColumn**: `String|String[]|COLUMN_SORT_OPTIONS|COLUMN_SORT_OPTIONS[]` Columns to sort by
75
+ * **virtualTable**: `boolean=true` When set, the table will work in virtual mode, which means only the visible rows are rendered. Rows must have fixed height in this mode.
76
+ * **estimatedRowHeight**: `number=40` Sets the estimated row height for the table. This is used for virtual table mode, to calculate the estimated scroll size.
77
+ * **resizableColumns**: `boolean=true` Turns on or off the resizable columns globally.
78
+ * **movableColumns**: `boolean=true` Turns on or off the movable columns globally.
79
+ * **sortableColumns**: `number=1` How many columns can you sort by, one after another?
80
+ * **adjustColumnWidthForSortArrow**: `boolean=true` When set, the columns will automatically grow to accommodate for the sort arrow.
81
+ * **relativeWidthGrowsToFillWidth**: `boolean=true` When set, relative width columns automatically grow to fill the table's width.
82
+ * **relativeWidthShrinksToFillWidth**: `boolean=false` When set, relative width columns automatically shrink to fill the table's width.
83
+ * **convertColumnWidthsToRelative**: `boolean=false` When set, auto-width columns are automatically converted to relatives.
84
+ * **autoFillTableWidth**: `boolean=false` When set, columns are stretched proportionally to fill the table width (only if there is space left). Will supersede `relativeWidthGrowsToFillWidth` in the future.
85
+ * **cellClasses**: `string` Classes to add to the DOM element of all cells
86
+ * **sortColumn**: `string|string[]|COLUMN_SORT_OPTIONS|COLUMN_SORT_OPTIONS[]` Columns to sort by
86
87
  * Can be a column or an array of columns.
87
- * Each column is a `String` or a `COLUMN_SORT_OPTIONS`:
88
- * **column**: `String` Column name
89
- * **descending**: `Boolean=false` Is this column sorted in descending order?
90
- * **cellFormatter**: `Function(String value, String columnName, Object rowData)String` *(optional)* A formatter function which will return the HTML for the cell. By default the formatter is a plain HTML formatter.
91
- * **headerCellFormatter**: `Function(String value, String columnName)String` *(optional)* A formatter function which will return the HTML for the cell's header. By default the formatter is a plain HTML formatter.
92
- * **rowsBufferSize**: `Number=10` The size of the rows buffer, for virtual table
93
- * **minColumnWidth**: `Number=35` In pixels, the minimum width for a column
94
- * **resizeAreaWidth**: `Number=8` The size of the area where you can drag to resize.
88
+ * Each column is a `string` or a `COLUMN_SORT_OPTIONS`:
89
+ * **column**: `string` Column name
90
+ * **descending**: `boolean=false` Is this column sorted in descending order?
91
+ * **cellFormatter**: `Function(string value, string columnName, Object rowData)string` *(optional)* A formatter function which will return the HTML for the cell. By default the formatter is a plain HTML formatter.
92
+ * **headerCellFormatter**: `Function(string value, string columnName)string` *(optional)* A formatter function which will return the HTML for the cell's header. By default the formatter is a plain HTML formatter.
93
+ * **rowsBufferSize**: `number=10` The size of the rows buffer, for virtual table
94
+ * **minColumnWidth**: `number=35` In pixels, the minimum width for a column
95
+ * **resizeAreaWidth**: `number=8` The size of the area where you can drag to resize.
95
96
  * **onComparatorRequired**: `function(columnName: string, descending: boolean, defaultComparator: function(a,b):number):{function(a,b):number}` A callback that can pass a comparator function for each column and mode as required.
96
- * **resizerClassName**: `String='dgtable-resize'` Class name for the dragged resizing element (showing when resizing a column)
97
- * **tableClassName**: `String='dgtable'` Class name for the table
98
- * **allowCellPreview**: `Boolean=true` When set, hovering on truncated cells will show a preview of the full content.
99
- * **allowHeaderCellPreview**: `Boolean=true` Allow for toggling off **allowCellPreview** for headers specifically.
100
- * **cellPreviewAutoBackground**: `Boolean=true` When set, the preview cell will receive its background automatically from the cell.
101
- * **cellPreviewClassName**: `String='dgtable-cell-preview'` Class name for the cell preview element
102
- * **className**: `String='dgtable-wrapper'` Element class name.
97
+ * **resizerClassName**: `string='dgtable-resize'` Class name for the dragged resizing element (showing when resizing a column)
98
+ * **tableClassName**: `string='dgtable'` Class name for the table
99
+ * **allowCellPreview**: `boolean=true` When set, hovering on truncated cells will show a preview of the full content.
100
+ * **allowHeaderCellPreview**: `boolean=true` Allow for toggling off **allowCellPreview** for headers specifically.
101
+ * **cellPreviewAutoBackground**: `boolean=true` When set, the preview cell will receive its background automatically from the cell.
102
+ * **cellPreviewClassName**: `string='dgtable-cell-preview'` Class name for the cell preview element
103
+ * **className**: `string='dgtable-wrapper'` Element class name.
103
104
  * **el**: `Element?` Optional element to take over
104
- * **filter**: `Function(row: Object, args: Object): Boolean` *(optional)* A filter function for using with the `filter` method
105
+ * **filter**: `Function(row: Object, args: Object): boolean` *(optional)* A filter function for using with the `filter` method
105
106
 
106
107
  #### Events triggered by DGTable:
107
108
 
@@ -161,7 +162,7 @@ To create a new table, just use `var myTable = new DGTable(INIT_OPTIONS)`.
161
162
  * `filterclear`: A filter was cleared
162
163
  * `sort`: The data was sorted
163
164
  * 1st argument: `Array` of sort constructs `[{ "column": "column's name", "descending": true/false }, ...]`
164
- * 2nd argument: `Boolean` that determines whether this is a primary sort or a resort (sort()/header click, vs resort(), addRows(), etc.). If `true`, this is a resort.
165
+ * 2nd argument: `boolean` that determines whether this is a primary sort or a resort (sort()/header click, vs resort(), addRows(), etc.). If `true`, this is a resort.
165
166
  * 3rd argument: `Function` - the comparator that was used to sort.
166
167
  * `headercontextmenu`: A context menu should be shown for a header cell
167
168
  * 1st argument: The column's name
@@ -174,114 +175,114 @@ To create a new table, just use `var myTable = new DGTable(INIT_OPTIONS)`.
174
175
  * `once(eventName, {Function?} callback)`: Adds a one-shot event listener
175
176
  * `off(eventName, {Function?} callback)`: Removes an event listener
176
177
  * `render()`: Renders the view. Should be called after adding to the DOM, and when the viewport has changed and the table has no knowledge of it.
177
- * `clearAndRender({Boolean} render = true)`: Forces a full render of the table
178
- * `setColumns({COLUMN_OPTIONS[]} columns, {Boolean} render = true) {DGTable}`: Sets the table columns
179
- * `addColumn({COLUMN_OPTIONS} columnData, {String|Number} before = -1, {Boolean} render = true) {DGTable}`: Add a column to the table
178
+ * `clearAndRender({boolean} render = true)`: Forces a full render of the table
179
+ * `setColumns({COLUMN_OPTIONS[]} columns, {boolean} render = true) {DGTable}`: Sets the table columns
180
+ * `addColumn({COLUMN_OPTIONS} columnData, {string|number} before = -1, {boolean} render = true) {DGTable}`: Add a column to the table
180
181
  * **columnData**: Column properties. Same manner as in the **columns** options when initializing the DGTable
181
182
  * **before**: Column name or order to be inserted before.
182
183
  * *returns* Self, to allow for call chaining.
183
- * `removeColumn({String} column, {Boolean} render = true) {DGTable}`: Remove a column from the table
184
+ * `removeColumn({string} column, {boolean} render = true) {DGTable}`: Remove a column from the table
184
185
  * **column**: Column name
185
186
  * *returns* Self, to allow for call chaining.
186
- * `setFilter({Function(row: Object, args: Object): Boolean} filterFunc) {DGTable}`: Sets a new filtering function, set null for default.
187
+ * `setFilter({Function(row: Object, args: Object): boolean} filterFunc) {DGTable}`: Sets a new filtering function, set null for default.
187
188
  * **filterFunc**: The filtering function receives a row and an options object, and returns true for any row that passes the filter.
188
189
  * *returns* Self, to allow for call chaining.
189
- * `setCellFormatter({Function(value: *, columnName: String, row: Object):String|null} formatter) {DGTable}`: Sets a new cell formatter.
190
+ * `setCellFormatter({Function(value: *, columnName: string, row: Object):string|null} formatter) {DGTable}`: Sets a new cell formatter.
190
191
  * **formatter**: The cell formatter. Should return an HTML.
191
192
  * *returns* Self, to allow for call chaining.
192
- * `setHeaderCellFormatter({Function(label: String, columnName: String):String|null} formatter) {DGTable}`: Sets a new header cell formatter.
193
+ * `setHeaderCellFormatter({Function(label: string, columnName: string):string|null} formatter) {DGTable}`: Sets a new header cell formatter.
193
194
  * **formatter**: The cell formatter. Should return an HTML.
194
195
  * *returns* Self, to allow for call chaining.
195
196
  * `filter({Object} args) {DGTable}`: Filter the visible rows in the table
196
197
  * **args**: Options to pass to the filtering function
197
198
  * *returns* Self, to allow for call chaining.
198
- * `filter({{column: String, keyword: String, caseSensitive: Boolean}} args) {DGTable}`: Syntax for default filtering function.
199
+ * `filter({{column: string, keyword: string, caseSensitive: boolean}} args) {DGTable}`: Syntax for default filtering function.
199
200
  * **args.column**: Name of the column to filter on
200
201
  * **args.keyword**: Tests the specified column if contains this keyword
201
202
  * **args.caseSensitive**: Use caseSensitive filtering
202
203
  * *returns* Self, to allow for call chaining.
203
204
  * `clearFilter() {DGTable}`: Clears the current filter
204
205
  * *returns* Self, to allow for call chaining.
205
- * `setColumnLabel({String} column, {String} label) {DGTable}`: Set a new label to a column
206
+ * `setColumnLabel({string} column, {string} label) {DGTable}`: Set a new label to a column
206
207
  * **column**: Name of the column
207
208
  * **label**: New label for the column
208
209
  * *returns* Self, to allow for call chaining.
209
- * `moveColumn({String|Number} src, {String|Number} dest, visibleOnly = true) {DGTable}`: Move a column to a new position
210
+ * `moveColumn({string|number} src, {string|number} dest, visibleOnly = true) {DGTable}`: Move a column to a new position
210
211
  * **src**: Name or position of the column to be moved
211
212
  * **dest**: Name of the column currently in the desired position, or the position itself
212
213
  * **visibleOnly**: Should consider only visible columns and visible-relative indexes
213
214
  * *returns* Self, to allow for call chaining.
214
- * `sort({String?} column, {Boolean?} descending, {Boolean=false} add) {DGTable}`: Sort the table. This does not render automatically, so you may need to call render() too.
215
+ * `sort({string?} column, {boolean?} descending, {boolean=false} add) {DGTable}`: Sort the table. This does not render automatically, so you may need to call render() too.
215
216
  * **src**: Name of the column to sort on
216
217
  * **descending**: Sort in descending order (if not specified, defaults to false or reverses current descending mode if sorting by same column)
217
218
  * **add**: Should this sort be on top of the existing sort? (For multiple column sort)
218
219
  * *returns* Self, to allow for call chaining.
219
220
  * `resort() {DGTable}`: Re-sort the table using current sort specifiers. This does not render automatically, so you may need to call render() too.
220
221
  * *returns* Self, to allow for call chaining.
221
- * `setColumnVisible({String} column, {Boolean} visible) {DGTable}`: Show or hide a column
222
+ * `setColumnVisible({string} column, {boolean} visible) {DGTable}`: Show or hide a column
222
223
  * **column**: Unique column name
223
224
  * **visible**: New visibility mode for the column
224
225
  * *returns* Self, to allow for call chaining.
225
- * `isColumnVisible({String} column, {Boolean} visible) {Boolean}`: Get the visibility mode of a column
226
+ * `isColumnVisible({string} column, {boolean} visible) {boolean}`: Get the visibility mode of a column
226
227
  * *returns* True if visible
227
- * `setMinColumnWidth({Number} minColumnWidth) {DGTable}`: Globally set the minimum column width
228
+ * `setMinColumnWidth({number} minColumnWidth) {DGTable}`: Globally set the minimum column width
228
229
  * **minColumnWidth**: Minimum column width
229
230
  * *returns* Self, to allow for call chaining.
230
- * `getMinColumnWidth() {Number}`: Get the current minimum column width
231
+ * `getMinColumnWidth() {number}`: Get the current minimum column width
231
232
  * *returns* Minimum column width
232
- * `setSortableColumns({Number} sortableColumns) {DGTable}`: Set the limit on concurrent columns sortedh
233
+ * `setSortableColumns({number} sortableColumns) {DGTable}`: Set the limit on concurrent columns sortedh
233
234
  * **sortableColumns**: Minimum column width
234
235
  * *returns* Self, to allow for call chaining.
235
- * `getSortableColumns() {Number}`: Get the limit on concurrent columns sorted
236
+ * `getSortableColumns() {number}`: Get the limit on concurrent columns sorted
236
237
  * *returns* How many sortable columns are allowed?
237
238
  * `getHeaderRowElement() {Element}`: Get the DOM element of the header row
238
239
  * *returns* a DOM element
239
- * `setMovableColumns({Boolean} movableColumns) {DGTable}`: *Undocumented yet*
240
- * `getMovableColumns() {Boolean}`: *Undocumented yet*
241
- * `setResizableColumns({Boolean} resizableColumns) {DGTable}`: *Undocumented yet*
242
- * `getResizableColumns() {Boolean}`: *Undocumented yet*
243
- * `setComparatorCallback({Function(String,Boolean)Function(a,b)Boolean} comparatorCallback) {DGTable}`: *Undocumented yet*
244
- * `setColumnWidth({String} column, {Number|String} width) {DGTable}`: *Undocumented yet*
245
- * `getColumnWidth({String} column) {String|null}`: *Undocumented yet*
246
- * `getColumnConfig({String} column name) {SERIALIZED_COLUMN}`: *Undocumented yet*
240
+ * `setMovableColumns({boolean} movableColumns) {DGTable}`: *Undocumented yet*
241
+ * `getMovableColumns() {boolean}`: *Undocumented yet*
242
+ * `setResizableColumns({boolean} resizableColumns) {DGTable}`: *Undocumented yet*
243
+ * `getResizableColumns() {boolean}`: *Undocumented yet*
244
+ * `setComparatorCallback({Function(string,boolean)Function(a,b)boolean} comparatorCallback) {DGTable}`: *Undocumented yet*
245
+ * `setColumnWidth({string} column, {number|string} width) {DGTable}`: *Undocumented yet*
246
+ * `getColumnWidth({string} column) {string|null}`: *Undocumented yet*
247
+ * `getColumnConfig({string} column name) {SERIALIZED_COLUMN}`: *Undocumented yet*
247
248
  * `getColumnsConfig() {Object}`: *Undocumented yet*
248
249
  * `getSortedColumns() {Array.<SERIALIZED_COLUMN_SORT>}`: *Undocumented yet*
249
- * `getHtmlForRowCell(row: Number, columnName: String) {String}`: Returns the HTML for specified cell in a row.
250
+ * `getHtmlForRowCell(row: number, columnName: string) {string}`: Returns the HTML for specified cell in a row.
250
251
  * **row**: Index of row
251
252
  * **columnName**: Name of cell
252
253
  * *returns* HTML for cell. By default cell content is *not* HTML encoded, you should encode appropriately in your `cellFormatter`.
253
- * `getHtmlForRowDataCell(rowData: Object, columnName: String) {string|null}`: Returns the HTML string for a specific cell. Can be used externally for special cases (i.e. when setting a fresh HTML in the cell preview through the callback).
254
+ * `getHtmlForRowDataCell(rowData: Object, columnName: string) {string|null}`: Returns the HTML string for a specific cell. Can be used externally for special cases (i.e. when setting a fresh HTML in the cell preview through the callback).
254
255
  * **rowData**: Actual row data
255
256
  * **columnName**: Name of column
256
257
  * *returns* string for the specified cell
257
- * `getDataForRow(row: Number): Object`: Gets the row data for a specific row
258
+ * `getDataForRow(row: number): Object`: Gets the row data for a specific row
258
259
  * *returns* row data of the row at physical index **row**
259
- * `getRowCount(): Number`: Gets the number of rows
260
+ * `getRowCount(): number`: Gets the number of rows
260
261
  * *returns* the number of rows
261
- * `getIndexForRow(row: Object): Number`: Finds the index of the specified row
262
+ * `getIndexForRow(row: Object): number`: Finds the index of the specified row
262
263
  * *returns* the index of the specified row
263
- * `getFilteredRowCount(): Number`: Gets the number of filtered rows
264
+ * `getFilteredRowCount(): number`: Gets the number of filtered rows
264
265
  * *returns* the number of rows in the filtered set (defaults to full row count if no filtering is active)
265
- * `getIndexForFilteredRow(row: Object): Number`: Finds the index of the specified row within the filtered results
266
+ * `getIndexForFilteredRow(row: Object): number`: Finds the index of the specified row within the filtered results
266
267
  * *returns* the index of the specified row
267
- * `getDataForFilteredRow(row: Number): Object`: *Undocumented yet*
268
- * `getRowElement(physicalRowIndex: Number): Element`: Returns the element of the specified row
269
- * `getRowYPos(physicalRowIndex: Number): Number?`: Returns the Y pos of the specified row
268
+ * `getDataForFilteredRow(row: number): Object`: *Undocumented yet*
269
+ * `getRowElement(physicalRowIndex: number): Element`: Returns the element of the specified row
270
+ * `getRowYPos(physicalRowIndex: number): number?`: Returns the Y pos of the specified row
270
271
  * `tableWidthChanged() {DGTable}`: *Undocumented yet*
271
272
  * `tableHeightChanged() {DGTable}`: *Undocumented yet*
272
- * `addRows({Object[]} data, {Number} at = -1, {Boolean} resort = false, {Boolean} render = true) {DGTable}`: Adds the specified rows at the specified position, and optionally resorts the data
273
- * `removeRow({Number} physicalRowIndex, {Boolean} render = true) {DGTable}`: Removes one row at the specified position
274
- * `removeRows({Number} physicalRowIndex, {Number} count, {Boolean} render = true) {DGTable}`: Removes rows at the specified position
275
- * `refreshRow({Number} physicalRowIndex) {DGTable}`: Refreshes the row specified
273
+ * `addRows({Object[]} data, {number} at = -1, {boolean} resort = false, {boolean} render = true) {DGTable}`: Adds the specified rows at the specified position, and optionally resorts the data
274
+ * `removeRow({number} physicalRowIndex, {boolean} render = true) {DGTable}`: Removes one row at the specified position
275
+ * `removeRows({number} physicalRowIndex, {number} count, {boolean} render = true) {DGTable}`: Removes rows at the specified position
276
+ * `refreshRow({number} physicalRowIndex) {DGTable}`: Refreshes the row specified
276
277
  * *returns* Self
277
278
  * `refreshAllVirtualRows() {DGTable}`: Refreshes all virtual rows
278
279
  * *returns* Self
279
- * `setRows(data: Object[], resort: Boolean=false) {DGTable}`: Rests the table rows to the provided array of rows.
280
+ * `setRows(data: Object[], resort: boolean=false) {DGTable}`: Rests the table rows to the provided array of rows.
280
281
  * **data**: New rows for the table
281
282
  * **resort**: Should re-sort the table?
282
283
  * *returns* Self, to allow for call chaining.
283
284
  * `getUrlForElementContent({string} id) {string?}`: *Undocumented yet*
284
- * `isWorkerSupported() {Boolean}`: *Undocumented yet*
285
+ * `isWorkerSupported() {boolean}`: *Undocumented yet*
285
286
  * `createWebWorker({string} url) {Worker?}`: *Undocumented yet*
286
287
  * `unbindWebWorker({Worker} worker) {DGTable}`: *Undocumented yet*
287
288
  * `hideCellPreview() {DGTable}`: Hide any cell preview showing currently, or prevent showing a cell preview from within the `cellpreview` event.