@crypto512/jicon-mcp 1.3.0 → 2.0.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 (160) hide show
  1. package/README.md +68 -85
  2. package/TOOL_LIST.md +704 -87
  3. package/dist/config/constants.d.ts +18 -7
  4. package/dist/config/constants.d.ts.map +1 -1
  5. package/dist/config/constants.js +21 -8
  6. package/dist/config/constants.js.map +1 -1
  7. package/dist/config/loader.d.ts +11 -11
  8. package/dist/config/loader.d.ts.map +1 -1
  9. package/dist/config/loader.js +53 -93
  10. package/dist/config/loader.js.map +1 -1
  11. package/dist/config/types.d.ts +3 -6
  12. package/dist/config/types.d.ts.map +1 -1
  13. package/dist/config/types.js +2 -4
  14. package/dist/config/types.js.map +1 -1
  15. package/dist/confluence/formatters.js +1 -1
  16. package/dist/confluence/formatters.js.map +1 -1
  17. package/dist/confluence/tools.d.ts +4 -0
  18. package/dist/confluence/tools.d.ts.map +1 -1
  19. package/dist/confluence/tools.js +180 -125
  20. package/dist/confluence/tools.js.map +1 -1
  21. package/dist/index.js +17 -26
  22. package/dist/index.js.map +1 -1
  23. package/dist/jira/formatters.d.ts +1 -0
  24. package/dist/jira/formatters.d.ts.map +1 -1
  25. package/dist/jira/formatters.js +13 -12
  26. package/dist/jira/formatters.js.map +1 -1
  27. package/dist/jira/tools.d.ts +4 -0
  28. package/dist/jira/tools.d.ts.map +1 -1
  29. package/dist/jira/tools.js +189 -50
  30. package/dist/jira/tools.js.map +1 -1
  31. package/dist/permissions/tool-registry.d.ts +2 -2
  32. package/dist/permissions/tool-registry.d.ts.map +1 -1
  33. package/dist/permissions/tool-registry.js +4 -2
  34. package/dist/permissions/tool-registry.js.map +1 -1
  35. package/dist/permissions/write-home-validator.d.ts.map +1 -1
  36. package/dist/permissions/write-home-validator.js +13 -3
  37. package/dist/permissions/write-home-validator.js.map +1 -1
  38. package/dist/tempo/defaults.d.ts +17 -0
  39. package/dist/tempo/defaults.d.ts.map +1 -0
  40. package/dist/tempo/defaults.js +26 -0
  41. package/dist/tempo/defaults.js.map +1 -0
  42. package/dist/tempo/tools.d.ts +5 -0
  43. package/dist/tempo/tools.d.ts.map +1 -1
  44. package/dist/tempo/tools.js +108 -34
  45. package/dist/tempo/tools.js.map +1 -1
  46. package/dist/utils/buffer-pipeline/index.d.ts +30 -0
  47. package/dist/utils/buffer-pipeline/index.d.ts.map +1 -0
  48. package/dist/utils/buffer-pipeline/index.js +317 -0
  49. package/dist/utils/buffer-pipeline/index.js.map +1 -0
  50. package/dist/utils/buffer-pipeline/output/csv.d.ts +20 -0
  51. package/dist/utils/buffer-pipeline/output/csv.d.ts.map +1 -0
  52. package/dist/utils/buffer-pipeline/output/csv.js +117 -0
  53. package/dist/utils/buffer-pipeline/output/csv.js.map +1 -0
  54. package/dist/utils/buffer-pipeline/output/json.d.ts +16 -0
  55. package/dist/utils/buffer-pipeline/output/json.d.ts.map +1 -0
  56. package/dist/utils/buffer-pipeline/output/json.js +48 -0
  57. package/dist/utils/buffer-pipeline/output/json.js.map +1 -0
  58. package/dist/utils/buffer-pipeline/output/markdown.d.ts +15 -0
  59. package/dist/utils/buffer-pipeline/output/markdown.d.ts.map +1 -0
  60. package/dist/utils/buffer-pipeline/output/markdown.js +105 -0
  61. package/dist/utils/buffer-pipeline/output/markdown.js.map +1 -0
  62. package/dist/utils/buffer-pipeline/output/xhtml-list.d.ts +16 -0
  63. package/dist/utils/buffer-pipeline/output/xhtml-list.d.ts.map +1 -0
  64. package/dist/utils/buffer-pipeline/output/xhtml-list.js +81 -0
  65. package/dist/utils/buffer-pipeline/output/xhtml-list.js.map +1 -0
  66. package/dist/utils/buffer-pipeline/output/xhtml-table.d.ts +15 -0
  67. package/dist/utils/buffer-pipeline/output/xhtml-table.d.ts.map +1 -0
  68. package/dist/utils/buffer-pipeline/output/xhtml-table.js +176 -0
  69. package/dist/utils/buffer-pipeline/output/xhtml-table.js.map +1 -0
  70. package/dist/utils/buffer-pipeline/schema.d.ts +1878 -0
  71. package/dist/utils/buffer-pipeline/schema.d.ts.map +1 -0
  72. package/dist/utils/buffer-pipeline/schema.js +168 -0
  73. package/dist/utils/buffer-pipeline/schema.js.map +1 -0
  74. package/dist/utils/buffer-pipeline/stages/filter.d.ts +32 -0
  75. package/dist/utils/buffer-pipeline/stages/filter.d.ts.map +1 -0
  76. package/dist/utils/buffer-pipeline/stages/filter.js +208 -0
  77. package/dist/utils/buffer-pipeline/stages/filter.js.map +1 -0
  78. package/dist/utils/buffer-pipeline/stages/format.d.ts +45 -0
  79. package/dist/utils/buffer-pipeline/stages/format.d.ts.map +1 -0
  80. package/dist/utils/buffer-pipeline/stages/format.js +160 -0
  81. package/dist/utils/buffer-pipeline/stages/format.js.map +1 -0
  82. package/dist/utils/buffer-pipeline/stages/group-by.d.ts +25 -0
  83. package/dist/utils/buffer-pipeline/stages/group-by.d.ts.map +1 -0
  84. package/dist/utils/buffer-pipeline/stages/group-by.js +190 -0
  85. package/dist/utils/buffer-pipeline/stages/group-by.js.map +1 -0
  86. package/dist/utils/buffer-pipeline/stages/select.d.ts +54 -0
  87. package/dist/utils/buffer-pipeline/stages/select.d.ts.map +1 -0
  88. package/dist/utils/buffer-pipeline/stages/select.js +228 -0
  89. package/dist/utils/buffer-pipeline/stages/select.js.map +1 -0
  90. package/dist/utils/buffer-pipeline/stages/sort.d.ts +20 -0
  91. package/dist/utils/buffer-pipeline/stages/sort.d.ts.map +1 -0
  92. package/dist/utils/buffer-pipeline/stages/sort.js +96 -0
  93. package/dist/utils/buffer-pipeline/stages/sort.js.map +1 -0
  94. package/dist/utils/buffer-pipeline/types.d.ts +277 -0
  95. package/dist/utils/buffer-pipeline/types.d.ts.map +1 -0
  96. package/dist/utils/buffer-pipeline/types.js +8 -0
  97. package/dist/utils/buffer-pipeline/types.js.map +1 -0
  98. package/dist/utils/buffer-tools.d.ts +749 -19
  99. package/dist/utils/buffer-tools.d.ts.map +1 -1
  100. package/dist/utils/buffer-tools.js +738 -491
  101. package/dist/utils/buffer-tools.js.map +1 -1
  102. package/dist/utils/content-buffer.d.ts +55 -4
  103. package/dist/utils/content-buffer.d.ts.map +1 -1
  104. package/dist/utils/content-buffer.js +107 -9
  105. package/dist/utils/content-buffer.js.map +1 -1
  106. package/dist/utils/jicon-help.d.ts +1 -1
  107. package/dist/utils/jicon-help.d.ts.map +1 -1
  108. package/dist/utils/jicon-help.js +253 -28
  109. package/dist/utils/jicon-help.js.map +1 -1
  110. package/dist/utils/json-structure.d.ts +121 -0
  111. package/dist/utils/json-structure.d.ts.map +1 -0
  112. package/dist/utils/json-structure.js +637 -0
  113. package/dist/utils/json-structure.js.map +1 -0
  114. package/dist/utils/plantuml/include-expander.d.ts +31 -30
  115. package/dist/utils/plantuml/include-expander.d.ts.map +1 -1
  116. package/dist/utils/plantuml/include-expander.js +167 -133
  117. package/dist/utils/plantuml/include-expander.js.map +1 -1
  118. package/dist/utils/plantuml/index.d.ts +3 -3
  119. package/dist/utils/plantuml/index.d.ts.map +1 -1
  120. package/dist/utils/plantuml/index.js +4 -4
  121. package/dist/utils/plantuml/index.js.map +1 -1
  122. package/dist/utils/plantuml/service.d.ts +13 -24
  123. package/dist/utils/plantuml/service.d.ts.map +1 -1
  124. package/dist/utils/plantuml/service.js +49 -99
  125. package/dist/utils/plantuml/service.js.map +1 -1
  126. package/dist/utils/plantuml/tools.d.ts.map +1 -1
  127. package/dist/utils/plantuml/tools.js +33 -72
  128. package/dist/utils/plantuml/tools.js.map +1 -1
  129. package/dist/utils/plantuml/types.d.ts +1 -35
  130. package/dist/utils/plantuml/types.d.ts.map +1 -1
  131. package/dist/utils/plantuml/types.js +1 -11
  132. package/dist/utils/plantuml/types.js.map +1 -1
  133. package/dist/utils/plantuml/validation-helper.d.ts +1 -1
  134. package/dist/utils/plantuml/validation-helper.js +12 -12
  135. package/dist/utils/plantuml/validation-helper.js.map +1 -1
  136. package/dist/utils/response-formatter.d.ts +61 -6
  137. package/dist/utils/response-formatter.d.ts.map +1 -1
  138. package/dist/utils/response-formatter.js +174 -91
  139. package/dist/utils/response-formatter.js.map +1 -1
  140. package/dist/utils/url-tools.d.ts.map +1 -1
  141. package/dist/utils/url-tools.js +22 -0
  142. package/dist/utils/url-tools.js.map +1 -1
  143. package/dist/utils/xhtml/error-locator.js +2 -2
  144. package/dist/utils/xhtml/error-locator.js.map +1 -1
  145. package/dist/utils/xhtml/index.d.ts +1 -1
  146. package/dist/utils/xhtml/index.d.ts.map +1 -1
  147. package/dist/utils/xhtml/index.js +1 -1
  148. package/dist/utils/xhtml/index.js.map +1 -1
  149. package/dist/utils/xhtml/parser.d.ts +34 -5
  150. package/dist/utils/xhtml/parser.d.ts.map +1 -1
  151. package/dist/utils/xhtml/parser.js +66 -11
  152. package/dist/utils/xhtml/parser.js.map +1 -1
  153. package/dist/utils/xhtml/plantuml.d.ts.map +1 -1
  154. package/dist/utils/xhtml/plantuml.js +5 -3
  155. package/dist/utils/xhtml/plantuml.js.map +1 -1
  156. package/dist/utils/xhtml/serializer.d.ts.map +1 -1
  157. package/dist/utils/xhtml/serializer.js +12 -15
  158. package/dist/utils/xhtml/serializer.js.map +1 -1
  159. package/package.json +12 -4
  160. package/crypto512-jicon-mcp-1.3.0.tgz +0 -0
