mind-elixir 5.8.2 → 5.8.3-beta.1
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/LICENSE +21 -21
- package/dist/MindElixir.css +1 -1
- package/dist/MindElixir.iife.js +2 -2
- package/dist/MindElixir.js +5 -5
- package/dist/MindElixirLite.css +1 -1
- package/dist/MindElixirLite.iife.js +4 -4
- package/dist/MindElixirLite.js +171 -171
- package/package.json +111 -111
- package/readme.md +470 -470
package/readme.md
CHANGED
|
@@ -1,470 +1,470 @@
|
|
|
1
|
-
<p align="center">
|
|
2
|
-
<a href="https://docs.mind-elixir.com" target="_blank" rel="noopener noreferrer">
|
|
3
|
-
<img width="150" src="https://raw.githubusercontent.com/ssshooter/mind-elixir-core/master/images/logo2.png" alt="mindelixir logo2">
|
|
4
|
-
</a>
|
|
5
|
-
<h1 align="center">Mind Elixir</h1>
|
|
6
|
-
</p>
|
|
7
|
-
|
|
8
|
-
<p align="center">
|
|
9
|
-
<a href="https://trendshift.io/repositories/13049" target="_blank"><img src="https://trendshift.io/api/badge/repositories/13049" alt="SSShooter%2Fmind-elixir-core | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
|
|
10
|
-
</p>
|
|
11
|
-
|
|
12
|
-
<p align="center">
|
|
13
|
-
<a href="https://www.npmjs.com/package/mind-elixir">
|
|
14
|
-
<img src="https://img.shields.io/npm/v/mind-elixir" alt="version">
|
|
15
|
-
</a>
|
|
16
|
-
<a href="https://github.com/ssshooter/mind-elixir-core/blob/master/LICENSE">
|
|
17
|
-
<img src="https://img.shields.io/npm/l/mind-elixir" alt="license">
|
|
18
|
-
</a>
|
|
19
|
-
<a href="https://app.codacy.com/gh/ssshooter/mind-elixir-core?utm_source=github.com&utm_medium=referral&utm_content=ssshooter/mind-elixir-core&utm_campaign=Badge_Grade_Settings">
|
|
20
|
-
<img src="https://api.codacy.com/project/badge/Grade/09fadec5bf094886b30cea6aabf3a88b" alt="code quality">
|
|
21
|
-
</a>
|
|
22
|
-
<a href="https://bundlephobia.com/result?p=mind-elixir">
|
|
23
|
-
<img src="https://badgen.net/bundlephobia/dependency-count/mind-elixir" alt="dependency-count">
|
|
24
|
-
</a>
|
|
25
|
-
<a href="https://dependents.info/SSShooter/mind-elixir-core">
|
|
26
|
-
<img src="https://dependents.info/SSShooter/mind-elixir-core/badge" alt="dependents count badge" />
|
|
27
|
-
</a>
|
|
28
|
-
<a href="https://packagephobia.com/result?p=mind-elixir">
|
|
29
|
-
<img src="https://packagephobia.com/badge?p=mind-elixir" alt="package size">
|
|
30
|
-
</a>
|
|
31
|
-
</p>
|
|
32
|
-
|
|
33
|
-
[English](/readme.md) |
|
|
34
|
-
[中文](/readme/zh.md) |
|
|
35
|
-
[Español](/readme/es.md) |
|
|
36
|
-
[Français](/readme/fr.md) |
|
|
37
|
-
[Português](/readme/pt.md) |
|
|
38
|
-
[Русский](/readme/ru.md) |
|
|
39
|
-
[日本語](/readme/ja.md) |
|
|
40
|
-
[한국어](/readme/ko.md)
|
|
41
|
-
|
|
42
|
-
Mind elixir is a open source JavaScript mind map core. You can use it with any frontend framework you like.
|
|
43
|
-
|
|
44
|
-
## Features
|
|
45
|
-
|
|
46
|
-
### 🎨 **User Experience**
|
|
47
|
-
|
|
48
|
-
- **Fluent UX** - Smooth and intuitive interactions
|
|
49
|
-
- **Well designed** - Clean and modern interface
|
|
50
|
-
- **Mobile friendly** - Touch events for mobile devices
|
|
51
|
-
- **Efficient shortcuts** - Keyboard shortcuts for power users
|
|
52
|
-
|
|
53
|
-
### ⚡ **Performance & Architecture**
|
|
54
|
-
|
|
55
|
-
- **Lightweight** - Minimal bundle size
|
|
56
|
-
- **High performance** - Optimized for large mind maps
|
|
57
|
-
- **Framework agnostic** - Works with any frontend framework
|
|
58
|
-
- **Pluginable** - Extensible architecture
|
|
59
|
-
|
|
60
|
-
### 🛠️ **Core Features**
|
|
61
|
-
|
|
62
|
-
- **Interactive editing** - Built-in drag and drop / node edit capabilities
|
|
63
|
-
- **Bulk operations** - Multi-node selection and operations
|
|
64
|
-
- **Undo / Redo** - Complete operation history
|
|
65
|
-
- **Node connections & summarization** - Custom node linking and content summarization
|
|
66
|
-
|
|
67
|
-
### 📤 **Export & Customization**
|
|
68
|
-
|
|
69
|
-
- **Multiple export formats** - SVG / PNG / HTML export
|
|
70
|
-
- **Easy styling** - Customize mindmap with CSS variables
|
|
71
|
-
- **Theme support** - Built-in themes and custom styling
|
|
72
|
-
|
|
73
|
-
[v5 Breaking Changes](https://github.com/SSShooter/mind-elixir-core/wiki/Breaking-Change#500)
|
|
74
|
-
|
|
75
|
-
## Build with AI
|
|
76
|
-
|
|
77
|
-
Use `npx skills add` to install guides to your project:
|
|
78
|
-
|
|
79
|
-
**Integration Guide**:
|
|
80
|
-
|
|
81
|
-
```bash
|
|
82
|
-
npx skills add https://github.com/ssshooter/mind-elixir-core/blob/master/skills/integrate-mind-elixir
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
**Other Skills**:
|
|
86
|
-
|
|
87
|
-
- [Customize Markdown](skills/customize-markdown/SKILL.md): `npx skills add https://github.com/ssshooter/mind-elixir-core/blob/master/skills/customize-markdown`
|
|
88
|
-
- [Export as Image](skills/export-mindmap-image/SKILL.md): `npx skills add https://github.com/ssshooter/mind-elixir-core/blob/master/skills/export-mindmap-image`
|
|
89
|
-
- [Streaming Mindmap](skills/streaming-mindmap/SKILL.md): `npx skills add https://github.com/ssshooter/mind-elixir-core/blob/master/skills/streaming-mindmap`
|
|
90
|
-
|
|
91
|
-
<details>
|
|
92
|
-
<summary>Table of Contents</summary>
|
|
93
|
-
|
|
94
|
-
- [Used by](#used-by)
|
|
95
|
-
- [Features](#features)
|
|
96
|
-
- [🎨 **User Experience**](#-user-experience)
|
|
97
|
-
- [⚡ **Performance \& Architecture**](#-performance--architecture)
|
|
98
|
-
- [🛠️ **Core Features**](#️-core-features)
|
|
99
|
-
- [📤 **Export \& Customization**](#-export--customization)
|
|
100
|
-
- [Build with AI](#%EF%B8%8F-build-with-ai)
|
|
101
|
-
- [Try now](#try-now)
|
|
102
|
-
- [Playground](#playground)
|
|
103
|
-
- [Documentation](#documentation)
|
|
104
|
-
- [Usage](#usage)
|
|
105
|
-
- [Install](#install)
|
|
106
|
-
- [NPM](#npm)
|
|
107
|
-
- [Script tag](#script-tag)
|
|
108
|
-
- [Init](#init)
|
|
109
|
-
- [Data Structure](#data-structure)
|
|
110
|
-
- [Event Handling](#event-handling)
|
|
111
|
-
- [Data Export And Import](#data-export-and-import)
|
|
112
|
-
- [Markdown Support](#markdown-support)
|
|
113
|
-
- [Operation Guards](#operation-guards)
|
|
114
|
-
- [Export as a Image](#export-as-a-image)
|
|
115
|
-
- [Deprecated API](#deprecated-api)
|
|
116
|
-
- [Theme](#theme)
|
|
117
|
-
- [Shortcuts](#shortcuts)
|
|
118
|
-
- [Who's using](#whos-using)
|
|
119
|
-
- [Ecosystem](#ecosystem)
|
|
120
|
-
- [Development](#development)
|
|
121
|
-
- [Acknowledgments](#acknowledgments)
|
|
122
|
-
- [Contributors](#contributors)
|
|
123
|
-
|
|
124
|
-
</details>
|
|
125
|
-
|
|
126
|
-
## Used by
|
|
127
|
-
|
|
128
|
-
<a href="https://dependents.info/SSShooter/mind-elixir-core">
|
|
129
|
-
<img src="https://dependents.info/SSShooter/mind-elixir-core/image" alt="network dependents image" />
|
|
130
|
-
</a>
|
|
131
|
-
|
|
132
|
-
## Try now
|
|
133
|
-
|
|
134
|
-

|
|
135
|
-
|
|
136
|
-
### Playground
|
|
137
|
-
|
|
138
|
-
- Vanilla JS - https://codepen.io/ssshooter/pen/vEOqWjE
|
|
139
|
-
- React - https://codesandbox.io/p/devbox/mind-elixir-3-x-react-18-x-forked-f3mtcd
|
|
140
|
-
- Vue3 - https://codesandbox.io/p/sandbox/mind-elixir-3-x-vue3-lth484
|
|
141
|
-
|
|
142
|
-
## Documentation
|
|
143
|
-
|
|
144
|
-
https://docs.mind-elixir.com/
|
|
145
|
-
|
|
146
|
-
## Usage
|
|
147
|
-
|
|
148
|
-
### Install
|
|
149
|
-
|
|
150
|
-
#### NPM
|
|
151
|
-
|
|
152
|
-
```bash
|
|
153
|
-
npm i mind-elixir -S
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
```javascript
|
|
157
|
-
import MindElixir from 'mind-elixir'
|
|
158
|
-
import 'mind-elixir/style.css'
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
#### Script tag
|
|
162
|
-
|
|
163
|
-
```html
|
|
164
|
-
<script type="module" src="https://cdn.jsdelivr.net/npm/mind-elixir/dist/MindElixir.js"></script>
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
And in your CSS file:
|
|
168
|
-
|
|
169
|
-
```css
|
|
170
|
-
@import 'https://cdn.jsdelivr.net/npm/mind-elixir/dist/style.css';
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
### Init
|
|
174
|
-
|
|
175
|
-
```html
|
|
176
|
-
<div id="map"></div>
|
|
177
|
-
<style>
|
|
178
|
-
#map {
|
|
179
|
-
height: 500px;
|
|
180
|
-
width: 100%;
|
|
181
|
-
}
|
|
182
|
-
</style>
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
```javascript
|
|
186
|
-
import MindElixir from 'mind-elixir'
|
|
187
|
-
import 'mind-elixir/style.css'
|
|
188
|
-
import example from 'mind-elixir/dist/example1'
|
|
189
|
-
|
|
190
|
-
let options = {
|
|
191
|
-
el: '#map', // or HTMLDivElement
|
|
192
|
-
direction: MindElixir.LEFT,
|
|
193
|
-
toolBar: true, // default true
|
|
194
|
-
keypress: true, // default true
|
|
195
|
-
locale: 'en', // [zh_CN,zh_TW,en,ja,pt,ru,ro] waiting for PRs
|
|
196
|
-
overflowHidden: false, // default false
|
|
197
|
-
mainLinkStyle: 2, // [1,2] default 1
|
|
198
|
-
mouseSelectionButton: 0, // 0 for left button, 2 for right button, default 0
|
|
199
|
-
contextMenu: {
|
|
200
|
-
focus: true,
|
|
201
|
-
link: true,
|
|
202
|
-
extend: [
|
|
203
|
-
{
|
|
204
|
-
name: 'Node edit',
|
|
205
|
-
onclick: () => {
|
|
206
|
-
alert('extend menu')
|
|
207
|
-
},
|
|
208
|
-
},
|
|
209
|
-
],
|
|
210
|
-
}, // default true
|
|
211
|
-
before: {
|
|
212
|
-
insertSibling(type, obj) {
|
|
213
|
-
return true
|
|
214
|
-
},
|
|
215
|
-
},
|
|
216
|
-
// Custom markdown parser (optional)
|
|
217
|
-
// markdown: (text) => customMarkdownParser(text), // provide your own markdown parser function
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
let mind = new MindElixir(options)
|
|
221
|
-
|
|
222
|
-
mind.install(plugin) // install your plugin
|
|
223
|
-
|
|
224
|
-
// create new map data
|
|
225
|
-
const data = MindElixir.new('new topic')
|
|
226
|
-
// or `example`
|
|
227
|
-
// or the data return from `.getData()`
|
|
228
|
-
mind.init(data)
|
|
229
|
-
|
|
230
|
-
// get a node
|
|
231
|
-
MindElixir.E('node-id')
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
### Data Structure
|
|
235
|
-
|
|
236
|
-
```javascript
|
|
237
|
-
// whole node data structure up to now
|
|
238
|
-
const nodeData = {
|
|
239
|
-
topic: 'node topic',
|
|
240
|
-
id: 'bd1c24420cd2c2f5',
|
|
241
|
-
style: { fontSize: '32', color: '#3298db', background: '#ecf0f1' },
|
|
242
|
-
expanded: true,
|
|
243
|
-
parent: null,
|
|
244
|
-
tags: ['Tag'],
|
|
245
|
-
icons: ['😀'],
|
|
246
|
-
hyperLink: 'https://github.com/ssshooter/mind-elixir-core',
|
|
247
|
-
image: {
|
|
248
|
-
url: 'https://raw.githubusercontent.com/ssshooter/mind-elixir-core/master/images/logo2.png', // required
|
|
249
|
-
// you need to query the height and width of the image and calculate the appropriate value to display the image
|
|
250
|
-
height: 90, // required
|
|
251
|
-
width: 90, // required
|
|
252
|
-
},
|
|
253
|
-
children: [
|
|
254
|
-
{
|
|
255
|
-
topic: 'child',
|
|
256
|
-
id: 'xxxx',
|
|
257
|
-
// ...
|
|
258
|
-
},
|
|
259
|
-
],
|
|
260
|
-
}
|
|
261
|
-
```
|
|
262
|
-
|
|
263
|
-
### Event Handling
|
|
264
|
-
|
|
265
|
-
```javascript
|
|
266
|
-
mind.bus.addListener('operation', operation => {
|
|
267
|
-
console.log(operation)
|
|
268
|
-
// return {
|
|
269
|
-
// name: action name,
|
|
270
|
-
// obj: target object
|
|
271
|
-
// }
|
|
272
|
-
|
|
273
|
-
// name: [insertSibling|addChild|removeNode|beginEdit|finishEdit]
|
|
274
|
-
// obj: target
|
|
275
|
-
|
|
276
|
-
// name: moveNode
|
|
277
|
-
// obj: {from:target1,to:target2}
|
|
278
|
-
})
|
|
279
|
-
|
|
280
|
-
mind.bus.addListener('selectNodes', nodes => {
|
|
281
|
-
console.log(nodes)
|
|
282
|
-
})
|
|
283
|
-
|
|
284
|
-
mind.bus.addListener('expandNode', node => {
|
|
285
|
-
console.log('expandNode: ', node)
|
|
286
|
-
})
|
|
287
|
-
```
|
|
288
|
-
|
|
289
|
-
### Data Export And Import
|
|
290
|
-
|
|
291
|
-
```javascript
|
|
292
|
-
// data export
|
|
293
|
-
const data = mind.getData() // javascript object, see src/example.js
|
|
294
|
-
mind.getDataString() // stringify object
|
|
295
|
-
|
|
296
|
-
// data import
|
|
297
|
-
// initiate
|
|
298
|
-
let mind = new MindElixir(options)
|
|
299
|
-
mind.init(data)
|
|
300
|
-
// data update
|
|
301
|
-
mind.refresh(data)
|
|
302
|
-
```
|
|
303
|
-
|
|
304
|
-
### Markdown Support
|
|
305
|
-
|
|
306
|
-
Mind Elixir supports custom markdown parsing:
|
|
307
|
-
|
|
308
|
-
```javascript
|
|
309
|
-
// Disable markdown (default)
|
|
310
|
-
let mind = new MindElixir({
|
|
311
|
-
// markdown option omitted - no markdown processing
|
|
312
|
-
})
|
|
313
|
-
|
|
314
|
-
// Use custom markdown parser
|
|
315
|
-
let mind = new MindElixir({
|
|
316
|
-
markdown: text => {
|
|
317
|
-
// Your custom markdown implementation
|
|
318
|
-
return text
|
|
319
|
-
.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
|
|
320
|
-
.replace(/\*(.*?)\*/g, '<em>$1</em>')
|
|
321
|
-
.replace(/`(.*?)`/g, '<code>$1</code>')
|
|
322
|
-
},
|
|
323
|
-
})
|
|
324
|
-
|
|
325
|
-
// Use any markdown library (e.g., marked, markdown-it, etc.)
|
|
326
|
-
import { marked } from 'marked'
|
|
327
|
-
let mind = new MindElixir({
|
|
328
|
-
markdown: text => marked(text),
|
|
329
|
-
})
|
|
330
|
-
```
|
|
331
|
-
|
|
332
|
-
### Operation Guards
|
|
333
|
-
|
|
334
|
-
```javascript
|
|
335
|
-
let mind = new MindElixir({
|
|
336
|
-
// ...
|
|
337
|
-
before: {
|
|
338
|
-
async addChild(el, obj) {
|
|
339
|
-
try {
|
|
340
|
-
await saveDataToDb()
|
|
341
|
-
return true
|
|
342
|
-
} catch (err) {
|
|
343
|
-
return false
|
|
344
|
-
}
|
|
345
|
-
},
|
|
346
|
-
},
|
|
347
|
-
})
|
|
348
|
-
```
|
|
349
|
-
|
|
350
|
-
## Export as a Image
|
|
351
|
-
|
|
352
|
-
Install `@zumer/snapdom`, then:
|
|
353
|
-
|
|
354
|
-
```typescript
|
|
355
|
-
import { snapdom } from '@zumer/snapdom'
|
|
356
|
-
|
|
357
|
-
const download = async () => {
|
|
358
|
-
const result = await snapdom(mind.nodes)
|
|
359
|
-
await result.download({ format: 'jpg', filename: 'my-capture' })
|
|
360
|
-
}
|
|
361
|
-
```
|
|
362
|
-
|
|
363
|
-
For other export formats and advanced options, see the [Mind Elixir documentation](https://ssshooter.com/en/how-to-use-mind-elixir/#exporting-images).
|
|
364
|
-
|
|
365
|
-
### Deprecated API
|
|
366
|
-
|
|
367
|
-
> ⚠️ **Deprecated**: The `mind.exportSvg()` method is deprecated and will be removed in a future version.
|
|
368
|
-
|
|
369
|
-
```typescript
|
|
370
|
-
// DEPRECATED - Do not use in new projects
|
|
371
|
-
const svgData = await mind.exportSvg()
|
|
372
|
-
```
|
|
373
|
-
|
|
374
|
-
## Theme
|
|
375
|
-
|
|
376
|
-
```javascript
|
|
377
|
-
const options = {
|
|
378
|
-
// ...
|
|
379
|
-
theme: {
|
|
380
|
-
name: 'Dark',
|
|
381
|
-
// main lines color palette
|
|
382
|
-
palette: ['#848FA0', '#748BE9', '#D2F9FE', '#4145A5', '#789AFA', '#706CF4', '#EF987F', '#775DD5', '#FCEECF', '#DA7FBC'],
|
|
383
|
-
// overwrite css variables
|
|
384
|
-
cssVar: {
|
|
385
|
-
'--main-color': '#ffffff',
|
|
386
|
-
'--main-bgcolor': '#4c4f69',
|
|
387
|
-
'--color': '#cccccc',
|
|
388
|
-
'--bgcolor': '#252526',
|
|
389
|
-
'--panel-color': '255, 255, 255',
|
|
390
|
-
'--panel-bgcolor': '45, 55, 72',
|
|
391
|
-
},
|
|
392
|
-
// all variables see /src/index.less
|
|
393
|
-
},
|
|
394
|
-
// ...
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
// ...
|
|
398
|
-
|
|
399
|
-
mind.changeTheme({
|
|
400
|
-
name: 'Latte',
|
|
401
|
-
palette: ['#dd7878', '#ea76cb', '#8839ef', '#e64553', '#fe640b', '#df8e1d', '#40a02b', '#209fb5', '#1e66f5', '#7287fd'],
|
|
402
|
-
cssVar: {
|
|
403
|
-
'--main-color': '#444446',
|
|
404
|
-
'--main-bgcolor': '#ffffff',
|
|
405
|
-
'--color': '#777777',
|
|
406
|
-
'--bgcolor': '#f6f6f6',
|
|
407
|
-
},
|
|
408
|
-
})
|
|
409
|
-
```
|
|
410
|
-
|
|
411
|
-
Be aware that Mind Elixir will not observe the change of `prefers-color-scheme`. Please change the theme **manually** when the scheme changes.
|
|
412
|
-
|
|
413
|
-
## Shortcuts
|
|
414
|
-
|
|
415
|
-
See [Shortcuts Guide](https://docs.mind-elixir.com/docs/guides/shortcuts) for detailed information.
|
|
416
|
-
|
|
417
|
-
## Who's using
|
|
418
|
-
|
|
419
|
-
- [Mind Elixir Desktop](https://desktop.mind-elixir.com/)
|
|
420
|
-
- [ebook-to-mindmap](https://github.com/SSShooter/ebook-to-mindmap)
|
|
421
|
-
- [M10C-Video-Summary](https://github.com/SSShooter/M10C-Video-Summary)
|
|
422
|
-
|
|
423
|
-
## Ecosystem
|
|
424
|
-
|
|
425
|
-
- [@mind-elixir/node-menu](https://github.com/ssshooter/node-menu)
|
|
426
|
-
- [@mind-elixir/node-menu-neo](https://github.com/ssshooter/node-menu-neo)
|
|
427
|
-
- [@mind-elixir/export-xmind](https://github.com/ssshooter/export-xmind)
|
|
428
|
-
- [@mind-elixir/export-html](https://github.com/ssshooter/export-html)
|
|
429
|
-
- [mind-elixir-react](https://github.com/ssshooter/mind-elixir-react)
|
|
430
|
-
|
|
431
|
-
PRs are welcome!
|
|
432
|
-
|
|
433
|
-
## Development
|
|
434
|
-
|
|
435
|
-
```
|
|
436
|
-
pnpm i
|
|
437
|
-
pnpm dev
|
|
438
|
-
```
|
|
439
|
-
|
|
440
|
-
Test generated files with `dev.dist.ts`:
|
|
441
|
-
|
|
442
|
-
```
|
|
443
|
-
pnpm build
|
|
444
|
-
pnpm link ./
|
|
445
|
-
```
|
|
446
|
-
|
|
447
|
-
Update docs:
|
|
448
|
-
|
|
449
|
-
```
|
|
450
|
-
# Install api-extractor
|
|
451
|
-
pnpm install -g @microsoft/api-extractor
|
|
452
|
-
# Maintain /src/docs.ts
|
|
453
|
-
# Generate docs
|
|
454
|
-
pnpm doc
|
|
455
|
-
pnpm doc:md
|
|
456
|
-
```
|
|
457
|
-
|
|
458
|
-
Use [DeepWiki](https://deepwiki.com/SSShooter/mind-elixir-core) to learn more about Mind Elixir
|
|
459
|
-
|
|
460
|
-
## Acknowledgments
|
|
461
|
-
|
|
462
|
-
- [@viselect/vanilla](https://github.com/simonwep/selection/tree/master/packages/vanilla)
|
|
463
|
-
|
|
464
|
-
## Contributors
|
|
465
|
-
|
|
466
|
-
Thanks for your contributions to Mind Elixir! Your support and dedication make this project better.
|
|
467
|
-
|
|
468
|
-
<a href="https://github.com/SSShooter/mind-elixir-core/graphs/contributors">
|
|
469
|
-
<img src="https://contrib.rocks/image?repo=SSShooter/mind-elixir-core" />
|
|
470
|
-
</a>
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="https://docs.mind-elixir.com" target="_blank" rel="noopener noreferrer">
|
|
3
|
+
<img width="150" src="https://raw.githubusercontent.com/ssshooter/mind-elixir-core/master/images/logo2.png" alt="mindelixir logo2">
|
|
4
|
+
</a>
|
|
5
|
+
<h1 align="center">Mind Elixir</h1>
|
|
6
|
+
</p>
|
|
7
|
+
|
|
8
|
+
<p align="center">
|
|
9
|
+
<a href="https://trendshift.io/repositories/13049" target="_blank"><img src="https://trendshift.io/api/badge/repositories/13049" alt="SSShooter%2Fmind-elixir-core | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
<p align="center">
|
|
13
|
+
<a href="https://www.npmjs.com/package/mind-elixir">
|
|
14
|
+
<img src="https://img.shields.io/npm/v/mind-elixir" alt="version">
|
|
15
|
+
</a>
|
|
16
|
+
<a href="https://github.com/ssshooter/mind-elixir-core/blob/master/LICENSE">
|
|
17
|
+
<img src="https://img.shields.io/npm/l/mind-elixir" alt="license">
|
|
18
|
+
</a>
|
|
19
|
+
<a href="https://app.codacy.com/gh/ssshooter/mind-elixir-core?utm_source=github.com&utm_medium=referral&utm_content=ssshooter/mind-elixir-core&utm_campaign=Badge_Grade_Settings">
|
|
20
|
+
<img src="https://api.codacy.com/project/badge/Grade/09fadec5bf094886b30cea6aabf3a88b" alt="code quality">
|
|
21
|
+
</a>
|
|
22
|
+
<a href="https://bundlephobia.com/result?p=mind-elixir">
|
|
23
|
+
<img src="https://badgen.net/bundlephobia/dependency-count/mind-elixir" alt="dependency-count">
|
|
24
|
+
</a>
|
|
25
|
+
<a href="https://dependents.info/SSShooter/mind-elixir-core">
|
|
26
|
+
<img src="https://dependents.info/SSShooter/mind-elixir-core/badge" alt="dependents count badge" />
|
|
27
|
+
</a>
|
|
28
|
+
<a href="https://packagephobia.com/result?p=mind-elixir">
|
|
29
|
+
<img src="https://packagephobia.com/badge?p=mind-elixir" alt="package size">
|
|
30
|
+
</a>
|
|
31
|
+
</p>
|
|
32
|
+
|
|
33
|
+
[English](/readme.md) |
|
|
34
|
+
[中文](/readme/zh.md) |
|
|
35
|
+
[Español](/readme/es.md) |
|
|
36
|
+
[Français](/readme/fr.md) |
|
|
37
|
+
[Português](/readme/pt.md) |
|
|
38
|
+
[Русский](/readme/ru.md) |
|
|
39
|
+
[日本語](/readme/ja.md) |
|
|
40
|
+
[한국어](/readme/ko.md)
|
|
41
|
+
|
|
42
|
+
Mind elixir is a open source JavaScript mind map core. You can use it with any frontend framework you like.
|
|
43
|
+
|
|
44
|
+
## Features
|
|
45
|
+
|
|
46
|
+
### 🎨 **User Experience**
|
|
47
|
+
|
|
48
|
+
- **Fluent UX** - Smooth and intuitive interactions
|
|
49
|
+
- **Well designed** - Clean and modern interface
|
|
50
|
+
- **Mobile friendly** - Touch events for mobile devices
|
|
51
|
+
- **Efficient shortcuts** - Keyboard shortcuts for power users
|
|
52
|
+
|
|
53
|
+
### ⚡ **Performance & Architecture**
|
|
54
|
+
|
|
55
|
+
- **Lightweight** - Minimal bundle size
|
|
56
|
+
- **High performance** - Optimized for large mind maps
|
|
57
|
+
- **Framework agnostic** - Works with any frontend framework
|
|
58
|
+
- **Pluginable** - Extensible architecture
|
|
59
|
+
|
|
60
|
+
### 🛠️ **Core Features**
|
|
61
|
+
|
|
62
|
+
- **Interactive editing** - Built-in drag and drop / node edit capabilities
|
|
63
|
+
- **Bulk operations** - Multi-node selection and operations
|
|
64
|
+
- **Undo / Redo** - Complete operation history
|
|
65
|
+
- **Node connections & summarization** - Custom node linking and content summarization
|
|
66
|
+
|
|
67
|
+
### 📤 **Export & Customization**
|
|
68
|
+
|
|
69
|
+
- **Multiple export formats** - SVG / PNG / HTML export
|
|
70
|
+
- **Easy styling** - Customize mindmap with CSS variables
|
|
71
|
+
- **Theme support** - Built-in themes and custom styling
|
|
72
|
+
|
|
73
|
+
[v5 Breaking Changes](https://github.com/SSShooter/mind-elixir-core/wiki/Breaking-Change#500)
|
|
74
|
+
|
|
75
|
+
## Build with AI
|
|
76
|
+
|
|
77
|
+
Use `npx skills add` to install guides to your project:
|
|
78
|
+
|
|
79
|
+
**Integration Guide**:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
npx skills add https://github.com/ssshooter/mind-elixir-core/blob/master/skills/integrate-mind-elixir
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**Other Skills**:
|
|
86
|
+
|
|
87
|
+
- [Customize Markdown](skills/customize-markdown/SKILL.md): `npx skills add https://github.com/ssshooter/mind-elixir-core/blob/master/skills/customize-markdown`
|
|
88
|
+
- [Export as Image](skills/export-mindmap-image/SKILL.md): `npx skills add https://github.com/ssshooter/mind-elixir-core/blob/master/skills/export-mindmap-image`
|
|
89
|
+
- [Streaming Mindmap](skills/streaming-mindmap/SKILL.md): `npx skills add https://github.com/ssshooter/mind-elixir-core/blob/master/skills/streaming-mindmap`
|
|
90
|
+
|
|
91
|
+
<details>
|
|
92
|
+
<summary>Table of Contents</summary>
|
|
93
|
+
|
|
94
|
+
- [Used by](#used-by)
|
|
95
|
+
- [Features](#features)
|
|
96
|
+
- [🎨 **User Experience**](#-user-experience)
|
|
97
|
+
- [⚡ **Performance \& Architecture**](#-performance--architecture)
|
|
98
|
+
- [🛠️ **Core Features**](#️-core-features)
|
|
99
|
+
- [📤 **Export \& Customization**](#-export--customization)
|
|
100
|
+
- [Build with AI](#%EF%B8%8F-build-with-ai)
|
|
101
|
+
- [Try now](#try-now)
|
|
102
|
+
- [Playground](#playground)
|
|
103
|
+
- [Documentation](#documentation)
|
|
104
|
+
- [Usage](#usage)
|
|
105
|
+
- [Install](#install)
|
|
106
|
+
- [NPM](#npm)
|
|
107
|
+
- [Script tag](#script-tag)
|
|
108
|
+
- [Init](#init)
|
|
109
|
+
- [Data Structure](#data-structure)
|
|
110
|
+
- [Event Handling](#event-handling)
|
|
111
|
+
- [Data Export And Import](#data-export-and-import)
|
|
112
|
+
- [Markdown Support](#markdown-support)
|
|
113
|
+
- [Operation Guards](#operation-guards)
|
|
114
|
+
- [Export as a Image](#export-as-a-image)
|
|
115
|
+
- [Deprecated API](#deprecated-api)
|
|
116
|
+
- [Theme](#theme)
|
|
117
|
+
- [Shortcuts](#shortcuts)
|
|
118
|
+
- [Who's using](#whos-using)
|
|
119
|
+
- [Ecosystem](#ecosystem)
|
|
120
|
+
- [Development](#development)
|
|
121
|
+
- [Acknowledgments](#acknowledgments)
|
|
122
|
+
- [Contributors](#contributors)
|
|
123
|
+
|
|
124
|
+
</details>
|
|
125
|
+
|
|
126
|
+
## Used by
|
|
127
|
+
|
|
128
|
+
<a href="https://dependents.info/SSShooter/mind-elixir-core">
|
|
129
|
+
<img src="https://dependents.info/SSShooter/mind-elixir-core/image" alt="network dependents image" />
|
|
130
|
+
</a>
|
|
131
|
+
|
|
132
|
+
## Try now
|
|
133
|
+
|
|
134
|
+

|
|
135
|
+
|
|
136
|
+
### Playground
|
|
137
|
+
|
|
138
|
+
- Vanilla JS - https://codepen.io/ssshooter/pen/vEOqWjE
|
|
139
|
+
- React - https://codesandbox.io/p/devbox/mind-elixir-3-x-react-18-x-forked-f3mtcd
|
|
140
|
+
- Vue3 - https://codesandbox.io/p/sandbox/mind-elixir-3-x-vue3-lth484
|
|
141
|
+
|
|
142
|
+
## Documentation
|
|
143
|
+
|
|
144
|
+
https://docs.mind-elixir.com/
|
|
145
|
+
|
|
146
|
+
## Usage
|
|
147
|
+
|
|
148
|
+
### Install
|
|
149
|
+
|
|
150
|
+
#### NPM
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
npm i mind-elixir -S
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
```javascript
|
|
157
|
+
import MindElixir from 'mind-elixir'
|
|
158
|
+
import 'mind-elixir/style.css'
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
#### Script tag
|
|
162
|
+
|
|
163
|
+
```html
|
|
164
|
+
<script type="module" src="https://cdn.jsdelivr.net/npm/mind-elixir/dist/MindElixir.js"></script>
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
And in your CSS file:
|
|
168
|
+
|
|
169
|
+
```css
|
|
170
|
+
@import 'https://cdn.jsdelivr.net/npm/mind-elixir/dist/style.css';
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Init
|
|
174
|
+
|
|
175
|
+
```html
|
|
176
|
+
<div id="map"></div>
|
|
177
|
+
<style>
|
|
178
|
+
#map {
|
|
179
|
+
height: 500px;
|
|
180
|
+
width: 100%;
|
|
181
|
+
}
|
|
182
|
+
</style>
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
```javascript
|
|
186
|
+
import MindElixir from 'mind-elixir'
|
|
187
|
+
import 'mind-elixir/style.css'
|
|
188
|
+
import example from 'mind-elixir/dist/example1'
|
|
189
|
+
|
|
190
|
+
let options = {
|
|
191
|
+
el: '#map', // or HTMLDivElement
|
|
192
|
+
direction: MindElixir.LEFT,
|
|
193
|
+
toolBar: true, // default true
|
|
194
|
+
keypress: true, // default true
|
|
195
|
+
locale: 'en', // [zh_CN,zh_TW,en,ja,pt,ru,ro] waiting for PRs
|
|
196
|
+
overflowHidden: false, // default false
|
|
197
|
+
mainLinkStyle: 2, // [1,2] default 1
|
|
198
|
+
mouseSelectionButton: 0, // 0 for left button, 2 for right button, default 0
|
|
199
|
+
contextMenu: {
|
|
200
|
+
focus: true,
|
|
201
|
+
link: true,
|
|
202
|
+
extend: [
|
|
203
|
+
{
|
|
204
|
+
name: 'Node edit',
|
|
205
|
+
onclick: () => {
|
|
206
|
+
alert('extend menu')
|
|
207
|
+
},
|
|
208
|
+
},
|
|
209
|
+
],
|
|
210
|
+
}, // default true
|
|
211
|
+
before: {
|
|
212
|
+
insertSibling(type, obj) {
|
|
213
|
+
return true
|
|
214
|
+
},
|
|
215
|
+
},
|
|
216
|
+
// Custom markdown parser (optional)
|
|
217
|
+
// markdown: (text) => customMarkdownParser(text), // provide your own markdown parser function
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
let mind = new MindElixir(options)
|
|
221
|
+
|
|
222
|
+
mind.install(plugin) // install your plugin
|
|
223
|
+
|
|
224
|
+
// create new map data
|
|
225
|
+
const data = MindElixir.new('new topic')
|
|
226
|
+
// or `example`
|
|
227
|
+
// or the data return from `.getData()`
|
|
228
|
+
mind.init(data)
|
|
229
|
+
|
|
230
|
+
// get a node
|
|
231
|
+
MindElixir.E('node-id')
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Data Structure
|
|
235
|
+
|
|
236
|
+
```javascript
|
|
237
|
+
// whole node data structure up to now
|
|
238
|
+
const nodeData = {
|
|
239
|
+
topic: 'node topic',
|
|
240
|
+
id: 'bd1c24420cd2c2f5',
|
|
241
|
+
style: { fontSize: '32', color: '#3298db', background: '#ecf0f1' },
|
|
242
|
+
expanded: true,
|
|
243
|
+
parent: null,
|
|
244
|
+
tags: ['Tag'],
|
|
245
|
+
icons: ['😀'],
|
|
246
|
+
hyperLink: 'https://github.com/ssshooter/mind-elixir-core',
|
|
247
|
+
image: {
|
|
248
|
+
url: 'https://raw.githubusercontent.com/ssshooter/mind-elixir-core/master/images/logo2.png', // required
|
|
249
|
+
// you need to query the height and width of the image and calculate the appropriate value to display the image
|
|
250
|
+
height: 90, // required
|
|
251
|
+
width: 90, // required
|
|
252
|
+
},
|
|
253
|
+
children: [
|
|
254
|
+
{
|
|
255
|
+
topic: 'child',
|
|
256
|
+
id: 'xxxx',
|
|
257
|
+
// ...
|
|
258
|
+
},
|
|
259
|
+
],
|
|
260
|
+
}
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### Event Handling
|
|
264
|
+
|
|
265
|
+
```javascript
|
|
266
|
+
mind.bus.addListener('operation', operation => {
|
|
267
|
+
console.log(operation)
|
|
268
|
+
// return {
|
|
269
|
+
// name: action name,
|
|
270
|
+
// obj: target object
|
|
271
|
+
// }
|
|
272
|
+
|
|
273
|
+
// name: [insertSibling|addChild|removeNode|beginEdit|finishEdit]
|
|
274
|
+
// obj: target
|
|
275
|
+
|
|
276
|
+
// name: moveNode
|
|
277
|
+
// obj: {from:target1,to:target2}
|
|
278
|
+
})
|
|
279
|
+
|
|
280
|
+
mind.bus.addListener('selectNodes', nodes => {
|
|
281
|
+
console.log(nodes)
|
|
282
|
+
})
|
|
283
|
+
|
|
284
|
+
mind.bus.addListener('expandNode', node => {
|
|
285
|
+
console.log('expandNode: ', node)
|
|
286
|
+
})
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### Data Export And Import
|
|
290
|
+
|
|
291
|
+
```javascript
|
|
292
|
+
// data export
|
|
293
|
+
const data = mind.getData() // javascript object, see src/example.js
|
|
294
|
+
mind.getDataString() // stringify object
|
|
295
|
+
|
|
296
|
+
// data import
|
|
297
|
+
// initiate
|
|
298
|
+
let mind = new MindElixir(options)
|
|
299
|
+
mind.init(data)
|
|
300
|
+
// data update
|
|
301
|
+
mind.refresh(data)
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### Markdown Support
|
|
305
|
+
|
|
306
|
+
Mind Elixir supports custom markdown parsing:
|
|
307
|
+
|
|
308
|
+
```javascript
|
|
309
|
+
// Disable markdown (default)
|
|
310
|
+
let mind = new MindElixir({
|
|
311
|
+
// markdown option omitted - no markdown processing
|
|
312
|
+
})
|
|
313
|
+
|
|
314
|
+
// Use custom markdown parser
|
|
315
|
+
let mind = new MindElixir({
|
|
316
|
+
markdown: text => {
|
|
317
|
+
// Your custom markdown implementation
|
|
318
|
+
return text
|
|
319
|
+
.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
|
|
320
|
+
.replace(/\*(.*?)\*/g, '<em>$1</em>')
|
|
321
|
+
.replace(/`(.*?)`/g, '<code>$1</code>')
|
|
322
|
+
},
|
|
323
|
+
})
|
|
324
|
+
|
|
325
|
+
// Use any markdown library (e.g., marked, markdown-it, etc.)
|
|
326
|
+
import { marked } from 'marked'
|
|
327
|
+
let mind = new MindElixir({
|
|
328
|
+
markdown: text => marked(text),
|
|
329
|
+
})
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
### Operation Guards
|
|
333
|
+
|
|
334
|
+
```javascript
|
|
335
|
+
let mind = new MindElixir({
|
|
336
|
+
// ...
|
|
337
|
+
before: {
|
|
338
|
+
async addChild(el, obj) {
|
|
339
|
+
try {
|
|
340
|
+
await saveDataToDb()
|
|
341
|
+
return true
|
|
342
|
+
} catch (err) {
|
|
343
|
+
return false
|
|
344
|
+
}
|
|
345
|
+
},
|
|
346
|
+
},
|
|
347
|
+
})
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
## Export as a Image
|
|
351
|
+
|
|
352
|
+
Install `@zumer/snapdom`, then:
|
|
353
|
+
|
|
354
|
+
```typescript
|
|
355
|
+
import { snapdom } from '@zumer/snapdom'
|
|
356
|
+
|
|
357
|
+
const download = async () => {
|
|
358
|
+
const result = await snapdom(mind.nodes)
|
|
359
|
+
await result.download({ format: 'jpg', filename: 'my-capture' })
|
|
360
|
+
}
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
For other export formats and advanced options, see the [Mind Elixir documentation](https://ssshooter.com/en/how-to-use-mind-elixir/#exporting-images).
|
|
364
|
+
|
|
365
|
+
### Deprecated API
|
|
366
|
+
|
|
367
|
+
> ⚠️ **Deprecated**: The `mind.exportSvg()` method is deprecated and will be removed in a future version.
|
|
368
|
+
|
|
369
|
+
```typescript
|
|
370
|
+
// DEPRECATED - Do not use in new projects
|
|
371
|
+
const svgData = await mind.exportSvg()
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
## Theme
|
|
375
|
+
|
|
376
|
+
```javascript
|
|
377
|
+
const options = {
|
|
378
|
+
// ...
|
|
379
|
+
theme: {
|
|
380
|
+
name: 'Dark',
|
|
381
|
+
// main lines color palette
|
|
382
|
+
palette: ['#848FA0', '#748BE9', '#D2F9FE', '#4145A5', '#789AFA', '#706CF4', '#EF987F', '#775DD5', '#FCEECF', '#DA7FBC'],
|
|
383
|
+
// overwrite css variables
|
|
384
|
+
cssVar: {
|
|
385
|
+
'--main-color': '#ffffff',
|
|
386
|
+
'--main-bgcolor': '#4c4f69',
|
|
387
|
+
'--color': '#cccccc',
|
|
388
|
+
'--bgcolor': '#252526',
|
|
389
|
+
'--panel-color': '255, 255, 255',
|
|
390
|
+
'--panel-bgcolor': '45, 55, 72',
|
|
391
|
+
},
|
|
392
|
+
// all variables see /src/index.less
|
|
393
|
+
},
|
|
394
|
+
// ...
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// ...
|
|
398
|
+
|
|
399
|
+
mind.changeTheme({
|
|
400
|
+
name: 'Latte',
|
|
401
|
+
palette: ['#dd7878', '#ea76cb', '#8839ef', '#e64553', '#fe640b', '#df8e1d', '#40a02b', '#209fb5', '#1e66f5', '#7287fd'],
|
|
402
|
+
cssVar: {
|
|
403
|
+
'--main-color': '#444446',
|
|
404
|
+
'--main-bgcolor': '#ffffff',
|
|
405
|
+
'--color': '#777777',
|
|
406
|
+
'--bgcolor': '#f6f6f6',
|
|
407
|
+
},
|
|
408
|
+
})
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
Be aware that Mind Elixir will not observe the change of `prefers-color-scheme`. Please change the theme **manually** when the scheme changes.
|
|
412
|
+
|
|
413
|
+
## Shortcuts
|
|
414
|
+
|
|
415
|
+
See [Shortcuts Guide](https://docs.mind-elixir.com/docs/guides/shortcuts) for detailed information.
|
|
416
|
+
|
|
417
|
+
## Who's using
|
|
418
|
+
|
|
419
|
+
- [Mind Elixir Desktop](https://desktop.mind-elixir.com/)
|
|
420
|
+
- [ebook-to-mindmap](https://github.com/SSShooter/ebook-to-mindmap)
|
|
421
|
+
- [M10C-Video-Summary](https://github.com/SSShooter/M10C-Video-Summary)
|
|
422
|
+
|
|
423
|
+
## Ecosystem
|
|
424
|
+
|
|
425
|
+
- [@mind-elixir/node-menu](https://github.com/ssshooter/node-menu)
|
|
426
|
+
- [@mind-elixir/node-menu-neo](https://github.com/ssshooter/node-menu-neo)
|
|
427
|
+
- [@mind-elixir/export-xmind](https://github.com/ssshooter/export-xmind)
|
|
428
|
+
- [@mind-elixir/export-html](https://github.com/ssshooter/export-html)
|
|
429
|
+
- [mind-elixir-react](https://github.com/ssshooter/mind-elixir-react)
|
|
430
|
+
|
|
431
|
+
PRs are welcome!
|
|
432
|
+
|
|
433
|
+
## Development
|
|
434
|
+
|
|
435
|
+
```
|
|
436
|
+
pnpm i
|
|
437
|
+
pnpm dev
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
Test generated files with `dev.dist.ts`:
|
|
441
|
+
|
|
442
|
+
```
|
|
443
|
+
pnpm build
|
|
444
|
+
pnpm link ./
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
Update docs:
|
|
448
|
+
|
|
449
|
+
```
|
|
450
|
+
# Install api-extractor
|
|
451
|
+
pnpm install -g @microsoft/api-extractor
|
|
452
|
+
# Maintain /src/docs.ts
|
|
453
|
+
# Generate docs
|
|
454
|
+
pnpm doc
|
|
455
|
+
pnpm doc:md
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
Use [DeepWiki](https://deepwiki.com/SSShooter/mind-elixir-core) to learn more about Mind Elixir
|
|
459
|
+
|
|
460
|
+
## Acknowledgments
|
|
461
|
+
|
|
462
|
+
- [@viselect/vanilla](https://github.com/simonwep/selection/tree/master/packages/vanilla)
|
|
463
|
+
|
|
464
|
+
## Contributors
|
|
465
|
+
|
|
466
|
+
Thanks for your contributions to Mind Elixir! Your support and dedication make this project better.
|
|
467
|
+
|
|
468
|
+
<a href="https://github.com/SSShooter/mind-elixir-core/graphs/contributors">
|
|
469
|
+
<img src="https://contrib.rocks/image?repo=SSShooter/mind-elixir-core" />
|
|
470
|
+
</a>
|