cyclecad 2.0.1 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/IMPLEMENTATION_GUIDE.md +502 -0
- package/INTEGRATION-GUIDE.md +377 -0
- package/MODULES_PHASES_6_7.md +780 -0
- package/app/index.html +106 -2
- package/app/js/brep-kernel.js +1353 -455
- package/app/js/help-module.js +1437 -0
- package/app/js/kernel.js +364 -40
- package/app/js/modules/animation-module.js +967 -0
- package/app/js/modules/assembly-module.js +47 -3
- package/app/js/modules/cam-module.js +1067 -0
- package/app/js/modules/collaboration-module.js +1102 -0
- package/app/js/modules/data-module.js +1656 -0
- package/app/js/modules/drawing-module.js +54 -8
- package/app/js/modules/formats-module.js +1173 -0
- package/app/js/modules/inspection-module.js +937 -0
- package/app/js/modules/mesh-module.js +968 -0
- package/app/js/modules/operations-module.js +40 -7
- package/app/js/modules/plugin-module.js +957 -0
- package/app/js/modules/rendering-module.js +1306 -0
- package/app/js/modules/scripting-module.js +955 -0
- package/app/js/modules/simulation-module.js +60 -3
- package/app/js/modules/sketch-module.js +1032 -90
- package/app/js/modules/step-module.js +47 -6
- package/app/js/modules/surface-module.js +728 -0
- package/app/js/modules/version-module.js +1410 -0
- package/app/js/modules/viewport-module.js +95 -8
- package/app/test-agent-v2.html +881 -1316
- package/docs/ARCHITECTURE.html +838 -1408
- package/docs/DEVELOPER-GUIDE.md +1504 -0
- package/docs/TUTORIAL.md +740 -0
- package/package.json +1 -1
- package/.github/scripts/cad-diff.js +0 -590
- package/.github/workflows/cad-diff.yml +0 -117
package/docs/ARCHITECTURE.html
CHANGED
|
@@ -1,1429 +1,859 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
border-top: 1px solid #30363d;
|
|
484
|
-
margin-top: 60px;
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
.footer a {
|
|
488
|
-
color: #58a6ff;
|
|
489
|
-
text-decoration: none;
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
.footer a:hover {
|
|
493
|
-
color: #79c0ff;
|
|
494
|
-
}
|
|
495
|
-
</style>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>cycleCAD v2.0 — LEGO Microkernel Architecture</title>
|
|
7
|
+
<style>
|
|
8
|
+
* {
|
|
9
|
+
margin: 0;
|
|
10
|
+
padding: 0;
|
|
11
|
+
box-sizing: border-box;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
body {
|
|
15
|
+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
16
|
+
background: linear-gradient(135deg, #0f172a 0%, #1a1f35 100%);
|
|
17
|
+
color: #e2e8f0;
|
|
18
|
+
min-height: 100vh;
|
|
19
|
+
overflow-x: hidden;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.container {
|
|
23
|
+
max-width: 1600px;
|
|
24
|
+
margin: 0 auto;
|
|
25
|
+
padding: 40px 20px;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
header {
|
|
29
|
+
text-align: center;
|
|
30
|
+
margin-bottom: 60px;
|
|
31
|
+
animation: slideDown 0.8s ease-out;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
h1 {
|
|
35
|
+
font-size: 2.5em;
|
|
36
|
+
margin-bottom: 10px;
|
|
37
|
+
background: linear-gradient(120deg, #06b6d4, #3b82f6);
|
|
38
|
+
-webkit-background-clip: text;
|
|
39
|
+
-webkit-text-fill-color: transparent;
|
|
40
|
+
background-clip: text;
|
|
41
|
+
letter-spacing: -1px;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.subtitle {
|
|
45
|
+
font-size: 1.1em;
|
|
46
|
+
color: #94a3b8;
|
|
47
|
+
margin-bottom: 30px;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.stats-bar {
|
|
51
|
+
display: grid;
|
|
52
|
+
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
|
53
|
+
gap: 20px;
|
|
54
|
+
margin-top: 30px;
|
|
55
|
+
padding: 20px;
|
|
56
|
+
background: rgba(30, 41, 59, 0.6);
|
|
57
|
+
border: 1px solid rgba(148, 163, 184, 0.2);
|
|
58
|
+
border-radius: 12px;
|
|
59
|
+
backdrop-filter: blur(10px);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.stat {
|
|
63
|
+
text-align: center;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.stat-value {
|
|
67
|
+
font-size: 1.8em;
|
|
68
|
+
font-weight: bold;
|
|
69
|
+
color: #06b6d4;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.stat-label {
|
|
73
|
+
font-size: 0.85em;
|
|
74
|
+
color: #94a3b8;
|
|
75
|
+
margin-top: 5px;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.diagram-container {
|
|
79
|
+
display: grid;
|
|
80
|
+
grid-template-columns: 1fr 350px;
|
|
81
|
+
gap: 30px;
|
|
82
|
+
margin-bottom: 40px;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.layers {
|
|
86
|
+
display: flex;
|
|
87
|
+
flex-direction: column;
|
|
88
|
+
gap: 20px;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.layer {
|
|
92
|
+
border: 1px solid rgba(148, 163, 184, 0.2);
|
|
93
|
+
border-radius: 12px;
|
|
94
|
+
padding: 20px;
|
|
95
|
+
background: rgba(30, 41, 59, 0.4);
|
|
96
|
+
backdrop-filter: blur(10px);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.layer-title {
|
|
100
|
+
font-size: 0.9em;
|
|
101
|
+
font-weight: 600;
|
|
102
|
+
color: #94a3b8;
|
|
103
|
+
text-transform: uppercase;
|
|
104
|
+
letter-spacing: 1px;
|
|
105
|
+
margin-bottom: 15px;
|
|
106
|
+
display: flex;
|
|
107
|
+
align-items: center;
|
|
108
|
+
gap: 8px;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.layer-title::before {
|
|
112
|
+
content: '';
|
|
113
|
+
display: inline-block;
|
|
114
|
+
width: 4px;
|
|
115
|
+
height: 14px;
|
|
116
|
+
background: currentColor;
|
|
117
|
+
border-radius: 2px;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.modules-grid {
|
|
121
|
+
display: grid;
|
|
122
|
+
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
|
123
|
+
gap: 12px;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.module-block {
|
|
127
|
+
padding: 16px;
|
|
128
|
+
background: rgba(15, 23, 42, 0.8);
|
|
129
|
+
border: 2px solid rgba(148, 163, 184, 0.3);
|
|
130
|
+
border-radius: 10px;
|
|
131
|
+
cursor: pointer;
|
|
132
|
+
transition: all 0.3s ease;
|
|
133
|
+
position: relative;
|
|
134
|
+
overflow: hidden;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.module-block::before {
|
|
138
|
+
content: '';
|
|
139
|
+
position: absolute;
|
|
140
|
+
top: 0;
|
|
141
|
+
left: -100%;
|
|
142
|
+
width: 100%;
|
|
143
|
+
height: 100%;
|
|
144
|
+
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.1), transparent);
|
|
145
|
+
transition: left 0.5s;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.module-block:hover::before {
|
|
149
|
+
left: 100%;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.module-block:hover {
|
|
153
|
+
border-color: currentColor;
|
|
154
|
+
box-shadow: 0 0 20px rgba(6, 182, 212, 0.3);
|
|
155
|
+
transform: translateY(-4px);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.module-block.core { --color: #06b6d4; }
|
|
159
|
+
.module-block.engine { --color: #3b82f6; }
|
|
160
|
+
.module-block.tool { --color: #22c55e; }
|
|
161
|
+
.module-block.data { --color: #f59e0b; }
|
|
162
|
+
.module-block.service { --color: #a855f7; }
|
|
163
|
+
|
|
164
|
+
.module-status {
|
|
165
|
+
display: inline-block;
|
|
166
|
+
width: 8px;
|
|
167
|
+
height: 8px;
|
|
168
|
+
background: currentColor;
|
|
169
|
+
border-radius: 50%;
|
|
170
|
+
margin-left: 8px;
|
|
171
|
+
animation: pulse 2s ease-in-out infinite;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.module-status.loaded {
|
|
175
|
+
--color: #22c55e;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.module-status.standby {
|
|
179
|
+
--color: #f59e0b;
|
|
180
|
+
animation: none;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
.module-status.unloaded {
|
|
184
|
+
--color: #ef4444;
|
|
185
|
+
animation: none;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.module-name {
|
|
189
|
+
font-weight: 600;
|
|
190
|
+
font-size: 0.95em;
|
|
191
|
+
margin-bottom: 8px;
|
|
192
|
+
color: var(--color);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.module-stats {
|
|
196
|
+
font-size: 0.75em;
|
|
197
|
+
color: #94a3b8;
|
|
198
|
+
display: flex;
|
|
199
|
+
justify-content: space-between;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
.module-icon {
|
|
203
|
+
font-size: 1.8em;
|
|
204
|
+
margin-bottom: 8px;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
.detail-panel {
|
|
208
|
+
border: 1px solid rgba(148, 163, 184, 0.2);
|
|
209
|
+
border-radius: 12px;
|
|
210
|
+
padding: 24px;
|
|
211
|
+
background: rgba(30, 41, 59, 0.6);
|
|
212
|
+
backdrop-filter: blur(10px);
|
|
213
|
+
max-height: 80vh;
|
|
214
|
+
overflow-y: auto;
|
|
215
|
+
position: sticky;
|
|
216
|
+
top: 20px;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
.detail-panel.empty {
|
|
220
|
+
display: flex;
|
|
221
|
+
align-items: center;
|
|
222
|
+
justify-content: center;
|
|
223
|
+
color: #64748b;
|
|
224
|
+
font-style: italic;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.detail-header {
|
|
228
|
+
margin-bottom: 24px;
|
|
229
|
+
padding-bottom: 16px;
|
|
230
|
+
border-bottom: 1px solid rgba(148, 163, 184, 0.2);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.detail-title {
|
|
234
|
+
font-size: 1.4em;
|
|
235
|
+
font-weight: 600;
|
|
236
|
+
margin-bottom: 8px;
|
|
237
|
+
color: var(--color);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
.detail-meta {
|
|
241
|
+
font-size: 0.85em;
|
|
242
|
+
color: #94a3b8;
|
|
243
|
+
display: flex;
|
|
244
|
+
gap: 12px;
|
|
245
|
+
flex-wrap: wrap;
|
|
246
|
+
margin-top: 12px;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
.detail-meta-item {
|
|
250
|
+
background: rgba(6, 182, 212, 0.1);
|
|
251
|
+
padding: 4px 10px;
|
|
252
|
+
border-radius: 6px;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
.detail-section {
|
|
256
|
+
margin-bottom: 20px;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.detail-section-title {
|
|
260
|
+
font-size: 0.9em;
|
|
261
|
+
font-weight: 600;
|
|
262
|
+
color: #cbd5e1;
|
|
263
|
+
text-transform: uppercase;
|
|
264
|
+
letter-spacing: 0.5px;
|
|
265
|
+
margin-bottom: 10px;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.detail-description {
|
|
269
|
+
font-size: 0.9em;
|
|
270
|
+
line-height: 1.6;
|
|
271
|
+
color: #cbd5e1;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
.commands-list {
|
|
275
|
+
display: grid;
|
|
276
|
+
grid-template-columns: 1fr;
|
|
277
|
+
gap: 8px;
|
|
278
|
+
font-size: 0.85em;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
.command-item {
|
|
282
|
+
padding: 8px;
|
|
283
|
+
background: rgba(59, 130, 246, 0.1);
|
|
284
|
+
border-left: 3px solid #3b82f6;
|
|
285
|
+
border-radius: 4px;
|
|
286
|
+
font-family: 'Courier New', monospace;
|
|
287
|
+
color: #93c5fd;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
.dependencies-list {
|
|
291
|
+
font-size: 0.85em;
|
|
292
|
+
color: #cbd5e1;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
.dependency {
|
|
296
|
+
display: flex;
|
|
297
|
+
align-items: center;
|
|
298
|
+
padding: 6px 0;
|
|
299
|
+
gap: 8px;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
.dependency::before {
|
|
303
|
+
content: '→';
|
|
304
|
+
color: #06b6d4;
|
|
305
|
+
font-weight: bold;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
.tabs {
|
|
309
|
+
display: flex;
|
|
310
|
+
gap: 12px;
|
|
311
|
+
margin-bottom: 40px;
|
|
312
|
+
border-bottom: 1px solid rgba(148, 163, 184, 0.2);
|
|
313
|
+
padding-bottom: 16px;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
.tab-btn {
|
|
317
|
+
padding: 10px 16px;
|
|
318
|
+
background: none;
|
|
319
|
+
border: none;
|
|
320
|
+
color: #94a3b8;
|
|
321
|
+
cursor: pointer;
|
|
322
|
+
font-size: 0.95em;
|
|
323
|
+
font-weight: 500;
|
|
324
|
+
transition: all 0.3s ease;
|
|
325
|
+
position: relative;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
.tab-btn:hover {
|
|
329
|
+
color: #e2e8f0;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
.tab-btn.active {
|
|
333
|
+
color: #06b6d4;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
.tab-btn.active::after {
|
|
337
|
+
content: '';
|
|
338
|
+
position: absolute;
|
|
339
|
+
bottom: -16px;
|
|
340
|
+
left: 0;
|
|
341
|
+
right: 0;
|
|
342
|
+
height: 2px;
|
|
343
|
+
background: #06b6d4;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
.tab-content {
|
|
347
|
+
display: none;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
.tab-content.active {
|
|
351
|
+
display: block;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
.dependency-graph {
|
|
355
|
+
background: rgba(30, 41, 59, 0.4);
|
|
356
|
+
border: 1px solid rgba(148, 163, 184, 0.2);
|
|
357
|
+
border-radius: 12px;
|
|
358
|
+
padding: 20px;
|
|
359
|
+
min-height: 400px;
|
|
360
|
+
position: relative;
|
|
361
|
+
overflow: hidden;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
.graph-legend {
|
|
365
|
+
display: grid;
|
|
366
|
+
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
|
|
367
|
+
gap: 12px;
|
|
368
|
+
margin-bottom: 20px;
|
|
369
|
+
padding-bottom: 16px;
|
|
370
|
+
border-bottom: 1px solid rgba(148, 163, 184, 0.2);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
.legend-item {
|
|
374
|
+
display: flex;
|
|
375
|
+
align-items: center;
|
|
376
|
+
gap: 8px;
|
|
377
|
+
font-size: 0.85em;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
.legend-color {
|
|
381
|
+
width: 12px;
|
|
382
|
+
height: 12px;
|
|
383
|
+
border-radius: 50%;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
.graph-container {
|
|
387
|
+
min-height: 500px;
|
|
388
|
+
border: 1px dashed rgba(148, 163, 184, 0.2);
|
|
389
|
+
border-radius: 8px;
|
|
390
|
+
padding: 20px;
|
|
391
|
+
position: relative;
|
|
392
|
+
font-size: 0.85em;
|
|
393
|
+
line-height: 1.8;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
.graph-node {
|
|
397
|
+
display: inline-block;
|
|
398
|
+
padding: 8px 12px;
|
|
399
|
+
background: rgba(30, 41, 59, 0.8);
|
|
400
|
+
border: 1px solid;
|
|
401
|
+
border-radius: 6px;
|
|
402
|
+
margin-bottom: 10px;
|
|
403
|
+
margin-right: 10px;
|
|
404
|
+
cursor: pointer;
|
|
405
|
+
transition: all 0.3s ease;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
.graph-node:hover {
|
|
409
|
+
transform: scale(1.05);
|
|
410
|
+
box-shadow: 0 0 15px rgba(6, 182, 212, 0.3);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
.graph-node.core { border-color: #06b6d4; color: #06b6d4; }
|
|
414
|
+
.graph-node.engine { border-color: #3b82f6; color: #3b82f6; }
|
|
415
|
+
.graph-node.tool { border-color: #22c55e; color: #22c55e; }
|
|
416
|
+
.graph-node.data { border-color: #f59e0b; color: #f59e0b; }
|
|
417
|
+
.graph-node.service { border-color: #a855f7; color: #a855f7; }
|
|
418
|
+
|
|
419
|
+
.data-flow {
|
|
420
|
+
margin: 30px 0;
|
|
421
|
+
padding: 20px;
|
|
422
|
+
background: rgba(6, 182, 212, 0.05);
|
|
423
|
+
border-left: 4px solid #06b6d4;
|
|
424
|
+
border-radius: 8px;
|
|
425
|
+
font-size: 0.9em;
|
|
426
|
+
font-family: 'Courier New', monospace;
|
|
427
|
+
color: #93c5fd;
|
|
428
|
+
line-height: 1.8;
|
|
429
|
+
overflow-x: auto;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
@keyframes slideDown {
|
|
433
|
+
from {
|
|
434
|
+
opacity: 0;
|
|
435
|
+
transform: translateY(-20px);
|
|
436
|
+
}
|
|
437
|
+
to {
|
|
438
|
+
opacity: 1;
|
|
439
|
+
transform: translateY(0);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
@keyframes pulse {
|
|
444
|
+
0%, 100% { opacity: 1; }
|
|
445
|
+
50% { opacity: 0.5; }
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
@keyframes fadeIn {
|
|
449
|
+
from { opacity: 0; }
|
|
450
|
+
to { opacity: 1; }
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
.tab-content.active {
|
|
454
|
+
animation: fadeIn 0.3s ease;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
@media (max-width: 1200px) {
|
|
458
|
+
.diagram-container {
|
|
459
|
+
grid-template-columns: 1fr;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
.detail-panel {
|
|
463
|
+
position: relative;
|
|
464
|
+
top: 0;
|
|
465
|
+
max-height: none;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
@media (max-width: 768px) {
|
|
470
|
+
h1 {
|
|
471
|
+
font-size: 1.8em;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
.stats-bar {
|
|
475
|
+
grid-template-columns: repeat(2, 1fr);
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
.modules-grid {
|
|
479
|
+
grid-template-columns: repeat(2, 1fr);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
</style>
|
|
496
483
|
</head>
|
|
497
484
|
<body>
|
|
485
|
+
<div class="container">
|
|
498
486
|
<header>
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
487
|
+
<h1>cycleCAD v2.0 — LEGO Microkernel Architecture</h1>
|
|
488
|
+
<p class="subtitle">Click any module to see its API, dependencies, and memory footprint</p>
|
|
489
|
+
<div class="stats-bar">
|
|
490
|
+
<div class="stat">
|
|
491
|
+
<div class="stat-value">10</div>
|
|
492
|
+
<div class="stat-label">Core Modules</div>
|
|
493
|
+
</div>
|
|
494
|
+
<div class="stat">
|
|
495
|
+
<div class="stat-value">55+</div>
|
|
496
|
+
<div class="stat-label">Commands</div>
|
|
497
|
+
</div>
|
|
498
|
+
<div class="stat">
|
|
499
|
+
<div class="stat-value">7,349</div>
|
|
500
|
+
<div class="stat-label">Lines of Code</div>
|
|
501
|
+
</div>
|
|
502
|
+
<div class="stat">
|
|
503
|
+
<div class="stat-value">30+</div>
|
|
504
|
+
<div class="stat-label">Events</div>
|
|
505
|
+
</div>
|
|
506
|
+
<div class="stat">
|
|
507
|
+
<div class="stat-value">512 MB</div>
|
|
508
|
+
<div class="stat-label">Memory Budget</div>
|
|
509
|
+
</div>
|
|
510
|
+
</div>
|
|
502
511
|
</header>
|
|
503
512
|
|
|
504
|
-
<
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
<a
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
513
|
+
<div class="diagram-container">
|
|
514
|
+
<div class="layers" id="layers"></div>
|
|
515
|
+
<div class="detail-panel empty" id="detailPanel">
|
|
516
|
+
<p>Click a module to view details</p>
|
|
517
|
+
</div>
|
|
518
|
+
</div>
|
|
519
|
+
|
|
520
|
+
<div class="tabs">
|
|
521
|
+
<button class="tab-btn active" data-tab="overview">Overview</button>
|
|
522
|
+
<button class="tab-btn" data-tab="dependencies">Dependencies</button>
|
|
523
|
+
<button class="tab-btn" data-tab="dataflow">Data Flow</button>
|
|
524
|
+
</div>
|
|
525
|
+
|
|
526
|
+
<div id="overview" class="tab-content active">
|
|
527
|
+
<div style="margin-bottom: 40px;">
|
|
528
|
+
<p style="color: #cbd5e1; line-height: 1.8; margin-bottom: 20px;">
|
|
529
|
+
cycleCAD uses a LEGO microkernel architecture where the tiny core manages module loading, lifecycle, and inter-module communication. Each module is independently versioned and can be hot-swapped at runtime. The kernel enforces strict API contracts — modules are black boxes that expose only their command/event interfaces.
|
|
530
|
+
</p>
|
|
531
|
+
<p style="color: #cbd5e1; line-height: 1.8;">
|
|
532
|
+
This design enables:
|
|
533
|
+
</p>
|
|
534
|
+
<ul style="color: #cbd5e1; margin: 15px 0 0 20px; line-height: 1.8;">
|
|
535
|
+
<li><strong>Fast load times:</strong> Only core modules load initially. Others lazy-load on demand.</li>
|
|
536
|
+
<li><strong>Independent scaling:</strong> Modules can be optimized or rewritten without touching the kernel.</li>
|
|
537
|
+
<li><strong>Zero coupling:</strong> Modules communicate only through the event bus. No direct imports.</li>
|
|
538
|
+
<li><strong>Rich extensibility:</strong> New modules integrate instantly via the kernel API.</li>
|
|
539
|
+
<li><strong>Offline fallbacks:</strong> Each module has a lightweight offline variant.</li>
|
|
540
|
+
</ul>
|
|
541
|
+
</div>
|
|
542
|
+
</div>
|
|
543
|
+
|
|
544
|
+
<div id="dependencies" class="tab-content">
|
|
545
|
+
<div class="dependency-graph">
|
|
546
|
+
<div class="graph-legend">
|
|
547
|
+
<div class="legend-item">
|
|
548
|
+
<div class="legend-color" style="background: #06b6d4;"></div>
|
|
549
|
+
<span>Core</span>
|
|
550
|
+
</div>
|
|
551
|
+
<div class="legend-item">
|
|
552
|
+
<div class="legend-color" style="background: #3b82f6;"></div>
|
|
553
|
+
<span>Engine</span>
|
|
554
|
+
</div>
|
|
555
|
+
<div class="legend-item">
|
|
556
|
+
<div class="legend-color" style="background: #22c55e;"></div>
|
|
557
|
+
<span>Tool</span>
|
|
558
|
+
</div>
|
|
559
|
+
<div class="legend-item">
|
|
560
|
+
<div class="legend-color" style="background: #f59e0b;"></div>
|
|
561
|
+
<span>Data</span>
|
|
562
|
+
</div>
|
|
563
|
+
<div class="legend-item">
|
|
564
|
+
<div class="legend-color" style="background: #a855f7;"></div>
|
|
565
|
+
<span>Service</span>
|
|
566
|
+
</div>
|
|
567
|
+
</div>
|
|
568
|
+
<div class="graph-container" id="dependencyGraph"></div>
|
|
569
|
+
</div>
|
|
570
|
+
</div>
|
|
571
|
+
|
|
572
|
+
<div id="dataflow" class="tab-content">
|
|
573
|
+
<h3 style="margin-bottom: 20px;">Data Flow Paths</h3>
|
|
574
|
+
|
|
575
|
+
<div class="data-flow">
|
|
576
|
+
<strong>User Input → Geometry:</strong><br>
|
|
577
|
+
UI Input → Kernel.exec() → Sketch/Operations → B-Rep Kernel → Viewport.addMesh() → Renderer
|
|
578
|
+
</div>
|
|
579
|
+
|
|
580
|
+
<div class="data-flow">
|
|
581
|
+
<strong>STEP Import:</strong><br>
|
|
582
|
+
File Input → STEP Module → Web Worker → WASM Parser → Mesh Array → Kernel.emit('step:complete') → Viewport Render
|
|
583
|
+
</div>
|
|
584
|
+
|
|
585
|
+
<div class="data-flow">
|
|
586
|
+
<strong>Assembly Animation:</strong><br>
|
|
587
|
+
Assembly.animateJoint() → Kernel.emit('joint:moved') → Viewport.updateMatrices() → Renderer → FPS Loop
|
|
588
|
+
</div>
|
|
589
|
+
|
|
590
|
+
<div class="data-flow">
|
|
591
|
+
<strong>Simulation Results:</strong><br>
|
|
592
|
+
FEA Solver → Mesh + Scalar Data → Viewport.setColorMap() → GPU Texture → Renderer
|
|
593
|
+
</div>
|
|
594
|
+
|
|
595
|
+
<div class="data-flow">
|
|
596
|
+
<strong>Undo/Redo Stack:</strong><br>
|
|
597
|
+
Feature Tree → History Manager → Kernel.swap(stateSnapshot) → All modules restore via events
|
|
598
|
+
</div>
|
|
599
|
+
</div>
|
|
600
|
+
</div>
|
|
601
|
+
|
|
602
|
+
<script>
|
|
603
|
+
const modules = [
|
|
604
|
+
{
|
|
605
|
+
id: 'kernel', name: 'Microkernel', category: 'core', lines: 684, memory: 2, icon: '⚙️',
|
|
606
|
+
file: 'app/js/kernel.js', layer: 1,
|
|
607
|
+
description: 'Tiny core that manages everything. Module registry, event bus, command system, memory manager, shared state, hot-swap engine.',
|
|
608
|
+
commands: ['register', 'load', 'activate', 'deactivate', 'unload', 'swap', 'exec', 'on', 'off', 'emit'],
|
|
609
|
+
dependencies: [],
|
|
610
|
+
events: ['module:loaded', 'module:activated', 'module:deactivated', 'module:error', 'module:swapped'],
|
|
611
|
+
status: 'loaded',
|
|
612
|
+
},
|
|
613
|
+
{
|
|
614
|
+
id: 'viewport', name: '3D Viewport', category: 'engine', lines: 530, memory: 30, icon: '🎥',
|
|
615
|
+
file: 'app/js/modules/viewport-module.js', layer: 3,
|
|
616
|
+
description: 'Three.js r170 renderer. Scene, camera, lights, shadows, grid, OrbitControls, raycaster selection, ViewCube.',
|
|
617
|
+
commands: ['viewport.fitAll', 'viewport.fitTo', 'viewport.setView', 'viewport.toggleGrid', 'viewport.toggleWireframe', 'viewport.screenshot', 'viewport.addMesh', 'viewport.removeMesh'],
|
|
618
|
+
dependencies: [],
|
|
619
|
+
events: ['part:selected', 'part:deselected', 'viewport:ready', 'viewport:resize'],
|
|
620
|
+
status: 'loaded',
|
|
621
|
+
},
|
|
622
|
+
{
|
|
623
|
+
id: 'sketch', name: 'Sketch Engine', category: 'engine', lines: 720, memory: 15, icon: '✏️',
|
|
624
|
+
file: 'app/js/modules/sketch-module.js', layer: 3,
|
|
625
|
+
description: '17 sketch tools with Fusion 360 parity. Line, rect, circle, arc, ellipse, spline, polygon, slot, text, trim, extend, offset, mirror, fillet, chamfer, construction, dimension.',
|
|
626
|
+
commands: ['sketch.start', 'sketch.finish', 'sketch.setTool', 'sketch.addEntity', 'sketch.trim', 'sketch.extend', 'sketch.offset', 'sketch.mirror'],
|
|
627
|
+
dependencies: ['viewport'],
|
|
628
|
+
events: ['sketch:started', 'sketch:finished', 'sketch:entityAdded', 'sketch:toolChanged', 'sketch:dimensionAdded'],
|
|
629
|
+
status: 'loaded',
|
|
630
|
+
},
|
|
631
|
+
{
|
|
632
|
+
id: 'operations', name: '3D Operations', category: 'engine', lines: 660, memory: 10, icon: '🔧',
|
|
633
|
+
file: 'app/js/modules/operations-module.js', layer: 3,
|
|
634
|
+
description: 'Smart dispatch: uses B-Rep kernel if loaded, mesh fallback if not. 28 operations including extrude, revolve, fillet, chamfer, boolean, pattern, mirror, shell, draft, hole, thread.',
|
|
635
|
+
commands: ['ops.box', 'ops.cylinder', 'ops.sphere', 'ops.extrude', 'ops.revolve', 'ops.fillet', 'ops.chamfer', 'ops.shell', 'ops.hole', 'ops.thread', 'ops.union', 'ops.cut'],
|
|
636
|
+
dependencies: ['viewport', 'sketch'],
|
|
637
|
+
events: ['feature:created', 'feature:edited', 'feature:deleted', 'rebuild:complete'],
|
|
638
|
+
status: 'loaded',
|
|
639
|
+
},
|
|
640
|
+
{
|
|
641
|
+
id: 'brep-kernel', name: 'B-Rep Kernel', category: 'engine', lines: 853, memory: 55, icon: '💎',
|
|
642
|
+
file: 'app/js/brep-kernel.js', layer: 3,
|
|
643
|
+
description: 'OpenCascade.js WASM solid modeling kernel. Real edge fillets, real booleans, STEP I/O, mass properties. 50MB WASM downloads on first use (lazy loaded).',
|
|
644
|
+
commands: ['brep.makeBox', 'brep.makeCylinder', 'brep.fillet', 'brep.booleanUnion', 'brep.booleanCut', 'brep.importSTEP', 'brep.exportSTEP'],
|
|
645
|
+
dependencies: ['viewport'],
|
|
646
|
+
events: ['brep:initialized', 'brep:wasmLoaded', 'brep:operationComplete'],
|
|
647
|
+
status: 'standby',
|
|
648
|
+
},
|
|
649
|
+
{
|
|
650
|
+
id: 'drawing', name: '2D Drawing', category: 'tool', lines: 883, memory: 20, icon: '📐',
|
|
651
|
+
file: 'app/js/modules/drawing-module.js', layer: 4,
|
|
652
|
+
description: 'Engineering drawing workspace. Orthographic/section views, dimensions, GD&T, annotations, title blocks, BOM. Export to PDF/DXF/SVG.',
|
|
653
|
+
commands: ['drawing.create', 'drawing.addView', 'drawing.addDimension', 'drawing.addAnnotation', 'drawing.addBOM', 'drawing.export'],
|
|
654
|
+
dependencies: ['viewport', 'operations'],
|
|
655
|
+
events: ['drawing:created', 'drawing:viewAdded', 'drawing:exported'],
|
|
656
|
+
status: 'standby',
|
|
657
|
+
},
|
|
658
|
+
{
|
|
659
|
+
id: 'assembly', name: 'Assembly', category: 'tool', lines: 582, memory: 25, icon: '🔗',
|
|
660
|
+
file: 'app/js/modules/assembly-module.js', layer: 4,
|
|
661
|
+
description: '7 joint types (rigid, revolute, slider, cylindrical, pin-slot, planar, ball). Joint limits, animation, interference check, exploded views, BOM.',
|
|
662
|
+
commands: ['assembly.insertComponent', 'assembly.createJoint', 'assembly.setJointLimits', 'assembly.animateJoint', 'assembly.checkInterference'],
|
|
663
|
+
dependencies: ['viewport', 'operations'],
|
|
664
|
+
events: ['assembly:componentInserted', 'assembly:jointCreated', 'assembly:interferenceFound'],
|
|
665
|
+
status: 'standby',
|
|
666
|
+
},
|
|
667
|
+
{
|
|
668
|
+
id: 'simulation', name: 'FEA Simulation', category: 'tool', lines: 834, memory: 40, icon: '📊',
|
|
669
|
+
file: 'app/js/modules/simulation-module.js', layer: 4,
|
|
670
|
+
description: 'Finite element analysis. Static stress (von Mises), thermal, modal frequency, buckling. Tetrahedral meshing, loads, boundary conditions, color results.',
|
|
671
|
+
commands: ['sim.setup', 'sim.setMaterial', 'sim.addLoad', 'sim.addConstraint', 'sim.mesh', 'sim.solve', 'sim.showResults'],
|
|
672
|
+
dependencies: ['viewport', 'operations'],
|
|
673
|
+
events: ['sim:meshGenerated', 'sim:solveStart', 'sim:solveComplete', 'sim:resultsReady'],
|
|
674
|
+
status: 'standby',
|
|
675
|
+
},
|
|
676
|
+
{
|
|
677
|
+
id: 'step-io', name: 'STEP I/O', category: 'data', lines: 510, memory: 60, icon: '📦',
|
|
678
|
+
file: 'app/js/modules/step-module.js', layer: 5,
|
|
679
|
+
description: 'Dual-path STEP import: browser WASM (occt-import-js) for <50MB files, server-side (CadQuery/OCP) for larger files. Web Worker with heartbeat and timeout.',
|
|
680
|
+
commands: ['step.import', 'step.export', 'step.importFromURL', 'step.getMetadata'],
|
|
681
|
+
dependencies: ['viewport'],
|
|
682
|
+
events: ['step:importStart', 'step:importProgress', 'step:importComplete', 'step:importError'],
|
|
683
|
+
status: 'standby',
|
|
684
|
+
},
|
|
685
|
+
{
|
|
686
|
+
id: 'ai-copilot', name: 'AI Copilot', category: 'service', lines: 645, memory: 35, icon: '🤖',
|
|
687
|
+
file: 'app/js/modules/ai-copilot.js', layer: 5,
|
|
688
|
+
description: 'Text-to-CAD, NL editing, smart autocomplete. Gemini/Groq/offline fallback. Understands design intent, suggests optimizations, generates documentation.',
|
|
689
|
+
commands: ['ai.chat', 'ai.textToCAD', 'ai.suggestOptimization', 'ai.generateDocumentation'],
|
|
690
|
+
dependencies: ['viewport', 'operations', 'sketch'],
|
|
691
|
+
events: ['ai:response', 'ai:operation', 'ai:error'],
|
|
692
|
+
status: 'standby',
|
|
693
|
+
},
|
|
694
|
+
];
|
|
695
|
+
|
|
696
|
+
const layerMap = {
|
|
697
|
+
1: { title: 'LEGO Microkernel (Core)', color: '#06b6d4' },
|
|
698
|
+
3: { title: 'Core Engine Modules', color: '#3b82f6' },
|
|
699
|
+
4: { title: 'Tool Modules', color: '#22c55e' },
|
|
700
|
+
5: { title: 'Service & Data Modules', color: '#a855f7' },
|
|
701
|
+
};
|
|
702
|
+
|
|
703
|
+
let selectedModule = null;
|
|
704
|
+
|
|
705
|
+
function createLayerHTML() {
|
|
706
|
+
const container = document.getElementById('layers');
|
|
707
|
+
const grouped = {};
|
|
708
|
+
|
|
709
|
+
modules.forEach(m => {
|
|
710
|
+
if (!grouped[m.layer]) grouped[m.layer] = [];
|
|
711
|
+
grouped[m.layer].push(m);
|
|
712
|
+
});
|
|
713
|
+
|
|
714
|
+
Object.keys(grouped)
|
|
715
|
+
.sort((a, b) => parseInt(a) - parseInt(b))
|
|
716
|
+
.forEach(layer => {
|
|
717
|
+
const layerInfo = layerMap[layer];
|
|
718
|
+
const html = `
|
|
719
|
+
<div class="layer">
|
|
720
|
+
<div class="layer-title" style="color: ${layerInfo.color};">${layerInfo.title}</div>
|
|
721
|
+
<div class="modules-grid">
|
|
722
|
+
${grouped[layer].map(m => `
|
|
723
|
+
<div class="module-block ${m.category}" data-id="${m.id}" style="--color: var(--color);">
|
|
724
|
+
<div class="module-icon">${m.icon}</div>
|
|
725
|
+
<div class="module-name">${m.name}<span class="module-status ${m.status}"></span></div>
|
|
726
|
+
<div class="module-stats">
|
|
727
|
+
<span>${m.lines} lines</span>
|
|
728
|
+
<span>${m.memory} MB</span>
|
|
638
729
|
</div>
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
<h3>Layer Responsibilities</h3>
|
|
643
|
-
<table>
|
|
644
|
-
<tr>
|
|
645
|
-
<th>Layer</th>
|
|
646
|
-
<th>Components</th>
|
|
647
|
-
<th>Responsibility</th>
|
|
648
|
-
</tr>
|
|
649
|
-
<tr>
|
|
650
|
-
<td><strong>User</strong></td>
|
|
651
|
-
<td>UI, Voice, API, CLI</td>
|
|
652
|
-
<td>All user-facing interfaces — interactive, voice, programmatic, command-line</td>
|
|
653
|
-
</tr>
|
|
654
|
-
<tr>
|
|
655
|
-
<td><strong>Geometry</strong></td>
|
|
656
|
-
<td>Three.js, OpenCASCADE, Sketch, Solver</td>
|
|
657
|
-
<td>3D geometry creation, editing, constraint solving, B-rep operations</td>
|
|
658
|
-
</tr>
|
|
659
|
-
<tr>
|
|
660
|
-
<td><strong>AI</strong></td>
|
|
661
|
-
<td>LLMs, Text-to-CAD, Vision</td>
|
|
662
|
-
<td>Natural language understanding, design automation, image recognition</td>
|
|
663
|
-
</tr>
|
|
664
|
-
<tr>
|
|
665
|
-
<td><strong>Data</strong></td>
|
|
666
|
-
<td>IndexedDB, localStorage, Cloud</td>
|
|
667
|
-
<td>Persistence, caching, sync, backup</td>
|
|
668
|
-
</tr>
|
|
669
|
-
<tr>
|
|
670
|
-
<td><strong>Platform</strong></td>
|
|
671
|
-
<td>APIs, Servers, Collaboration</td>
|
|
672
|
-
<td>Integration, multi-user, automation, CI/CD</td>
|
|
673
|
-
</tr>
|
|
674
|
-
</table>
|
|
675
|
-
</section>
|
|
676
|
-
|
|
677
|
-
<!-- Module Map -->
|
|
678
|
-
<section id="modules">
|
|
679
|
-
<h2>3. Module Map (50+ Files)</h2>
|
|
680
|
-
<p>All 50+ JS modules organized by category. Each module is a standalone ES6 file (~200-2000 lines) with zero dependencies (imports from CDN only).</p>
|
|
681
|
-
|
|
682
|
-
<h3>ENGINE (Geometry & Rendering)</h3>
|
|
683
|
-
<div class="module-grid">
|
|
684
|
-
<div class="module-card">
|
|
685
|
-
<h4>app.js</h4>
|
|
686
|
-
<div class="lines">794 lines</div>
|
|
687
|
-
<span class="category engine">ENGINE</span>
|
|
688
|
-
<p>App state, mode management, history, save/load</p>
|
|
689
|
-
</div>
|
|
690
|
-
<div class="module-card">
|
|
691
|
-
<h4>viewport.js</h4>
|
|
692
|
-
<div class="lines">751 lines</div>
|
|
693
|
-
<span class="category engine">ENGINE</span>
|
|
694
|
-
<p>Three.js scene, camera, lights, shadows, grid, selection</p>
|
|
695
|
-
</div>
|
|
696
|
-
<div class="module-card">
|
|
697
|
-
<h4>sketch.js</h4>
|
|
698
|
-
<div class="lines">899 lines</div>
|
|
699
|
-
<span class="category engine">ENGINE</span>
|
|
700
|
-
<p>2D canvas overlay, line/rect/circle/arc, grid snap, constraints</p>
|
|
701
|
-
</div>
|
|
702
|
-
<div class="module-card">
|
|
703
|
-
<h4>operations.js</h4>
|
|
704
|
-
<div class="lines">1078 lines</div>
|
|
705
|
-
<span class="category engine">ENGINE</span>
|
|
706
|
-
<p>Extrude, revolve, fillet, chamfer, boolean, shell, pattern</p>
|
|
707
|
-
</div>
|
|
708
|
-
<div class="module-card">
|
|
709
|
-
<h4>constraint-solver.js</h4>
|
|
710
|
-
<div class="lines">1047 lines</div>
|
|
711
|
-
<span class="category engine">ENGINE</span>
|
|
712
|
-
<p>2D constraint solver, 12 types, iterative relaxation</p>
|
|
713
|
-
</div>
|
|
714
|
-
<div class="module-card">
|
|
715
|
-
<h4>assembly.js</h4>
|
|
716
|
-
<div class="lines">1103 lines</div>
|
|
717
|
-
<span class="category engine">ENGINE</span>
|
|
718
|
-
<p>Assembly workspace, components, mates, joints</p>
|
|
719
|
-
</div>
|
|
720
|
-
</div>
|
|
721
|
-
|
|
722
|
-
<h3>AI (LLM & Automation)</h3>
|
|
723
|
-
<div class="module-grid">
|
|
724
|
-
<div class="module-card">
|
|
725
|
-
<h4>ai-chat.js</h4>
|
|
726
|
-
<div class="lines">992 lines</div>
|
|
727
|
-
<span class="category ai">AI</span>
|
|
728
|
-
<p>Gemini Flash + Groq + offline NLP fallback chatbot</p>
|
|
729
|
-
</div>
|
|
730
|
-
<div class="module-card">
|
|
731
|
-
<h4>agent-api.js</h4>
|
|
732
|
-
<div class="lines">1180 lines</div>
|
|
733
|
-
<span class="category ai">AI</span>
|
|
734
|
-
<p>JSON-RPC Agent API, 55 commands, 10 namespaces</p>
|
|
735
|
-
</div>
|
|
736
|
-
<div class="module-card">
|
|
737
|
-
<h4>text-to-cad.js</h4>
|
|
738
|
-
<div class="lines">745 lines</div>
|
|
739
|
-
<span class="category ai">AI</span>
|
|
740
|
-
<p>Parse user text → CAD commands, intent detection, templates</p>
|
|
741
|
-
</div>
|
|
742
|
-
<div class="module-card">
|
|
743
|
-
<h4>ai-vision.js</h4>
|
|
744
|
-
<div class="lines">612 lines</div>
|
|
745
|
-
<span class="category ai">AI</span>
|
|
746
|
-
<p>Gemini Vision API, image → part identification</p>
|
|
747
|
-
</div>
|
|
748
|
-
</div>
|
|
749
|
-
|
|
750
|
-
<h3>DATA (Persistence & Import/Export)</h3>
|
|
751
|
-
<div class="module-grid">
|
|
752
|
-
<div class="module-card">
|
|
753
|
-
<h4>export.js</h4>
|
|
754
|
-
<div class="lines">658 lines</div>
|
|
755
|
-
<span class="category data">DATA</span>
|
|
756
|
-
<p>STL, OBJ, glTF 2.0, STEP export</p>
|
|
757
|
-
</div>
|
|
758
|
-
<div class="module-card">
|
|
759
|
-
<h4>inventor-parser.js</h4>
|
|
760
|
-
<div class="lines">1138 lines</div>
|
|
761
|
-
<span class="category data">DATA</span>
|
|
762
|
-
<p>OLE2/CFB binary parser for .ipt/.iam files</p>
|
|
763
|
-
</div>
|
|
764
|
-
<div class="module-card">
|
|
765
|
-
<h4>reverse-engineer.js</h4>
|
|
766
|
-
<div class="lines">1275 lines</div>
|
|
767
|
-
<span class="category data">DATA</span>
|
|
768
|
-
<p>STL import, geometry analysis, feature detection</p>
|
|
769
|
-
</div>
|
|
770
|
-
<div class="module-card">
|
|
771
|
-
<h4>dxf-export.js</h4>
|
|
772
|
-
<div class="lines">1174 lines</div>
|
|
773
|
-
<span class="category data">DATA</span>
|
|
774
|
-
<p>DXF export, engineering drawings, multi-view projection</p>
|
|
775
|
-
</div>
|
|
776
|
-
</div>
|
|
777
|
-
|
|
778
|
-
<h3>I/O (Integration & Tools)</h3>
|
|
779
|
-
<div class="module-grid">
|
|
780
|
-
<div class="module-card">
|
|
781
|
-
<h4>project-loader.js</h4>
|
|
782
|
-
<div class="lines">579 lines</div>
|
|
783
|
-
<span class="category io">I/O</span>
|
|
784
|
-
<p>Parse .ipj files, index Inventor project folders</p>
|
|
785
|
-
</div>
|
|
786
|
-
<div class="module-card">
|
|
787
|
-
<h4>project-browser.js</h4>
|
|
788
|
-
<div class="lines">741 lines</div>
|
|
789
|
-
<span class="category io">I/O</span>
|
|
790
|
-
<p>Folder tree UI, file categories, search, stats</p>
|
|
791
|
-
</div>
|
|
792
|
-
<div class="module-card">
|
|
793
|
-
<h4>shortcuts.js</h4>
|
|
794
|
-
<div class="lines">350 lines</div>
|
|
795
|
-
<span class="category io">I/O</span>
|
|
796
|
-
<p>25+ keyboard shortcuts</p>
|
|
797
|
-
</div>
|
|
798
|
-
<div class="module-card">
|
|
799
|
-
<h4>params.js</h4>
|
|
800
|
-
<div class="lines">523 lines</div>
|
|
801
|
-
<span class="category io">I/O</span>
|
|
802
|
-
<p>Parameter editor, material selector, 6 materials</p>
|
|
803
|
-
</div>
|
|
730
|
+
</div>
|
|
731
|
+
`).join('')}
|
|
732
|
+
</div>
|
|
804
733
|
</div>
|
|
734
|
+
`;
|
|
735
|
+
container.innerHTML += html;
|
|
736
|
+
});
|
|
805
737
|
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
<h4>marketplace.js</h4>
|
|
828
|
-
<div class="lines">1994 lines</div>
|
|
829
|
-
<span class="category platform">PLATFORM</span>
|
|
830
|
-
<p>Model marketplace, publish, buy, rate, earn royalties</p>
|
|
831
|
-
</div>
|
|
832
|
-
</div>
|
|
833
|
-
</section>
|
|
834
|
-
|
|
835
|
-
<!-- Technical Decisions -->
|
|
836
|
-
<section id="decisions">
|
|
837
|
-
<h2>4. Key Technical Decisions (ADRs)</h2>
|
|
838
|
-
|
|
839
|
-
<h3>Why Three.js?</h3>
|
|
840
|
-
<p><strong>Decision:</strong> Use Three.js r170 (ES modules via CDN) instead of Babylon.js or custom WebGL.</p>
|
|
841
|
-
<p><strong>Rationale:</strong></p>
|
|
842
|
-
<ul style="margin-left: 20px; margin-bottom: 12px;">
|
|
843
|
-
<li>✅ <strong>Zero build step</strong> — import ES modules directly from CDN (jsdelivr)</li>
|
|
844
|
-
<li>✅ <strong>Mature ecosystem</strong> — 15+ years, millions of projects, extensive docs</li>
|
|
845
|
-
<li>✅ <strong>PBR materials</strong> — realistic rendering with metalness/roughness</li>
|
|
846
|
-
<li>✅ <strong>WebGL 2.0</strong> — shadow maps, normal maps, deferred rendering</li>
|
|
847
|
-
<li>✅ <strong>OrbitControls.js</strong> — production-ready camera navigation</li>
|
|
848
|
-
</ul>
|
|
849
|
-
|
|
850
|
-
<h3>Why OpenCascade.js?</h3>
|
|
851
|
-
<p><strong>Decision:</strong> Use OpenCascade.js WASM B-rep kernel (50MB download) instead of JSCAD or Manifold.</p>
|
|
852
|
-
<p><strong>Rationale:</strong></p>
|
|
853
|
-
<ul style="margin-left: 20px; margin-bottom: 12px;">
|
|
854
|
-
<li>✅ <strong>Real B-rep geometry</strong> — solids, not meshes. True booleans, fillets, proper topology</li>
|
|
855
|
-
<li>✅ <strong>STEP/IGES support</strong> — parse and generate industry-standard CAD formats</li>
|
|
856
|
-
<li>✅ <strong>Industrial-grade</strong> — used in Fusion 360, FreeCAD, AutoCAD</li>
|
|
857
|
-
<li>✅ <strong>Lazy-loaded</strong> — 50MB WASM only downloaded when user imports STEP file</li>
|
|
858
|
-
</ul>
|
|
859
|
-
|
|
860
|
-
<h3>Why ES Modules via CDN?</h3>
|
|
861
|
-
<p><strong>Decision:</strong> Import all dependencies (Three.js, Plotly, QRCode, etc.) from CDN with import maps. No webpack, no build step, no node_modules.</p>
|
|
862
|
-
<p><strong>Rationale:</strong></p>
|
|
863
|
-
<ul style="margin-left: 20px; margin-bottom: 12px;">
|
|
864
|
-
<li>✅ <strong>Zero build complexity</strong> — edit app.js, refresh browser, changes are live</li>
|
|
865
|
-
<li>✅ <strong>Browser-native</strong> — ES6 modules are a web standard (2015)</li>
|
|
866
|
-
<li>✅ <strong>Smaller artifact</strong> — no webpack overhead, tree-shaking by browser</li>
|
|
867
|
-
<li>✅ <strong>Easy versioning</strong> — pin Three.js to r170 in import map, instant updates</li>
|
|
868
|
-
</ul>
|
|
869
|
-
|
|
870
|
-
<h3>Why Gemini Flash?</h3>
|
|
871
|
-
<p><strong>Decision:</strong> Use Google Gemini Flash (multi-modal) instead of GPT-4 or Claude.</p>
|
|
872
|
-
<p><strong>Rationale:</strong></p>
|
|
873
|
-
<ul style="margin-left: 20px; margin-bottom: 12px;">
|
|
874
|
-
<li>✅ <strong>Vision API</strong> — understand sketches, screenshots, part images</li>
|
|
875
|
-
<li>✅ <strong>Fast + cheap</strong> — $0.075/1M input tokens (vs GPT-4: $30/1M)</li>
|
|
876
|
-
<li>✅ <strong>Multimodal</strong> — text + image in same prompt</li>
|
|
877
|
-
<li>✅ <strong>100K context window</strong> — entire design history in context</li>
|
|
878
|
-
</ul>
|
|
879
|
-
|
|
880
|
-
<h3>Why BroadcastChannel for Multiplayer?</h3>
|
|
881
|
-
<p><strong>Decision:</strong> Use BroadcastChannel API (same browser, same origin) for MVP multiplayer. Upgrade to WebRTC in Phase C.</p>
|
|
882
|
-
<p><strong>Rationale:</strong></p>
|
|
883
|
-
<ul style="margin-left: 20px; margin-bottom: 12px;">
|
|
884
|
-
<li>✅ <strong>Zero server</strong> — works peer-to-peer in same browser (dev + testing)</li>
|
|
885
|
-
<li>✅ <strong>Instant MVP</strong> — test multiplayer UX without infrastructure</li>
|
|
886
|
-
<li>✅ <strong>Upgrade path clear</strong> — swap BroadcastChannel for WebRTC+Firestore later</li>
|
|
887
|
-
</ul>
|
|
888
|
-
</section>
|
|
889
|
-
|
|
890
|
-
<!-- B-Rep Kernel -->
|
|
891
|
-
<section id="brep">
|
|
892
|
-
<h2>5. B-Rep Kernel Architecture</h2>
|
|
893
|
-
<p>The B-rep (Boundary Representation) kernel is the heart of cycleCAD's geometry engine. It's powered by <strong>OpenCascade.js</strong>, a 50MB WASM package compiled from the OpenCascade C++ library.</p>
|
|
894
|
-
|
|
895
|
-
<h3>WASM Loading Pipeline</h3>
|
|
896
|
-
<div class="flow-diagram">
|
|
897
|
-
<div class="flow-step">User imports STEP</div>
|
|
898
|
-
<div class="flow-arrow">→</div>
|
|
899
|
-
<div class="flow-step key">Lazy-load 50MB WASM</div>
|
|
900
|
-
<div class="flow-arrow">→</div>
|
|
901
|
-
<div class="flow-step">Parse STEP binary</div>
|
|
902
|
-
<div class="flow-arrow">→</div>
|
|
903
|
-
<div class="flow-step">Read B-rep topology</div>
|
|
904
|
-
<div class="flow-arrow">→</div>
|
|
905
|
-
<div class="flow-step key">Tessellate to mesh</div>
|
|
906
|
-
<div class="flow-arrow">→</div>
|
|
907
|
-
<div class="flow-step">Render in Three.js</div>
|
|
908
|
-
</div>
|
|
738
|
+
document.querySelectorAll('.module-block').forEach(block => {
|
|
739
|
+
block.addEventListener('click', () => selectModule(block.dataset.id));
|
|
740
|
+
});
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
function selectModule(moduleId) {
|
|
744
|
+
selectedModule = modules.find(m => m.id === moduleId);
|
|
745
|
+
const panel = document.getElementById('detailPanel');
|
|
746
|
+
|
|
747
|
+
if (!selectedModule) return;
|
|
748
|
+
|
|
749
|
+
panel.className = 'detail-panel';
|
|
750
|
+
panel.innerHTML = `
|
|
751
|
+
<div class="detail-header" style="--color: ${getCategoryColor(selectedModule.category)};">
|
|
752
|
+
<div class="detail-title">${selectedModule.icon} ${selectedModule.name}</div>
|
|
753
|
+
<div class="detail-meta">
|
|
754
|
+
<div class="detail-meta-item">${selectedModule.category.toUpperCase()}</div>
|
|
755
|
+
<div class="detail-meta-item">v${(selectedModule.lines / 100).toFixed(1)}</div>
|
|
756
|
+
<div class="detail-meta-item" style="background: rgba(22, 163, 74, 0.1); color: #86efac;">⚡ ${selectedModule.status}</div>
|
|
757
|
+
</div>
|
|
758
|
+
</div>
|
|
909
759
|
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
<th>Input</th>
|
|
915
|
-
<th>Output</th>
|
|
916
|
-
<th>Status</th>
|
|
917
|
-
</tr>
|
|
918
|
-
<tr>
|
|
919
|
-
<td><strong>Extrude</strong></td>
|
|
920
|
-
<td>Face (2D sketch)</td>
|
|
921
|
-
<td>Solid (3D box)</td>
|
|
922
|
-
<td><span class="badge feature">Live</span></td>
|
|
923
|
-
</tr>
|
|
924
|
-
<tr>
|
|
925
|
-
<td><strong>Revolve</strong></td>
|
|
926
|
-
<td>Face + axis</td>
|
|
927
|
-
<td>Solid (rotated)</td>
|
|
928
|
-
<td><span class="badge feature">Live</span></td>
|
|
929
|
-
</tr>
|
|
930
|
-
<tr>
|
|
931
|
-
<td><strong>Fillet</strong></td>
|
|
932
|
-
<td>Edge + radius</td>
|
|
933
|
-
<td>Solid (rounded)</td>
|
|
934
|
-
<td><span class="badge feature">Live</span></td>
|
|
935
|
-
</tr>
|
|
936
|
-
<tr>
|
|
937
|
-
<td><strong>Boolean Union</strong></td>
|
|
938
|
-
<td>2 solids</td>
|
|
939
|
-
<td>1 solid (fused)</td>
|
|
940
|
-
<td><span class="badge feature">Live</span></td>
|
|
941
|
-
</tr>
|
|
942
|
-
<tr>
|
|
943
|
-
<td><strong>Boolean Cut</strong></td>
|
|
944
|
-
<td>Solid A − Solid B</td>
|
|
945
|
-
<td>Solid A with hole</td>
|
|
946
|
-
<td><span class="badge feature">Live</span></td>
|
|
947
|
-
</tr>
|
|
948
|
-
<tr>
|
|
949
|
-
<td><strong>Shell</strong></td>
|
|
950
|
-
<td>Solid + thickness</td>
|
|
951
|
-
<td>Hollow (thin-wall)</td>
|
|
952
|
-
<td><span class="badge feature">Live</span></td>
|
|
953
|
-
</tr>
|
|
954
|
-
<tr>
|
|
955
|
-
<td><strong>STEP Export</strong></td>
|
|
956
|
-
<td>B-rep shape</td>
|
|
957
|
-
<td>.step file</td>
|
|
958
|
-
<td><span class="badge status">Q2 2026</span></td>
|
|
959
|
-
</tr>
|
|
960
|
-
</table>
|
|
961
|
-
|
|
962
|
-
<h3>Undo Stack</h3>
|
|
963
|
-
<p>Every geometry operation is pushed to an undo stack. The stack stores:</p>
|
|
964
|
-
<pre>
|
|
965
|
-
{
|
|
966
|
-
featureType: "extrude",
|
|
967
|
-
parameters: { depth: 50, sketch: {...} },
|
|
968
|
-
result: BRepShape,
|
|
969
|
-
timestamp: Date.now()
|
|
970
|
-
}
|
|
971
|
-
</pre>
|
|
972
|
-
<p>Undo/redo works by replaying the feature list from the beginning (deterministic rebuilds).</p>
|
|
973
|
-
</section>
|
|
974
|
-
|
|
975
|
-
<!-- AI Pipeline -->
|
|
976
|
-
<section id="ai">
|
|
977
|
-
<h2>6. AI Pipeline</h2>
|
|
978
|
-
<p>cycleCAD has a <strong>3-tier AI architecture</strong>: Cloud LLM (Gemini Flash), Local LLM (Groq Llama), and Offline NLP fallback. Users can use any tier; they trade cost/speed for accuracy.</p>
|
|
979
|
-
|
|
980
|
-
<h3>Text-to-CAD Flow</h3>
|
|
981
|
-
<div class="flow-diagram">
|
|
982
|
-
<div class="flow-step">User: "draw a box 50×30×20mm"</div>
|
|
983
|
-
<div class="flow-arrow">→</div>
|
|
984
|
-
<div class="flow-step key">Detect intent: CREATE</div>
|
|
985
|
-
<div class="flow-arrow">→</div>
|
|
986
|
-
<div class="flow-step key">Extract params: {w:50, h:30, d:20}</div>
|
|
987
|
-
<div class="flow-arrow">→</div>
|
|
988
|
-
<div class="flow-step">Call shape.box(50, 30, 20)</div>
|
|
989
|
-
<div class="flow-arrow">→</div>
|
|
990
|
-
<div class="flow-step">Create B-rep solid</div>
|
|
991
|
-
<div class="flow-arrow">→</div>
|
|
992
|
-
<div class="flow-step key">Render in viewport</div>
|
|
993
|
-
</div>
|
|
760
|
+
<div class="detail-section">
|
|
761
|
+
<div class="detail-section-title">Description</div>
|
|
762
|
+
<p class="detail-description">${selectedModule.description}</p>
|
|
763
|
+
</div>
|
|
994
764
|
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
<th>Speed</th>
|
|
1002
|
-
<th>Accuracy</th>
|
|
1003
|
-
<th>Use Case</th>
|
|
1004
|
-
</tr>
|
|
1005
|
-
<tr>
|
|
1006
|
-
<td><strong>Cloud</strong></td>
|
|
1007
|
-
<td>Google Gemini Flash</td>
|
|
1008
|
-
<td>$0.075/1M tokens</td>
|
|
1009
|
-
<td>~2s</td>
|
|
1010
|
-
<td>95%</td>
|
|
1011
|
-
<td>Complex, multi-step designs</td>
|
|
1012
|
-
</tr>
|
|
1013
|
-
<tr>
|
|
1014
|
-
<td><strong>Local</strong></td>
|
|
1015
|
-
<td>Groq Llama 3.1 8B</td>
|
|
1016
|
-
<td>$0.02/1M tokens</td>
|
|
1017
|
-
<td>~1s</td>
|
|
1018
|
-
<td>85%</td>
|
|
1019
|
-
<td>Cost-conscious, latency-critical</td>
|
|
1020
|
-
</tr>
|
|
1021
|
-
<tr>
|
|
1022
|
-
<td><strong>Offline</strong></td>
|
|
1023
|
-
<td>NLP + keyword matching</td>
|
|
1024
|
-
<td>Free</td>
|
|
1025
|
-
<td><100ms</td>
|
|
1026
|
-
<td>70%</td>
|
|
1027
|
-
<td>No internet, simple commands</td>
|
|
1028
|
-
</tr>
|
|
1029
|
-
</table>
|
|
1030
|
-
|
|
1031
|
-
<h3>Supported Intents</h3>
|
|
1032
|
-
<p><span class="badge feature">CREATE</span> <span class="badge feature">HOLE</span> <span class="badge feature">FILLET</span> <span class="badge feature">CHAMFER</span> <span class="badge feature">PATTERN</span> <span class="badge feature">MIRROR</span> <span class="badge feature">SHELL</span> <span class="badge feature">THREAD</span> <span class="badge feature">EXPORT</span> <span class="badge feature">MEASURE</span></p>
|
|
1033
|
-
</section>
|
|
1034
|
-
|
|
1035
|
-
<!-- Killer Features -->
|
|
1036
|
-
<section id="features">
|
|
1037
|
-
<h2>7. Killer Features</h2>
|
|
1038
|
-
|
|
1039
|
-
<h3>1. Text-to-CAD with Real B-Rep Geometry</h3>
|
|
1040
|
-
<p>Type "design a cylindrical bearing bore 25mm diameter" and cycleCAD generates production-ready B-rep geometry. Unlike image generators, the output is editable, parametric, and manufacturable.</p>
|
|
1041
|
-
|
|
1042
|
-
<h3>2. STEP Drag-and-Drop Import</h3>
|
|
1043
|
-
<p>Drag a .step file onto the viewport. cycleCAD instantly parses it (server-side STEP converter for >50MB files) and renders it. Exploded view, part selection, assembly tree all auto-generated.</p>
|
|
1044
|
-
|
|
1045
|
-
<h3>3. GitHub Actions CAD Visual Diff</h3>
|
|
1046
|
-
<p>Commit a design to GitHub. Our GitHub Action renders both versions as 3D screenshots. Visual diff shows what changed — moved parts in orange, new parts in green, deleted parts in red.</p>
|
|
1047
|
-
<pre>
|
|
1048
|
-
# Render CAD diff on every commit
|
|
1049
|
-
- uses: vvlars-cmd/cyclecad-diff@v1
|
|
1050
|
-
with:
|
|
1051
|
-
before: main
|
|
1052
|
-
after: HEAD
|
|
1053
|
-
</pre>
|
|
1054
|
-
|
|
1055
|
-
<h3>4. 35+ Parametric Parts Library</h3>
|
|
1056
|
-
<p>Built-in library of parametric parts: ISO bolts, DIN standard hardware, MISUMI components, bearing housings, motor mounts, etc. Drag-drop into assembly, adjust parameters, auto-BOM.</p>
|
|
1057
|
-
|
|
1058
|
-
<h3>5. Real-Time Multiplayer (BroadcastChannel MVP)</h3>
|
|
1059
|
-
<p>Two tabs of cycleCAD in the same browser stay in sync via BroadcastChannel. Edit in one tab, see changes in the other instantly. Full upgrade to WebRTC+Firestore in Phase C.</p>
|
|
1060
|
-
|
|
1061
|
-
<h3>6. Design for Manufacturing (DFM) Analysis</h3>
|
|
1062
|
-
<p>AI analyzes your design:</p>
|
|
1063
|
-
<ul style="margin-left: 20px; margin-bottom: 12px;">
|
|
1064
|
-
<li>🔴 Thin walls <1mm (risky for injection molding)</li>
|
|
1065
|
-
<li>🟡 Sharp internal corners (add fillet to avoid stress)</li>
|
|
1066
|
-
<li>🟢 Feasible for CNC milling with 3-axis</li>
|
|
1067
|
-
</ul>
|
|
1068
|
-
|
|
1069
|
-
<h3>7. Inventory Tracking & Reorder</h3>
|
|
1070
|
-
<p>Design a part, get BOM, auto-search MISUMI/McMaster-Carr, place order via REST API. Tracks inventory in IndexedDB. Reorder when stock < threshold.</p>
|
|
1071
|
-
</section>
|
|
1072
|
-
|
|
1073
|
-
<!-- Data Flow -->
|
|
1074
|
-
<section id="dataflow">
|
|
1075
|
-
<h2>8. Data Flow</h2>
|
|
1076
|
-
|
|
1077
|
-
<h3>How User Text Becomes 3D Geometry</h3>
|
|
1078
|
-
<div class="flow-diagram">
|
|
1079
|
-
<div class="flow-step">app.js: captureText()</div>
|
|
1080
|
-
<div class="flow-arrow">→</div>
|
|
1081
|
-
<div class="flow-step">text-to-cad.js: parseIntent()</div>
|
|
1082
|
-
<div class="flow-arrow">→</div>
|
|
1083
|
-
<div class="flow-step key">ai-chat.js: sendToGemini()</div>
|
|
1084
|
-
<div class="flow-arrow">→</div>
|
|
1085
|
-
<div class="flow-step">agent-api.js: execute()</div>
|
|
1086
|
-
<div class="flow-arrow">→</div>
|
|
1087
|
-
<div class="flow-step key">operations.js: extrude()</div>
|
|
1088
|
-
<div class="flow-arrow">→</div>
|
|
1089
|
-
<div class="flow-step">viewport.js: render()</div>
|
|
1090
|
-
</div>
|
|
765
|
+
<div class="detail-section">
|
|
766
|
+
<div class="detail-section-title">Commands (${selectedModule.commands.length})</div>
|
|
767
|
+
<div class="commands-list">
|
|
768
|
+
${selectedModule.commands.map(cmd => `<div class="command-item">${cmd}</div>`).join('')}
|
|
769
|
+
</div>
|
|
770
|
+
</div>
|
|
1091
771
|
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
</
|
|
1099
|
-
|
|
1100
|
-
<td><code>window.appState</code></td>
|
|
1101
|
-
<td>app.js</td>
|
|
1102
|
-
<td>Mode (sketch/3d), selectedFeature, history, clipboard</td>
|
|
1103
|
-
</tr>
|
|
1104
|
-
<tr>
|
|
1105
|
-
<td><code>window.sceneState</code></td>
|
|
1106
|
-
<td>viewport.js</td>
|
|
1107
|
-
<td>Three.js scene, camera, renderer, lights</td>
|
|
1108
|
-
</tr>
|
|
1109
|
-
<tr>
|
|
1110
|
-
<td><code>window.sketchState</code></td>
|
|
1111
|
-
<td>sketch.js</td>
|
|
1112
|
-
<td>Canvas entities (lines/circles), constraints, DOF</td>
|
|
1113
|
-
</tr>
|
|
1114
|
-
<tr>
|
|
1115
|
-
<td><code>window.featureTree</code></td>
|
|
1116
|
-
<td>operations.js</td>
|
|
1117
|
-
<td>Array of features: [{type, params, result, ...}]</td>
|
|
1118
|
-
</tr>
|
|
1119
|
-
<tr>
|
|
1120
|
-
<td><code>window.inventory</code></td>
|
|
1121
|
-
<td>IndexedDB</td>
|
|
1122
|
-
<td>Parts, stock levels, reorder points</td>
|
|
1123
|
-
</tr>
|
|
1124
|
-
</table>
|
|
1125
|
-
|
|
1126
|
-
<h3>Multiplayer Sync (BroadcastChannel)</h3>
|
|
1127
|
-
<pre>
|
|
1128
|
-
// Tab A (sender)
|
|
1129
|
-
const channel = new BroadcastChannel('cyclecad-sync');
|
|
1130
|
-
channel.postMessage({
|
|
1131
|
-
type: 'FEATURE_ADDED',
|
|
1132
|
-
payload: { featureType: 'extrude', depth: 50 }
|
|
1133
|
-
});
|
|
1134
|
-
|
|
1135
|
-
// Tab B (receiver)
|
|
1136
|
-
channel.onmessage = (e) => {
|
|
1137
|
-
if (e.data.type === 'FEATURE_ADDED') {
|
|
1138
|
-
operations.extrude(e.data.payload);
|
|
1139
|
-
viewport.render();
|
|
1140
|
-
}
|
|
1141
|
-
};
|
|
1142
|
-
</pre>
|
|
1143
|
-
</section>
|
|
1144
|
-
|
|
1145
|
-
<!-- Performance -->
|
|
1146
|
-
<section id="performance">
|
|
1147
|
-
<h2>9. Performance Characteristics</h2>
|
|
1148
|
-
|
|
1149
|
-
<h3>Load Time Targets</h3>
|
|
1150
|
-
<table>
|
|
1151
|
-
<tr>
|
|
1152
|
-
<th>Scenario</th>
|
|
1153
|
-
<th>Target</th>
|
|
1154
|
-
<th>Achieved</th>
|
|
1155
|
-
<th>Notes</th>
|
|
1156
|
-
</tr>
|
|
1157
|
-
<tr>
|
|
1158
|
-
<td>App startup (no WASM)</td>
|
|
1159
|
-
<td>< 100ms</td>
|
|
1160
|
-
<td>85ms</td>
|
|
1161
|
-
<td>ES modules from CDN, cached</td>
|
|
1162
|
-
</tr>
|
|
1163
|
-
<tr>
|
|
1164
|
-
<td>First 3D operation</td>
|
|
1165
|
-
<td>< 500ms</td>
|
|
1166
|
-
<td>350ms</td>
|
|
1167
|
-
<td>Three.js + geometry kernel ready</td>
|
|
1168
|
-
</tr>
|
|
1169
|
-
<tr>
|
|
1170
|
-
<td>WASM kernel load (lazy)</td>
|
|
1171
|
-
<td>< 5s</td>
|
|
1172
|
-
<td>3.2s</td>
|
|
1173
|
-
<td>50MB download, only on STEP import</td>
|
|
1174
|
-
</tr>
|
|
1175
|
-
<tr>
|
|
1176
|
-
<td>STEP parse (<50MB)</td>
|
|
1177
|
-
<td>< 5s</td>
|
|
1178
|
-
<td>2.8s</td>
|
|
1179
|
-
<td>Browser WASM, main thread</td>
|
|
1180
|
-
</tr>
|
|
1181
|
-
<tr>
|
|
1182
|
-
<td>STEP parse (>50MB)</td>
|
|
1183
|
-
<td>< 10s</td>
|
|
1184
|
-
<td>8.5s</td>
|
|
1185
|
-
<td>Server-side OCCT, faster</td>
|
|
1186
|
-
</tr>
|
|
1187
|
-
<tr>
|
|
1188
|
-
<td>Fillet edge (small)</td>
|
|
1189
|
-
<td>< 100ms</td>
|
|
1190
|
-
<td>45ms</td>
|
|
1191
|
-
<td>OpenCascade.js B-rep kernel</td>
|
|
1192
|
-
</tr>
|
|
1193
|
-
<tr>
|
|
1194
|
-
<td>Boolean union (complex)</td>
|
|
1195
|
-
<td>< 1s</td>
|
|
1196
|
-
<td>650ms</td>
|
|
1197
|
-
<td>Two 1000+ triangle solids</td>
|
|
1198
|
-
</tr>
|
|
1199
|
-
<tr>
|
|
1200
|
-
<td>Viewport FPS (idle)</td>
|
|
1201
|
-
<td>60 FPS</td>
|
|
1202
|
-
<td>60 FPS</td>
|
|
1203
|
-
<td>RequestAnimationFrame, no geometry changes</td>
|
|
1204
|
-
</tr>
|
|
1205
|
-
</table>
|
|
1206
|
-
|
|
1207
|
-
<h3>Memory Usage</h3>
|
|
1208
|
-
<table>
|
|
1209
|
-
<tr>
|
|
1210
|
-
<th>State</th>
|
|
1211
|
-
<th>Memory</th>
|
|
1212
|
-
<th>Notes</th>
|
|
1213
|
-
</tr>
|
|
1214
|
-
<tr>
|
|
1215
|
-
<td>App startup (no scene)</td>
|
|
1216
|
-
<td>~12 MB</td>
|
|
1217
|
-
<td>JS engine + ES modules cached</td>
|
|
1218
|
-
</tr>
|
|
1219
|
-
<tr>
|
|
1220
|
-
<td>Empty scene (no geometry)</td>
|
|
1221
|
-
<td>~18 MB</td>
|
|
1222
|
-
<td>Three.js + WebGL context</td>
|
|
1223
|
-
</tr>
|
|
1224
|
-
<tr>
|
|
1225
|
-
<td>Simple box (100 triangles)</td>
|
|
1226
|
-
<td>~22 MB</td>
|
|
1227
|
-
<td>BufferGeometry + material</td>
|
|
1228
|
-
</tr>
|
|
1229
|
-
<tr>
|
|
1230
|
-
<td>Complex assembly (10K triangles)</td>
|
|
1231
|
-
<td>~45 MB</td>
|
|
1232
|
-
<td>Typical CAD project</td>
|
|
1233
|
-
</tr>
|
|
1234
|
-
<tr>
|
|
1235
|
-
<td>WASM kernel (lazy-loaded)</td>
|
|
1236
|
-
<td>+50 MB</td>
|
|
1237
|
-
<td>Only loaded on STEP import</td>
|
|
1238
|
-
</tr>
|
|
1239
|
-
</table>
|
|
1240
|
-
</section>
|
|
1241
|
-
|
|
1242
|
-
<!-- Deployment -->
|
|
1243
|
-
<section id="deployment">
|
|
1244
|
-
<h2>10. Deployment Architecture</h2>
|
|
1245
|
-
|
|
1246
|
-
<h3>GitHub Pages (Free Tier)</h3>
|
|
1247
|
-
<p>cycleCAD.com runs on GitHub Pages, no server, no database:</p>
|
|
1248
|
-
<ul style="margin-left: 20px; margin-bottom: 12px;">
|
|
1249
|
-
<li>Static HTML/CSS/JS served globally from GitHub CDN</li>
|
|
1250
|
-
<li>All state in browser (IndexedDB + localStorage)</li>
|
|
1251
|
-
<li>No backend = no downtime, no infrastructure costs</li>
|
|
1252
|
-
</ul>
|
|
1253
|
-
|
|
1254
|
-
<h3>Docker (Self-Hosted / Enterprise)</h3>
|
|
1255
|
-
<pre>
|
|
1256
|
-
# 3-service stack
|
|
1257
|
-
version: '3'
|
|
1258
|
-
services:
|
|
1259
|
-
cyclecad: # nginx + app (port 3000)
|
|
1260
|
-
converter: # FastAPI STEP→GLB (port 8787)
|
|
1261
|
-
cycledb: # PostgreSQL for enterprise (port 5432)
|
|
1262
|
-
</pre>
|
|
1263
|
-
|
|
1264
|
-
<h3>npm Package</h3>
|
|
1265
|
-
<p>Embed cycleCAD in any web app:</p>
|
|
1266
|
-
<pre>
|
|
1267
|
-
npm install cyclecad
|
|
1268
|
-
import cyclecad from 'cyclecad';
|
|
1269
|
-
|
|
1270
|
-
const app = new cyclecad.App({ container: '#viewport' });
|
|
1271
|
-
app.shape.box(50, 30, 20);
|
|
1272
|
-
app.export.stl('box.stl');
|
|
1273
|
-
</pre>
|
|
1274
|
-
|
|
1275
|
-
<h3>CLI Tool</h3>
|
|
1276
|
-
<pre>
|
|
1277
|
-
npm install -g cyclecad
|
|
1278
|
-
cyclecad design.cad --format stl --output box.stl
|
|
1279
|
-
cyclecad --repl # Interactive REPL
|
|
1280
|
-
</pre>
|
|
1281
|
-
|
|
1282
|
-
<h3>MCP Server (for Claude, Cursor, VS Code)</h3>
|
|
1283
|
-
<pre>
|
|
1284
|
-
npx @cyclecad/mcp-server --port 3000
|
|
1285
|
-
|
|
1286
|
-
# In .cursor/rules.txt:
|
|
1287
|
-
mcp://cyclecad-mcp:3000
|
|
1288
|
-
- shape.box
|
|
1289
|
-
- shape.cylinder
|
|
1290
|
-
- operations.extrude
|
|
1291
|
-
- export.stl
|
|
1292
|
-
- ... (55 total tools)
|
|
1293
|
-
</pre>
|
|
1294
|
-
</section>
|
|
1295
|
-
|
|
1296
|
-
<!-- Roadmap -->
|
|
1297
|
-
<section id="roadmap">
|
|
1298
|
-
<h2>11. Roadmap (4 Phases)</h2>
|
|
1299
|
-
|
|
1300
|
-
<div class="roadmap">
|
|
1301
|
-
<div class="roadmap-phase">
|
|
1302
|
-
<h4>Phase A: NOW</h4>
|
|
1303
|
-
<h4 style="font-size: 0.85rem; color: #8b949e; font-weight: 400; margin-bottom: 12px;">Q2 2026</h4>
|
|
1304
|
-
<ul>
|
|
1305
|
-
<li>B-rep kernel ✅</li>
|
|
1306
|
-
<li>Text-to-CAD ✅</li>
|
|
1307
|
-
<li>Parts Library ✅</li>
|
|
1308
|
-
<li>STEP import via server</li>
|
|
1309
|
-
<li>Real STEP export</li>
|
|
1310
|
-
</ul>
|
|
1311
|
-
</div>
|
|
1312
|
-
|
|
1313
|
-
<div class="roadmap-phase">
|
|
1314
|
-
<h4>Phase B: NEXT</h4>
|
|
1315
|
-
<h4 style="font-size: 0.85rem; color: #8b949e; font-weight: 400; margin-bottom: 12px;">Q3-Q4 2026</h4>
|
|
1316
|
-
<ul>
|
|
1317
|
-
<li>ExplodeView merge</li>
|
|
1318
|
-
<li>Plugin API</li>
|
|
1319
|
-
<li>Cloud storage</li>
|
|
1320
|
-
<li>DFM analysis</li>
|
|
1321
|
-
<li>CAM integration</li>
|
|
1322
|
-
</ul>
|
|
1323
|
-
</div>
|
|
1324
|
-
|
|
1325
|
-
<div class="roadmap-phase">
|
|
1326
|
-
<h4>Phase C: GROWTH</h4>
|
|
1327
|
-
<h4 style="font-size: 0.85rem; color: #8b949e; font-weight: 400; margin-bottom: 12px;">Q1 2027</h4>
|
|
1328
|
-
<ul>
|
|
1329
|
-
<li>Real-time collab</li>
|
|
1330
|
-
<li>Enterprise SSO</li>
|
|
1331
|
-
<li>Self-hosted</li>
|
|
1332
|
-
<li>Mobile app</li>
|
|
1333
|
-
<li>Marketplace launch</li>
|
|
1334
|
-
</ul>
|
|
1335
|
-
</div>
|
|
1336
|
-
|
|
1337
|
-
<div class="roadmap-phase">
|
|
1338
|
-
<h4>Phase D: PLATFORM</h4>
|
|
1339
|
-
<h4 style="font-size: 0.85rem; color: #8b949e; font-weight: 400; margin-bottom: 12px;">Q2-Q3 2027</h4>
|
|
1340
|
-
<ul>
|
|
1341
|
-
<li>Connected fabs</li>
|
|
1342
|
-
<li>Supply chain</li>
|
|
1343
|
-
<li>Circular economy</li>
|
|
1344
|
-
<li>Agent swarms</li>
|
|
1345
|
-
<li>Manufacturing API</li>
|
|
1346
|
-
</ul>
|
|
1347
|
-
</div>
|
|
772
|
+
${selectedModule.dependencies.length > 0 ? `
|
|
773
|
+
<div class="detail-section">
|
|
774
|
+
<div class="detail-section-title">Dependencies</div>
|
|
775
|
+
<div class="dependencies-list">
|
|
776
|
+
${selectedModule.dependencies.map(dep => {
|
|
777
|
+
const depModule = modules.find(m => m.id === dep);
|
|
778
|
+
return `<div class="dependency">${depModule?.name || dep}</div>`;
|
|
779
|
+
}).join('')}
|
|
1348
780
|
</div>
|
|
781
|
+
</div>
|
|
782
|
+
` : ''}
|
|
783
|
+
|
|
784
|
+
<div class="detail-section">
|
|
785
|
+
<div class="detail-section-title">Events (${selectedModule.events.length})</div>
|
|
786
|
+
<div class="commands-list">
|
|
787
|
+
${selectedModule.events.map(evt => `<div class="command-item">${evt}</div>`).join('')}
|
|
788
|
+
</div>
|
|
789
|
+
</div>
|
|
1349
790
|
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
<tr>
|
|
1358
|
-
<td><strong>Apr 2026</strong></td>
|
|
1359
|
-
<td>v1.0 launch — Real B-rep + Text-to-CAD</td>
|
|
1360
|
-
<td>1,000 GitHub stars</td>
|
|
1361
|
-
</tr>
|
|
1362
|
-
<tr>
|
|
1363
|
-
<td><strong>Jun 2026</strong></td>
|
|
1364
|
-
<td>ExplodeView merge + AI vision</td>
|
|
1365
|
-
<td>5,000 weekly npm downloads</td>
|
|
1366
|
-
</tr>
|
|
1367
|
-
<tr>
|
|
1368
|
-
<td><strong>Sep 2026</strong></td>
|
|
1369
|
-
<td>Pro launch (€49/mo collab + cloud)</td>
|
|
1370
|
-
<td>1,000 paying users</td>
|
|
1371
|
-
</tr>
|
|
1372
|
-
<tr>
|
|
1373
|
-
<td><strong>Jan 2027</strong></td>
|
|
1374
|
-
<td>Marketplace live (creator royalties)</td>
|
|
1375
|
-
<td>100+ marketplace parts, $50K GMV</td>
|
|
1376
|
-
</tr>
|
|
1377
|
-
<tr>
|
|
1378
|
-
<td><strong>Jun 2027</strong></td>
|
|
1379
|
-
<td>Connected fab network (3+ manufacturers)</td>
|
|
1380
|
-
<td>10,000 parts ordered via cycleCAD</td>
|
|
1381
|
-
</tr>
|
|
1382
|
-
</table>
|
|
1383
|
-
</section>
|
|
1384
|
-
|
|
1385
|
-
<div class="footer">
|
|
1386
|
-
<p style="margin-bottom: 12px;"><strong>cycleCAD</strong> — Agent-First OS for Manufacturing</p>
|
|
1387
|
-
<p style="font-size: 0.9rem; margin-bottom: 12px;">
|
|
1388
|
-
<a href="https://cyclecad.com">cyclecad.com</a> ·
|
|
1389
|
-
<a href="https://github.com/vvlars-cmd/cyclecad">GitHub</a> ·
|
|
1390
|
-
<a href="https://www.npmjs.com/package/cyclecad">npm</a>
|
|
1391
|
-
</p>
|
|
1392
|
-
<p style="font-size: 0.85rem;">MIT License · MIT Design doc inspired by Amazon Working Backwards · Built by SACHIN · Updated 2026-03-30</p>
|
|
791
|
+
<div class="detail-section">
|
|
792
|
+
<div class="detail-section-title">Metrics</div>
|
|
793
|
+
<div style="display: grid; gap: 8px; font-size: 0.9em;">
|
|
794
|
+
<div><span style="color: #94a3b8;">Lines of Code:</span> <strong>${selectedModule.lines}</strong></div>
|
|
795
|
+
<div><span style="color: #94a3b8;">Memory:</span> <strong>${selectedModule.memory} MB</strong></div>
|
|
796
|
+
<div><span style="color: #94a3b8;">File:</span> <strong style="font-size: 0.85em;">${selectedModule.file}</strong></div>
|
|
797
|
+
</div>
|
|
1393
798
|
</div>
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
799
|
+
`;
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
function getCategoryColor(category) {
|
|
803
|
+
const colors = {
|
|
804
|
+
core: '#06b6d4',
|
|
805
|
+
engine: '#3b82f6',
|
|
806
|
+
tool: '#22c55e',
|
|
807
|
+
data: '#f59e0b',
|
|
808
|
+
service: '#a855f7',
|
|
809
|
+
};
|
|
810
|
+
return colors[category] || '#e2e8f0';
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
function createDependencyGraph() {
|
|
814
|
+
const container = document.getElementById('dependencyGraph');
|
|
815
|
+
let html = '<div style="margin-bottom: 20px;">All modules and their dependencies:</div>\n\n';
|
|
816
|
+
|
|
817
|
+
const categories = {};
|
|
818
|
+
modules.forEach(m => {
|
|
819
|
+
if (!categories[m.category]) categories[m.category] = [];
|
|
820
|
+
categories[m.category].push(m);
|
|
821
|
+
});
|
|
822
|
+
|
|
823
|
+
Object.keys(categories).forEach(cat => {
|
|
824
|
+
html += `<div style="margin-bottom: 20px;"><strong style="color: ${getCategoryColor(cat)};">${cat.toUpperCase()}:</strong></div>\n`;
|
|
825
|
+
categories[cat].forEach(m => {
|
|
826
|
+
const deps = m.dependencies.length > 0
|
|
827
|
+
? m.dependencies.map(d => modules.find(x => x.id === d)?.name || d).join(', ')
|
|
828
|
+
: '(independent)';
|
|
829
|
+
html += `<div style="margin-left: 20px; margin-bottom: 8px;">
|
|
830
|
+
<span class="graph-node ${m.category}" data-module="${m.id}" style="cursor: pointer;">${m.icon} ${m.name}</span>
|
|
831
|
+
<span style="color: #64748b; font-size: 0.8em;"> → ${deps}</span>
|
|
832
|
+
</div>\n`;
|
|
1416
833
|
});
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
834
|
+
});
|
|
835
|
+
|
|
836
|
+
container.innerHTML = html;
|
|
837
|
+
|
|
838
|
+
document.querySelectorAll('.graph-node').forEach(node => {
|
|
839
|
+
node.addEventListener('click', () => selectModule(node.dataset.module));
|
|
840
|
+
});
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
function setupTabs() {
|
|
844
|
+
document.querySelectorAll('.tab-btn').forEach(btn => {
|
|
845
|
+
btn.addEventListener('click', () => {
|
|
846
|
+
document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));
|
|
847
|
+
document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));
|
|
848
|
+
btn.classList.add('active');
|
|
849
|
+
document.getElementById(btn.dataset.tab).classList.add('active');
|
|
1426
850
|
});
|
|
1427
|
-
|
|
851
|
+
});
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
createLayerHTML();
|
|
855
|
+
createDependencyGraph();
|
|
856
|
+
setupTabs();
|
|
857
|
+
</script>
|
|
1428
858
|
</body>
|
|
1429
859
|
</html>
|