package/README.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Jicon - Jira & Confluence MCP Server
2
2
 
3
+ <!--
4
+ README.md Guidelines:
5
+ - Keep this file USER-FOCUSED: describe features and benefits, not implementation details
6
+ - NO tool names, function signatures, or technical API details here
7
+ - Tool documentation belongs in TOOL_LIST.md
8
+ - Development documentation belongs in CLAUDE.md
9
+ -->
10
+
3
11
  [![npm version](https://badge.fury.io/js/%40crypto512%2Fjicon-mcp.svg)](https://badge.fury.io/js/%40crypto512%2Fjicon-mcp)
4
12
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
13
 
@@ -110,65 +118,61 @@ Add to `opencode.jsonc` in your project root or `~/.config/opencode/opencode.jso
110
118
 
111
119
  ## Configuration
112
120
 
121
+ All configuration is done through environment variables.
122
+
113
123
  ### Environment Variables
114
124
 
115
- | Variable | Description |
116
- |----------|-------------|
117
- | `JIRA_URL` | Your Jira instance URL |
118
- | `JIRA_USERNAME` | Your email (omit for Data Center PAT) |
119
- | `JIRA_API_TOKEN` | API token or Personal Access Token |
120
- | `JIRA_AUTH_TYPE` | Optional: `basic` or `bearer` (auto-detected from username) |
121
- | `CONFLUENCE_URL` | Your Confluence instance URL |
122
- | `CONFLUENCE_USERNAME` | Your email (omit for Data Center PAT) |
123
- | `CONFLUENCE_API_TOKEN` | API token or Personal Access Token |
124
- | `CONFLUENCE_AUTH_TYPE` | Optional: `basic` or `bearer` (auto-detected from username) |
125
+ | Variable | Type | Default | Description |
126
+ |----------|------|---------|-------------|
127
+ | `JIRA_URL` | string | - | Jira instance URL |
128
+ | `JIRA_USERNAME` | string | - | Email (omit for Data Center PAT) |
129
+ | `JIRA_API_TOKEN` | string | - | API token or Personal Access Token |
130
+ | `JIRA_AUTH_TYPE` | `basic`\|`bearer` | auto | Auth type (auto-detected from username) |
131
+ | `CONFLUENCE_URL` | string | - | Confluence instance URL |
132
+ | `CONFLUENCE_USERNAME` | string | - | Email (omit for Data Center PAT) |
133
+ | `CONFLUENCE_API_TOKEN` | string | - | API token or Personal Access Token |
134
+ | `CONFLUENCE_AUTH_TYPE` | `basic`\|`bearer` | auto | Auth type (auto-detected from username) |
135
+ | `JICON_PERMISSIONS_MODE` | `readonly`\|`full`\|`custom` | `readonly` | Permission mode |
136
+ | `JICON_PERMISSIONS_WHITELIST` | comma-separated | - | Tools to allow (custom mode) |
137
+ | `JICON_PERMISSIONS_BLACKLIST` | comma-separated | - | Tools to deny (custom mode) |
138
+ | `JICON_CONFLUENCE_WRITE_HOME` | `true`\|`false` | `false` | Restrict Confluence writes to personal space |
139
+ | `JICON_DISABLE_DOCKER` | `true`\|`false` | `false` | Disable PlantUML/Docker features |
140
+ | `JICON_MAX_OUTPUT` | number | `16000` | Maximum output characters |
125
141
 
126
142
  **Note:** Tempo uses the same Jira credentials - no separate configuration needed.
127
143
 
128
- ### Configuration File (Optional)
144
+ ### Permission Modes
129
145
 
130
- Create `.jicon.json` in your project root for project-specific settings, or `~/.config/jicon/jicon.json` for user-wide settings:
146
+ Control what operations are allowed. **By default, Jicon runs in read-only mode** - all read tools across Jira, Confluence, and Tempo are available, but no write operations.
131
147
 
148
+ **Read-Only** (default):
132
149
  ```json
133
150
  {
134
- "jira": {
135
- "url": "https://jira.example.com",
136
- "username": "your-email@example.com",
137
- "token": "your-api-token"
138
- },
139
- "confluence": {
140
- "url": "https://confluence.example.com",
141
- "username": "your-email@example.com",
142
- "token": "your-api-token"
151
+ "env": {
152
+ "JIRA_URL": "https://jira.example.com",
153
+ "JIRA_API_TOKEN": "your-token"
143
154
  }
144
155
  }
145
156
  ```
146
157
 
147
- **Priority:** Project config → User config → Environment variables
148
-
149
- **Important:** Add `.jicon.json` to your `.gitignore`!
150
-
151
- ### Permission Modes
152
-
153
- Control what operations are allowed. **By default, Jicon runs in read-only mode** - all read tools across Jira, Confluence, and Tempo are available, but no write operations. Safe for exploration without risk of accidental modifications.
154
-
155
- **Read-Only** (default) - all read tools enabled:
156
- ```json
157
- { "permissions": { "mode": "readonly" } }
158
- ```
159
-
160
- **Full Access** - all operations enabled:
158
+ **Full Access**:
161
159
  ```json
162
- { "permissions": { "mode": "full" } }
160
+ {
161
+ "env": {
162
+ "JIRA_URL": "https://jira.example.com",
163
+ "JIRA_API_TOKEN": "your-token",
164
+ "JICON_PERMISSIONS_MODE": "full"
165
+ }
166
+ }
163
167
  ```
164
168
 
165
- **Custom** - fine-grained control with whitelist and blacklist:
169
+ **Custom** - fine-grained control:
166
170
  ```json
167
171
  {
168
- "permissions": {
169
- "mode": "custom",
170
- "whitelist": ["jira_all", "confluence_all", "tempo_all"],
171
- "blacklist": ["confluence_delete_page", "tempo_delete_worklog"]
172
+ "env": {
173
+ "JICON_PERMISSIONS_MODE": "custom",
174
+ "JICON_PERMISSIONS_WHITELIST": "jira_all,confluence_all,tempo_all",
175
+ "JICON_PERMISSIONS_BLACKLIST": "confluence_delete_page,tempo_delete_worklog"
172
176
  }
173
177
  }
174
178
  ```
@@ -176,10 +180,10 @@ Control what operations are allowed. **By default, Jicon runs in read-only mode*
176
180
  **Safe Write** - recommended for controlled write access:
177
181
  ```json
178
182
  {
179
- "permissions": {
180
- "mode": "custom",
181
- "whitelist": ["jira_read", "confluence_write", "tempo_read"],
182
- "confluenceWriteHome": true
183
+ "env": {
184
+ "JICON_PERMISSIONS_MODE": "custom",
185
+ "JICON_PERMISSIONS_WHITELIST": "jira_read,confluence_write,tempo_read",
186
+ "JICON_CONFLUENCE_WRITE_HOME": "true"
183
187
  }
184
188
  }
185
189
  ```
@@ -189,31 +193,31 @@ This configuration allows:
189
193
  - **Confluence**: Write restricted to your personal space only
190
194
  - **Tempo**: Read-only (view worklogs, no time logging)
191
195
 
192
- The `confluenceWriteHome: true` setting ensures all Confluence write operations (drafts, comments, attachments) can only target your personal space, preventing accidental modifications to shared team spaces.
193
-
194
196
  **Draft Only** - create new documents without reading existing content:
195
197
  ```json
196
198
  {
197
- "permissions": {
198
- "mode": "custom",
199
- "whitelist": ["confluence_draft"]
199
+ "env": {
200
+ "JICON_PERMISSIONS_MODE": "custom",
201
+ "JICON_PERMISSIONS_WHITELIST": "confluence_draft"
200
202
  }
201
203
  }
202
204
  ```
203
205
 
204
- Includes: `confluence_draft_create`, `confluence_draft_save`, `confluence_draft_delete`, plus space discovery (`confluence_get_current_user_space`, `confluence_list_spaces`) to know where to create drafts. No page content is exposed.
205
-
206
206
  **Virtual actions** (for whitelist): `jira_read`, `jira_write`, `jira_all`, `confluence_read`, `confluence_write`, `confluence_draft`, `confluence_all`, `tempo_read`, `tempo_write`, `tempo_all`
207
207
 
208
- **Individual tools** (for blacklist): See [TOOL_LIST.md](TOOL_LIST.md) for all tool names (e.g., `confluence_delete_page`, `tempo_delete_worklog`)
208
+ **Individual tools** (for blacklist): See [TOOL_LIST.md](TOOL_LIST.md) for all tool names
209
209
 
210
210
  ### Docker Configuration
211
211
 
212
212
  PlantUML validation requires Docker. The container starts when MCP loads and does **not auto-restart** if it stops - you'll need to restart the MCP server.
213
213
 
214
- **Disable Docker/PlantUML** - if you don't need PlantUML validation:
214
+ **Disable Docker/PlantUML**:
215
215
  ```json
216
- { "disableDocker": true }
216
+ {
217
+ "env": {
218
+ "JICON_DISABLE_DOCKER": "true"
219
+ }
220
+ }
217
221
  ```
218
222
 
219
223
  When disabled, PlantUML tools return clear errors instead of failing silently.
@@ -274,7 +278,7 @@ The Confluence Data Center REST API has specific limitations for draft managemen
274
278
  Since the API cannot create a "draft version" of an existing page, Jicon uses a workaround:
275
279
  1. Creates a `[jicon-mcp REVIEW] Title` draft linked to the original via label
276
280
  2. User reviews the draft content
277
- 3. `confluence_review_publish` copies content to original page and deletes draft
281
+ 3. User approves to publish changes to the original page
278
282
 
279
283
  This achieves "draft before publish" semantics within API constraints.
280
284
 
@@ -286,7 +290,7 @@ This achieves "draft before publish" semantics within API constraints.
286
290
 
287
291
  ## Features
288
292
 
289
- ### 69 Tools Across 3 Services
293
+ ### 71 Tools Across 3 Services
290
294
 
291
295
  | Service | Capabilities |
292
296
  |---------|--------------|
@@ -300,24 +304,11 @@ Plus utility tools for content buffering, time calculations, URL generation, and
300
304
 
301
305
  All data-heavy tools (search, list, get) return **buffered responses** for efficient handling of large datasets. Instead of returning raw data, tools return a `bufferId` with metadata:
302
306
 
303
- ```json
304
- {
305
- "bufferId": "buf_abc123",
306
- "metadata": {
307
- "resourceType": "jira_search",
308
- "title": "JQL: project = PROJ AND status = 'In Progress'"
309
- },
310
- "totalSize": 125000,
311
- "hint": "Use buffer_get_chunk(bufferId) to read, buffer_grep(bufferId, pattern) to search"
312
- }
313
- ```
314
-
315
- **Working with buffers:**
316
- - `buffer_get_chunk(bufferId, offset, limit)` - Read data in chunks
317
- - `buffer_grep(bufferId, pattern)` - Search within buffered data
318
- - `buffer_list()` - List all active buffers with metadata
319
-
320
- The buffer metadata includes `resourceType` and `title` to track origin (e.g., which query or resource the data came from).
307
+ **Buffer capabilities:**
308
+ - Read content in chunks or search within buffered data
309
+ - Server-side data transformation: filtering, grouping, sorting, aggregations
310
+ - Export to multiple formats: XHTML tables, lists, CSV, JSON, Markdown
311
+ - Track buffer origin with metadata (resource type, query, title)
321
312
 
322
313
  ### Safe Confluence Editing (Review Workflow)
323
314
 
@@ -332,18 +323,10 @@ Confluence write operations use a **review workflow** for safety:
332
323
  1. **Ask the AI**: *"Add a PlantUML diagram to page https://confluence.example.com/..."*
333
324
  2. **Review Draft Created**: Jicon creates a `[jicon-mcp REVIEW] Page Title` draft linked to the original
334
325
  3. **You Review**: Check the draft content in Confluence UI
335
- 4. **Publish or Discard**:
336
- - AI can run `confluence_review_publish` to apply changes to original page
337
- - Or `confluence_review_discard` to cancel without changes
338
- - Or you can manually copy content if preferred
326
+ 4. **Publish or Discard**: Apply changes to the original page, discard them, or manually copy content
339
327
 
340
328
  This means the AI assistant **never directly modifies** existing pages - all changes are staged as review drafts that require your approval. Combined with `confluenceWriteHome: true`, this ensures complete control over what gets published.
341
329
 
342
- **Review Workflow Tools:**
343
- - `confluence_review_list()` - Find all `[jicon-mcp REVIEW]` drafts
344
- - `confluence_review_publish(reviewDraftId)` - Apply changes to original page
345
- - `confluence_review_discard(reviewDraftId)` - Discard without changes
346
-
347
330
  ### PlantUML Diagrams
348
331
 
349
332
  Create and validate UML diagrams directly in Confluence pages. The PlantUML Docker container starts automatically when the MCP server loads (if Docker is available). If Docker is unavailable or the container stops, PlantUML tools return clear errors - restart the MCP server to retry. Use `"disableDocker": true` in config to skip PlantUML entirely.
@@ -358,7 +341,7 @@ For complete tool documentation with parameters and examples, see **[TOOL_LIST.m
358
341
  - Use API tokens with minimal required permissions
359
342
  - Rotate tokens regularly
360
343
  - Use read-only mode for exploration
361
- - Never commit `.jicon.json` to version control
344
+ - Never commit credentials to version control
362
345
 
363
346
  ## License
364
347