monday-sdk-js 0.4.12 → 0.5.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/package.json +2 -1
- package/types/client-context.type.ts +238 -0
- package/types/client-data.interface.ts +132 -113
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "monday-sdk-js",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"repository": "https://github.com/mondaycom/monday-sdk-js",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"node-fetch": "^2.6.0"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
|
+
"monday-ui-react-core": "^2.63.2",
|
|
22
23
|
"@babel/cli": "^7.6.0",
|
|
23
24
|
"@babel/core": "^7.6.0",
|
|
24
25
|
"@babel/node": "^7.6.1",
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import type { Theme } from "monday-ui-react-core/dist/types/components/ThemeProvider/ThemeProviderConstants";
|
|
2
|
+
|
|
3
|
+
type User = {
|
|
4
|
+
id: string;
|
|
5
|
+
isAdmin: boolean;
|
|
6
|
+
isGuest: boolean;
|
|
7
|
+
isViewOnly: boolean;
|
|
8
|
+
countryCode: string;
|
|
9
|
+
currentLanguage: string;
|
|
10
|
+
timeFormat: string;
|
|
11
|
+
timeZoneOffset: number;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
type Account = {
|
|
15
|
+
id: string;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
type App = {
|
|
19
|
+
id: number;
|
|
20
|
+
clientId: string;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
type AppVersion = {
|
|
24
|
+
id: number;
|
|
25
|
+
name: string;
|
|
26
|
+
status: string;
|
|
27
|
+
type: string;
|
|
28
|
+
versionData: {
|
|
29
|
+
major: number;
|
|
30
|
+
minor: number;
|
|
31
|
+
patch: number;
|
|
32
|
+
type: string;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export type BaseContext = {
|
|
37
|
+
themeConfig?: Theme;
|
|
38
|
+
theme: string;
|
|
39
|
+
account: Account;
|
|
40
|
+
user: User;
|
|
41
|
+
region: string;
|
|
42
|
+
app: App;
|
|
43
|
+
appVersion: AppVersion;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export type AppFeatureBoardViewContext = BaseContext & {
|
|
47
|
+
boardId: number;
|
|
48
|
+
boardIds: number[];
|
|
49
|
+
boardViewId: number;
|
|
50
|
+
viewMode: string;
|
|
51
|
+
instanceId: number;
|
|
52
|
+
instanceType: string;
|
|
53
|
+
workspaceId: number;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export type AppFeatureAiBoardMainMenuHeaderContext = BaseContext & {
|
|
57
|
+
location: string;
|
|
58
|
+
locationContext: {
|
|
59
|
+
boardId: number;
|
|
60
|
+
workspaceId: number;
|
|
61
|
+
};
|
|
62
|
+
appFeatureId: number;
|
|
63
|
+
withExternalWidth: boolean;
|
|
64
|
+
withHeaderPadding: boolean;
|
|
65
|
+
boardId: number;
|
|
66
|
+
workspaceId: number;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export type AppFeatureDashboardWidgetContext = BaseContext & {
|
|
70
|
+
boardIds: number[];
|
|
71
|
+
widgetId: number;
|
|
72
|
+
viewMode: string;
|
|
73
|
+
editMode: boolean;
|
|
74
|
+
instanceId: number;
|
|
75
|
+
instanceType: string;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export type AppFeatureItemMenuActionContext = BaseContext & {
|
|
79
|
+
boardId: number;
|
|
80
|
+
pulseId: number;
|
|
81
|
+
itemId: number;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
export type AppFeatureItemBatchActionContext = BaseContext & {
|
|
85
|
+
boardId: number;
|
|
86
|
+
itemId: number;
|
|
87
|
+
selectedPulsesIds: number[];
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export type AppFeatureGroupMenuActionContext = BaseContext & {
|
|
91
|
+
groupId: string;
|
|
92
|
+
boardId: number;
|
|
93
|
+
groupColor: string;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
export type AppFeatureObjectContext = BaseContext & {
|
|
97
|
+
boardId: number;
|
|
98
|
+
boardIds: [number];
|
|
99
|
+
workspaceId: number;
|
|
100
|
+
appFeatureId: number;
|
|
101
|
+
instanceId: number;
|
|
102
|
+
instanceType: string;
|
|
103
|
+
isFullScreen: boolean;
|
|
104
|
+
isPresentingMode: boolean;
|
|
105
|
+
objectPermissions: string;
|
|
106
|
+
isFirstLevelControlPinned: boolean;
|
|
107
|
+
isSlidePanelOpen: boolean;
|
|
108
|
+
boardLoadingState: number;
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
export type AppFeatureWorkspaceViewContext = BaseContext & {
|
|
112
|
+
workspaceId: number;
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
export type AppFeatureItemViewContext = BaseContext & {
|
|
116
|
+
workspaceId: number;
|
|
117
|
+
boardId: number;
|
|
118
|
+
boardIds: [number];
|
|
119
|
+
itemId: number;
|
|
120
|
+
instanceId: number;
|
|
121
|
+
instanceType: string;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
export type AppFeatureAiDocQuickStartType = BaseContext & {
|
|
125
|
+
location: string;
|
|
126
|
+
locationContext: {
|
|
127
|
+
docId: number;
|
|
128
|
+
objectId: number;
|
|
129
|
+
workspaceId: number;
|
|
130
|
+
additionalSdkMethodsList: string[];
|
|
131
|
+
};
|
|
132
|
+
appFeatureId: number;
|
|
133
|
+
withExternalWidth: boolean;
|
|
134
|
+
withHeaderPadding: boolean;
|
|
135
|
+
docId: number;
|
|
136
|
+
objectId: number;
|
|
137
|
+
workspaceId: number;
|
|
138
|
+
additionalSdkMethodsList: string[];
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
export type AppFeatureAiDocTopBarContext = BaseContext & {
|
|
142
|
+
location: string;
|
|
143
|
+
locationContext: {
|
|
144
|
+
input: string;
|
|
145
|
+
docId: number;
|
|
146
|
+
objectId: number;
|
|
147
|
+
workspaceId: number;
|
|
148
|
+
additionalSdkMethodsList: string[];
|
|
149
|
+
};
|
|
150
|
+
appFeatureId: number;
|
|
151
|
+
withExternalWidth: boolean;
|
|
152
|
+
withHeaderPadding: boolean;
|
|
153
|
+
input: string;
|
|
154
|
+
docId: number;
|
|
155
|
+
objectId: number;
|
|
156
|
+
workspaceId: number;
|
|
157
|
+
additionalSdkMethodsList: string[];
|
|
158
|
+
};
|
|
159
|
+
export type FocusedBlock = {
|
|
160
|
+
id: string;
|
|
161
|
+
createdUserId: number;
|
|
162
|
+
accountId: number;
|
|
163
|
+
docId: number;
|
|
164
|
+
type: string;
|
|
165
|
+
content: {
|
|
166
|
+
alignment: string;
|
|
167
|
+
direction: string;
|
|
168
|
+
deltaFormat: Array<{
|
|
169
|
+
insert: string;
|
|
170
|
+
}>;
|
|
171
|
+
base64Encoded: string;
|
|
172
|
+
};
|
|
173
|
+
position: number;
|
|
174
|
+
parentBlockId: string | null;
|
|
175
|
+
createdAt: string;
|
|
176
|
+
updatedAt: string;
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
export type AppFeatureAiDocSlashCommandContext = BaseContext & {
|
|
180
|
+
location: string;
|
|
181
|
+
locationContext: {
|
|
182
|
+
focusedBlocks: FocusedBlock[];
|
|
183
|
+
canMoveToNextSelectedTextualBlock: boolean;
|
|
184
|
+
canMoveToPrevSelectedTextualBlock: boolean;
|
|
185
|
+
input: string;
|
|
186
|
+
isTextSelectedInBlock: boolean;
|
|
187
|
+
docId: number;
|
|
188
|
+
objectId: number;
|
|
189
|
+
workspaceId: number;
|
|
190
|
+
additionalSdkMethodsList: string[];
|
|
191
|
+
};
|
|
192
|
+
appFeatureId: number;
|
|
193
|
+
withExternalWidth: boolean;
|
|
194
|
+
withHeaderPadding: boolean;
|
|
195
|
+
focusedBlocks: FocusedBlock[];
|
|
196
|
+
canMoveToNextSelectedTextualBlock: boolean;
|
|
197
|
+
canMoveToPrevSelectedTextualBlock: boolean;
|
|
198
|
+
input: string;
|
|
199
|
+
isTextSelectedInBlock: boolean;
|
|
200
|
+
docId: number;
|
|
201
|
+
objectId: number;
|
|
202
|
+
workspaceId: number;
|
|
203
|
+
additionalSdkMethodsList: string[];
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
export type AppFeatureDocActionsContext = BaseContext & {
|
|
207
|
+
themeConfig: Theme;
|
|
208
|
+
docId: number;
|
|
209
|
+
objectId: number;
|
|
210
|
+
workspaceId: number;
|
|
211
|
+
focusedBlocks: FocusedBlock[];
|
|
212
|
+
placement: string;
|
|
213
|
+
highlightedText: string;
|
|
214
|
+
range: {
|
|
215
|
+
index: number;
|
|
216
|
+
length: number;
|
|
217
|
+
};
|
|
218
|
+
blockId: string;
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
export type AppFeatureContextMap = {
|
|
222
|
+
Base: BaseContext;
|
|
223
|
+
AppFeatureBoardView: AppFeatureBoardViewContext;
|
|
224
|
+
AppFeatureAiBoardMainMenuHeader: AppFeatureAiBoardMainMenuHeaderContext;
|
|
225
|
+
AppFeatureDashboardWidget: AppFeatureDashboardWidgetContext;
|
|
226
|
+
AppFeatureItemMenuAction: AppFeatureItemMenuActionContext;
|
|
227
|
+
AppFeatureItemBatchAction: AppFeatureItemBatchActionContext;
|
|
228
|
+
AppFeatureGroupMenuAction: AppFeatureGroupMenuActionContext;
|
|
229
|
+
AppFeatureObject: AppFeatureObjectContext;
|
|
230
|
+
AppFeatureWorkspaceView: AppFeatureWorkspaceViewContext;
|
|
231
|
+
AppFeatureItemView: AppFeatureItemViewContext;
|
|
232
|
+
AppFeatureAiDocQuickStart: AppFeatureAiDocQuickStartType;
|
|
233
|
+
AppFeatureAiDocTopBar: AppFeatureAiDocTopBarContext;
|
|
234
|
+
AppFeatureAiDocSlashCommand: AppFeatureAiDocSlashCommandContext;
|
|
235
|
+
AppFeatureDocActions: AppFeatureDocActionsContext;
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
export type AppFeatureTypes = keyof AppFeatureContextMap;
|
|
@@ -1,136 +1,155 @@
|
|
|
1
|
-
|
|
1
|
+
import { AppFeatureContextMap, AppFeatureTypes } from "./client-context.type";
|
|
2
2
|
|
|
3
|
-
type
|
|
3
|
+
type SubscribableEventsResponse<AppFeatureType extends AppFeatureTypes = AppFeatureTypes> = {
|
|
4
|
+
context: AppFeatureContextMap[AppFeatureType];
|
|
5
|
+
settings: Record<string, any>;
|
|
6
|
+
itemIds: number[];
|
|
7
|
+
events: Record<string, any>;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
type SubscribableEvents = keyof SubscribableEventsResponse;
|
|
11
|
+
|
|
12
|
+
type SettableTypes = "settings";
|
|
4
13
|
|
|
5
14
|
interface GetResponse {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
data: {
|
|
16
|
+
success: boolean;
|
|
17
|
+
value: any;
|
|
18
|
+
version?: any;
|
|
19
|
+
};
|
|
20
|
+
errorMessage?: string | undefined;
|
|
21
|
+
method: string;
|
|
22
|
+
requestId: string;
|
|
23
|
+
type?: string | undefined;
|
|
15
24
|
}
|
|
16
25
|
|
|
17
26
|
interface DeleteResponse {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
27
|
+
data: {
|
|
28
|
+
success: boolean;
|
|
29
|
+
value: any;
|
|
30
|
+
};
|
|
31
|
+
errorMessage?: string | undefined;
|
|
32
|
+
method: string;
|
|
33
|
+
requestId: string;
|
|
34
|
+
type?: string | undefined;
|
|
26
35
|
}
|
|
27
36
|
|
|
28
37
|
interface SetResponse {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
38
|
+
data: {
|
|
39
|
+
success: boolean;
|
|
40
|
+
version: string;
|
|
41
|
+
reason?: string | undefined;
|
|
42
|
+
error?: string | undefined;
|
|
43
|
+
};
|
|
44
|
+
errorMessage?: string | undefined;
|
|
45
|
+
requestId: string;
|
|
46
|
+
method: string;
|
|
47
|
+
type?: string | undefined;
|
|
39
48
|
}
|
|
40
49
|
|
|
41
|
-
|
|
50
|
+
export type GetterResponse<AppFeatureType extends AppFeatureTypes = AppFeatureTypes> = {
|
|
51
|
+
context: AppFeatureContextMap[AppFeatureType];
|
|
52
|
+
settings: Record<string, any>;
|
|
53
|
+
itemIds: number[];
|
|
54
|
+
sessionToken: string;
|
|
55
|
+
};
|
|
42
56
|
export interface ClientData {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
57
|
+
/**
|
|
58
|
+
* Used for retrieving data from the parent monday.com application where your app is currently running.
|
|
59
|
+
* This object can only be used when your app is running inside an `iframe`. This can only be used in client-side apps.
|
|
60
|
+
* @param type The type of requested information (available values below)
|
|
61
|
+
* - `'context'` Information about where this app is currently displayed, depending on the type of feature
|
|
62
|
+
* - `'settings'` The application settings as configured by the user that installed the app
|
|
63
|
+
* - `'itemIds'` The list of item IDs that are filtered in the current board (or all items if no filters are applied)
|
|
64
|
+
* - `'sessionToken'` A JWT token which is decoded with your app's secret and can be used as a session token between your app's frontend & backend
|
|
65
|
+
* @param params Reserved for future use
|
|
66
|
+
*/
|
|
67
|
+
get<
|
|
68
|
+
CustomResponse,
|
|
69
|
+
T extends keyof GetterResponse = keyof GetterResponse,
|
|
70
|
+
AppFeatureType extends AppFeatureTypes = AppFeatureTypes
|
|
71
|
+
>(
|
|
72
|
+
type: T,
|
|
73
|
+
params?: object & { appFeatureType?: AppFeatureType }
|
|
74
|
+
): Promise<GetterResponse<AppFeatureType>[T] & CustomResponse>;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Creates a listener which allows subscribing to certain types of client-side events.
|
|
78
|
+
* @param typeOrTypes The type, or array of types, of events to subscribe to
|
|
79
|
+
* @param callback A callback function that is fired when the listener is triggered by a client-side event
|
|
80
|
+
* @param params Reserved for future use
|
|
81
|
+
*/
|
|
82
|
+
listen<
|
|
83
|
+
CustomResponse,
|
|
84
|
+
T extends SubscribableEvents = SubscribableEvents,
|
|
85
|
+
AppFeatureType extends AppFeatureTypes = AppFeatureTypes
|
|
86
|
+
>(
|
|
87
|
+
typeOrTypes: T | ReadonlyArray<T>,
|
|
88
|
+
callback: (res: { data: SubscribableEventsResponse<AppFeatureType>[T] & CustomResponse }) => void,
|
|
89
|
+
params?: object & { appFeatureType?: AppFeatureType }
|
|
90
|
+
): void;
|
|
56
91
|
|
|
92
|
+
/**
|
|
93
|
+
* Set data in your application, such as updating settings
|
|
94
|
+
* @param type The type of data that can be set
|
|
95
|
+
* @param params object containing the data you want to update
|
|
96
|
+
*/
|
|
97
|
+
set(type: SettableTypes, params: object): Promise<any>;
|
|
57
98
|
|
|
99
|
+
/**
|
|
100
|
+
* The Storage API is in early beta stages, its API is likely to change
|
|
101
|
+
*
|
|
102
|
+
* The monday apps infrastructure includes a persistent, key-value database storage that developers
|
|
103
|
+
* can leverage to store data without having to create their own backend and maintain their own database.
|
|
104
|
+
*
|
|
105
|
+
* The database currently offers instance-level storage only, meaning that each application instance (i.e. a single board view or a dashboard widget) maintains its own storage.
|
|
106
|
+
* Apps cannot share storage across accounts or even across apps installed in the same location.
|
|
107
|
+
*/
|
|
108
|
+
storage: {
|
|
58
109
|
/**
|
|
59
|
-
*
|
|
60
|
-
* @param
|
|
61
|
-
* @param callback A callback function that is fired when the listener is triggered by a client-side event
|
|
62
|
-
* @param params Reserved for future use
|
|
110
|
+
* Returns a stored value from the database under `key` for the app (**without any reference to the instance**)
|
|
111
|
+
* @param {string} key - Used to access to stored data
|
|
63
112
|
*/
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
callback: (res: { data: object }) => void,
|
|
67
|
-
params?: object,
|
|
68
|
-
): void;
|
|
69
|
-
|
|
113
|
+
getItem(key: string): Promise<GetResponse>;
|
|
114
|
+
|
|
70
115
|
/**
|
|
71
|
-
*
|
|
72
|
-
* @param
|
|
73
|
-
* @param params object containing the data you want to update
|
|
116
|
+
* Deletes a stored value from the database under `key` for the app (**without any reference to the instance**)
|
|
117
|
+
* @param {string} key - Used to delete the stored data
|
|
74
118
|
*/
|
|
75
|
-
|
|
76
|
-
type: SettableTypes,
|
|
77
|
-
params: object,
|
|
78
|
-
): Promise<any>;
|
|
119
|
+
deleteItem(key: string): Promise<DeleteResponse>;
|
|
79
120
|
|
|
80
121
|
/**
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
* The database currently offers instance-level storage only, meaning that each application instance (i.e. a single board view or a dashboard widget) maintains its own storage.
|
|
87
|
-
* Apps cannot share storage across accounts or even across apps installed in the same location.
|
|
122
|
+
* Stores `value` under `key` in the database for the app (**without any reference to the instance**)
|
|
123
|
+
* @param {string} key - Used to delete the stored data
|
|
124
|
+
* @param {any} value - The value to store
|
|
125
|
+
* @param {object=} options
|
|
126
|
+
* @param {string=} options.previous_version - Use the new version of the storage (instance-less)
|
|
88
127
|
*/
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
instance: {
|
|
115
|
-
/**
|
|
116
|
-
* Returns a stored value from the database under `key` for a specific app instance
|
|
117
|
-
* @param key
|
|
118
|
-
*/
|
|
119
|
-
getItem(key: string): Promise<GetResponse>;
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Deletes a stored value from the database under `key` for a specific app instance
|
|
123
|
-
* @param key
|
|
124
|
-
*/
|
|
125
|
-
deleteItem(key: string): Promise<DeleteResponse>;
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Stores `value` under `key` in the database for a specific app instance
|
|
129
|
-
* @param key
|
|
130
|
-
* @param value
|
|
131
|
-
* @param options
|
|
132
|
-
*/
|
|
133
|
-
setItem(key: string, value: any, options?: { previous_version?: string }): Promise<SetResponse>;
|
|
134
|
-
};
|
|
128
|
+
setItem(key: string, value: any, options?: { previous_version?: string }): Promise<SetResponse>;
|
|
129
|
+
/***
|
|
130
|
+
* The instance storage is a key-value database that is scoped to a specific app instance.
|
|
131
|
+
* **Does not work** for instance-less apps.
|
|
132
|
+
*/
|
|
133
|
+
instance: {
|
|
134
|
+
/**
|
|
135
|
+
* Returns a stored value from the database under `key` for a specific app instance
|
|
136
|
+
* @param key
|
|
137
|
+
*/
|
|
138
|
+
getItem(key: string): Promise<GetResponse>;
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Deletes a stored value from the database under `key` for a specific app instance
|
|
142
|
+
* @param key
|
|
143
|
+
*/
|
|
144
|
+
deleteItem(key: string): Promise<DeleteResponse>;
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Stores `value` under `key` in the database for a specific app instance
|
|
148
|
+
* @param key
|
|
149
|
+
* @param value
|
|
150
|
+
* @param options
|
|
151
|
+
*/
|
|
152
|
+
setItem(key: string, value: any, options?: { previous_version?: string }): Promise<SetResponse>;
|
|
135
153
|
};
|
|
154
|
+
};
|
|
136
155
|
}
|