@adaptabletools/adaptable-cjs 18.0.11 → 18.1.0-canary.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.
Files changed (126) hide show
  1. package/agGrid.d.ts +4 -3
  2. package/agGrid.js +6 -1
  3. package/base.css +7 -2
  4. package/base.css.map +1 -1
  5. package/index.css +11 -2
  6. package/index.css.map +1 -1
  7. package/package.json +2 -2
  8. package/src/AdaptableOptions/ActionColumnOptions.d.ts +1 -1
  9. package/src/AdaptableOptions/ColumnFilterOptions.d.ts +27 -1
  10. package/src/AdaptableOptions/ExportOptions.d.ts +20 -7
  11. package/src/AdaptableOptions/ExpressionOptions.d.ts +12 -2
  12. package/src/AdaptableOptions/Fdc3Options.d.ts +48 -43
  13. package/src/Api/ColumnApi.d.ts +1 -1
  14. package/src/Api/Events/Fdc3MessageInfo.d.ts +5 -7
  15. package/src/Api/ExpressionApi.d.ts +2 -2
  16. package/src/Api/Fdc3Api.d.ts +14 -19
  17. package/src/Api/Implementation/ConfigApiImpl.js +3 -0
  18. package/src/Api/Implementation/Fdc3ApiImpl.d.ts +14 -16
  19. package/src/Api/Implementation/Fdc3ApiImpl.js +35 -11
  20. package/src/Api/Internal/AlertInternalApi.d.ts +17 -2
  21. package/src/Api/Internal/AlertInternalApi.js +196 -25
  22. package/src/Api/Internal/ColumnFilterInternalApi.d.ts +2 -0
  23. package/src/Api/Internal/ColumnFilterInternalApi.js +20 -0
  24. package/src/Api/Internal/ExportInternalApi.d.ts +3 -3
  25. package/src/Api/Internal/ExportInternalApi.js +31 -17
  26. package/src/Api/Internal/ExpressionInternalApi.d.ts +5 -1
  27. package/src/Api/Internal/ExpressionInternalApi.js +80 -0
  28. package/src/Api/Internal/Fdc3InternalApi.d.ts +8 -10
  29. package/src/Api/Internal/Fdc3InternalApi.js +5 -9
  30. package/src/PredefinedConfig/Common/AdaptableField.d.ts +18 -0
  31. package/src/PredefinedConfig/Common/AdaptableField.js +2 -0
  32. package/src/PredefinedConfig/Common/AdaptableIcon.d.ts +1 -1
  33. package/src/PredefinedConfig/Common/AdaptablePredicate.js +18 -1
  34. package/src/PredefinedConfig/Common/Fdc3Context.d.ts +7 -226
  35. package/src/PredefinedConfig/Common/Fdc3Context.js +44 -32
  36. package/src/PredefinedConfig/Common/Fdc3Intent.d.ts +6 -89
  37. package/src/PredefinedConfig/Common/Fdc3Intent.js +27 -74
  38. package/src/PredefinedConfig/Common/RowSummary.d.ts +2 -1
  39. package/src/PredefinedConfig/StyledColumnState.d.ts +1 -1
  40. package/src/Redux/ActionsReducers/FormatColumnRedux.js +0 -3
  41. package/src/Strategy/AdaptableModuleBase.js +1 -3
  42. package/src/Strategy/AlertModule.d.ts +1 -1
  43. package/src/Strategy/AlertModule.js +8 -8
  44. package/src/Utilities/ExpressionFunctions/aggregatedScalarExpressionFunctions.d.ts +3 -1
  45. package/src/Utilities/ExpressionFunctions/aggregatedScalarExpressionFunctions.js +14 -13
  46. package/src/Utilities/Services/Fdc3Service.d.ts +1 -1
  47. package/src/Utilities/Services/QueryLanguageService.d.ts +8 -4
  48. package/src/Utilities/Services/QueryLanguageService.js +105 -6
  49. package/src/Utilities/Services/ReportService.js +8 -5
  50. package/src/Utilities/Services/RowSummaryService.js +3 -1
  51. package/src/Utilities/divideBy100.d.ts +1 -0
  52. package/src/Utilities/divideBy100.js +34 -0
  53. package/src/Utilities/times100.d.ts +1 -0
  54. package/src/Utilities/times100.js +27 -0
  55. package/src/View/Alert/Wizard/AlertMessageWizardSection.js +1 -1
  56. package/src/View/Alert/Wizard/AlertNotificationWizardSection.js +2 -2
  57. package/src/View/Alert/Wizard/AlertScopeWizardSection.js +2 -1
  58. package/src/View/CalculatedColumn/Wizard/CalculatedColumnExpressionWizardSection.js +1 -1
  59. package/src/View/Components/EntityRulesEditor/index.d.ts +1 -0
  60. package/src/View/Components/EntityRulesEditor/index.js +11 -7
  61. package/src/View/Components/ExpressionWizard.js +1 -1
  62. package/src/View/Components/FilterForm/QuickFilterValues.js +28 -4
  63. package/src/View/Components/Popups/AdaptablePopup/AdaptablePopupModuleView.js +6 -2
  64. package/src/View/Components/Selectors/FieldSelector.d.ts +13 -0
  65. package/src/View/Components/Selectors/FieldSelector.js +26 -0
  66. package/src/View/Components/Selectors/PermittedValuesSelector.js +8 -4
  67. package/src/View/Export/Wizard/ReportRowsWizardSection.js +1 -1
  68. package/src/View/FormatColumn/Wizard/FormatColumnRuleWizardSection.js +1 -1
  69. package/src/View/GridFilter/GridFilterExpressionEditor.js +1 -1
  70. package/src/View/Layout/Wizard/sections/GridFilterSection.js +4 -2
  71. package/src/View/Layout/Wizard/sections/RowSummarySection.js +7 -1
  72. package/src/View/NamedQuery/Wizard/NamedQueryExpressionWizardSection.js +1 -1
  73. package/src/View/Wizard/OnePageAdaptableWizard.js +3 -2
  74. package/src/agGrid/AdaptableAgGrid.d.ts +1 -2
  75. package/src/agGrid/AdaptableAgGrid.js +65 -37
  76. package/src/agGrid/AgGridAdapter.d.ts +2 -0
  77. package/src/agGrid/AgGridAdapter.js +12 -2
  78. package/src/agGrid/AgGridColumnAdapter.d.ts +3 -0
  79. package/src/agGrid/AgGridColumnAdapter.js +24 -1
  80. package/src/agGrid/AgGridMenuAdapter.js +1 -1
  81. package/src/agGrid/editors/AdaptableDateEditor/InternalAdaptableDateEditor.d.ts +0 -1
  82. package/src/agGrid/editors/AdaptableDateEditor/InternalAdaptableDateEditor.js +0 -2
  83. package/src/agGrid/editors/AdaptableDateEditor/index.d.ts +4 -16
  84. package/src/agGrid/editors/AdaptableDateEditor/index.js +6 -19
  85. package/src/agGrid/editors/AdaptableNumberEditor/InternalAdaptableNumberEditor.js +6 -1
  86. package/src/agGrid/editors/AdaptableNumberEditor/index.d.ts +4 -3
  87. package/src/agGrid/editors/AdaptableNumberEditor/index.js +6 -2
  88. package/src/agGrid/editors/AdaptablePercentageEditor/InternalAdaptablePercentageEditor.d.ts +23 -0
  89. package/src/agGrid/editors/AdaptablePercentageEditor/InternalAdaptablePercentageEditor.js +84 -0
  90. package/src/agGrid/editors/AdaptablePercentageEditor/index.d.ts +47 -0
  91. package/src/agGrid/editors/AdaptablePercentageEditor/index.js +153 -0
  92. package/src/agGrid/weightedAverage.js +3 -2
  93. package/src/components/Accordion.js +1 -1
  94. package/src/components/Datepicker/DatepickerContext.d.ts +0 -2
  95. package/src/components/Datepicker/index.js +3 -4
  96. package/src/components/ExpressionEditor/DataTableEditor.d.ts +17 -0
  97. package/src/components/ExpressionEditor/DataTableEditor.js +68 -0
  98. package/src/components/ExpressionEditor/EditorInput.js +21 -8
  99. package/src/components/ExpressionEditor/NamedQueryEditor.d.ts +5 -0
  100. package/src/components/ExpressionEditor/NamedQueryEditor.js +35 -0
  101. package/src/components/ExpressionEditor/QueryBuilder/QueryBuilder.d.ts +10 -0
  102. package/src/components/ExpressionEditor/QueryBuilder/QueryBuilder.js +7 -4
  103. package/src/components/ExpressionEditor/QueryBuilder/QueryBuilderInputs.d.ts +3 -2
  104. package/src/components/ExpressionEditor/QueryBuilder/QueryBuilderInputs.js +72 -14
  105. package/src/components/ExpressionEditor/QueryBuilder/QueryPredicateBuilder.js +27 -19
  106. package/src/components/ExpressionEditor/QueryBuilder/utils.d.ts +9 -1
  107. package/src/components/ExpressionEditor/QueryBuilder/utils.js +46 -4
  108. package/src/components/ExpressionEditor/index.d.ts +3 -1
  109. package/src/components/ExpressionEditor/index.js +67 -92
  110. package/src/components/Input/NumberInput.d.ts +2 -1
  111. package/src/components/Input/NumberInput.js +6 -5
  112. package/src/components/OverlayTrigger/index.js +10 -6
  113. package/src/components/icons/column-outline.d.ts +3 -0
  114. package/src/components/icons/column-outline.js +7 -0
  115. package/src/components/icons/index.js +5 -1
  116. package/src/components/icons/sync.d.ts +3 -0
  117. package/src/components/icons/sync.js +7 -0
  118. package/src/env.js +2 -2
  119. package/src/metamodel/adaptable.metamodel.d.ts +78 -200
  120. package/src/metamodel/adaptable.metamodel.js +1 -1
  121. package/src/parser/src/predicate/mapExpressionToQlPredicate.d.ts +1 -0
  122. package/src/parser/src/predicate/mapExpressionToQlPredicate.js +13 -3
  123. package/src/parser/src/predicate/mapQlPredicateToExpression.js +4 -1
  124. package/src/parser/src/types.d.ts +101 -1
  125. package/src/types.d.ts +9 -7
  126. package/tsconfig.cjs.tsbuildinfo +1 -1
