@prismatic-io/spectral 8.0.0 → 8.0.2

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.
@@ -1,10 +1,5 @@
1
- import { Inputs, DataSourceResult, DataSourceType, ActionInputParameters, ActionLogger, CustomerAttributes, InstanceAttributes, UserAttributes } from ".";
1
+ import { Inputs, DataSourceResult, DataSourceType, ActionInputParameters, ConfigVarResultCollection, ActionContext } from ".";
2
2
  /** Context provided to perform method containing helpers and contextual data */
3
- export interface DataSourceContext {
4
- logger: ActionLogger;
5
- customer: CustomerAttributes;
6
- instance: InstanceAttributes;
7
- user: UserAttributes;
8
- }
3
+ export declare type DataSourceContext<TConfigVars extends ConfigVarResultCollection> = Pick<ActionContext<TConfigVars>, "logger" | "customer" | "instance" | "user" | "configVars">;
9
4
  /** Definition of the function to perform when a Data Source is invoked. */
10
- export declare type DataSourcePerformFunction<TInputs extends Inputs, TDataSourceType extends DataSourceType> = (context: DataSourceContext, params: ActionInputParameters<TInputs>) => Promise<DataSourceResult<TDataSourceType>>;
5
+ export declare type DataSourcePerformFunction<TInputs extends Inputs, TConfigVars extends ConfigVarResultCollection, TDataSourceType extends DataSourceType> = (context: DataSourceContext<TConfigVars>, params: ActionInputParameters<TInputs>) => Promise<DataSourceResult<TDataSourceType>>;
@@ -1,4 +1,4 @@
1
- import { ObjectSelection, ObjectFieldMap, JSONForm, Element, Connection } from "./Inputs";
1
+ import { ObjectSelection, ObjectFieldMap, JSONForm, Element } from "./Inputs";
2
2
  /** The type of field that is appropriate for rendering the data that is the result of the data source perform function. */
3
3
  declare type DataSourceTypeMap = {
4
4
  string: string;
@@ -9,10 +9,8 @@ declare type DataSourceTypeMap = {
9
9
  value: string;
10
10
  };
11
11
  code: string;
12
- credential: unknown;
13
12
  boolean: boolean;
14
13
  number: number;
15
- connection: Connection;
16
14
  objectSelection: ObjectSelection;
17
15
  objectFieldMap: ObjectFieldMap;
18
16
  jsonForm: JSONForm;
@@ -35,6 +35,11 @@ export declare type ObjectFieldMap = {
35
35
  fields: Element[];
36
36
  }[];
37
37
  };
