agentic-numerical-control 0.1.5 → 0.1.8
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/README.md +44 -44
- package/dist/jobs.html +137 -0
- package/dist/machine.html +164 -0
- package/dist/server/analysis.js +356 -0
- package/dist/server/autostart.js +18 -18
- package/dist/server/cncjs.js +96 -1
- package/dist/server/history.js +48 -0
- package/dist/server/jobs.js +60 -3
- package/dist/server/machines.js +96 -0
- package/dist/server/program.js +14 -0
- package/dist/server/server.js +365 -52
- package/dist/setup.html +156 -0
- package/dist/viewer.html +299 -265
- package/package.json +73 -73
- package/product.json +8 -8
- package/samples/demo-pocket-profile.nc +130 -130
- package/sim/virtual-port.cjs +134 -134
package/package.json
CHANGED
|
@@ -1,73 +1,73 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "agentic-numerical-control",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Agentic Numerical Control: see and run CNC jobs from your AI assistant. A 3D toolpath viewer, live machine status and job control for CNCjs/GRBL machines.",
|
|
5
|
-
"scripts": {
|
|
6
|
-
"build": "tsc --noEmit -p tsconfig.app.json && cross-env INPUT=viewer.html vite build && tsc -p tsconfig.build.json",
|
|
7
|
-
"dev": "npm run build && tsx server/cli.ts start",
|
|
8
|
-
"dev:serve": "npm run build && tsx server/cli.ts serve",
|
|
9
|
-
"dev:stdio": "npm run build 1>&2 && tsx server/cli.ts stdio",
|
|
10
|
-
"sim:build": "node sim/build.mjs",
|
|
11
|
-
"sim:e2e": "node sim/e2e.mjs",
|
|
12
|
-
"prepack": "npm run build",
|
|
13
|
-
"demo:site": "tsx scripts/build-demo.ts"
|
|
14
|
-
},
|
|
15
|
-
"license": "MIT",
|
|
16
|
-
"dependencies": {
|
|
17
|
-
"@modelcontextprotocol/express": "^2.0.0",
|
|
18
|
-
"@modelcontextprotocol/ext-apps": "^2.0.3",
|
|
19
|
-
"@modelcontextprotocol/node": "^2.0.0",
|
|
20
|
-
"@modelcontextprotocol/server": "^2.0.0",
|
|
21
|
-
"cncjs": "^1.11.5",
|
|
22
|
-
"cors": "^2.8.6",
|
|
23
|
-
"express": "^5.3.0",
|
|
24
|
-
"gcode-toolpath": "^3.0.0",
|
|
25
|
-
"jsonwebtoken": "^9.0.3",
|
|
26
|
-
"socket.io-client": "^2.2.0",
|
|
27
|
-
"three": "^0.186.1",
|
|
28
|
-
"ws": "^8.22.0",
|
|
29
|
-
"zod": "^4.6.7"
|
|
30
|
-
},
|
|
31
|
-
"devDependencies": {
|
|
32
|
-
"@types/cors": "^2.8.19",
|
|
33
|
-
"@types/express": "^5.0.6",
|
|
34
|
-
"@types/jsonwebtoken": "^9.0.10",
|
|
35
|
-
"@types/node": "^26.6.5",
|
|
36
|
-
"@types/three": "^0.186.0",
|
|
37
|
-
"@types/ws": "^8.18.2",
|
|
38
|
-
"cross-env": "^10.1.0",
|
|
39
|
-
"tsx": "^4.23.15",
|
|
40
|
-
"typescript": "^5.9.3",
|
|
41
|
-
"vite": "^6.4.4",
|
|
42
|
-
"vite-plugin-singlefile": "^2.3.3"
|
|
43
|
-
},
|
|
44
|
-
"type": "module",
|
|
45
|
-
"bin": {
|
|
46
|
-
"agentic-numerical-control": "dist/server/cli.js",
|
|
47
|
-
"anc": "dist/server/cli.js"
|
|
48
|
-
},
|
|
49
|
-
"files": [
|
|
50
|
-
"dist",
|
|
51
|
-
"product.json",
|
|
52
|
-
"samples/demo-pocket-profile.nc",
|
|
53
|
-
"sim/virtual-port.cjs"
|
|
54
|
-
],
|
|
55
|
-
"engines": {
|
|
56
|
-
"node": ">=20"
|
|
57
|
-
},
|
|
58
|
-
"homepage": "https://agenticnumericalcontrol.com",
|
|
59
|
-
"keywords": [
|
|
60
|
-
"cnc",
|
|
61
|
-
"grbl",
|
|
62
|
-
"cncjs",
|
|
63
|
-
"mcp",
|
|
64
|
-
"mcp-app",
|
|
65
|
-
"claude",
|
|
66
|
-
"gcode",
|
|
67
|
-
"toolpath"
|
|
68
|
-
],
|
|
69
|
-
"repository": {
|
|
70
|
-
"type": "git",
|
|
71
|
-
"url": "git+https://github.com/EdwardCoventry/agentic-numerical-control.git"
|
|
72
|
-
}
|
|
73
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "agentic-numerical-control",
|
|
3
|
+
"version": "0.1.8",
|
|
4
|
+
"description": "Agentic Numerical Control: see and run CNC jobs from your AI assistant. A 3D toolpath viewer, live machine status and job control for CNCjs/GRBL machines.",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"build": "tsc --noEmit -p tsconfig.app.json && cross-env INPUT=viewer.html vite build && cross-env INPUT=jobs.html vite build && cross-env INPUT=machine.html vite build && cross-env INPUT=setup.html vite build && tsc -p tsconfig.build.json",
|
|
7
|
+
"dev": "npm run build && tsx server/cli.ts start",
|
|
8
|
+
"dev:serve": "npm run build && tsx server/cli.ts serve",
|
|
9
|
+
"dev:stdio": "npm run build 1>&2 && tsx server/cli.ts stdio",
|
|
10
|
+
"sim:build": "node sim/build.mjs",
|
|
11
|
+
"sim:e2e": "node sim/e2e.mjs",
|
|
12
|
+
"prepack": "npm run build",
|
|
13
|
+
"demo:site": "tsx scripts/build-demo.ts && tsx scripts/build-catalogue.ts"
|
|
14
|
+
},
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@modelcontextprotocol/express": "^2.0.0",
|
|
18
|
+
"@modelcontextprotocol/ext-apps": "^2.0.3",
|
|
19
|
+
"@modelcontextprotocol/node": "^2.0.0",
|
|
20
|
+
"@modelcontextprotocol/server": "^2.0.0",
|
|
21
|
+
"cncjs": "^1.11.5",
|
|
22
|
+
"cors": "^2.8.6",
|
|
23
|
+
"express": "^5.3.0",
|
|
24
|
+
"gcode-toolpath": "^3.0.0",
|
|
25
|
+
"jsonwebtoken": "^9.0.3",
|
|
26
|
+
"socket.io-client": "^2.2.0",
|
|
27
|
+
"three": "^0.186.1",
|
|
28
|
+
"ws": "^8.22.0",
|
|
29
|
+
"zod": "^4.6.7"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@types/cors": "^2.8.19",
|
|
33
|
+
"@types/express": "^5.0.6",
|
|
34
|
+
"@types/jsonwebtoken": "^9.0.10",
|
|
35
|
+
"@types/node": "^26.6.5",
|
|
36
|
+
"@types/three": "^0.186.0",
|
|
37
|
+
"@types/ws": "^8.18.2",
|
|
38
|
+
"cross-env": "^10.1.0",
|
|
39
|
+
"tsx": "^4.23.15",
|
|
40
|
+
"typescript": "^5.9.3",
|
|
41
|
+
"vite": "^6.4.4",
|
|
42
|
+
"vite-plugin-singlefile": "^2.3.3"
|
|
43
|
+
},
|
|
44
|
+
"type": "module",
|
|
45
|
+
"bin": {
|
|
46
|
+
"agentic-numerical-control": "dist/server/cli.js",
|
|
47
|
+
"anc": "dist/server/cli.js"
|
|
48
|
+
},
|
|
49
|
+
"files": [
|
|
50
|
+
"dist",
|
|
51
|
+
"product.json",
|
|
52
|
+
"samples/demo-pocket-profile.nc",
|
|
53
|
+
"sim/virtual-port.cjs"
|
|
54
|
+
],
|
|
55
|
+
"engines": {
|
|
56
|
+
"node": ">=20"
|
|
57
|
+
},
|
|
58
|
+
"homepage": "https://agenticnumericalcontrol.com",
|
|
59
|
+
"keywords": [
|
|
60
|
+
"cnc",
|
|
61
|
+
"grbl",
|
|
62
|
+
"cncjs",
|
|
63
|
+
"mcp",
|
|
64
|
+
"mcp-app",
|
|
65
|
+
"claude",
|
|
66
|
+
"gcode",
|
|
67
|
+
"toolpath"
|
|
68
|
+
],
|
|
69
|
+
"repository": {
|
|
70
|
+
"type": "git",
|
|
71
|
+
"url": "git+https://github.com/EdwardCoventry/agentic-numerical-control.git"
|
|
72
|
+
}
|
|
73
|
+
}
|
package/product.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "agentic-numerical-control",
|
|
3
|
-
"displayName": "Agentic Numerical Control",
|
|
4
|
-
"shortName": "anc",
|
|
5
|
-
"dirName": "AgenticNumericalControl",
|
|
6
|
-
"cloudUrl": "https://api.agenticnumericalcontrol.com",
|
|
7
|
-
"siteUrl": "https://agenticnumericalcontrol.com"
|
|
8
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "agentic-numerical-control",
|
|
3
|
+
"displayName": "Agentic Numerical Control",
|
|
4
|
+
"shortName": "anc",
|
|
5
|
+
"dirName": "AgenticNumericalControl",
|
|
6
|
+
"cloudUrl": "https://api.agenticnumericalcontrol.com",
|
|
7
|
+
"siteUrl": "https://agenticnumericalcontrol.com"
|
|
8
|
+
}
|
|
@@ -1,130 +1,130 @@
|
|
|
1
|
-
(Agentic Numerical Control demo: pocket, profile, drill)
|
|
2
|
-
G21 G90 G17 G54
|
|
3
|
-
M3 S12000
|
|
4
|
-
G0 Z5
|
|
5
|
-
G0 X-20.000 Y-12.000
|
|
6
|
-
G1 Z-1.500 F300
|
|
7
|
-
G1 Y-12.000 F1200
|
|
8
|
-
G1 X20.000
|
|
9
|
-
G1 Y-9.000 F1200
|
|
10
|
-
G1 X-20.000
|
|
11
|
-
G1 Y-6.000 F1200
|
|
12
|
-
G1 X20.000
|
|
13
|
-
G1 Y-3.000 F1200
|
|
14
|
-
G1 X-20.000
|
|
15
|
-
G1 Y0.000 F1200
|
|
16
|
-
G1 X20.000
|
|
17
|
-
G1 Y3.000 F1200
|
|
18
|
-
G1 X-20.000
|
|
19
|
-
G1 Y6.000 F1200
|
|
20
|
-
G1 X20.000
|
|
21
|
-
G1 Y9.000 F1200
|
|
22
|
-
G1 X-20.000
|
|
23
|
-
G1 Y12.000 F1200
|
|
24
|
-
G1 X20.000
|
|
25
|
-
G0 Z5
|
|
26
|
-
G0 X-20.000 Y-12.000
|
|
27
|
-
G1 Z-3.000 F300
|
|
28
|
-
G1 Y-12.000 F1200
|
|
29
|
-
G1 X20.000
|
|
30
|
-
G1 Y-9.000 F1200
|
|
31
|
-
G1 X-20.000
|
|
32
|
-
G1 Y-6.000 F1200
|
|
33
|
-
G1 X20.000
|
|
34
|
-
G1 Y-3.000 F1200
|
|
35
|
-
G1 X-20.000
|
|
36
|
-
G1 Y0.000 F1200
|
|
37
|
-
G1 X20.000
|
|
38
|
-
G1 Y3.000 F1200
|
|
39
|
-
G1 X-20.000
|
|
40
|
-
G1 Y6.000 F1200
|
|
41
|
-
G1 X20.000
|
|
42
|
-
G1 Y9.000 F1200
|
|
43
|
-
G1 X-20.000
|
|
44
|
-
G1 Y12.000 F1200
|
|
45
|
-
G1 X20.000
|
|
46
|
-
G0 Z5
|
|
47
|
-
G0 X-29.000 Y-25.000
|
|
48
|
-
G1 Z-2.000 F300
|
|
49
|
-
G1 X29.000 F1000
|
|
50
|
-
G3 X35.000 Y-19.000 I0 J6.000
|
|
51
|
-
G1 Y19.000
|
|
52
|
-
G3 X29.000 Y25.000 I-6.000 J0
|
|
53
|
-
G1 X-29.000
|
|
54
|
-
G3 X-35.000 Y19.000 I0 J-6.000
|
|
55
|
-
G1 Y-19.000
|
|
56
|
-
G3 X-29.000 Y-25.000 I6.000 J0
|
|
57
|
-
G0 Z5
|
|
58
|
-
G0 X-29.000 Y-25.000
|
|
59
|
-
G1 Z-4.000 F300
|
|
60
|
-
G1 X29.000 F1000
|
|
61
|
-
G3 X35.000 Y-19.000 I0 J6.000
|
|
62
|
-
G1 Y19.000
|
|
63
|
-
G3 X29.000 Y25.000 I-6.000 J0
|
|
64
|
-
G1 X-29.000
|
|
65
|
-
G3 X-35.000 Y19.000 I0 J-6.000
|
|
66
|
-
G1 Y-19.000
|
|
67
|
-
G3 X-29.000 Y-25.000 I6.000 J0
|
|
68
|
-
G0 Z5
|
|
69
|
-
G0 X-29.000 Y-25.000
|
|
70
|
-
G1 Z-6.000 F300
|
|
71
|
-
G1 X29.000 F1000
|
|
72
|
-
G3 X35.000 Y-19.000 I0 J6.000
|
|
73
|
-
G1 Y19.000
|
|
74
|
-
G3 X29.000 Y25.000 I-6.000 J0
|
|
75
|
-
G1 X-29.000
|
|
76
|
-
G3 X-35.000 Y19.000 I0 J-6.000
|
|
77
|
-
G1 Y-19.000
|
|
78
|
-
G3 X-29.000 Y-25.000 I6.000 J0
|
|
79
|
-
G0 Z5
|
|
80
|
-
G0 X-28.000 Y-18.000
|
|
81
|
-
G1 Z-2.000 F200
|
|
82
|
-
G0 Z1
|
|
83
|
-
G1 Z-4.000 F200
|
|
84
|
-
G0 Z1
|
|
85
|
-
G1 Z-6.000 F200
|
|
86
|
-
G0 Z1
|
|
87
|
-
G1 Z-8.000 F200
|
|
88
|
-
G0 Z1
|
|
89
|
-
G0 Z5
|
|
90
|
-
G0 X28.000 Y-18.000
|
|
91
|
-
G1 Z-2.000 F200
|
|
92
|
-
G0 Z1
|
|
93
|
-
G1 Z-4.000 F200
|
|
94
|
-
G0 Z1
|
|
95
|
-
G1 Z-6.000 F200
|
|
96
|
-
G0 Z1
|
|
97
|
-
G1 Z-8.000 F200
|
|
98
|
-
G0 Z1
|
|
99
|
-
G0 Z5
|
|
100
|
-
G0 X28.000 Y18.000
|
|
101
|
-
G1 Z-2.000 F200
|
|
102
|
-
G0 Z1
|
|
103
|
-
G1 Z-4.000 F200
|
|
104
|
-
G0 Z1
|
|
105
|
-
G1 Z-6.000 F200
|
|
106
|
-
G0 Z1
|
|
107
|
-
G1 Z-8.000 F200
|
|
108
|
-
G0 Z1
|
|
109
|
-
G0 Z5
|
|
110
|
-
G0 X-28.000 Y18.000
|
|
111
|
-
G1 Z-2.000 F200
|
|
112
|
-
G0 Z1
|
|
113
|
-
G1 Z-4.000 F200
|
|
114
|
-
G0 Z1
|
|
115
|
-
G1 Z-6.000 F200
|
|
116
|
-
G0 Z1
|
|
117
|
-
G1 Z-8.000 F200
|
|
118
|
-
G0 Z1
|
|
119
|
-
G0 Z5
|
|
120
|
-
G0 X4 Y0
|
|
121
|
-
G1 Z0 F300
|
|
122
|
-
G2 X4 Y0 Z-1.500 I-4 J0 F600
|
|
123
|
-
G2 X4 Y0 Z-3.000 I-4 J0 F600
|
|
124
|
-
G2 X4 Y0 Z-4.500 I-4 J0 F600
|
|
125
|
-
G2 X4 Y0 Z-6.000 I-4 J0 F600
|
|
126
|
-
G2 X4 Y0 I-4 J0
|
|
127
|
-
G0 Z5
|
|
128
|
-
M5
|
|
129
|
-
G0 X0 Y0
|
|
130
|
-
M30
|
|
1
|
+
(Agentic Numerical Control demo: pocket, profile, drill)
|
|
2
|
+
G21 G90 G17 G54
|
|
3
|
+
M3 S12000
|
|
4
|
+
G0 Z5
|
|
5
|
+
G0 X-20.000 Y-12.000
|
|
6
|
+
G1 Z-1.500 F300
|
|
7
|
+
G1 Y-12.000 F1200
|
|
8
|
+
G1 X20.000
|
|
9
|
+
G1 Y-9.000 F1200
|
|
10
|
+
G1 X-20.000
|
|
11
|
+
G1 Y-6.000 F1200
|
|
12
|
+
G1 X20.000
|
|
13
|
+
G1 Y-3.000 F1200
|
|
14
|
+
G1 X-20.000
|
|
15
|
+
G1 Y0.000 F1200
|
|
16
|
+
G1 X20.000
|
|
17
|
+
G1 Y3.000 F1200
|
|
18
|
+
G1 X-20.000
|
|
19
|
+
G1 Y6.000 F1200
|
|
20
|
+
G1 X20.000
|
|
21
|
+
G1 Y9.000 F1200
|
|
22
|
+
G1 X-20.000
|
|
23
|
+
G1 Y12.000 F1200
|
|
24
|
+
G1 X20.000
|
|
25
|
+
G0 Z5
|
|
26
|
+
G0 X-20.000 Y-12.000
|
|
27
|
+
G1 Z-3.000 F300
|
|
28
|
+
G1 Y-12.000 F1200
|
|
29
|
+
G1 X20.000
|
|
30
|
+
G1 Y-9.000 F1200
|
|
31
|
+
G1 X-20.000
|
|
32
|
+
G1 Y-6.000 F1200
|
|
33
|
+
G1 X20.000
|
|
34
|
+
G1 Y-3.000 F1200
|
|
35
|
+
G1 X-20.000
|
|
36
|
+
G1 Y0.000 F1200
|
|
37
|
+
G1 X20.000
|
|
38
|
+
G1 Y3.000 F1200
|
|
39
|
+
G1 X-20.000
|
|
40
|
+
G1 Y6.000 F1200
|
|
41
|
+
G1 X20.000
|
|
42
|
+
G1 Y9.000 F1200
|
|
43
|
+
G1 X-20.000
|
|
44
|
+
G1 Y12.000 F1200
|
|
45
|
+
G1 X20.000
|
|
46
|
+
G0 Z5
|
|
47
|
+
G0 X-29.000 Y-25.000
|
|
48
|
+
G1 Z-2.000 F300
|
|
49
|
+
G1 X29.000 F1000
|
|
50
|
+
G3 X35.000 Y-19.000 I0 J6.000
|
|
51
|
+
G1 Y19.000
|
|
52
|
+
G3 X29.000 Y25.000 I-6.000 J0
|
|
53
|
+
G1 X-29.000
|
|
54
|
+
G3 X-35.000 Y19.000 I0 J-6.000
|
|
55
|
+
G1 Y-19.000
|
|
56
|
+
G3 X-29.000 Y-25.000 I6.000 J0
|
|
57
|
+
G0 Z5
|
|
58
|
+
G0 X-29.000 Y-25.000
|
|
59
|
+
G1 Z-4.000 F300
|
|
60
|
+
G1 X29.000 F1000
|
|
61
|
+
G3 X35.000 Y-19.000 I0 J6.000
|
|
62
|
+
G1 Y19.000
|
|
63
|
+
G3 X29.000 Y25.000 I-6.000 J0
|
|
64
|
+
G1 X-29.000
|
|
65
|
+
G3 X-35.000 Y19.000 I0 J-6.000
|
|
66
|
+
G1 Y-19.000
|
|
67
|
+
G3 X-29.000 Y-25.000 I6.000 J0
|
|
68
|
+
G0 Z5
|
|
69
|
+
G0 X-29.000 Y-25.000
|
|
70
|
+
G1 Z-6.000 F300
|
|
71
|
+
G1 X29.000 F1000
|
|
72
|
+
G3 X35.000 Y-19.000 I0 J6.000
|
|
73
|
+
G1 Y19.000
|
|
74
|
+
G3 X29.000 Y25.000 I-6.000 J0
|
|
75
|
+
G1 X-29.000
|
|
76
|
+
G3 X-35.000 Y19.000 I0 J-6.000
|
|
77
|
+
G1 Y-19.000
|
|
78
|
+
G3 X-29.000 Y-25.000 I6.000 J0
|
|
79
|
+
G0 Z5
|
|
80
|
+
G0 X-28.000 Y-18.000
|
|
81
|
+
G1 Z-2.000 F200
|
|
82
|
+
G0 Z1
|
|
83
|
+
G1 Z-4.000 F200
|
|
84
|
+
G0 Z1
|
|
85
|
+
G1 Z-6.000 F200
|
|
86
|
+
G0 Z1
|
|
87
|
+
G1 Z-8.000 F200
|
|
88
|
+
G0 Z1
|
|
89
|
+
G0 Z5
|
|
90
|
+
G0 X28.000 Y-18.000
|
|
91
|
+
G1 Z-2.000 F200
|
|
92
|
+
G0 Z1
|
|
93
|
+
G1 Z-4.000 F200
|
|
94
|
+
G0 Z1
|
|
95
|
+
G1 Z-6.000 F200
|
|
96
|
+
G0 Z1
|
|
97
|
+
G1 Z-8.000 F200
|
|
98
|
+
G0 Z1
|
|
99
|
+
G0 Z5
|
|
100
|
+
G0 X28.000 Y18.000
|
|
101
|
+
G1 Z-2.000 F200
|
|
102
|
+
G0 Z1
|
|
103
|
+
G1 Z-4.000 F200
|
|
104
|
+
G0 Z1
|
|
105
|
+
G1 Z-6.000 F200
|
|
106
|
+
G0 Z1
|
|
107
|
+
G1 Z-8.000 F200
|
|
108
|
+
G0 Z1
|
|
109
|
+
G0 Z5
|
|
110
|
+
G0 X-28.000 Y18.000
|
|
111
|
+
G1 Z-2.000 F200
|
|
112
|
+
G0 Z1
|
|
113
|
+
G1 Z-4.000 F200
|
|
114
|
+
G0 Z1
|
|
115
|
+
G1 Z-6.000 F200
|
|
116
|
+
G0 Z1
|
|
117
|
+
G1 Z-8.000 F200
|
|
118
|
+
G0 Z1
|
|
119
|
+
G0 Z5
|
|
120
|
+
G0 X4 Y0
|
|
121
|
+
G1 Z0 F300
|
|
122
|
+
G2 X4 Y0 Z-1.500 I-4 J0 F600
|
|
123
|
+
G2 X4 Y0 Z-3.000 I-4 J0 F600
|
|
124
|
+
G2 X4 Y0 Z-4.500 I-4 J0 F600
|
|
125
|
+
G2 X4 Y0 Z-6.000 I-4 J0 F600
|
|
126
|
+
G2 X4 Y0 I-4 J0
|
|
127
|
+
G0 Z5
|
|
128
|
+
M5
|
|
129
|
+
G0 X0 Y0
|
|
130
|
+
M30
|