@fkui/vue 6.27.0 → 6.28.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.
@@ -430,7 +430,7 @@ export declare class FInteractiveTablePageObject implements BasePageObject {
430
430
  * Both row and column are 1-indexed, i.e. 1:1 selects the first cell in the
431
431
  * first row.
432
432
  *
433
- * Neither the marker for expandable rows or the checkbox for selectable
433
+ * Neither the marker for expandable rows or the radio/checkbox for selectable
434
434
  * rows are included in the column count, i.e. `1` always refers to the
435
435
  * first column with content.
436
436
  *
@@ -454,7 +454,7 @@ export declare class FInteractiveTablePageObject implements BasePageObject {
454
454
  /**
455
455
  * Get table header cell (`<th>` in `<thead>`).
456
456
  *
457
- * Neither the marker for expandable rows or the checkbox for selectable
457
+ * Neither the marker for expandable rows or the radio/checkbox for selectable
458
458
  * rows are included in the column count, i.e. `1` always refers to the
459
459
  * first column with content.
460
460
  *
@@ -466,7 +466,7 @@ export declare class FInteractiveTablePageObject implements BasePageObject {
466
466
  /**
467
467
  * Get all table headers (`<th>` in `<thead>`).
468
468
  *
469
- * Includes the headers for checkboxes in selectable rows and markers in expandable rows.
469
+ * Includes the headers for radios/checkboxes in selectable rows and markers in expandable rows.
470
470
  */
471
471
  headersRow(): DefaultCypressChainable;
472
472
  /**
@@ -491,17 +491,34 @@ export declare class FInteractiveTablePageObject implements BasePageObject {
491
491
  * parent row while if the first row is expanded the second row refers to
492
492
  * the first expanded row under the first row.
493
493
  *
494
- * Requires a `selectable` table.
494
+ * Requires a `selectable` table of type `multi`.
495
495
  *
496
496
  * @public
497
+ * @deprecated Use ´.selectable()´ instead. Deprecated since v6.28.0.
497
498
  * @param row - Row number (1-indexed).
498
499
  * @returns Page object for `FCheckboxField`.
499
500
  */
500
501
  checkbox(row: number): FCheckboxFieldPageObject;
502
+ /**
503
+ * Get selectable input element (checkbox or radio) in given row.
504
+ *
505
+ * For expandable rows the row count depend on whenever a row is expanded or
506
+ * not. If the first row is collapsed the second row refers to the next
507
+ * parent row while if the first row is expanded the second row refers to
508
+ * the first expanded row under the first row.
509
+ *
510
+ * Requires a `selectable` table.
511
+ *
512
+ * @public
513
+ * @since v6.28.0
514
+ * @param row - Row number (1-indexed).
515
+ * @returns Input element.
516
+ */
517
+ selectable(row: number): DefaultCypressChainable;
501
518
  /**
502
519
  * Get sort order icon in given column.
503
520
  *
504
- * Index includes the columns for checkboxes in selectable rows and markers in expandable rows.
521
+ * Index includes the columns for radios/checkboxes in selectable rows and markers in expandable rows.
505
522
  *
506
523
  * @param index - Column index (0-indexed).
507
524
  * @param order - Column sort order.
@@ -934,7 +951,7 @@ export declare class FTableColumnPageObject implements BasePageObject {
934
951
  */
935
952
  tableRowHeaderContent(): DefaultCypressChainable;
936
953
  /**
937
- * @deprecated Use ´FInteractiveTablePageObject.checkbox()´ instead. Deprecated since v6.11.0.
954
+ * @deprecated Use ´FInteractiveTablePageObject.selectable()´ instead. Deprecated since v6.11.0.
938
955
  */
939
956
  checkbox(): FCheckboxFieldPageObject;
940
957
  }
@@ -2177,6 +2177,7 @@ expandedClass(): string;
2177
2177
  hasOutsideSlot(): boolean;
2178
2178
  haveNotifications(): boolean;
2179
2179
  screenReaderNotificationText(): string;
2180
+ notificationTitle(): string;
2180
2181
  }, {
2181
2182
  onClickHeadingButton(event: MouseEvent): void;
2182
2183
  }, ComponentOptions, ComponentOptionsMixin, "toggle"[], "toggle", PublicProps, Readonly<ExtractPropTypes< {
@@ -3101,103 +3102,71 @@ flip: string;
3101
3102
  rotate: string;
3102
3103
  }, {}, {}, {}, string, ComponentProvideOptions, true, {}, any>;