38
+ export declare type Schedule = {
39
+ value: string;
40
+ schedule_type: string;
41
+ time_zone: string;
42
+ };
38
43
  export declare type JSONForm = {
39
44
  /**
40
45
  * The data/JSON schema defines the underlying data to
@@ -248,5 +253,5 @@ export interface InputFieldChoice {
248
253
  /** InputField collection enumeration */
249
254
  export declare type InputFieldCollection = "valuelist" | "keyvaluelist";
250
255
  /** Config variable result collection */
251
- export declare type ConfigVarResultCollection = Record<string, string | Connection | JSONForm | ObjectSelection>;
256
+ export declare type ConfigVarResultCollection = Record<string, string | Schedule | Connection | JSONForm | ObjectSelection | ObjectFieldMap>;
252
257
  export {};
@@ -1,10 +1,14 @@
1
- import { DataSourceDefinition, ConnectionDefinition, ActionPerformFunction, ActionPerformReturn, TriggerEventFunction, TriggerPerformFunction, Inputs, TriggerResult, DataSourceType, Connection as ConnectionResult, TriggerPayload } from ".";
2
- export declare type ConfigVarCollection = Record<string, ConfigVar>;
3
- export declare type ConfigVarDefinitionsToResults<TConfigVars extends ConfigVarCollection> = {
4
- [Key in keyof TConfigVars]: TConfigVars[Key]["inputs"] extends Record<string, any> ? ConnectionResult : string;
5
- };
1
+ import { DataSourceDefinition, ConnectionDefinition, ActionPerformFunction, ActionPerformReturn, TriggerEventFunction, TriggerPerformFunction, Inputs, TriggerResult, DataSourceType, TriggerPayload, Connection, JSONForm, ObjectFieldMap, ObjectSelection, ConfigVarResultCollection, Schedule } from ".";
2
+ import { Prettify, UnionToIntersection, ValueOf } from "./utils";
3
+ declare type ToDataSourceRuntimeType<TType extends DataSourceType> = TType extends "jsonForm" ? JSONForm : TType extends "objectSelection" ? ObjectSelection : TType extends "objectFieldMap" ? ObjectFieldMap : string;
4
+ declare type ToRuntimeType<TType extends ConfigVarDataType> = TType extends ConfigVarDataType.Schedule ? Schedule : string;
5
+ export declare type ElementToRuntimeType<TElement extends ConfigPageElement> = TElement extends ConnectionConfigVar ? Connection : TElement extends DataSourceConfigVar ? ToDataSourceRuntimeType<TElement["dataSourceType"]> : TElement extends StandardConfigVar ? ToRuntimeType<TElement["dataType"]> : never;
6
+ declare type GetElements<TConfigPages extends ConfigPages> = TConfigPages extends ConfigPages ? UnionToIntersection<ValueOf<TConfigPages>["elements"]> : never;
7
+ export declare type ExtractConfigVars<TConfigPages extends ConfigPages, TElements extends ConfigPage["elements"] = GetElements<TConfigPages>> = Prettify<{
8
+ [Key in keyof TElements]: ElementToRuntimeType<TElements[Key]>;
9
+ }>;
6
10
  /** Defines attributes of a Code-Native Integration. */
7
- export declare type IntegrationDefinition<TConfigVars extends ConfigVarCollection = ConfigVarCollection> = {
11
+ export declare type IntegrationDefinition<TConfigPages extends ConfigPages> = {
8
12
  /** The unique name for this Integration. */
9
13
  name: string;
10
14
  /** Optional description for this Integration. */
@@ -27,16 +31,12 @@ export declare type IntegrationDefinition<TConfigVars extends ConfigVarCollectio
27
31
  * Cannot specify this if a Preprocess Flow is also configured. */
28
32
  triggerPreprocessFlowConfig?: PreprocessFlowConfig;
29
33
  /** Flows for this Integration. */
30
- flows: Flow<TConfigVars>[];
31
- /** Config Vars used on this Integration. */
32
- configVars?: TConfigVars;
34
+ flows: Flow<TConfigPages>[];
33
35
  /** Config Wizard Pages for this Integration. */
34
- configPages?: ConfigPage<TConfigVars>[];
35
- /** Specifies any Data Sources that are defined as part of this Integration. */
36
- dataSources?: Record<string, CodeNativeDataSource>;
36
+ configPages?: TConfigPages;
37
37
  };
38
38
  /** Defines attributes of a Flow of a Code-Native Integration. */
39
- export interface Flow<TConfigVars extends ConfigVarCollection = ConfigVarCollection, TTriggerPayload extends TriggerPayload = TriggerPayload> {
39
+ export interface Flow<TConfigPages extends ConfigPages, TTriggerPayload extends TriggerPayload = TriggerPayload> {
40
40
  /** The unique name for this Flow. */
41
41
  name: string;
42
42
  /** A unique, unchanging value that is used to maintain identity for the Flow even if the name changes. */
@@ -58,11 +58,11 @@ export interface Flow<TConfigVars extends ConfigVarCollection = ConfigVarCollect
58
58
  /** Optional error handling configuration. */
59
59
  errorConfig?: StepErrorConfig;
60
60
  /** Specifies the trigger function for this Flow, which returns a payload and optional HTTP response. */
61
- onTrigger: TriggerPerformFunction<Inputs, ConfigVarDefinitionsToResults<TConfigVars>, true, false, TriggerResult<false, TTriggerPayload>>;
61
+ onTrigger: TriggerPerformFunction<Inputs, ExtractConfigVars<TConfigPages>, false, TriggerResult<false, TTriggerPayload>>;
62
62
  /** Specifies the function to execute when an Instance of this Integration is deployed. */
63
- onInstanceDeploy?: TriggerEventFunction<Inputs, ConfigVarDefinitionsToResults<TConfigVars>, true>;
63
+ onInstanceDeploy?: TriggerEventFunction<Inputs, ExtractConfigVars<TConfigPages>>;
64
64
  /** Specifies the function to execute when an Instance of an Integration is deleted. */
65
- onInstanceDelete?: TriggerEventFunction<Inputs, ConfigVarDefinitionsToResults<TConfigVars>, true>;
65
+ onInstanceDelete?: TriggerEventFunction<Inputs, ExtractConfigVars<TConfigPages>>;
66
66
  /** Specifies the main function for this Flow */
67
67
  onExecution: ActionPerformFunction<{
68
68
  onTrigger: {
@@ -72,22 +72,16 @@ export interface Flow<TConfigVars extends ConfigVarCollection = ConfigVarCollect
72
72
  results: TTriggerPayload;
73
73
  };
74
74
  };
75
- }, ConfigVarDefinitionsToResults<TConfigVars>, true, false, ActionPerformReturn<false, unknown>>;
75
+ }, ExtractConfigVars<TConfigPages>, false, ActionPerformReturn<false, unknown>>;
76
76
  }
77
- /** Defines attributes of a Data Source that is defined as part of a Code Native Integration. */
78
- export declare type CodeNativeDataSource = Pick<DataSourceDefinition<Inputs, DataSourceType>, "display" | "perform" | "dataSourceType" | "detailDataSource">;
79
77
  /** Common attribute shared by all types of Config Vars. */
80
78
  declare type BaseConfigVar = {
81
- /** The unique key for this Config Var. */
82
- key: string;
83
79
  /** A unique, unchanging value that is used to maintain identity for the Config Var even if the key changes. */
84
80
  stableKey: string;
85
81
  /** Optional description for this Config Var. */
86
82
  description?: string;
87
83
  /** Optional value that specifies whether this Config Var is only configurable by Organization users. @default false */
88
84
  orgOnly?: boolean;
89
- /** Optional input values for this Config Var. */
90
- inputs?: InputValues;
91
85
  /** Optional value that specifies whether this Config Var is visible to an Organization deployer. @default true */
92
86
  visibleToOrgDeployer?: boolean;
93
87
  /** Optional value that specifies whether this Config Var is visible to a Customer deployer. @default true */
@@ -95,10 +89,10 @@ declare type BaseConfigVar = {
95
89
  };
96
90
  /** Defines attributes of a standard Config Var. */
97
91
  export declare type StandardConfigVar = BaseConfigVar & {
98
- /** Optional default value for the Config Var. */
99
- defaultValue?: string;
100
92
  /** The data type of the Config Var. */
101
93
  dataType: ConfigVarDataType;
94
+ /** Optional default value for the Config Var. */
95
+ defaultValue?: string;
102
96
  /** Optional list of picklist values if the Config Var is a multi-choice selection value. */
103
97
  pickList?: string[];
104
98
  /** Optional schedule type that defines the cadence of the schedule. */
@@ -109,55 +103,22 @@ export declare type StandardConfigVar = BaseConfigVar & {
109
103
  codeLanguage?: CodeLanguageType;
110
104
  /** Optional value to specify the type of collection if the Config Var is multi-value. */
111
105
  collectionType?: CollectionType;
112
- /** Optional value to specify the key of a Data Source defined in this CNI
113
- * where the Config Var sources its values. */
114
- dataSource?: string;
115
106
  };
107
+ /** Defines attributes of a data source Config Var. */
108
+ export declare type DataSourceConfigVar = BaseConfigVar & Omit<DataSourceDefinition<Inputs, ConfigVarResultCollection, DataSourceType>, "display" | "inputs" | "examplePayload">;
116
109
  /** Defines attributes of a Config Var that represents a Connection. */
117
- export declare type ConnectionConfigVar = Omit<BaseConfigVar, "description" | "inputs"> & ConnectionDefinition;
118
- export declare type ConfigVar = StandardConfigVar | ConnectionConfigVar;
110
+ export declare type ConnectionConfigVar = BaseConfigVar & Omit<ConnectionDefinition, "label" | "comments" | "key">;
111
+ export declare type ConfigVar = StandardConfigVar | DataSourceConfigVar | ConnectionConfigVar;
112
+ export declare const isDataSourceConfigVar: (cv: ConfigVar) => cv is DataSourceConfigVar;
113
+ export declare const isConnectionConfigVar: (cv: ConfigVar) => cv is ConnectionConfigVar;
114
+ export declare type ConfigPageElement = string | ConfigVar;
115
+ export declare type ConfigPages = Record<string, ConfigPage>;
119
116
  /** Defines attributes of a Config Wizard Page used when deploying an Instance of an Integration. */
120
- export declare type ConfigPage<TConfigVars extends ConfigVarCollection = ConfigVarCollection> = {
121
- /** The unique name for this Config Page. */
122
- name: string;
117
+ export declare type ConfigPage = {
118
+ /** Elements included on this Config Page. */
119
+ elements: Record<string, ConfigPageElement>;
123
120
  /** Specifies an optional tagline for this Config Page. */
124
121
  tagline?: string;
125
- /** Optional value that specifies whether this Config Page is configured as
126
- * part of User Level Configuration. @default false */
127
- userLevelConfigured?: boolean;
128
- /** Elements included on this Config Page. */
129
- elements: ConfigPageElement<TConfigVars>[];
130
- };
131
- /** Defines attributes of Inputs for Connections, Actions, Triggers,
132
- * Data Sources, and Config Vars. */
133
- export declare type InputValues = Record<string, InputValue>;
134
- export declare type InputValue = SimpleInputValue | ComplexInputValue;
135
- export declare type SimpleInputValue = {
136
- name?: string;
137
- type: SimpleInputValueType;
138
- value: string;
139
- meta?: Record<string, unknown>;
140
- };
141
- export declare type ComplexInputValue = {
142
- name?: string;
143
- type: "complex";
144
- value: ComplexInputValueType;
145
- meta?: Record<string, unknown>;
146
- };
147
- export declare type ComplexInputValueType = (string | InputValue | ComplexInputValueType)[];
148
- /** Defines attributes of an Element that appears on a Config Wizard Page. */
149
- export declare type ConfigPageElement<TConfigVars extends ConfigVarCollection = ConfigVarCollection> = HTMLConfigPageElement | JSONFormConfigPageElement | ConfigVarPageElement<TConfigVars>;
150
- declare type HTMLConfigPageElement = {
151
- type: ConfigPageElementType.HTML;
152
- value: string;
153
- };
154
- declare type JSONFormConfigPageElement = {
155
- type: ConfigPageElementType.JSONForm;
156
- value: string;
157
- };
158
- declare type ConfigVarPageElement<TConfigVars extends ConfigVarCollection = ConfigVarCollection> = {
159
- type: ConfigPageElementType.ConfigVar;
160
- value: keyof TConfigVars;
161
122
  };
162
123
  /** Defines attributes of a Preprocess Flow Configuration used by a Flow of an Integration. */
163
124
  export declare type PreprocessFlowConfig = {
@@ -204,13 +165,6 @@ export declare type FlowSchedule = {
204
165
  /** Specifies an optional value to use as the timezone. */
205
166
  timeZone?: string;
206
167
  };
207
- /** Choices of Simple Input Value Types that may be used by Simple Input Values. */
208
- export declare enum SimpleInputValueType {
209
- Value = "value",
210
- Reference = "reference",
211
- ConfigVar = "configVar",
212
- Template = "template"
213
- }
214
168
  /** Choices of Endpoint Types that may be used by Instances of an Integration. */
215
169
  export declare enum EndpointType {
216
170
  FlowSpecific = "flow_specific",
@@ -224,12 +178,6 @@ export declare enum EndpointSecurityType {
224
178
  CustomerRequired = "customer_required",
225
179
  Organization = "organization"
226
180
  }
227
- /** Choices of Config Page Element Types that may be used for Elements on a Config Wizard Page. */
228
- export declare enum ConfigPageElementType {
229
- ConfigVar = "configVar",
230
- HTML = "htmlElement",
231
- JSONForm = "jsonForm"
232
- }
233
181
  /** Choices of Step Error Handlers that define the behavior when a step error occurs. */
234
182
  export declare enum StepErrorHandlerType {
235
183
  Fail = "fail",
@@ -254,10 +202,7 @@ export declare enum ConfigVarDataType {
254
202
  Schedule = "schedule",
255
203
  Code = "code",
256
204
  Boolean = "boolean",
257
- Number = "number",
258
- ObjectSelection = "objectSelection",
259
- ObjectFieldMap = "objectFieldMap",
260
- JSONForm = "jsonForm"
205
+ Number = "number"
261
206
  }
262
207
  /** Choices of programming languages that may be used for Config Var code values. */
263
208
  export declare enum CodeLanguageType {
@@ -1,14 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CollectionType = exports.CodeLanguageType = exports.ConfigVarDataType = exports.ScheduleType = exports.StepErrorHandlerType = exports.ConfigPageElementType = exports.EndpointSecurityType = exports.EndpointType = exports.SimpleInputValueType = void 0;
4
- /** Choices of Simple Input Value Types that may be used by Simple Input Values. */
5
- var SimpleInputValueType;
6
- (function (SimpleInputValueType) {
7
- SimpleInputValueType["Value"] = "value";
8
- SimpleInputValueType["Reference"] = "reference";
9
- SimpleInputValueType["ConfigVar"] = "configVar";
10
- SimpleInputValueType["Template"] = "template";
11
- })(SimpleInputValueType = exports.SimpleInputValueType || (exports.SimpleInputValueType = {}));
3
+ exports.CollectionType = exports.CodeLanguageType = exports.ConfigVarDataType = exports.ScheduleType = exports.StepErrorHandlerType = exports.EndpointSecurityType = exports.EndpointType = exports.isConnectionConfigVar = exports.isDataSourceConfigVar = void 0;
4
+ const isDataSourceConfigVar = (cv) => "dataSourceType" in cv;
5
+ exports.isDataSourceConfigVar = isDataSourceConfigVar;
6
+ const isConnectionConfigVar = (cv) => "inputs" in cv;
7
+ exports.isConnectionConfigVar = isConnectionConfigVar;
12
8
  /** Choices of Endpoint Types that may be used by Instances of an Integration. */
13
9
  var EndpointType;
14
10
  (function (EndpointType) {
@@ -24,13 +20,6 @@ var EndpointSecurityType;
24
20
  EndpointSecurityType["CustomerRequired"] = "customer_required";
25
21
  EndpointSecurityType["Organization"] = "organization";
26
22
  })(EndpointSecurityType = exports.EndpointSecurityType || (exports.EndpointSecurityType = {}));
27
- /** Choices of Config Page Element Types that may be used for Elements on a Config Wizard Page. */
28
- var ConfigPageElementType;
29
- (function (ConfigPageElementType) {
30
- ConfigPageElementType["ConfigVar"] = "configVar";
31
- ConfigPageElementType["HTML"] = "htmlElement";
32
- ConfigPageElementType["JSONForm"] = "jsonForm";
33
- })(ConfigPageElementType = exports.ConfigPageElementType || (exports.ConfigPageElementType = {}));
34
23
  /** Choices of Step Error Handlers that define the behavior when a step error occurs. */
35
24
  var StepErrorHandlerType;
36
25
  (function (StepErrorHandlerType) {
@@ -59,9 +48,6 @@ var ConfigVarDataType;
59
48
  ConfigVarDataType["Code"] = "code";
60
49
  ConfigVarDataType["Boolean"] = "boolean";
61
50
  ConfigVarDataType["Number"] = "number";
62
- ConfigVarDataType["ObjectSelection"] = "objectSelection";
63
- ConfigVarDataType["ObjectFieldMap"] = "objectFieldMap";
64
- ConfigVarDataType["JSONForm"] = "jsonForm";
65
51
  })(ConfigVarDataType = exports.ConfigVarDataType || (exports.ConfigVarDataType = {}));
66
52
  /** Choices of programming languages that may be used for Config Var code values. */
67
53
  var CodeLanguageType;
@@ -10,11 +10,11 @@ export interface TriggerDefinition<TInputs extends Inputs, TConfigVars extends C
10
10
  /** Defines how the Trigger is displayed in the Prismatic interface. */
11
11
  display: ActionDisplayDefinition;
12
12
  /** Function to perform when this Trigger is invoked. */
13
- perform: TriggerPerformFunction<TInputs, TConfigVars, false, TAllowsBranching, TResult>;
13
+ perform: TriggerPerformFunction<TInputs, TConfigVars, TAllowsBranching, TResult>;
14
14
  /** Function to execute when an Instance of an Integration with a Flow that uses this Trigger is deployed. */
15
- onInstanceDeploy?: TriggerEventFunction<TInputs, TConfigVars, false>;
15
+ onInstanceDeploy?: TriggerEventFunction<TInputs, TConfigVars>;
16
16
  /** Function to execute when an Instance of an Integration with a Flow that uses this Trigger is deleted. */
17
- onInstanceDelete?: TriggerEventFunction<TInputs, TConfigVars, false>;
17
+ onInstanceDelete?: TriggerEventFunction<TInputs, TConfigVars>;
18
18
  /** InputFields to present in the Prismatic interface for configuration of this Trigger. */
19
19
  inputs: TInputs;
20
20
  /** Specifies whether this Trigger supports executing the Integration on a recurring schedule. */
@@ -10,4 +10,4 @@ export declare type TriggerEventFunctionReturn = {
10
10
  integrationState?: Record<string, unknown>;
11
11
  };
12
12
  /** Definition of the function to execute when a Trigger Event occurs. */
13
- export declare type TriggerEventFunction<TInputs extends Inputs, TConfigVars extends ConfigVarResultCollection, THasConfigVars extends boolean> = (context: ActionContext<TConfigVars, THasConfigVars>, params: ActionInputParameters<TInputs>) => Promise<void | TriggerEventFunctionReturn>;
13
+ export declare type TriggerEventFunction<TInputs extends Inputs, TConfigVars extends ConfigVarResultCollection> = (context: ActionContext<TConfigVars>, params: ActionInputParameters<TInputs>) => Promise<void | TriggerEventFunctionReturn>;
@@ -1,3 +1,3 @@
1
1
  import { Inputs, TriggerResult, ActionInputParameters, ActionContext, TriggerPayload, ConfigVarResultCollection } from ".";
2
2
  /** Definition of the function to perform when a Trigger is invoked. */
3
- export declare type TriggerPerformFunction<TInputs extends Inputs, TConfigVars extends ConfigVarResultCollection, THasConfigVars extends boolean, TAllowsBranching extends boolean | undefined, TResult extends TriggerResult<TAllowsBranching, TriggerPayload>> = (context: ActionContext<TConfigVars, THasConfigVars>, payload: TriggerPayload, params: ActionInputParameters<TInputs>) => Promise<TResult>;
3
+ export declare type TriggerPerformFunction<TInputs extends Inputs, TConfigVars extends ConfigVarResultCollection, TAllowsBranching extends boolean | undefined, TResult extends TriggerResult<TAllowsBranching, TriggerPayload>> = (context: ActionContext<TConfigVars>, payload: TriggerPayload, params: ActionInputParameters<TInputs>) => Promise<TResult>;
@@ -0,0 +1,5 @@
1
+ export declare type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
2
+ export declare type Prettify<T> = {
3
+ [K in keyof T]: T[K];
4
+ };
5
+ export declare type ValueOf<T> = T[keyof T];
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prismatic-io/spectral",
3
- "version": "8.0.0",
3
+ "version": "8.0.2",
4
4
  "description": "Utility library for building Prismatic components",
5
5
  "keywords": [
6
6
  "prismatic"
@@ -43,6 +43,7 @@
43
43
  "date-fns": "2.30.0",
44
44
  "form-data": "4.0.0",
45
45
  "jest-mock": "27.0.3",
46
+ "lodash": "4.17.21",
46
47
  "safe-stable-stringify": "2.3.1",
47
48
  "serialize-error": "8.1.0",
48
49
  "url-join": "5.0.0",
@@ -52,6 +53,7 @@
52
53
  },
53
54
  "devDependencies": {
54
55
  "@types/jest": "27.4.1",
56
+ "@types/lodash": "4.14.202",
55
57
  "@types/node": "14.14.35",
56
58
  "@types/sax": "1.2.4",
57
59
  "@types/url-join": "4.0.1",