@@ -292,7 +292,7 @@ export interface ColumnApi {
292
292
  setColumnDefinitions(columnDefinitions: (ColDef | ColGroupDef)[]): void;
293
293
  }
294
294
  /**
295
- * Column Configuration
295
+ * Configuration of an AG Grid Column, used for runtime updating of ColDefs
296
296
  */
297
297
  export interface ColumnConfig {
298
298
  /** Column Id */
@@ -1,7 +1,5 @@
1
1
  import { BaseEventInfo } from './BaseEventInfo';
2
- import { Fdc3Context } from '../../PredefinedConfig/Common/Fdc3Context';
3
- import { Fdc3IntentType } from '../../PredefinedConfig/Common/Fdc3Intent';
4
- import { AppIdentifier, ContextMetadata } from '@finos/fdc3';
2
+ import { AppIdentifier, Context, ContextMetadata, Intent } from '@finos/fdc3';
5
3
  /**
6
4
  * EventInfo returned by FDC3 Message events
7
5
  */
@@ -21,11 +19,11 @@ export interface Fdc3MessageSentInfo extends BaseEventInfo {
21
19
  /**
22
20
  * FDC3 Intent which caused Event to fire (if type is `RaiseIntent`)
23
21
  */
24
- intent?: Fdc3IntentType;
22
+ intent?: Intent;
25
23
  /**
26
24
  * Full FDC3 Context for object related to the Event
27
25
  */
28
- context: Fdc3Context;
26
+ context: Context;
29
27
  /**
30
28
  * Target application for the message
31
29
  */
@@ -46,11 +44,11 @@ export interface Fdc3MessageReceivedInfo extends BaseEventInfo {
46
44
  /**
47
45
  * FDC3 Intent which caused Event to fire (if type is `IntentRaised`)
48
46
  */
49
- intent?: Fdc3IntentType;
47
+ intent?: Intent;
50
48
  /**
51
49
  * Full FDC3 Context for object related to the Event
52
50
  */
53
- context: Fdc3Context;
51
+ context: Context;
54
52
  /**
55
53
  * Metadata associated with the FDC3 Context
56
54
  */
@@ -48,12 +48,12 @@ export interface ExpressionApi {
48
48
  */
49
49
  getASTForExpression(expression: string): any;
50
50
  /**
51
- * Returns the Expression string of the given AdaptableQuery: can be Boolean, AggregatedBoolean, Scalar, AggregatedScalar or Observable Expression
51
+ * Returns Expression string of given AdaptableQuery: can be Boolean, AggregatedBoolean, Scalar, AggregatedScalar or Observable
52
52
  * @param query - the AdaptableQuery
53
53
  */
54
54
  getAdaptableQueryExpression(query: Partial<AdaptableQuery>): string | undefined;
55
55
  /**
56
- * Returns the Expression string of the given AdaptableQuery with the column friendly names (instead of their technical IDs)
56
+ * Returns Expression string of given AdaptableQuery with column friendly names (instead of Column IDs)
57
57
  * @param query - the AdaptableQuery
58
58
  */
59
59
  getAdaptableQueryExpressionWithColumnFriendlyNames(query: Partial<AdaptableQuery>): string | undefined;
@@ -1,7 +1,5 @@
1
- import { Fdc3Context, Fdc3ContextType, Fdc3StandardContextType } from '../PredefinedConfig/Common/Fdc3Context';
2
1
  import { IRowNode } from '@ag-grid-community/core';
3
- import { AppIdentifier, DesktopAgent, IntentResolution } from '@finos/fdc3';
4
- import { Fdc3IntentType, Fdc3StandardIntentType } from '../PredefinedConfig/Common/Fdc3Intent';
2
+ import { AppIdentifier, Context, ContextType, DesktopAgent, Intent, IntentResolution } from '@finos/fdc3';
5
3
  /**
6
4
  * Provides run-time access to AdapTable's FDC3 functionality
7
5
  */
@@ -14,30 +12,27 @@ export interface Fdc3Api {
14
12
  * Returns the human-friendly label for the given Context Type
15
13
  * @param contextType - The FDC3 Context Type
16
14
  */
17
- getContextLabel(contextType: Fdc3ContextType): string;
15
+ getContextLabel(contextType: ContextType): string;
18
16
  /**
19
17
  * Builds FDC3 Context Data based on the given Context Type and Row Node
20
18
  * @param contextType - The FDC3 Context Type
21
19
  * @param rowNode - The Row Node
22
20
  */
23
- buildContextDataFromRow(contextType: Fdc3ContextType, rowNode: IRowNode): Fdc3Context;
21
+ buildContextDataFromRow(contextType: ContextType, rowNode: IRowNode): Context;
24
22
  /**
25
23
  * Builds FDC3 Context Data based on the given Context Type and the Row Node with the given Primary Key Value
26
24
  * @param contextType - The FDC3 Context Type
27
25
  * @param primaryKeyValue - The Primary Key Value
28
26
  */
29
- buildContextDataForPrimaryKey(contextType: Fdc3ContextType, primaryKeyValue: string | number): Fdc3Context | undefined;
27
+ buildContextDataForPrimaryKey(contextType: ContextType, primaryKeyValue: string | number): Context | undefined;
30
28
  /**
31
- * Returns the FDC3 Context Type for the given Intent
32
- * @param intent - The FDC3 Intent
29
+ * @deprecated no longer relevant as of FDC3 v2.1
33
30
  */
34
- getPossibleContextTypes(intent: Fdc3StandardIntentType): Fdc3StandardContextType[];
31
+ getPossibleContextTypes(intent: Intent): ContextType[];
35
32
  /**
36
- * Checks if the given Context Type is compatible with the given Intent
37
- * @param contextType - The FDC3 Context Type
38
- * @param intent - The FDC3 Intent
33
+ * @deprecated no longer relevant as of FDC3 v2.1
39
34
  */
40
- isContextCompatibleWithIntent(contextType: Fdc3StandardContextType, intent: Fdc3StandardIntentType): boolean;
35
+ isContextCompatibleWithIntent(contextType: ContextType, intent: Intent): boolean;
41
36
  /**
42
37
  * Raises an Intent with the given Context from the given Row Node
43
38
  * @param rowNode - The Row Node
@@ -45,7 +40,7 @@ export interface Fdc3Api {
45
40
  * @param contextType - The FDC3 Context Type
46
41
  * @param appIdentifier - The App Identifier
47
42
  */
48
- raiseIntentFromRow(rowNode: IRowNode, intent: Fdc3IntentType, contextType: Fdc3ContextType, appIdentifier?: AppIdentifier): Promise<IntentResolution>;
43
+ raiseIntentFromRow(rowNode: IRowNode, intent: Intent, contextType: ContextType, appIdentifier?: AppIdentifier): Promise<IntentResolution>;
49
44
  /**
50
45
  * Raises an Intent with the given Context from the given Row Node with the given Primary Key Value
51
46
  * @param primaryKeyValue - The Primary Key Value
@@ -53,33 +48,33 @@ export interface Fdc3Api {
53
48
  * @param contextType - The FDC3 Context Type
54
49
  * @param appIdentifier - The App Identifier
55
50
  */
56
- raiseIntentFromPrimaryKey(primaryKeyValue: string | number, intent: Fdc3IntentType, contextType: Fdc3ContextType, appIdentifier?: AppIdentifier): Promise<IntentResolution> | undefined;
51
+ raiseIntentFromPrimaryKey(primaryKeyValue: string | number, intent: Intent, contextType: ContextType, appIdentifier?: AppIdentifier): Promise<IntentResolution> | undefined;
57
52
  /**
58
53
  * Finds and raises an Intent based on the given Context from the given Row Node
59
54
  * @param rowNode - The Row Node
60
55
  * @param contextType - The FDC3 Context Type
61
56
  * @param appIdentifier - The App Identifier
62
57
  */
63
- raiseIntentForContextFromRow(rowNode: IRowNode, contextType: Fdc3ContextType, appIdentifier?: AppIdentifier): Promise<IntentResolution>;
58
+ raiseIntentForContextFromRow(rowNode: IRowNode, contextType: ContextType, appIdentifier?: AppIdentifier): Promise<IntentResolution>;
64
59
  /**
65
60
  * Finds and raises an Intent based on the given Context from the given Row Node with the given Primary Key Value
66
61
  * @param primaryKeyValue - The Primary Key Value
67
62
  * @param contextType - The FDC3 Context Type
68
63
  * @param appIdentifier - The App Identifier
69
64
  */
70
- raiseIntentForContextFromPrimaryKey(primaryKeyValue: string | number, contextType: Fdc3ContextType, appIdentifier?: AppIdentifier): Promise<IntentResolution> | undefined;
65
+ raiseIntentForContextFromPrimaryKey(primaryKeyValue: string | number, contextType: ContextType, appIdentifier?: AppIdentifier): Promise<IntentResolution> | undefined;
71
66
  /**
72
67
  * Broadcasts the given Context from the given Row Node
73
68
  * @param rowNode - The Row Node
74
69
  * @param contextType - The FDC3 Context Type
75
70
  */
76
- broadcastFromRow(rowNode: IRowNode, contextType: Fdc3ContextType): Promise<void>;
71
+ broadcastFromRow(rowNode: IRowNode, contextType: ContextType): Promise<void>;
77
72
  /**
78
73
  * Broadcasts the given Context from the given Row Node with the given Primary Key Value
79
74
  * @param primaryKeyValue - The Primary Key Value
80
75
  * @param contextType - The FDC3 Context Type
81
76
  */
82
- broadcastFromPrimaryKey(primaryKeyValue: string | number, contextType: Fdc3ContextType): Promise<void> | undefined;
77
+ broadcastFromPrimaryKey(primaryKeyValue: string | number, contextType: ContextType): Promise<void> | undefined;
83
78
  /**
84
79
  * Checks if the given Context Type is a FDC3 standard Context Type
85
80
  */
@@ -49,6 +49,9 @@ class ConfigApiImpl extends ApiBase_1.ApiBase {
49
49
  var _a;
50
50
  const adaptableOptions = this.adaptable.adaptableOptions;
51
51
  const oldState = this.getPersistedState();
52
+ // clearing filters so that AG Grid doesnt display the filter icon in a column header after grid reloads
53
+ // but this is a hack so would be nicer if there was a better way to do this
54
+ this.getAdaptableApi().gridApi.clearGridFiltering();
52
55
  const clearStateFn = ((_a = adaptableOptions.stateOptions) === null || _a === void 0 ? void 0 : _a.clearState) ||
53
56
  (() => {
54
57
  localStorage.removeItem(adaptableOptions.adaptableStateKey);
@@ -1,28 +1,26 @@
1
1
  import { IRowNode } from '@ag-grid-community/core';
2
- import { DesktopAgent, IntentResolution } from '@finos/fdc3';
2
+ import { Context, ContextType, DesktopAgent, Intent, IntentResolution, StandardContextType, StandardIntent } from '@finos/fdc3';
3
3
  import { ApiBase } from './ApiBase';
4
4
  import { Fdc3Api } from '../Fdc3Api';
5
5
  import { Fdc3InternalApi } from '../Internal/Fdc3InternalApi';
6
6
  import { IAdaptable } from '../../AdaptableInterfaces/IAdaptable';
7
- import { Fdc3Context, Fdc3StandardContextType } from '../../PredefinedConfig/Common/Fdc3Context';
8
- import { Fdc3StandardIntentType } from '../../PredefinedConfig/Common/Fdc3Intent';
9
7
  import { AppIdentifier } from '@finos/fdc3/dist/api/AppIdentifier';
10
8
  export declare class Fdc3ApiImpl extends ApiBase implements Fdc3Api {
11
9
  internalApi: Fdc3InternalApi;
12
10
  constructor(adaptable: IAdaptable);
13
11
  getDesktopAgent(): DesktopAgent;
14
- buildContextDataFromRow(contextType: Fdc3StandardContextType, rowNode: IRowNode): Fdc3Context;
15
- buildContextDataForPrimaryKey(contextType: Fdc3StandardContextType, primaryKeyValue: string | number): Fdc3Context | undefined;
16
- getPossibleContextTypes(intent: Fdc3StandardIntentType): Fdc3StandardContextType[];
17
- isContextCompatibleWithIntent(contextType: Fdc3StandardContextType, intent: Fdc3StandardIntentType): boolean;
18
- raiseIntentFromPrimaryKey(primaryKeyValue: string | number, intent: Fdc3StandardIntentType, contextType: Fdc3StandardContextType, appIdentifier?: AppIdentifier): Promise<IntentResolution> | undefined;
19
- raiseIntentFromRow(rowNode: IRowNode, intent: Fdc3StandardIntentType, contextType: Fdc3StandardContextType, appIdentifier?: AppIdentifier): Promise<IntentResolution>;
20
- raiseIntentForContextFromRow(rowNode: IRowNode, contextType: Fdc3StandardContextType, appIdentifier?: AppIdentifier): Promise<IntentResolution>;
21
- raiseIntentForContextFromPrimaryKey(primaryKeyValue: string | number, contextType: Fdc3StandardContextType, appIdentifier?: AppIdentifier): Promise<IntentResolution> | undefined;
22
- broadcastFromRow(rowNode: IRowNode, contextType: Fdc3StandardContextType): Promise<void>;
23
- broadcastFromPrimaryKey(primaryKeyValue: string | number, contextType: Fdc3StandardContextType): Promise<void> | undefined;
24
- getContextLabel(contextType: Fdc3StandardContextType): string;
25
- isStandardContextType(contextType: string): boolean;
26
- isStandardIntentType(intentType: string): boolean;
12
+ buildContextDataFromRow(contextType: ContextType, rowNode: IRowNode): Context;
13
+ buildContextDataForPrimaryKey(contextType: ContextType, primaryKeyValue: string | number): Context | undefined;
14
+ raiseIntentFromPrimaryKey(primaryKeyValue: string | number, intent: Intent, contextType: ContextType, appIdentifier?: AppIdentifier): Promise<IntentResolution> | undefined;
15
+ raiseIntentFromRow(rowNode: IRowNode, intent: Intent, contextType: ContextType, appIdentifier?: AppIdentifier): Promise<IntentResolution>;
16
+ raiseIntentForContextFromRow(rowNode: IRowNode, contextType: ContextType, appIdentifier?: AppIdentifier): Promise<IntentResolution>;
17
+ raiseIntentForContextFromPrimaryKey(primaryKeyValue: string | number, contextType: ContextType, appIdentifier?: AppIdentifier): Promise<IntentResolution> | undefined;
18
+ broadcastFromRow(rowNode: IRowNode, contextType: ContextType): Promise<void>;
19
+ broadcastFromPrimaryKey(primaryKeyValue: string | number, contextType: ContextType): Promise<void> | undefined;
20
+ getContextLabel(contextType: ContextType): string;
21
+ isStandardContextType(contextType: string): contextType is StandardContextType;
22
+ isStandardIntentType(intentType: string): intentType is StandardIntent;
27
23
  private getFdc3Service;
24
+ getPossibleContextTypes(intent: Intent): ContextType[];
25
+ isContextCompatibleWithIntent(contextType: ContextType, intent: Intent): boolean;
28
26
  }
@@ -4,7 +4,6 @@ exports.Fdc3ApiImpl = void 0;
4
4
  const ApiBase_1 = require("./ApiBase");
5
5
  const Fdc3InternalApi_1 = require("../Internal/Fdc3InternalApi");
6
6
  const Fdc3Context_1 = require("../../PredefinedConfig/Common/Fdc3Context");
7
- const Fdc3Intent_1 = require("../../PredefinedConfig/Common/Fdc3Intent");
8
7
  class Fdc3ApiImpl extends ApiBase_1.ApiBase {
9
8
  constructor(adaptable) {
10
9
  super(adaptable);
@@ -24,14 +23,6 @@ class Fdc3ApiImpl extends ApiBase_1.ApiBase {
24
23
  }
25
24
  return this.buildContextDataFromRow(contextType, rowNode);
26
25
  }
27
- getPossibleContextTypes(intent) {
28
- var _a;
29
- const compatibleContexts = (_a = Fdc3Intent_1.Fdc3IntentConfiguration[intent]) === null || _a === void 0 ? void 0 : _a.contexts;
30
- return compatibleContexts ? [...compatibleContexts] : [];
31
- }
32
- isContextCompatibleWithIntent(contextType, intent) {
33
- return this.getPossibleContextTypes(intent).includes(contextType);
34
- }
35
26
  raiseIntentFromPrimaryKey(primaryKeyValue, intent, contextType, appIdentifier) {
36
27
  const rowNode = this.getGridApi().getRowNodeForPrimaryKey(primaryKeyValue);
37
28
  if (!rowNode) {
@@ -69,8 +60,10 @@ class Fdc3ApiImpl extends ApiBase_1.ApiBase {
69
60
  return this.broadcastFromRow(rowNode, contextType);
70
61
  }
71
62
  getContextLabel(contextType) {
72
- var _a, _b;
73
- return (_b = (_a = Fdc3Context_1.ContextConfiguration[contextType]) === null || _a === void 0 ? void 0 : _a.label) !== null && _b !== void 0 ? _b : contextType;
63
+ var _a;
64
+ return this.isStandardContextType(contextType)
65
+ ? (_a = Fdc3Context_1.ContextConfiguration[contextType]) === null || _a === void 0 ? void 0 : _a.label
66
+ : contextType;
74
67
  }
75
68
  isStandardContextType(contextType) {
76
69
  return this.internalApi.isStandardContextType(contextType);
@@ -81,5 +74,36 @@ class Fdc3ApiImpl extends ApiBase_1.ApiBase {
81
74
  getFdc3Service() {
82
75
  return this.getAdaptableApi().internalApi.getFdc3Service();
83
76
  }
77
+ getPossibleContextTypes(intent) {
78
+ this.logWarn('Fdc3Api.getPossibleContextTypes is NO longer relevant as of FDC3 v1.2 and will be removed in a future version');
79
+ return [
80
+ 'fdc3.action',
81
+ 'fdc3.chart',
82
+ 'fdc3.chat.initSettings',
83
+ 'fdc3.chat.message',
84
+ 'fdc3.chat.room',
85
+ 'fdc3.chat.searchCriteria',
86
+ 'fdc3.contact',
87
+ 'fdc3.contactList',
88
+ 'fdc3.country',
89
+ 'fdc3.currency',
90
+ 'fdc3.email',
91
+ 'fdc3.instrument',
92
+ 'fdc3.instrumentList',
93
+ 'fdc3.interaction',
94
+ 'fdc3.message',
95
+ 'fdc3.organization',
96
+ 'fdc3.portfolio',
97
+ 'fdc3.position',
98
+ 'fdc3.nothing',
99
+ 'fdc3.timerange',
100
+ 'fdc3.transactionResult',
101
+ 'fdc3.valuation',
102
+ ];
103
+ }
104
+ isContextCompatibleWithIntent(contextType, intent) {
105
+ this.logWarn('Fdc3Api.isContextCompatibleWithIntent is NO longer relevant as of FDC3 v1.2 and will be removed in a future version');
106
+ return true;
107
+ }
84
108
  }
85
109
  exports.Fdc3ApiImpl = Fdc3ApiImpl;
@@ -77,12 +77,14 @@ export declare class AlertInternalApi extends ApiBase {
77
77
  * Returns a description of an Alert Definition
78
78
  * @param alertDefinition Alert Definition to use
79
79
  */
80
- getAlertDescription(alertDefinition: AlertDefinition, cellDataChangedInfo?: CellDataChangedInfo): string;
80
+ getAlertDescriptionForDataChange(alertDefinition: AlertDefinition, cellDataChangedInfo?: CellDataChangedInfo): string;
81
81
  /**
82
82
  * Returns a description title of an Alert Definition
83
83
  * @param alertDefinition Alert Definition to use
84
84
  */
85
- getAlertMessageHeader(alertDefinition: AlertDefinition, cellDataChangedInfo?: CellDataChangedInfo): string;
85
+ getAlertMessageHeaderForDataChange(alertDefinition: AlertDefinition, cellDataChangedInfo?: CellDataChangedInfo): string;
86
+ getAlertMessageForGridDataChange(alertDefinition: AlertDefinition, gridDataChangedInfo: GridDataChangedInfo): string;
87
+ getAlertHeaderForGridDataChange(alertDefinition: AlertDefinition, gridDataChangedInfo: GridDataChangedInfo): string;
86
88
  /**
87
89
  * Returns custom description for alert using the 'alertMessageText' property
88
90
  *
@@ -143,4 +145,17 @@ export declare class AlertInternalApi extends ApiBase {
143
145
  showAlertsForGridDataChanges(gridDataChangedInfo: GridDataChangedInfo, alertDefinitions: AlertDefinition[]): void;
144
146
  shouldFireAlertOnClient(alertDefinition: AlertDefinition): boolean;
145
147
  getDefaultAlertNotificationForm(): AlertButtonForm;
148
+ /**
149
+ * Supported tokens:
150
+ * - column-that-changed-name -> [column]
151
+ * - rowData.newValue -> [rowData.newValue]
152
+ * - rowData.oldValue -> [rowData.oldValue]
153
+ * - primaryKey -> [primaryKeyValue]
154
+ * - timestamp -> [timestamp]
155
+ * - trigger -> [trigger]
156
+ */
157
+ private annotateAlertText;
158
+ private replaceAll;
159
+ private extractColsFromText;
160
+ private extractContextKeysFromText;
146
161
  }
@@ -219,13 +219,36 @@ class AlertInternalApi extends ApiBase_1.ApiBase {
219
219
  * Returns a description of an Alert Definition
220
220
  * @param alertDefinition Alert Definition to use
221
221
  */
222
- getAlertDescription(alertDefinition, cellDataChangedInfo) {
223
- const customMessage = this.getCustomAlertDescription(alertDefinition, { cellDataChangedInfo });
222
+ getAlertDescriptionForDataChange(alertDefinition, cellDataChangedInfo) {
223
+ let customMessage = this.getCustomAlertDescription(alertDefinition, { cellDataChangedInfo });
224
+ const anotationContext = cellDataChangedInfo
225
+ ? {
226
+ column: cellDataChangedInfo.column,
227
+ rowNode: cellDataChangedInfo.rowNode,
228
+ oldValue: cellDataChangedInfo.oldValue,
229
+ newValue: cellDataChangedInfo.newValue,
230
+ primaryKeyValue: cellDataChangedInfo.primaryKeyValue,
231
+ timestamp: cellDataChangedInfo.changedAt,
232
+ trigger: cellDataChangedInfo.trigger,
233
+ }
234
+ : {};
224
235
  if (customMessage) {
236
+ customMessage = cellDataChangedInfo
237
+ ? this.annotateAlertText(customMessage, anotationContext)
238
+ : customMessage;
225
239
  return customMessage;
226
240
  }
227
241
  if (alertDefinition.MessageText != null) {
228
- return alertDefinition.MessageText;
242
+ let alertText = alertDefinition.MessageText;
243
+ try {
244
+ alertText = cellDataChangedInfo
245
+ ? this.annotateAlertText(alertText, anotationContext)
246
+ : alertText;
247
+ return alertText;
248
+ }
249
+ catch (e) {
250
+ this.logError('Error in getAlertMessageHeader', e);
251
+ }
229
252
  }
230
253
  let scopeDescription = this.getColumnScopeApi().getScopeDescription(alertDefinition.Scope);
231
254
  let ruleDescription = this.getAlertRuleDescription(alertDefinition);
@@ -235,11 +258,75 @@ class AlertInternalApi extends ApiBase_1.ApiBase {
235
258
  * Returns a description title of an Alert Definition
236
259
  * @param alertDefinition Alert Definition to use
237
260
  */
238
- getAlertMessageHeader(alertDefinition, cellDataChangedInfo) {
261
+ getAlertMessageHeaderForDataChange(alertDefinition, cellDataChangedInfo) {
239
262
  var _a, _b;
240
- return ((_a = this.getCustomAlertMessageHeader(alertDefinition, {
263
+ const anotationContext = cellDataChangedInfo
264
+ ? {
265
+ column: cellDataChangedInfo.column,
266
+ rowNode: cellDataChangedInfo.rowNode,
267
+ oldValue: cellDataChangedInfo.oldValue,
268
+ newValue: cellDataChangedInfo.newValue,
269
+ primaryKeyValue: cellDataChangedInfo.primaryKeyValue,
270
+ timestamp: cellDataChangedInfo.changedAt,
271
+ trigger: cellDataChangedInfo.trigger,
272
+ }
273
+ : {};
274
+ let message = (_a = this.getCustomAlertMessageHeader(alertDefinition, {
241
275
  cellDataChangedInfo,
242
- })) !== null && _a !== void 0 ? _a : (_b = cellDataChangedInfo === null || cellDataChangedInfo === void 0 ? void 0 : cellDataChangedInfo.column) === null || _b === void 0 ? void 0 : _b.friendlyName);
276
+ })) !== null && _a !== void 0 ? _a : (_b = cellDataChangedInfo === null || cellDataChangedInfo === void 0 ? void 0 : cellDataChangedInfo.column) === null || _b === void 0 ? void 0 : _b.friendlyName;
277
+ try {
278
+ message = cellDataChangedInfo ? this.annotateAlertText(message, anotationContext) : message;
279
+ }
280
+ catch (e) {
281
+ this.logError('Error in getAlertMessageHeader', e);
282
+ }
283
+ return message;
284
+ }
285
+ getAlertMessageForGridDataChange(alertDefinition, gridDataChangedInfo) {
286
+ const rowAdded = gridDataChangedInfo.rowTrigger === 'Add';
287
+ const numberOfChangedRows = gridDataChangedInfo.rowNodes.length;
288
+ const actionName = rowAdded ? 'Added' : 'Removed';
289
+ const defaultMessage = numberOfChangedRows > 1
290
+ ? `${numberOfChangedRows} rows were ${actionName.toLowerCase()}`
291
+ : `${numberOfChangedRows} row was ${actionName.toLowerCase()}`;
292
+ const customMessage = this.getCustomAlertDescription(alertDefinition, {
293
+ gridDataChangedInfo,
294
+ });
295
+ let alertMessage = alertDefinition.MessageText
296
+ ? alertDefinition.MessageText
297
+ : customMessage !== null && customMessage !== void 0 ? customMessage : defaultMessage;
298
+ try {
299
+ alertMessage = this.annotateAlertText(alertMessage, {
300
+ numberOfRows: numberOfChangedRows,
301
+ timestamp: gridDataChangedInfo.changedAt,
302
+ trigger: gridDataChangedInfo.rowTrigger,
303
+ });
304
+ }
305
+ catch (e) {
306
+ this.logError('Error in getAlertMessageForGridDataChange', e);
307
+ }
308
+ return alertMessage;
309
+ }
310
+ getAlertHeaderForGridDataChange(alertDefinition, gridDataChangedInfo) {
311
+ const rowAdded = gridDataChangedInfo.rowTrigger === 'Add';
312
+ const numberOfChangedRows = gridDataChangedInfo.rowNodes.length;
313
+ const actionName = rowAdded ? 'Added' : 'Removed';
314
+ const customHeader = this.getCustomAlertMessageHeader(alertDefinition, {
315
+ gridDataChangedInfo,
316
+ });
317
+ const alertHeader = numberOfChangedRows > 1 ? `${actionName} Rows` : `${actionName} Row `;
318
+ let header = customHeader !== null && customHeader !== void 0 ? customHeader : alertHeader;
319
+ try {
320
+ header = this.annotateAlertText(header, {
321
+ numberOfRows: numberOfChangedRows,
322
+ timestamp: gridDataChangedInfo.changedAt,
323
+ trigger: gridDataChangedInfo.rowTrigger,
324
+ });
325
+ }
326
+ catch (e) {
327
+ this.logError('Error in getAlertHeaderForGridDataChange', e);
328
+ }
329
+ return header;
243
330
  }
244
331
  /**
245
332
  * Returns custom description for alert using the 'alertMessageText' property
@@ -454,6 +541,7 @@ class AlertInternalApi extends ApiBase_1.ApiBase {
454
541
  }
455
542
  }
456
543
  });
544
+ ``;
457
545
  }
458
546
  return triggeredAlerts;
459
547
  }
@@ -470,7 +558,6 @@ class AlertInternalApi extends ApiBase_1.ApiBase {
470
558
  }
471
559
  isAlertPredicateTriggered(alert, dataChangedEvent, defaultNoPredicateReturn = false) {
472
560
  var _a;
473
- const adapatableApi = this.getAdaptableApi();
474
561
  const predicateDefHandlerContext = Object.assign({ value: dataChangedEvent.newValue, oldValue: dataChangedEvent.oldValue,
475
562
  // TODO send real display value
476
563
  displayValue: null, node: dataChangedEvent.rowNode, column: dataChangedEvent.column }, this.getAdaptableApi().internalApi.buildBaseContext());
@@ -484,7 +571,7 @@ class AlertInternalApi extends ApiBase_1.ApiBase {
484
571
  if ((0, IAlertService_1.isCellDataChangedInfo)(dataChangedInfo)) {
485
572
  alertDefinitions.forEach((alertDefinition) => {
486
573
  if (this.shouldFireAlertOnClient(alertDefinition)) {
487
- const alert = ObjectFactory_1.default.CreateCellChangedAlert(this.getAlertMessageHeader(alertDefinition, dataChangedInfo), this.getAlertDescription(alertDefinition, dataChangedInfo), alertDefinition, dataChangedInfo);
574
+ const alert = ObjectFactory_1.default.CreateCellChangedAlert(this.getAlertMessageHeaderForDataChange(alertDefinition, dataChangedInfo), this.getAlertDescriptionForDataChange(alertDefinition, dataChangedInfo), alertDefinition, dataChangedInfo);
488
575
  this.getAdaptableApi().alertApi.showAdaptableAlert(alert);
489
576
  }
490
577
  });
@@ -494,25 +581,9 @@ class AlertInternalApi extends ApiBase_1.ApiBase {
494
581
  }
495
582
  }
496
583
  showAlertsForGridDataChanges(gridDataChangedInfo, alertDefinitions) {
497
- const rowAdded = gridDataChangedInfo.rowTrigger === 'Add';
498
- const numberOfChangedRows = gridDataChangedInfo.rowNodes.length;
499
- const actionName = rowAdded ? 'Added' : 'Removed';
500
- const alertHeader = numberOfChangedRows > 1 ? `${actionName} Rows` : `${actionName} Row `;
501
- const defaultMessage = numberOfChangedRows > 1
502
- ? `${numberOfChangedRows} rows were ${actionName.toLowerCase()}`
503
- : `${numberOfChangedRows} row was ${actionName.toLowerCase()}`;
504
584
  alertDefinitions === null || alertDefinitions === void 0 ? void 0 : alertDefinitions.forEach((alertDefinition) => {
505
585
  if (this.shouldFireAlertOnClient(alertDefinition)) {
506
- const customMessage = this.getCustomAlertDescription(alertDefinition, {
507
- gridDataChangedInfo,
508
- });
509
- const customHeader = this.getCustomAlertMessageHeader(alertDefinition, {
510
- gridDataChangedInfo,
511
- });
512
- const alertMessage = alertDefinition.MessageText
513
- ? alertDefinition.MessageText
514
- : customMessage !== null && customMessage !== void 0 ? customMessage : defaultMessage;
515
- const alert = ObjectFactory_1.default.CreateRowChangedAlert(customHeader !== null && customHeader !== void 0 ? customHeader : alertHeader, alertMessage, alertDefinition, gridDataChangedInfo);
586
+ const alert = ObjectFactory_1.default.CreateRowChangedAlert(this.getAlertHeaderForGridDataChange(alertDefinition, gridDataChangedInfo), this.getAlertMessageForGridDataChange(alertDefinition, gridDataChangedInfo), alertDefinition, gridDataChangedInfo);
516
587
  this.getAlertApi().showAdaptableAlert(alert);
517
588
  }
518
589
  });
@@ -545,5 +616,105 @@ class AlertInternalApi extends ApiBase_1.ApiBase {
545
616
  ],
546
617
  };
547
618
  }
619
+ /**
620
+ * Supported tokens:
621
+ * - column-that-changed-name -> [column]
622
+ * - rowData.newValue -> [rowData.newValue]
623
+ * - rowData.oldValue -> [rowData.oldValue]
624
+ * - primaryKey -> [primaryKeyValue]
625
+ * - timestamp -> [timestamp]
626
+ * - trigger -> [trigger]
627
+ */
628
+ annotateAlertText(text, context) {
629
+ var _a, _b, _c;
630
+ if (!text) {
631
+ return text;
632
+ }
633
+ if (!context) {
634
+ return text;
635
+ }
636
+ if (context === null || context === void 0 ? void 0 : context.newValue) {
637
+ text = this.replaceAll(text, '[newValue]', context.newValue);
638
+ }
639
+ if (context === null || context === void 0 ? void 0 : context.oldValue) {
640
+ text = this.replaceAll(text, '[oldValue]', context.oldValue);
641
+ }
642
+ if (context === null || context === void 0 ? void 0 : context.primaryKeyValue) {
643
+ text = this.replaceAll(text, '[primaryKeyValue]', context.primaryKeyValue);
644
+ }
645
+ if (context === null || context === void 0 ? void 0 : context.timestamp) {
646
+ text = this.replaceAll(text, '[timestamp]', context.timestamp + '');
647
+ }
648
+ if (context === null || context === void 0 ? void 0 : context.numberOfRows) {
649
+ text = this.replaceAll(text, '[numberOfRows]', context.numberOfRows + '');
650
+ }
651
+ if (context === null || context === void 0 ? void 0 : context.trigger) {
652
+ const dataChangeTriggerMap = {
653
+ edit: 'Edit',
654
+ tick: 'Tick',
655
+ undo: 'Undo',
656
+ aggChange: 'AggChange',
657
+ };
658
+ const rowChangeTriggerMap = {
659
+ Add: 'Added',
660
+ Edit: 'Edited',
661
+ Delete: 'Deleted',
662
+ Load: 'Loaded',
663
+ };
664
+ const mappedTrigger =
665
+ // @ts-ignore
666
+ (_a = (dataChangeTriggerMap[context.trigger] || rowChangeTriggerMap[context.trigger])) !== null && _a !== void 0 ? _a : context.trigger;
667
+ text = this.replaceAll(text, '[trigger]', mappedTrigger);
668
+ }
669
+ if ((context === null || context === void 0 ? void 0 : context.column) && (context === null || context === void 0 ? void 0 : context.rowNode)) {
670
+ text = this.replaceAll(text, '[column]', this.getGridApi().getRawValueFromRowNode(context.rowNode, context.column.columnId));
671
+ }
672
+ if (context === null || context === void 0 ? void 0 : context.rowNode) {
673
+ const columns = this.extractColsFromText(text);
674
+ for (const column of columns) {
675
+ if (this.getColumnApi().getColumnWithColumnId(column)) {
676
+ text = this.replaceAll(text, `[rowData.${column}]`, this.getGridApi().getRawValueFromRowNode(context.rowNode, column));
677
+ }
678
+ }
679
+ }
680
+ if (text.indexOf('[context') !== -1) {
681
+ const agGridContext = (_c = (_b = this.adaptable.agGridAdapter).getGridOption) === null || _c === void 0 ? void 0 : _c.call(_b, 'context');
682
+ const agGridContextKeys = this.extractContextKeysFromText(text);
683
+ for (const key of agGridContextKeys) {
684
+ if (agGridContext[key]) {
685
+ text = this.replaceAll(text, `[context.${key}]`, agGridContext[key]);
686
+ }
687
+ }
688
+ }
689
+ return text;
690
+ }
691
+ replaceAll(text, toReplace, replaceWith) {
692
+ if (!text) {
693
+ return text;
694
+ }
695
+ // fails for []
696
+ toReplace = toReplace.replace('[', '\\[').replace(']', '\\]');
697
+ return text.replace(new RegExp(toReplace, 'g'), replaceWith);
698
+ }
699
+ extractColsFromText(text) {
700
+ // rowData.columnName => columnName
701
+ const regex = /\[rowData\.(.*?)\]/g;
702
+ let m;
703
+ const cols = [];
704
+ while ((m = regex.exec(text)) !== null) {
705
+ cols.push(m[1]);
706
+ }
707
+ return cols;
708
+ }
709
+ extractContextKeysFromText(text) {
710
+ // context.columnName => columnName
711
+ const regex = /\[context\.(.*?)\]/g;
712
+ let m;
713
+ const contextKeys = [];
714
+ while ((m = regex.exec(text)) !== null) {
715
+ contextKeys.push(m[1]);
716
+ }
717
+ return contextKeys;
718
+ }
548
719
  }
549
720
  exports.AlertInternalApi = AlertInternalApi;
@@ -6,6 +6,7 @@ import { ColumnFilter } from '../../PredefinedConfig/Common/ColumnFilter';
6
6
  import { IRowNode } from '@ag-grid-community/core';
7
7
  import { LayoutColumnFilterAction } from '../../Redux/ActionsReducers/LayoutRedux';
8
8
  import * as Redux from 'redux';
9
+ import { ColumnValuesFilterPredicate } from '../../AdaptableOptions/ColumnFilterOptions';
9
10
  export declare class ColumnFilterInternalApi extends ApiBase {
10
11
  /**
11
12
  * Returns Predicate Definition for given Column and Quick Filter shortcut
@@ -58,4 +59,5 @@ export declare class ColumnFilterInternalApi extends ApiBase {
58
59
  areColumnFiltersDifferent(oldFilters: ColumnFilter[], newFilters: ColumnFilter[]): boolean;
59
60
  getPredicateDefShortcuts(predicateDef: AdaptablePredicateDef): string[];
60
61
  getFilterValuesMaxNumberOfItems(column: AdaptableColumn): number | undefined;
62
+ getValuesFitlerPredicateIds(column: AdaptableColumn): ColumnValuesFilterPredicate[];
61
63
  }
@@ -210,5 +210,25 @@ class ColumnFilterInternalApi extends ApiBase_1.ApiBase {
210
210
  return maxFilterValues;
211
211
  }
212
212
  }
213
+ getValuesFitlerPredicateIds(column) {
214
+ var _a;
215
+ const valuesFilterOptions = (_a = this.getOptions().columnFilterOptions) === null || _a === void 0 ? void 0 : _a.valuesFilterOptions;
216
+ const availablePredicates = this.getPredicateApi().getPredicateDefsByModuleScope('columnFilter');
217
+ let predicateIds = [];
218
+ if (typeof (valuesFilterOptions === null || valuesFilterOptions === void 0 ? void 0 : valuesFilterOptions.predicates) === 'function') {
219
+ const columnFilterContext = Object.assign(Object.assign({}, this.getAdaptableApi().internalApi.buildBaseContext()), { column: column });
220
+ predicateIds = valuesFilterOptions.predicates(columnFilterContext);
221
+ }
222
+ else if (Array.isArray(valuesFilterOptions === null || valuesFilterOptions === void 0 ? void 0 : valuesFilterOptions.predicates)) {
223
+ predicateIds = valuesFilterOptions.predicates;
224
+ }
225
+ return predicateIds.filter((predicateId) => {
226
+ const predicate = availablePredicates.find((p) => p.id === predicateId);
227
+ if (!predicate) {
228
+ return false;
229
+ }
230
+ return this.getColumnScopeApi().isColumnInScope(column, predicate.columnScope);
231
+ });
232
+ }
213
233
  }
214
234
  exports.ColumnFilterInternalApi = ColumnFilterInternalApi;