3103
3104
 
3104
- declare const __VLS_export_23: <T extends object, K extends keyof T>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal_4<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
3105
- props: __VLS_PrettifyLocal_4<ExtractPublicPropTypes< {
3106
- /**
3107
- * The rows to be listed.
3108
- * The rows will be listed in the given array order.
3109
- */
3110
- rows: {
3111
- type: PropType<T[]>;
3112
- required: boolean;
3113
- };
3114
- /**
3115
- * When enabled hovering over a row will be highlighted.
3116
- */
3117
- hover: {
3118
- type: BooleanConstructor;
3119
- };
3120
- /**
3121
- * Unique attribute in rows.
3122
- */
3123
- keyAttribute: {
3124
- type: StringConstructor;
3125
- required: boolean;
3126
- default: undefined;
3127
- };
3128
- /**
3129
- * Attribute of expandable content in rows.
3130
- * If provided, the table can contain expandable rows.
3131
- */
3132
- expandableAttribute: {
3133
- type: StringConstructor;
3134
- default: string;
3135
- };
3136
- /**
3137
- * Element id for aria-describedby on expandable rows to describe expanded content.
3138
- */
3139
- expandableDescribedby: {
3140
- type: StringConstructor;
3141
- default: string;
3142
- };
3143
- /**
3144
- * When enabled the table rows will be selectable.
3145
- *
3146
- * The current set of selected rows can be accessed with `v-model`.
3147
- *
3148
- * The `select` and `unselect` events will be emitted when a row is selected
3149
- * or deselected.
3150
- */
3151
- selectable: {
3152
- type: BooleanConstructor;
3153
- };
3154
- /**
3155
- * When enabled alternating rows will use a different background color.
3156
- */
3157
- striped: {
3158
- type: BooleanConstructor;
3159
- };
3160
- /**
3161
- * Enable scrolling inside table.
3162
- *
3163
- * Can be one of the following values:
3164
- *
3165
- * - `"horizontal"`: Enables horizontal scrolling
3166
- * - `"vertical"`: Does nothing (deprecated)
3167
- * - `"both"`: Acts as horizontal (deprecated)
3168
- * - `"none"`: Disables scrolling (default)
3169
- */
3170
- scroll: {
3171
- type: PropType<TableScroll>;
3172
- default: TableScroll;
3173
- validator(value: string): boolean;
3174
- };
3175
- /**
3176
- * Enable showing the active row.
3177
- */
3178
- showActive: {
3179
- type: BooleanConstructor;
3180
- required: boolean;
3181
- default: boolean;
3182
- };
3183
- /**
3184
- * Currently selected rows.
3185
- * Requires `selectable` to be set.
3186
- */
3187
- modelValue: {
3188
- type: PropType<T[] | undefined>;
3189
- required: boolean;
3190
- default: undefined;
3191
- };
3192
- /**
3193
- * Current active row.
3194
- */
3195
- active: {
3196
- type: PropType<T | undefined>;
3197
- required: boolean;
3198
- default: undefined;
3199
- };
3200
- }> & {
3105
+ declare const __VLS_export_23: <T extends object, KeyAttribute extends AnyPropertyOf<T> = AnyPropertyOf<T>, ExpandableAttribute extends ArrayPropertyOf<T> = ArrayPropertyOf<T>>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal_4<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
3106
+ props: __VLS_PrettifyLocal_4<{
3107
+ /**
3108
+ * The rows to be listed.
3109
+ * The rows will be listed in the given array order.
3110
+ */
3111
+ rows: T[];
3112
+ /**
3113
+ * When enabled hovering over a row will be highlighted.
3114
+ */
3115
+ hover?: boolean;
3116
+ /**
3117
+ * Unique attribute in rows.
3118
+ */
3119
+ keyAttribute?: KeyAttribute;
3120
+ /**
3121
+ * Attribute of expandable content in rows.
3122
+ * If provided, the table can contain expandable rows.
3123
+ */
3124
+ expandableAttribute?: ExpandableAttribute;
3125
+ /**
3126
+ * Element id for aria-describedby on expandable rows to describe expanded content.
3127
+ */
3128
+ expandableDescribedby?: string;
3129
+ /**
3130
+ * When set the table rows will be selectable.
3131
+ *
3132
+ * For multiselect, set value to `"multi"` (or `true`).
3133
+ * For single select, set value to `"single"`.
3134
+ *
3135
+ * The current set of selected rows can be accessed with `v-model`.
3136
+ *
3137
+ * The `select` and `unselect` events will be emitted when a row is selected
3138
+ * or deselected.
3139
+ */
3140
+ selectable?: boolean | "single" | "multi";
3141
+ /**
3142
+ * When enabled alternating rows will use a different background color.
3143
+ */
3144
+ striped?: boolean;
3145
+ /**
3146
+ * Enable scrolling inside table.
3147
+ *
3148
+ * Can be one of the following values:
3149
+ *
3150
+ * - `"horizontal"`: Enables horizontal scrolling
3151
+ * - `"vertical"`: Does nothing (deprecated)
3152
+ * - `"both"`: Acts as horizontal (deprecated)
3153
+ * - `"none"`: Disables scrolling (default)
3154
+ */
3155
+ scroll?: TableScroll;
3156
+ /**
3157
+ * Enable showing the active row.
3158
+ */
3159
+ showActive?: boolean;
3160
+ /**
3161
+ * Currently selected rows.
3162
+ * Requires `selectable` to be set.
3163
+ */
3164
+ modelValue?: T[];
3165
+ /**
3166
+ * Current active row.
3167
+ */
3168
+ active?: T;
3169
+ } & {
3201
3170
  onSelect?: ((row: T) => any) | undefined;
3202
3171
  onCollapse?: ((row: T) => any) | undefined;
3203
3172
  "onUpdate:modelValue"?: ((rows: T[]) => any) | undefined;
@@ -3221,6 +3190,18 @@ declare const __VLS_export_23: <T extends object, K extends keyof T>(__VLS_props
3221
3190
  'checkbox-description'?: (props: {
3222
3191
  row: T;
3223
3192
  }) => any;
3193
+ } & {
3194
+ 'selectable-description'?: (props: {
3195
+ row: T;
3196
+ }) => any;
3197
+ } & {
3198
+ 'checkbox-description'?: (props: {
3199
+ row: T;
3200
+ }) => any;
3201
+ } & {
3202
+ 'selectable-description'?: (props: {
3203
+ row: T;
3204
+ }) => any;
3224
3205
  } & {
3225
3206
  default?: (props: {
3226
3207
  row: T;
@@ -3231,7 +3212,7 @@ declare const __VLS_export_23: <T extends object, K extends keyof T>(__VLS_props
3231
3212
  }) => any;
3232
3213
  } & {
3233
3214
  expandable?: (props: {
3234
- expandableRow: T;
3215
+ expandableRow: T[ExpandableAttribute] extends any[] ? T[ExpandableAttribute][number] : never;
3235
3216
  parentRow: T;
3236
3217
  }) => any;
3237
3218
  } & {
@@ -17249,7 +17230,7 @@ export declare function ActivateItemInjected<T>(): ActivateItemInterface<T>;
17249
17230
  export declare interface ActivateItemInterface<T> {
17250
17231
  registerCallbackAfterItemAdd(callback: ActivateItemCallback<T>): void;
17251
17232
  registerCallbackBeforeItemDelete(callback: ActivateItemCallback<T>): void;
17252
- setNestedKey(key: keyof T): void;
17233
+ setNestedKey(key: keyof T | null | undefined): void;
17253
17234
  }
17254
17235
 
17255
17236
  /**
@@ -17260,6 +17241,12 @@ export declare interface ActivateItemInterface<T> {
17260
17241
  */
17261
17242
  export declare type AnimationCallback = (expand: boolean) => void | Promise<void>;
17262
17243
 
17244
+ declare type AnyPropertyOf<T> = keyof T;
17245
+
17246
+ declare type ArrayPropertyOf<T> = {
17247
+ [K in keyof T]: IsArray<T[K], K>;
17248
+ }[keyof T];
17249
+
17263
17250
  /**
17264
17251
  * @public
17265
17252
  */
@@ -18261,6 +18248,8 @@ declare interface IPopupListboxProps {
18261
18248
 
18262
18249
  export declare const IPopupMenu: typeof __VLS_export_74;
18263
18250
 
18251
+ declare type IsArray<T, U> = T extends any[] | undefined ? U : never;
18252
+
18264
18253
  /**
18265
18254
  * @public
18266
18255
  */
@@ -9,9 +9,10 @@ module.exports = {
9
9
  rules: {
10
10
  "fkui/button-group": "error",
11
11
  "fkui/class-deprecated": "error",
12
+ "fkui/slot-deprecated": "error",
12
13
  "fkui/prefer-ficon": "error",
13
14
  "fkui/required-max-length": "error",
14
- "fkui/finteractivetable-checkbox-description": "error",
15
+ "fkui/finteractivetable-selectable-description": "error",
15
16
  "fkui/ftextfield-formatter-validation": "error",
16
17
  "fkui/no-template-modal": "error",
17
18
  "fkui/ftablecolumn-name": "error",
@@ -448,6 +448,7 @@ module.exports = defineMetadata({
448
448
  "caption",
449
449
  "row-description",
450
450
  "checkbox-description",
451
+ "selectable-description",
451
452
  "empty",
452
453
  "expandable",
453
454
  ],
@@ -12,4 +12,22 @@ function getDocumentationUrl(path) {
12
12
  return `${homepage}${path}`;
13
13
  }
14
14
 
15
- module.exports = { getDocumentationUrl };
15
+ /**
16
+ * @internal
17
+ * @param {import("html-validate").HtmlElement} element
18
+ * @returns {string[]}
19
+ */
20
+ function getSlots(element) {
21
+ return Object.fromEntries(
22
+ element.childElements
23
+ .filter((it) => it.is("template"))
24
+ .map((it) => {
25
+ const key = it.attributes.find((jt) =>
26
+ jt.key.startsWith("#"),
27
+ )?.key;
28
+ return [key, it];
29
+ }),
30
+ );
31
+ }
32
+
33
+ module.exports = { getDocumentationUrl, getSlots };
@@ -0,0 +1,57 @@
1
+ const {
2
+ Rule,
3
+ TextClassification,
4
+ classifyNodeText,
5
+ } = require("html-validate/node");
6
+ const { getDocumentationUrl, getSlots } = require("./common");
7
+
8
+ /**
9
+ * @param {import("html-validate").ElementReadyEvent} event
10
+ * @returns {boolean}
11
+ */
12
+ function isRelevant(event) {
13
+ return event.target.is("f-interactive-table");
14
+ }
15
+
16
+ class FInteractiveTableSelectableDescription extends Rule {
17
+ documentation() {
18
+ return {
19
+ description:
20
+ "`#selectable-description` slot must implemented and non-empty when `selectable` is enabled",
21
+ url: getDocumentationUrl("/components/table-and-list/table.html"),
22
+ };
23
+ }
24
+
25
+ setup() {
26
+ this.on("element:ready", isRelevant, (event) => {
27
+ const { target } = event;
28
+ const selectable = target.getAttribute("selectable");
29
+ if (!selectable) {
30
+ return;
31
+ }
32
+ const slots = getSlots(target);
33
+ const selectableDescription = slots["#selectable-description"];
34
+ if (!selectableDescription) {
35
+ this.report({
36
+ node: target,
37
+ location: selectable.keyLocation,
38
+ message:
39
+ "#selectable-description slot must be implemented when selectable is enabled",
40
+ });
41
+ return;
42
+ }
43
+
44
+ const textContent = classifyNodeText(selectableDescription);
45
+ if (textContent === TextClassification.EMPTY_TEXT) {
46
+ this.report({
47
+ node: selectableDescription,
48
+ location: selectableDescription.location,
49
+ message:
50
+ "#selectable-description cannot be empty when selectable is enabled",
51
+ });
52
+ }
53
+ });
54
+ }
55
+ }
56
+
57
+ module.exports = FInteractiveTableSelectableDescription;
@@ -1,20 +1,22 @@
1
1
  const buttongroup = require("./buttongroup.rule");
2
2
  const classdeprecated = require("./classdeprecated.rule");
3
- const FInteractiveTableCheckboxDescription = require("./finteractivetable-checkbox-description.rule");
3
+ const FInteractiveTableSelectableDescription = require("./finteractivetable-selectable-description.rule");
4
4
  const FTableColumnName = require("./ftablecolumn-name.rule");
5
5
  const ftextfieldFormatterValidation = require("./ftextfieldFormatterValidation.rule");
6
6
  const NoTemplateModal = require("./no-template-modal.rule");
7
7
  const PreferFIcon = require("./prefer-ficon.rule");
8
8
  const requiredmaxlength = require("./requiredmaxlength.rule");
9
+ const slotdeprecated = require("./slotdeprecated.rule");
9
10
 
10
11
  module.exports = {
11
12
  "fkui/button-group": buttongroup,
12
13
  "fkui/class-deprecated": classdeprecated,
13
14
  "fkui/prefer-ficon": PreferFIcon,
14
15
  "fkui/required-max-length": requiredmaxlength,
15
- "fkui/finteractivetable-checkbox-description":
16
- FInteractiveTableCheckboxDescription,
16
+ "fkui/finteractivetable-selectable-description":
17
+ FInteractiveTableSelectableDescription,
17
18
  "fkui/ftextfield-formatter-validation": ftextfieldFormatterValidation,
18
19
  "fkui/no-template-modal": NoTemplateModal,
19
20
  "fkui/ftablecolumn-name": FTableColumnName,
21
+ "fkui/slot-deprecated": slotdeprecated,
20
22
  };
@@ -0,0 +1,85 @@
1
+ const { Rule } = require("html-validate/node");
2
+ const { getDocumentationUrl, getSlots } = require("./common");
3
+
4
+ /**
5
+ * @typedef {import("html-validate").RuleDocumentation} RuleDocumentation
6
+ */
7
+
8
+ /**
9
+ * @typedef {Object} Entry
10
+ * @property {string} slot
11
+ * @property {string} component
12
+ * @property {string} [replacement]
13
+ * @property {string} [additionalMessage]
14
+ * @property {string} url
15
+ */
16
+
17
+ /** @type {Entry[]} */
18
+ const deprecatedSlots = [
19
+ {
20
+ slot: "#checkbox-description",
21
+ component: "f-interactive-table",
22
+ replacement: "selectable-description",
23
+ url: "/components/table-and-list/table.html",
24
+ },
25
+ ];
26
+
27
+ /**
28
+ * @param {import("html-validate").ElementReadyEvent} event
29
+ * @returns {boolean}
30
+ */
31
+ function isRelevant(event) {
32
+ return deprecatedSlots
33
+ .map((it) => it.component)
34
+ .includes(event.target.tagName);
35
+ }
36
+
37
+ /**
38
+ * @extends {Rule<Entry, void>}
39
+ */
40
+ class SlotDeprecated extends Rule {
41
+ /**
42
+ * @param {Entry} context
43
+ * @returns {RuleDocumentation}
44
+ */
45
+ documentation(context) {
46
+ const { url, replacement, additionalMessage } = context;
47
+ const message = replacement
48
+ ? `Slot \`${context.slot}\` is deprecated and should be replaced with \`${replacement}\``
49
+ : `Slot \`${context.slot}\` is deprecated.`;
50
+ return {
51
+ description: additionalMessage
52
+ ? `${message}\n\n${additionalMessage}`
53
+ : message,
54
+ url: getDocumentationUrl(url),
55
+ };
56
+ }
57
+
58
+ setup() {
59
+ this.on("element:ready", isRelevant, (event) => {
60
+ const { target } = event;
61
+ const slots = getSlots(target);
62
+ const entries = deprecatedSlots.filter((it) =>
63
+ target.is(it.component),
64
+ );
65
+
66
+ for (const entry of entries) {
67
+ const description = slots[entry.slot];
68
+ if (!description) {
69
+ continue;
70
+ }
71
+
72
+ this.report({
73
+ node: target,
74
+ location: description.location,
75
+ message: entry.replacement
76
+ ? `slot "{{ slot }}" is deprecated and replaced with "{{ replacement }}"`
77
+ : `slot "{{ slot }}" is deprecated`,
78
+ context: entry,
79
+ });
80
+ }
81
+ });
82
+ }
83
+ }
84
+
85
+ module.exports = SlotDeprecated;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fkui/vue",
3
- "version": "6.27.0",
3
+ "version": "6.28.0",
4
4
  "description": "Vue implementation of FKUI components",
5
5
  "keywords": [
6
6
  "fkui",
@@ -60,9 +60,9 @@
60
60
  "unit:watch": "jest --watch"
61
61
  },
62
62
  "peerDependencies": {
63
- "@fkui/date": "^6.27.0",
64
- "@fkui/design": "^6.27.0",
65
- "@fkui/logic": "^6.27.0",
63
+ "@fkui/date": "^6.28.0",
64
+ "@fkui/design": "^6.28.0",
65
+ "@fkui/logic": "^6.28.0",
66
66
  "fk-icons": "^4.30.1",
67
67
  "html-validate": ">= 7.9.0",
68
68
  "vue": "^3.5.0"
@@ -79,5 +79,5 @@
79
79
  "node": ">= 20",
80
80
  "npm": ">= 7"
81
81
  },
82
- "gitHead": "1634a325b0102a6aa74fee4b8767d9236a958b31"
82
+ "gitHead": "fe2ffaeb55b9e9f560cc6f660740bc3480f77cd8"
83
83
  }
@@ -1,73 +0,0 @@
1
- const {
2
- Rule,
3
- TextClassification,
4
- classifyNodeText,
5
- } = require("html-validate/node");
6
- const { getDocumentationUrl } = require("./common");
7
-
8
- /**
9
- * @param {import("html-validate").ElementReadyEvent} event
10
- * @returns {boolean}
11
- */
12
- function isRelevant(event) {
13
- return event.target.is("f-interactive-table");
14
- }
15
-
16
- /**
17
- * @param {import("html-validate").HtmlElement} element
18
- * @returns {string[]}
19
- */
20
- function getSlots(element) {
21
- return Object.fromEntries(
22
- element.childElements
23
- .filter((it) => it.is("template"))
24
- .map((it) => {
25
- const key = it.attributes.find((jt) =>
26
- jt.key.startsWith("#"),
27
- )?.key;
28
- return [key, it];
29
- }),
30
- );
31
- }
32
-
33
- class FInteractiveTableCheckboxDescription extends Rule {
34
- documentation() {
35
- return {
36
- description:
37
- "`#checkbox-description` slot must implemented and non-empty when `selectable` is enabled",
38
- url: getDocumentationUrl("/components/table-and-list/table.html"),
39
- };
40
- }
41
-
42
- setup() {
43
- this.on("element:ready", isRelevant, (event) => {
44
- const { target } = event;
45
- const selectable = target.getAttribute("selectable");
46
- if (!selectable) {
47
- return;
48
- }
49
- const slots = getSlots(target);
50
- const checkboxDescription = slots["#checkbox-description"];
51
- if (!checkboxDescription) {
52
- this.report({
53
- node: target,
54
- location: selectable.keyLocation,
55
- message:
56
- "#checkbox-description slot must be implemented when selectable is enabled",
57
- });
58
- return;
59
- }
60
- const textContent = classifyNodeText(checkboxDescription);
61
- if (textContent === TextClassification.EMPTY_TEXT) {
62
- this.report({
63
- node: checkboxDescription,
64
- location: checkboxDescription.location,
65
- message:
66
- "#checkbox-description cannot be empty when selectable is enabled",
67
- });
68
- }
69
- });
70
- }
71
- }
72
-
73
- module.exports = FInteractiveTableCheckboxDescription;