teamflect-mcp-server 1.0.13 → 1.0.14

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.
@@ -23,56 +23,56 @@ export function registerGoalTools(server, apiClient) {
23
23
  }).strict();
24
24
  server.registerTool("teamflect_get_goals", {
25
25
  title: "Get Goals",
26
- description: `Retrieve a list of goals from Teamflect based on filters.
27
-
28
- This tool searches for goals matching the specified criteria. You can filter by user, search terms, labels, and date ranges. Results are paginated.
29
-
30
- Args:
31
- - userOID (string, optional): Filter by user OID (UUID format)
32
- - userUPN (string, optional): Filter by user UPN (email address)
33
- - search (string, optional): Search term for title or owners
34
- - selectedLabels (string, optional): Filter by selected labels
35
- - limit (number, optional): Maximum number of items to return, between 1-500 (default: 200)
36
- - skip (number, optional): Number of items to skip for pagination (default: 0)
37
- - startDate (string, optional): Filter by start date (date format)
38
- - endDate (string, optional): Filter by end date (date format)
39
- - response_format ('markdown' | 'json', optional): Output format (default: 'markdown')
40
-
41
- Returns:
42
- For JSON format: Structured data with schema:
43
- {
44
- "total": number, // Total number of goals found
45
- "count": number, // Number of goals in this response
46
- "offset": number, // Current pagination offset
47
- "goals": [
48
- {
49
- "goalId": string,
50
- "title": string,
51
- "description": string,
52
- "status": string,
53
- "goalType": string,
54
- "startDate": string,
55
- "dueDate": string,
56
- "progress": {
57
- "currentValue": number,
58
- "targetValue": number,
59
- "formatType": string
60
- },
61
- "owners": [{"displayName": string, "mail": string}],
62
- "labels": [{"title": string}]
63
- }
64
- ],
65
- "has_more": boolean, // Whether more results are available
66
- "next_offset": number // Offset for next page (if has_more is true)
67
- }
68
-
69
- Examples:
70
- - Use when: "Get all active goals for john@example.com" -> params with status="Active", ownerEmail="john@example.com"
71
- - Use when: "List goals due this month" -> params with dueDate filter
72
- - Don't use when: You need a single goal by ID (use teamflect_get_goal instead)
73
-
74
- Error Handling:
75
- - Returns "Error: Authentication failed" if API key is invalid
26
+ description: `Retrieve a list of goals from Teamflect based on filters.
27
+
28
+ This tool searches for goals matching the specified criteria. You can filter by user, search terms, labels, and date ranges. Results are paginated.
29
+
30
+ Args:
31
+ - userOID (string, optional): Filter by user OID (UUID format)
32
+ - userUPN (string, optional): Filter by user UPN (email address)
33
+ - search (string, optional): Search term for title or owners
34
+ - selectedLabels (string, optional): Filter by selected labels
35
+ - limit (number, optional): Maximum number of items to return, between 1-500 (default: 200)
36
+ - skip (number, optional): Number of items to skip for pagination (default: 0)
37
+ - startDate (string, optional): Filter by start date (date format)
38
+ - endDate (string, optional): Filter by end date (date format)
39
+ - response_format ('markdown' | 'json', optional): Output format (default: 'markdown')
40
+
41
+ Returns:
42
+ For JSON format: Structured data with schema:
43
+ {
44
+ "total": number, // Total number of goals found
45
+ "count": number, // Number of goals in this response
46
+ "offset": number, // Current pagination offset
47
+ "goals": [
48
+ {
49
+ "goalId": string,
50
+ "title": string,
51
+ "description": string,
52
+ "status": string,
53
+ "goalType": string,
54
+ "startDate": string,
55
+ "dueDate": string,
56
+ "progress": {
57
+ "currentValue": number,
58
+ "targetValue": number,
59
+ "formatType": string
60
+ },
61
+ "owners": [{"displayName": string, "mail": string}],
62
+ "labels": [{"title": string}]
63
+ }
64
+ ],
65
+ "has_more": boolean, // Whether more results are available
66
+ "next_offset": number // Offset for next page (if has_more is true)
67
+ }
68
+
69
+ Examples:
70
+ - Use when: "Get all active goals for john@example.com" -> params with status="Active", ownerEmail="john@example.com"
71
+ - Use when: "List goals due this month" -> params with dueDate filter
72
+ - Don't use when: You need a single goal by ID (use teamflect_get_goal instead)
73
+
74
+ Error Handling:
75
+ - Returns "Error: Authentication failed" if API key is invalid
76
76
  - Returns "Error: Rate limit exceeded" if too many requests (429 status)`,
77
77
  inputSchema: GetGoalsInputSchema,
78
78
  annotations: {
@@ -191,19 +191,19 @@ Error Handling:
191
191
  }).strict();
192
192
  server.registerTool("teamflect_get_goal", {
193
193
  title: "Get Goal by ID",
194
- description: `Retrieve a single goal by its ID from Teamflect.
195
-
196
- This tool fetches detailed information about a specific goal including its progress, owners, labels, and comments.
197
-
198
- Args:
199
- - goalId (string, required): The unique identifier of the goal
200
- - response_format ('markdown' | 'json', optional): Output format (default: 'markdown')
201
-
202
- Returns:
203
- Complete goal details including all fields and relationships.
204
-
205
- Error Handling:
206
- - Returns "Error: Resource not found" if goalId doesn't exist
194
+ description: `Retrieve a single goal by its ID from Teamflect.
195
+
196
+ This tool fetches detailed information about a specific goal including its progress, owners, labels, and comments.
197
+
198
+ Args:
199
+ - goalId (string, required): The unique identifier of the goal
200
+ - response_format ('markdown' | 'json', optional): Output format (default: 'markdown')
201
+
202
+ Returns:
203
+ Complete goal details including all fields and relationships.
204
+
205
+ Error Handling:
206
+ - Returns "Error: Resource not found" if goalId doesn't exist
207
207
  - Returns "Error: Authentication failed" if API key is invalid`,
208
208
  inputSchema: GetGoalInputSchema,
209
209
  annotations: {
@@ -282,33 +282,33 @@ Error Handling:
282
282
  }).strict();
283
283
  server.registerTool("teamflect_create_goal", {
284
284
  title: "Create Goal",
285
- description: `Create a new goal in Teamflect.
286
-
287
- This tool creates a new goal with the specified properties. You can set owners, labels, progress targets, and optionally link it to a parent goal.
288
-
289
- Args:
290
- - title (string, required): Goal title (1-500 characters)
291
- - description (string, optional): Goal description (max 5000 characters)
292
- - goalType (string, optional): Goal type identifier (default: 'Self-development')
293
- - startDate (string, required): Start date in ISO format (YYYY-MM-DD)
294
- - dueDate (string, optional): Due date in ISO format (YYYY-MM-DD)
295
- - goalCreatorUPNorId (string, required): Goal creator User Principal Name (UPN) or ID
296
- - goalOwnerUPNorId (string, optional): Goal owner User Principal Name (UPN) or ID
297
- - isPrivate (boolean, optional): Whether the goal is private
298
- - progressFormatType (string, optional): Progress format type
299
- - currencyCode (string, optional): Currency code for currency-based goals
300
- - initialValue (number, optional): Initial progress value
301
- - targetValue (number, optional): Target progress value
302
- - parentGoalId (string, optional): Parent goal ID if this is a sub-goal
303
- - sendNotificationToOwner (boolean, optional): Whether to send notification to the goal owner
304
- - labelIds (array, optional): Array of label IDs to assign
305
- - response_format ('markdown' | 'json', optional): Output format (default: 'markdown')
306
-
307
- Returns:
308
- The created goal with all its details.
309
-
310
- Error Handling:
311
- - Returns "Error: Bad request" if required fields are missing or invalid
285
+ description: `Create a new goal in Teamflect.
286
+
287
+ This tool creates a new goal with the specified properties. You can set owners, labels, progress targets, and optionally link it to a parent goal.
288
+
289
+ Args:
290
+ - title (string, required): Goal title (1-500 characters)
291
+ - description (string, optional): Goal description (max 5000 characters)
292
+ - goalType (string, optional): Goal type identifier (default: 'Self-development')
293
+ - startDate (string, required): Start date in ISO format (YYYY-MM-DD)
294
+ - dueDate (string, optional): Due date in ISO format (YYYY-MM-DD)
295
+ - goalCreatorUPNorId (string, required): Goal creator User Principal Name (UPN) or ID
296
+ - goalOwnerUPNorId (string, optional): Goal owner User Principal Name (UPN) or ID
297
+ - isPrivate (boolean, optional): Whether the goal is private
298
+ - progressFormatType (string, optional): Progress format type
299
+ - currencyCode (string, optional): Currency code for currency-based goals
300
+ - initialValue (number, optional): Initial progress value
301
+ - targetValue (number, optional): Target progress value
302
+ - parentGoalId (string, optional): Parent goal ID if this is a sub-goal
303
+ - sendNotificationToOwner (boolean, optional): Whether to send notification to the goal owner
304
+ - labelIds (array, optional): Array of label IDs to assign
305
+ - response_format ('markdown' | 'json', optional): Output format (default: 'markdown')
306
+
307
+ Returns:
308
+ The created goal with all its details.
309
+
310
+ Error Handling:
311
+ - Returns "Error: Bad request" if required fields are missing or invalid
312
312
  - Returns "Error: Permission denied" if you don't have permission to create goals`,
313
313
  inputSchema: CreateGoalInputSchema,
314
314
  annotations: {
@@ -390,24 +390,24 @@ Error Handling:
390
390
  }).strict();
391
391
  server.registerTool("teamflect_update_goal_progress", {
392
392
  title: "Update Goal Progress",
393
- description: `Update the progress value of a goal in Teamflect.
394
-
395
- This tool updates the current progress value for a goal. You can optionally include a comment, update the status, and specify who is making the update.
396
-
397
- Args:
398
- - goalId (string, required): The ID of the goal to update
399
- - currentValue (number, required): New current progress value
400
- - comment (string, optional): Optional comment about the progress update (max 1000 characters)
401
- - status (string, optional): Optional status update. Possible values: 'On track', 'At risk', 'Off track', 'Closed'
402
- - goalUpdater (string, optional): Who will be seen as the updater. 'Owner' (default) or 'System'
403
- - goalUpdaterSystemName (string, optional): Name of the updater when goalUpdater is 'System'
404
- - response_format ('markdown' | 'json', optional): Output format (default: 'markdown')
405
-
406
- Returns:
407
- The updated goal with the new progress value.
408
-
409
- Error Handling:
410
- - Returns "Error: Resource not found" if goalId doesn't exist
393
+ description: `Update the progress value of a goal in Teamflect.
394
+
395
+ This tool updates the current progress value for a goal. You can optionally include a comment, update the status, and specify who is making the update.
396
+
397
+ Args:
398
+ - goalId (string, required): The ID of the goal to update
399
+ - currentValue (number, required): New current progress value
400
+ - comment (string, optional): Optional comment about the progress update (max 1000 characters)
401
+ - status (string, optional): Optional status update. Possible values: 'On track', 'At risk', 'Off track', 'Closed'
402
+ - goalUpdater (string, optional): Who will be seen as the updater. 'Owner' (default) or 'System'
403
+ - goalUpdaterSystemName (string, optional): Name of the updater when goalUpdater is 'System'
404
+ - response_format ('markdown' | 'json', optional): Output format (default: 'markdown')
405
+
406
+ Returns:
407
+ The updated goal with the new progress value.
408
+
409
+ Error Handling:
410
+ - Returns "Error: Resource not found" if goalId doesn't exist
411
411
  - Returns "Error: Bad request" if currentValue is invalid`,
412
412
  inputSchema: UpdateGoalProgressInputSchema,
413
413
  annotations: {
@@ -467,21 +467,21 @@ Error Handling:
467
467
  }).strict();
468
468
  server.registerTool("teamflect_comment_goal", {
469
469
  title: "Comment on Goal",
470
- description: `Add a comment to a goal in Teamflect.
471
-
472
- This tool adds a comment to the specified goal. Comments are useful for tracking discussions and updates about goal progress.
473
-
474
- Args:
475
- - goalId (string, required): The ID of the goal to comment on
476
- - commenterIdOrUPN (string, required): Commenter ID (UUID) or UPN (email address)
477
- - commentText (string, required): Comment text (1-1000 characters)
478
- - response_format ('markdown' | 'json', optional): Output format (default: 'markdown')
479
-
480
- Returns:
481
- The goal with the new comment added.
482
-
483
- Error Handling:
484
- - Returns "Error: Resource not found" if goalId doesn't exist
470
+ description: `Add a comment to a goal in Teamflect.
471
+
472
+ This tool adds a comment to the specified goal. Comments are useful for tracking discussions and updates about goal progress.
473
+
474
+ Args:
475
+ - goalId (string, required): The ID of the goal to comment on
476
+ - commenterIdOrUPN (string, required): Commenter ID (UUID) or UPN (email address)
477
+ - commentText (string, required): Comment text (1-1000 characters)
478
+ - response_format ('markdown' | 'json', optional): Output format (default: 'markdown')
479
+
480
+ Returns:
481
+ The goal with the new comment added.
482
+
483
+ Error Handling:
484
+ - Returns "Error: Resource not found" if goalId doesn't exist
485
485
  - Returns "Error: Bad request" if commentText is empty or too long`,
486
486
  inputSchema: CommentGoalInputSchema,
487
487
  annotations: {
@@ -14,19 +14,19 @@ export function registerRecognitionTools(server, apiClient) {
14
14
  }).strict();
15
15
  server.registerTool("teamflect_get_recognition", {
16
16
  title: "Get Recognition by ID",
17
- description: `Retrieve a single recognition by its ID from Teamflect.
18
-
19
- This tool fetches detailed information about a specific recognition including its badge, recipients, and description.
20
-
21
- Args:
22
- - recognitionId (string, required): The unique identifier of the recognition
23
- - response_format ('markdown' | 'json', optional): Output format (default: 'markdown')
24
-
25
- Returns:
26
- Complete recognition details including badge information and recipients.
27
-
28
- Error Handling:
29
- - Returns "Error: Resource not found" if recognitionId doesn't exist
17
+ description: `Retrieve a single recognition by its ID from Teamflect.
18
+
19
+ This tool fetches detailed information about a specific recognition including its badge, recipients, and description.
20
+
21
+ Args:
22
+ - recognitionId (string, required): The unique identifier of the recognition
23
+ - response_format ('markdown' | 'json', optional): Output format (default: 'markdown')
24
+
25
+ Returns:
26
+ Complete recognition details including badge information and recipients.
27
+
28
+ Error Handling:
29
+ - Returns "Error: Resource not found" if recognitionId doesn't exist
30
30
  - Returns "Error: Authentication failed" if API key is invalid`,
31
31
  inputSchema: GetRecognitionInputSchema,
32
32
  annotations: {
@@ -149,43 +149,43 @@ Error Handling:
149
149
  }).strict();
150
150
  server.registerTool("teamflect_search_recognitions", {
151
151
  title: "Search Recognitions",
152
- description: `Search for recognitions in Teamflect based on filters.
153
-
154
- This tool searches for recognitions matching the specified criteria. You can filter by recipients, title, and timestamps.
155
-
156
- Args:
157
- - recipientsIdsOrUPNS (array, optional): Filter by recipient IDs or UPNs (array of strings)
158
- - title (string, optional): Filter by recognition title
159
- - updated (string, optional): Filter by updated timestamp
160
- - created (string, optional): Filter by created timestamp
161
- - response_format ('markdown' | 'json', optional): Output format (default: 'markdown')
162
-
163
- Returns:
164
- For JSON format: Structured data with schema:
165
- {
166
- "total": number,
167
- "count": number,
168
- "offset": number,
169
- "recognitions": [
170
- {
171
- "id": string,
172
- "description": string,
173
- "createdAt": string,
174
- "isPrivate": boolean,
175
- "badge": {"id": string, "title": string, "description": string},
176
- "recipients": [{"displayName": string, "jobTitle": string, "mail": string}]
177
- }
178
- ],
179
- "has_more": boolean,
180
- "next_offset": number
181
- }
182
-
183
- Examples:
184
- - Use when: "Get all recognitions for john@example.com" -> params with recipientEmail="john@example.com"
185
- - Use when: "List public recognitions this month" -> params with isPrivate=false and date filters
186
-
187
- Error Handling:
188
- - Returns "Error: Authentication failed" if API key is invalid
152
+ description: `Search for recognitions in Teamflect based on filters.
153
+
154
+ This tool searches for recognitions matching the specified criteria. You can filter by recipients, title, and timestamps.
155
+
156
+ Args:
157
+ - recipientsIdsOrUPNS (array, optional): Filter by recipient IDs or UPNs (array of strings)
158
+ - title (string, optional): Filter by recognition title
159
+ - updated (string, optional): Filter by updated timestamp
160
+ - created (string, optional): Filter by created timestamp
161
+ - response_format ('markdown' | 'json', optional): Output format (default: 'markdown')
162
+
163
+ Returns:
164
+ For JSON format: Structured data with schema:
165
+ {
166
+ "total": number,
167
+ "count": number,
168
+ "offset": number,
169
+ "recognitions": [
170
+ {
171
+ "id": string,
172
+ "description": string,
173
+ "createdAt": string,
174
+ "isPrivate": boolean,
175
+ "badge": {"id": string, "title": string, "description": string},
176
+ "recipients": [{"displayName": string, "jobTitle": string, "mail": string}]
177
+ }
178
+ ],
179
+ "has_more": boolean,
180
+ "next_offset": number
181
+ }
182
+
183
+ Examples:
184
+ - Use when: "Get all recognitions for john@example.com" -> params with recipientEmail="john@example.com"
185
+ - Use when: "List public recognitions this month" -> params with isPrivate=false and date filters
186
+
187
+ Error Handling:
188
+ - Returns "Error: Authentication failed" if API key is invalid
189
189
  - Returns "Error: Rate limit exceeded" if too many requests`,
190
190
  inputSchema: SearchRecognitionsInputSchema,
191
191
  annotations: {
@@ -340,23 +340,23 @@ Error Handling:
340
340
  }).strict();
341
341
  server.registerTool("teamflect_create_recognition", {
342
342
  title: "Create Recognition",
343
- description: `Create a new recognition in Teamflect.
344
-
345
- This tool creates a recognition (award/badge) for one or more recipients. Recognitions can be public or private.
346
-
347
- Args:
348
- - senderIdOrUPN (string, required): Sender ID or User Principal Name (email or GUID)
349
- - recipientsIdsOrUPNS (array, required): Array of recipient IDs or UPNs (email addresses or GUIDs, at least one)
350
- - badgeTitle (string, required): Badge title
351
- - isPrivate (boolean, optional): Whether the recognition is private
352
- - description (string, required): Recognition description
353
- - response_format ('markdown' | 'json', optional): Output format (default: 'markdown')
354
-
355
- Returns:
356
- The created recognition(s) with all details.
357
-
358
- Error Handling:
359
- - Returns "Error: Bad request" if required fields are missing or invalid
343
+ description: `Create a new recognition in Teamflect.
344
+
345
+ This tool creates a recognition (award/badge) for one or more recipients. Recognitions can be public or private.
346
+
347
+ Args:
348
+ - senderIdOrUPN (string, required): Sender ID or User Principal Name (email or GUID)
349
+ - recipientsIdsOrUPNS (array, required): Array of recipient IDs or UPNs (email addresses or GUIDs, at least one)
350
+ - badgeTitle (string, required): Badge title
351
+ - isPrivate (boolean, optional): Whether the recognition is private
352
+ - description (string, required): Recognition description
353
+ - response_format ('markdown' | 'json', optional): Output format (default: 'markdown')
354
+
355
+ Returns:
356
+ The created recognition(s) with all details.
357
+
358
+ Error Handling:
359
+ - Returns "Error: Bad request" if required fields are missing or invalid
360
360
  - Returns "Error: Permission denied" if you don't have permission to create recognitions`,
361
361
  inputSchema: CreateRecognitionInputSchema,
362
362
  annotations: {
package/package.json CHANGED
@@ -1,63 +1,63 @@
1
- {
2
- "name": "teamflect-mcp-server",
3
- "version": "1.0.13",
4
- "description": "MCP server for Teamflect API integration",
5
- "type": "module",
6
- "main": "dist/index.js",
7
- "bin": {
8
- "teamflect-mcp-server": "dist/index.js"
9
- },
10
- "scripts": {
11
- "start": "node dist/index.js",
12
- "dev": "tsx watch src/index.ts",
13
- "build": "tsc",
14
- "clean": "rm -rf dist",
15
- "prepublishOnly": "npm run build",
16
- "test": "node test-all-tools.js",
17
- "test:watch": "node test-all-tools.js --watch",
18
- "test:coverage": "node test-all-tools.js --coverage",
19
- "test:curl": "powershell -ExecutionPolicy Bypass -File test-all-tools-curl.ps1"
20
- },
21
- "engines": {
22
- "node": ">=18"
23
- },
24
- "dependencies": {
25
- "@modelcontextprotocol/sdk": "^1.6.1",
26
- "axios": "^1.7.9",
27
- "dotenv": "^17.2.3",
28
- "express": "^4.18.2",
29
- "zod": "^3.23.8"
30
- },
31
- "devDependencies": {
32
- "@types/express": "^4.17.25",
33
- "@types/node": "^20.19.30",
34
- "tsx": "^4.19.2",
35
- "typescript": "^5.3.3"
36
- },
37
- "keywords": [
38
- "mcp",
39
- "teamflect",
40
- "performance-management",
41
- "goals",
42
- "feedback",
43
- "api",
44
- "integration",
45
- "claude",
46
- "cursor"
47
- ],
48
- "author": "",
49
- "license": "MIT",
50
- "repository": {
51
- "type": "git",
52
- "url": "https://Mohamedahmed@dev.azure.com/Mohamedahmed/AIMentorHub/_git/AIMentorHub.Teamflect.MCPServer"
53
- },
54
- "homepage": "https://dev.azure.com/Mohamedahmed/AIMentorHub/_git/AIMentorHub.Teamflect.MCPServer",
55
- "bugs": {
56
- "url": "https://dev.azure.com/Mohamedahmed/AIMentorHub/_git/AIMentorHub.Teamflect.MCPServer/issues"
57
- },
58
- "files": [
59
- "dist",
60
- "README.md",
61
- ".env.example"
62
- ]
63
- }
1
+ {
2
+ "name": "teamflect-mcp-server",
3
+ "version": "1.0.14",
4
+ "description": "MCP server for Teamflect API integration",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "teamflect-mcp-server": "dist/index.js"
9
+ },
10
+ "scripts": {
11
+ "start": "node dist/index.js",
12
+ "dev": "tsx watch src/index.ts",
13
+ "build": "tsc",
14
+ "clean": "rm -rf dist",
15
+ "prepublishOnly": "npm run build",
16
+ "test": "node test-all-tools.js",
17
+ "test:watch": "node test-all-tools.js --watch",
18
+ "test:coverage": "node test-all-tools.js --coverage",
19
+ "test:curl": "powershell -ExecutionPolicy Bypass -File test-all-tools-curl.ps1"
20
+ },
21
+ "engines": {
22
+ "node": ">=18"
23
+ },
24
+ "dependencies": {
25
+ "@modelcontextprotocol/sdk": "^1.6.1",
26
+ "axios": "^1.7.9",
27
+ "dotenv": "^17.2.3",
28
+ "express": "^4.18.2",
29
+ "zod": "^3.23.8"
30
+ },
31
+ "devDependencies": {
32
+ "@types/express": "^4.17.25",
33
+ "@types/node": "^20.19.30",
34
+ "tsx": "^4.19.2",
35
+ "typescript": "^5.3.3"
36
+ },
37
+ "keywords": [
38
+ "mcp",
39
+ "teamflect",
40
+ "performance-management",
41
+ "goals",
42
+ "feedback",
43
+ "api",
44
+ "integration",
45
+ "claude",
46
+ "cursor"
47
+ ],
48
+ "author": "",
49
+ "license": "MIT",
50
+ "repository": {
51
+ "type": "git",
52
+ "url": "https://Mohamedahmed@dev.azure.com/Mohamedahmed/AIMentorHub/_git/AIMentorHub.Teamflect.MCPServer"
53
+ },
54
+ "homepage": "https://dev.azure.com/Mohamedahmed/AIMentorHub/_git/AIMentorHub.Teamflect.MCPServer",
55
+ "bugs": {
56
+ "url": "https://dev.azure.com/Mohamedahmed/AIMentorHub/_git/AIMentorHub.Teamflect.MCPServer/issues"
57
+ },
58
+ "files": [
59
+ "dist",
60
+ "README.md",
61
+ ".env.example"
62
+ ]
63
+ }