cyclecad 0.2.2 → 0.3.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/API-BUILD-MANIFEST.txt +339 -0
- package/API-SERVER.md +535 -0
- package/Architecture-Deck.pptx +0 -0
- package/CLAUDE.md +172 -11
- package/CLI-BUILD-SUMMARY.md +504 -0
- package/CLI-INDEX.md +356 -0
- package/CLI-README.md +466 -0
- package/COLLABORATION-INTEGRATION-GUIDE.md +325 -0
- package/CONNECTED_FABS_GUIDE.md +612 -0
- package/CONNECTED_FABS_README.md +310 -0
- package/DELIVERABLES.md +343 -0
- package/DFM-ANALYZER-INTEGRATION.md +368 -0
- package/DFM-QUICK-START.js +253 -0
- package/Dockerfile +69 -0
- package/IMPLEMENTATION.md +327 -0
- package/LICENSE +31 -0
- package/MARKETPLACE_QUICK_REFERENCE.txt +294 -0
- package/MCP-INDEX.md +264 -0
- package/QUICKSTART-API.md +388 -0
- package/QUICKSTART-CLI.md +211 -0
- package/QUICKSTART-MCP.md +196 -0
- package/README-MCP.md +208 -0
- package/TEST-TOKEN-ENGINE.md +319 -0
- package/TOKEN-ENGINE-SUMMARY.md +266 -0
- package/TOKENS-README.md +263 -0
- package/TOOLS-REFERENCE.md +254 -0
- package/app/index.html +373 -3
- package/app/js/TOKEN-INTEGRATION.md +391 -0
- package/app/js/agent-api.js +3 -3
- package/app/js/ai-copilot.js +1435 -0
- package/app/js/cad-vr.js +917 -0
- package/app/js/cam-operations.js +638 -0
- package/app/js/cam-pipeline.js +840 -0
- package/app/js/collaboration-ui.js +995 -0
- package/app/js/collaboration.js +1116 -0
- package/app/js/connected-fabs-example.js +404 -0
- package/app/js/connected-fabs.js +1449 -0
- package/app/js/dfm-analyzer.js +1760 -0
- package/app/js/gcode-generator.js +485 -0
- package/app/js/gdt-training.js +1144 -0
- package/app/js/machine-profiles.js +534 -0
- package/app/js/marketplace-v2.js +766 -0
- package/app/js/marketplace.js +1994 -0
- package/app/js/material-library.js +2115 -0
- package/app/js/misumi-catalog.js +904 -0
- package/app/js/section-view.js +666 -0
- package/app/js/sketch-enhance.js +779 -0
- package/app/js/stock-manager.js +482 -0
- package/app/js/text-to-cad.js +806 -0
- package/app/js/token-dashboard.js +563 -0
- package/app/js/token-engine.js +743 -0
- package/app/js/tool-library.js +593 -0
- package/app/test-agent.html +1801 -0
- package/app/tutorials/advanced.html +1924 -0
- package/app/tutorials/basic.html +1160 -0
- package/app/tutorials/intermediate.html +1456 -0
- package/bin/cyclecad-cli.js +662 -0
- package/bin/cyclecad-mcp +2 -0
- package/bin/server.js +242 -0
- package/cycleCAD-Architecture.pptx +0 -0
- package/cycleCAD-Investor-Deck.pptx +0 -0
- package/demo-mcp.sh +60 -0
- package/docs/API-SERVER-SUMMARY.md +375 -0
- package/docs/API-SERVER.md +667 -0
- package/docs/CAM-EXAMPLES.md +344 -0
- package/docs/CAM-INTEGRATION.md +612 -0
- package/docs/CAM-QUICK-REFERENCE.md +199 -0
- package/docs/CLI-INTEGRATION.md +510 -0
- package/docs/CLI.md +872 -0
- package/docs/MARKETPLACE-API-SCHEMA.json +564 -0
- package/docs/MARKETPLACE-INTEGRATION.md +467 -0
- package/docs/MARKETPLACE-SETUP.html +439 -0
- package/docs/MCP-SERVER.md +403 -0
- package/examples/api-client-example.js +488 -0
- package/examples/api-client-example.py +359 -0
- package/examples/batch-manufacturing.txt +28 -0
- package/examples/batch-simple.txt +26 -0
- package/linkedin-post-combined.md +31 -0
- package/model-marketplace.html +1273 -0
- package/package.json +14 -3
- package/server/api-server.js +1120 -0
- package/server/mcp-server.js +1161 -0
- package/test-api-server.js +432 -0
- package/test-mcp.js +198 -0
- package/~$cycleCAD-Investor-Deck.pptx +0 -0
|
@@ -0,0 +1,904 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MISUMI Catalog Integration Module for cycleCAD
|
|
3
|
+
*
|
|
4
|
+
* Comprehensive mechanical components library with parametric configurator,
|
|
5
|
+
* search, BOM management, and direct MISUMI linking.
|
|
6
|
+
*
|
|
7
|
+
* Usage: window.cycleCAD.misumi.configure('linearMotion', 'shaft', {...})
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
(function() {
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
// Component database: organized by category
|
|
14
|
+
const COMPONENT_DB = {
|
|
15
|
+
linearMotion: {
|
|
16
|
+
shaft: {
|
|
17
|
+
name: 'Precision Shafts',
|
|
18
|
+
description: 'Ground and hardened precision shafts',
|
|
19
|
+
subtypes: {
|
|
20
|
+
induction: {
|
|
21
|
+
label: 'Induction Hardened',
|
|
22
|
+
pattern: 'PSFJ{dia}-{len}',
|
|
23
|
+
diameters: [3, 4, 5, 6, 8, 10, 12, 16, 20, 25, 32, 40, 50],
|
|
24
|
+
maxLengths: { 3: 500, 5: 500, 8: 800, 10: 1000, 16: 1000, 20: 1500, 25: 2000 },
|
|
25
|
+
material: 'SUJ2 Steel',
|
|
26
|
+
tolerance: 'h6',
|
|
27
|
+
weight: (d, l) => (d * d * l * 7.85) / 1000, // grams
|
|
28
|
+
price: (d, l) => 50 + (d * l * 0.08), // USD
|
|
29
|
+
image: 'shaft-induction'
|
|
30
|
+
},
|
|
31
|
+
ground: {
|
|
32
|
+
label: 'Precision Ground',
|
|
33
|
+
pattern: 'PSFG{dia}-{len}',
|
|
34
|
+
diameters: [3, 4, 5, 6, 8, 10, 12, 16, 20, 25, 32],
|
|
35
|
+
maxLengths: { 3: 400, 5: 500, 8: 700, 10: 900, 16: 1200, 25: 1500 },
|
|
36
|
+
material: 'Carbon Steel',
|
|
37
|
+
tolerance: 'g6',
|
|
38
|
+
weight: (d, l) => (d * d * l * 7.85) / 1000,
|
|
39
|
+
price: (d, l) => 45 + (d * l * 0.07),
|
|
40
|
+
image: 'shaft-ground'
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
bushing: {
|
|
45
|
+
name: 'Linear Bushings',
|
|
46
|
+
description: 'LM-type linear motion bushings',
|
|
47
|
+
subtypes: {
|
|
48
|
+
lm: {
|
|
49
|
+
label: 'LM Type',
|
|
50
|
+
pattern: 'LM{dia}UU',
|
|
51
|
+
sizes: [3, 4, 5, 6, 8, 10, 12, 16, 20, 25, 32, 40, 50],
|
|
52
|
+
material: 'Steel with bearing balls',
|
|
53
|
+
tolerance: 'Standard',
|
|
54
|
+
weight: (s) => s * 0.5 + 2,
|
|
55
|
+
price: (s) => 20 + (s * 1.5),
|
|
56
|
+
image: 'bushing-lm'
|
|
57
|
+
},
|
|
58
|
+
lme: {
|
|
59
|
+
label: 'LME Type (Extended)',
|
|
60
|
+
pattern: 'LME{dia}UU',
|
|
61
|
+
sizes: [3, 4, 5, 6, 8, 10, 12, 16, 20, 25, 32],
|
|
62
|
+
material: 'Steel with bearing balls',
|
|
63
|
+
tolerance: 'Standard',
|
|
64
|
+
weight: (s) => s * 0.8 + 3,
|
|
65
|
+
price: (s) => 28 + (s * 1.8),
|
|
66
|
+
image: 'bushing-lme'
|
|
67
|
+
},
|
|
68
|
+
flanged: {
|
|
69
|
+
label: 'Flanged',
|
|
70
|
+
pattern: 'LMF{dia}UU',
|
|
71
|
+
sizes: [4, 5, 6, 8, 10, 12, 16, 20, 25],
|
|
72
|
+
material: 'Steel with bearing balls',
|
|
73
|
+
tolerance: 'Standard',
|
|
74
|
+
weight: (s) => s * 1.0 + 5,
|
|
75
|
+
price: (s) => 35 + (s * 2.0),
|
|
76
|
+
image: 'bushing-flanged'
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
guide: {
|
|
81
|
+
name: 'Linear Guides',
|
|
82
|
+
description: 'Profile linear guides for precise motion',
|
|
83
|
+
subtypes: {
|
|
84
|
+
miniature: {
|
|
85
|
+
label: 'Miniature',
|
|
86
|
+
pattern: 'LGLV{size}-{len}',
|
|
87
|
+
sizes: [5, 7, 9, 12],
|
|
88
|
+
lengths: [50, 100, 150, 200, 300, 400, 500],
|
|
89
|
+
material: 'Stainless steel',
|
|
90
|
+
tolerance: 'H',
|
|
91
|
+
weight: (s, l) => (s + 2) * (l / 100) * 0.3,
|
|
92
|
+
price: (s, l) => 80 + (s * 5) + (l * 0.2),
|
|
93
|
+
image: 'guide-miniature'
|
|
94
|
+
},
|
|
95
|
+
standard: {
|
|
96
|
+
label: 'Standard',
|
|
97
|
+
pattern: 'LGLV{size}-{len}',
|
|
98
|
+
sizes: [15, 20, 25, 30, 35, 45],
|
|
99
|
+
lengths: [100, 150, 200, 300, 400, 500, 750, 1000],
|
|
100
|
+
material: 'Stainless steel',
|
|
101
|
+
tolerance: 'H',
|
|
102
|
+
weight: (s, l) => (s + 5) * (l / 100) * 0.6,
|
|
103
|
+
price: (s, l) => 150 + (s * 8) + (l * 0.4),
|
|
104
|
+
image: 'guide-standard'
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
ballScrew: {
|
|
109
|
+
name: 'Ball Screws',
|
|
110
|
+
description: 'Rolled and ground ball screws',
|
|
111
|
+
subtypes: {
|
|
112
|
+
rolled: {
|
|
113
|
+
label: 'Rolled',
|
|
114
|
+
pattern: 'BSRT{dia}x{lead}-{len}',
|
|
115
|
+
diameters: [8, 10, 12, 16, 20, 25, 32],
|
|
116
|
+
leads: [2, 3, 4, 5, 10, 16, 20],
|
|
117
|
+
lengths: [100, 200, 300, 500, 750, 1000, 1500],
|
|
118
|
+
material: 'Chrome Steel',
|
|
119
|
+
tolerance: 'C7',
|
|
120
|
+
weight: (d, l) => (d * d * l * 7.85) / 800,
|
|
121
|
+
price: (d, lead, l) => 120 + (d * 10) + (lead * 5) + (l * 0.3),
|
|
122
|
+
image: 'ballscrew-rolled'
|
|
123
|
+
},
|
|
124
|
+
ground: {
|
|
125
|
+
label: 'Ground',
|
|
126
|
+
pattern: 'BSGR{dia}x{lead}-{len}',
|
|
127
|
+
diameters: [10, 12, 16, 20, 25, 32],
|
|
128
|
+
leads: [2, 3, 4, 5, 10, 16],
|
|
129
|
+
lengths: [150, 300, 500, 750, 1000],
|
|
130
|
+
material: 'Chrome Steel',
|
|
131
|
+
tolerance: 'C5',
|
|
132
|
+
weight: (d, l) => (d * d * l * 7.85) / 750,
|
|
133
|
+
price: (d, lead, l) => 200 + (d * 15) + (lead * 8) + (l * 0.5),
|
|
134
|
+
image: 'ballscrew-ground'
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
|
|
140
|
+
fasteners: {
|
|
141
|
+
shcs: {
|
|
142
|
+
name: 'Socket Head Cap Screws',
|
|
143
|
+
description: 'ISO 4762 / DIN 912 socket head cap screws',
|
|
144
|
+
subtypes: {
|
|
145
|
+
steel: {
|
|
146
|
+
label: 'Steel (Bright)',
|
|
147
|
+
pattern: 'SHCS-{dia}x{length}-ST',
|
|
148
|
+
diameters: [2, 2.5, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24, 30],
|
|
149
|
+
lengths: [6, 8, 10, 12, 16, 20, 25, 30, 40, 50, 60, 80, 100],
|
|
150
|
+
material: 'Steel, Grade 8.8',
|
|
151
|
+
finish: 'Bright',
|
|
152
|
+
weight: (d, l) => (d * d * l * 7.85) / 2000,
|
|
153
|
+
price: (d, l) => 0.5 + (d * 0.15) + (l * 0.02),
|
|
154
|
+
image: 'shcs-steel'
|
|
155
|
+
},
|
|
156
|
+
stainless: {
|
|
157
|
+
label: 'Stainless A2',
|
|
158
|
+
pattern: 'SHCS-{dia}x{length}-A2',
|
|
159
|
+
diameters: [2, 3, 4, 5, 6, 8, 10, 12, 16],
|
|
160
|
+
lengths: [8, 10, 12, 16, 20, 25, 30, 40, 50, 60, 80],
|
|
161
|
+
material: 'Stainless Steel A2',
|
|
162
|
+
finish: 'Polished',
|
|
163
|
+
weight: (d, l) => (d * d * l * 7.98) / 2000,
|
|
164
|
+
price: (d, l) => 0.8 + (d * 0.25) + (l * 0.035),
|
|
165
|
+
image: 'shcs-stainless'
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
hexBolt: {
|
|
170
|
+
name: 'Hex Bolts',
|
|
171
|
+
description: 'ISO 4014 / DIN 933 hex bolts',
|
|
172
|
+
subtypes: {
|
|
173
|
+
steel: {
|
|
174
|
+
label: 'Steel, Grade 8.8',
|
|
175
|
+
pattern: 'HB-{dia}x{length}-8.8',
|
|
176
|
+
diameters: [3, 4, 5, 6, 8, 10, 12, 16, 20, 24],
|
|
177
|
+
lengths: [10, 12, 16, 20, 25, 30, 40, 50, 60, 80],
|
|
178
|
+
material: 'Steel, Grade 8.8',
|
|
179
|
+
finish: 'Zinc plated',
|
|
180
|
+
weight: (d, l) => (d * d * l * 7.85) / 1500,
|
|
181
|
+
price: (d, l) => 0.4 + (d * 0.08) + (l * 0.01),
|
|
182
|
+
image: 'hexbolt-steel'
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
setScrew: {
|
|
187
|
+
name: 'Set Screws',
|
|
188
|
+
description: 'ISO 4027 set screws with various points',
|
|
189
|
+
subtypes: {
|
|
190
|
+
cupPoint: {
|
|
191
|
+
label: 'Cup Point',
|
|
192
|
+
pattern: 'SS-{dia}x{length}-CUP',
|
|
193
|
+
diameters: [1.6, 2, 2.5, 3, 4, 5, 6, 8, 10],
|
|
194
|
+
lengths: [6, 8, 10, 12, 16, 20, 25, 30],
|
|
195
|
+
material: 'Steel, Grade 45H',
|
|
196
|
+
finish: 'Black oxide',
|
|
197
|
+
weight: (d, l) => (d * d * l * 7.85) / 3000,
|
|
198
|
+
price: (d, l) => 0.3 + (d * 0.1) + (l * 0.015),
|
|
199
|
+
image: 'setscrew-cup'
|
|
200
|
+
},
|
|
201
|
+
flatPoint: {
|
|
202
|
+
label: 'Flat Point',
|
|
203
|
+
pattern: 'SS-{dia}x{length}-FLAT',
|
|
204
|
+
diameters: [1.6, 2, 2.5, 3, 4, 5, 6, 8],
|
|
205
|
+
lengths: [6, 8, 10, 12, 16, 20, 25],
|
|
206
|
+
material: 'Steel, Grade 45H',
|
|
207
|
+
finish: 'Black oxide',
|
|
208
|
+
weight: (d, l) => (d * d * l * 7.85) / 3000,
|
|
209
|
+
price: (d, l) => 0.25 + (d * 0.08) + (l * 0.012),
|
|
210
|
+
image: 'setscrew-flat'
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
},
|
|
214
|
+
dowelPin: {
|
|
215
|
+
name: 'Dowel Pins',
|
|
216
|
+
description: 'Precision locating pins',
|
|
217
|
+
subtypes: {
|
|
218
|
+
standard: {
|
|
219
|
+
label: 'Standard (h7)',
|
|
220
|
+
pattern: 'DP-{dia}x{length}-STD',
|
|
221
|
+
diameters: [2, 3, 4, 5, 6, 8, 10, 12, 16],
|
|
222
|
+
lengths: [10, 12, 16, 20, 25, 30, 40, 50],
|
|
223
|
+
material: 'Steel',
|
|
224
|
+
tolerance: 'h7',
|
|
225
|
+
weight: (d, l) => (d * d * l * 7.85) / 2000,
|
|
226
|
+
price: (d, l) => 0.2 + (d * 0.05) + (l * 0.01),
|
|
227
|
+
image: 'dowel-standard'
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
hexNut: {
|
|
232
|
+
name: 'Hex Nuts',
|
|
233
|
+
description: 'ISO 4032 hex nuts',
|
|
234
|
+
subtypes: {
|
|
235
|
+
steel: {
|
|
236
|
+
label: 'Steel, Grade 8',
|
|
237
|
+
pattern: 'HN-{dia}-ST',
|
|
238
|
+
diameters: [3, 4, 5, 6, 8, 10, 12, 16, 20, 24],
|
|
239
|
+
material: 'Steel, Grade 8',
|
|
240
|
+
finish: 'Zinc plated',
|
|
241
|
+
weight: (d) => (d * d * 3 * 7.85) / 1000,
|
|
242
|
+
price: (d) => 0.15 + (d * 0.03),
|
|
243
|
+
image: 'hexnut-steel'
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
},
|
|
247
|
+
washer: {
|
|
248
|
+
name: 'Washers',
|
|
249
|
+
description: 'Flat and spring washers',
|
|
250
|
+
subtypes: {
|
|
251
|
+
flat: {
|
|
252
|
+
label: 'Flat (DIN 125)',
|
|
253
|
+
pattern: 'WF-{dia}-ST',
|
|
254
|
+
diameters: [3, 4, 5, 6, 8, 10, 12, 16, 20, 24],
|
|
255
|
+
material: 'Steel',
|
|
256
|
+
finish: 'Zinc plated',
|
|
257
|
+
weight: (d) => (d * d * 0.5 * 7.85) / 1000,
|
|
258
|
+
price: (d) => 0.08 + (d * 0.01),
|
|
259
|
+
image: 'washer-flat'
|
|
260
|
+
},
|
|
261
|
+
spring: {
|
|
262
|
+
label: 'Spring (DIN 127)',
|
|
263
|
+
pattern: 'WS-{dia}-ST',
|
|
264
|
+
diameters: [3, 4, 5, 6, 8, 10, 12, 16, 20],
|
|
265
|
+
material: 'Steel',
|
|
266
|
+
finish: 'Zinc plated',
|
|
267
|
+
weight: (d) => (d * d * 0.7 * 7.85) / 1000,
|
|
268
|
+
price: (d) => 0.12 + (d * 0.02),
|
|
269
|
+
image: 'washer-spring'
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
},
|
|
274
|
+
|
|
275
|
+
springs: {
|
|
276
|
+
compression: {
|
|
277
|
+
name: 'Compression Springs',
|
|
278
|
+
description: 'Helical compression springs',
|
|
279
|
+
subtypes: {
|
|
280
|
+
light: {
|
|
281
|
+
label: 'Light Duty',
|
|
282
|
+
pattern: 'CSL-{od}x{id}x{len}',
|
|
283
|
+
outerDiameters: [5, 6, 8, 10, 12, 16, 20, 25, 30],
|
|
284
|
+
loads: [1, 2, 5, 10, 15, 20], // Newton per mm
|
|
285
|
+
material: 'Music Wire',
|
|
286
|
+
tolerance: '±0.3mm',
|
|
287
|
+
weight: (od) => od * 0.3,
|
|
288
|
+
price: (od, load) => 5 + (od * 0.5) + (load * 0.2),
|
|
289
|
+
image: 'spring-compression-light'
|
|
290
|
+
},
|
|
291
|
+
medium: {
|
|
292
|
+
label: 'Medium Duty',
|
|
293
|
+
pattern: 'CSM-{od}x{id}x{len}',
|
|
294
|
+
outerDiameters: [8, 10, 12, 16, 20, 25, 32, 40],
|
|
295
|
+
loads: [10, 20, 30, 50, 75, 100],
|
|
296
|
+
material: 'Chrome Steel',
|
|
297
|
+
tolerance: '±0.5mm',
|
|
298
|
+
weight: (od) => od * 0.6,
|
|
299
|
+
price: (od, load) => 12 + (od * 1.0) + (load * 0.3),
|
|
300
|
+
image: 'spring-compression-medium'
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
},
|
|
304
|
+
extension: {
|
|
305
|
+
name: 'Extension Springs',
|
|
306
|
+
description: 'Helical extension springs with hooks',
|
|
307
|
+
subtypes: {
|
|
308
|
+
hookEnd: {
|
|
309
|
+
label: 'Hook Ends',
|
|
310
|
+
pattern: 'ESH-{od}x{id}x{len}',
|
|
311
|
+
outerDiameters: [4, 5, 6, 8, 10, 12, 16, 20],
|
|
312
|
+
loads: [1, 2, 5, 10, 20, 30, 50],
|
|
313
|
+
material: 'Music Wire',
|
|
314
|
+
hookType: 'Full loop',
|
|
315
|
+
weight: (od) => od * 0.25,
|
|
316
|
+
price: (od, load) => 6 + (od * 0.4) + (load * 0.25),
|
|
317
|
+
image: 'spring-extension-hook'
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
},
|
|
322
|
+
|
|
323
|
+
shaftsAndCouplings: {
|
|
324
|
+
shaftCollar: {
|
|
325
|
+
name: 'Shaft Collars',
|
|
326
|
+
description: 'Set screw and clamp-style collars',
|
|
327
|
+
subtypes: {
|
|
328
|
+
setScrew: {
|
|
329
|
+
label: 'Set Screw',
|
|
330
|
+
pattern: 'SC-{dia}x{width}-SS',
|
|
331
|
+
bores: [4, 5, 6, 8, 10, 12, 16, 20, 25],
|
|
332
|
+
widths: [10, 13, 16, 19, 25],
|
|
333
|
+
material: 'Cast iron',
|
|
334
|
+
finish: 'Black oxide',
|
|
335
|
+
weight: (d, w) => (d + 5) * (w / 5) * 0.8,
|
|
336
|
+
price: (d, w) => 3 + (d * 0.2) + (w * 0.3),
|
|
337
|
+
image: 'collar-setscrew'
|
|
338
|
+
},
|
|
339
|
+
clamp: {
|
|
340
|
+
label: 'Clamp Type',
|
|
341
|
+
pattern: 'SC-{dia}x{width}-CL',
|
|
342
|
+
bores: [6, 8, 10, 12, 16, 20, 25, 32],
|
|
343
|
+
widths: [13, 16, 19, 25, 32],
|
|
344
|
+
material: 'Stainless steel',
|
|
345
|
+
finish: 'Polished',
|
|
346
|
+
weight: (d, w) => (d + 6) * (w / 5) * 1.0,
|
|
347
|
+
price: (d, w) => 8 + (d * 0.35) + (w * 0.5),
|
|
348
|
+
image: 'collar-clamp'
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
},
|
|
352
|
+
flexibleCoupling: {
|
|
353
|
+
name: 'Flexible Couplings',
|
|
354
|
+
description: 'Flexible shaft couplings',
|
|
355
|
+
subtypes: {
|
|
356
|
+
jaw: {
|
|
357
|
+
label: 'Jaw Type',
|
|
358
|
+
pattern: 'FC-JAW-{dia1}x{dia2}',
|
|
359
|
+
sizes: [3, 4, 5, 6, 8, 10, 12, 16, 20],
|
|
360
|
+
material: 'Cast iron with elastomer',
|
|
361
|
+
misalignment: '1.5mm',
|
|
362
|
+
weight: (s) => s * 0.5 + 15,
|
|
363
|
+
price: (s) => 25 + (s * 2.0),
|
|
364
|
+
image: 'coupling-jaw'
|
|
365
|
+
},
|
|
366
|
+
beam: {
|
|
367
|
+
label: 'Beam Type',
|
|
368
|
+
pattern: 'FC-BEAM-{dia}',
|
|
369
|
+
sizes: [3, 4, 5, 6, 8, 10, 12],
|
|
370
|
+
material: 'Aluminum',
|
|
371
|
+
misalignment: '0.5mm',
|
|
372
|
+
weight: (s) => s * 0.2 + 8,
|
|
373
|
+
price: (s) => 15 + (s * 1.5),
|
|
374
|
+
image: 'coupling-beam'
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
},
|
|
379
|
+
|
|
380
|
+
positioning: {
|
|
381
|
+
locatingPin: {
|
|
382
|
+
name: 'Locating Pins',
|
|
383
|
+
description: 'Straight and tapered locating pins',
|
|
384
|
+
subtypes: {
|
|
385
|
+
straight: {
|
|
386
|
+
label: 'Straight',
|
|
387
|
+
pattern: 'LP-{dia}x{length}-ST',
|
|
388
|
+
diameters: [2, 3, 4, 5, 6, 8, 10, 12],
|
|
389
|
+
lengths: [10, 15, 20, 25, 30, 40, 50],
|
|
390
|
+
material: 'Hardened steel',
|
|
391
|
+
tolerance: 'h7',
|
|
392
|
+
weight: (d, l) => (d * d * l * 7.85) / 2000,
|
|
393
|
+
price: (d, l) => 1.5 + (d * 0.1) + (l * 0.02),
|
|
394
|
+
image: 'pin-straight'
|
|
395
|
+
},
|
|
396
|
+
tapered: {
|
|
397
|
+
label: 'Tapered (1:50)',
|
|
398
|
+
pattern: 'LP-{dia}x{length}-TAP',
|
|
399
|
+
diameters: [2, 3, 4, 5, 6, 8, 10],
|
|
400
|
+
lengths: [12, 16, 20, 25, 30, 40],
|
|
401
|
+
material: 'Hardened steel',
|
|
402
|
+
tolerance: 'h7',
|
|
403
|
+
weight: (d, l) => (d * d * l * 7.85) / 2500,
|
|
404
|
+
price: (d, l) => 2.0 + (d * 0.15) + (l * 0.025),
|
|
405
|
+
image: 'pin-tapered'
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
},
|
|
409
|
+
toggleClamp: {
|
|
410
|
+
name: 'Toggle Clamps',
|
|
411
|
+
description: 'Quick action toggle clamps',
|
|
412
|
+
subtypes: {
|
|
413
|
+
horizontal: {
|
|
414
|
+
label: 'Horizontal',
|
|
415
|
+
pattern: 'TC-HOR-{capacity}',
|
|
416
|
+
capacities: [100, 200, 300, 500, 750, 1000, 1500], // Newtons
|
|
417
|
+
material: 'Ductile iron',
|
|
418
|
+
stroke: (cap) => 20 + (cap / 100) * 5,
|
|
419
|
+
weight: (cap) => 0.5 + (cap / 200),
|
|
420
|
+
price: (cap) => 20 + (cap * 0.02),
|
|
421
|
+
image: 'clamp-toggle-horizontal'
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
},
|
|
425
|
+
levelingFeet: {
|
|
426
|
+
name: 'Leveling Feet',
|
|
427
|
+
description: 'Adjustable leveling feet and pads',
|
|
428
|
+
subtypes: {
|
|
429
|
+
threaded: {
|
|
430
|
+
label: 'Threaded',
|
|
431
|
+
pattern: 'LF-{thread}x{diameter}',
|
|
432
|
+
threads: ['M6', 'M8', 'M10', 'M12', 'M16', 'M20'],
|
|
433
|
+
diameters: [30, 40, 50, 60, 75, 100],
|
|
434
|
+
material: 'Steel base, elastomer pad',
|
|
435
|
+
padMaterial: 'Natural rubber',
|
|
436
|
+
weight: (d) => d * 0.5,
|
|
437
|
+
price: (t, d) => 8 + (d * 0.15),
|
|
438
|
+
image: 'feet-leveling'
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
};
|
|
444
|
+
|
|
445
|
+
// MCP server: encapsulate all methods
|
|
446
|
+
const MisumiCatalog = {
|
|
447
|
+
// Database getters
|
|
448
|
+
getCategory(catName) {
|
|
449
|
+
return COMPONENT_DB[catName] || null;
|
|
450
|
+
},
|
|
451
|
+
|
|
452
|
+
getComponentType(catName, typeName) {
|
|
453
|
+
const cat = COMPONENT_DB[catName];
|
|
454
|
+
return cat ? cat[typeName] : null;
|
|
455
|
+
},
|
|
456
|
+
|
|
457
|
+
getAllComponents() {
|
|
458
|
+
const all = [];
|
|
459
|
+
for (const [catKey, catVal] of Object.entries(COMPONENT_DB)) {
|
|
460
|
+
for (const [typeKey, typeVal] of Object.entries(catVal)) {
|
|
461
|
+
all.push({
|
|
462
|
+
category: catKey,
|
|
463
|
+
type: typeKey,
|
|
464
|
+
name: typeVal.name,
|
|
465
|
+
description: typeVal.description
|
|
466
|
+
});
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
return all;
|
|
470
|
+
},
|
|
471
|
+
|
|
472
|
+
// Parametric configurator
|
|
473
|
+
configure(category, type, params = {}) {
|
|
474
|
+
const comp = this.getComponentType(category, type);
|
|
475
|
+
if (!comp) return null;
|
|
476
|
+
|
|
477
|
+
const subtype = comp.subtypes[params.subtype || Object.keys(comp.subtypes)[0]];
|
|
478
|
+
if (!subtype) return null;
|
|
479
|
+
|
|
480
|
+
// Generate part number
|
|
481
|
+
let partNumber = subtype.pattern;
|
|
482
|
+
if (params.diameter) partNumber = partNumber.replace('{dia}', params.diameter);
|
|
483
|
+
if (params.length) partNumber = partNumber.replace('{len}', params.length);
|
|
484
|
+
if (params.lead) partNumber = partNumber.replace('{lead}', params.lead);
|
|
485
|
+
if (params.od) partNumber = partNumber.replace('{od}', params.od);
|
|
486
|
+
if (params.id) partNumber = partNumber.replace('{id}', params.id);
|
|
487
|
+
if (params.size) partNumber = partNumber.replace('{size}', params.size);
|
|
488
|
+
|
|
489
|
+
// Calculate weight and price
|
|
490
|
+
let weight = 0;
|
|
491
|
+
let priceUsd = 0;
|
|
492
|
+
if (params.diameter && params.length) {
|
|
493
|
+
weight = subtype.weight(params.diameter, params.length);
|
|
494
|
+
if (params.lead) {
|
|
495
|
+
priceUsd = subtype.price(params.diameter, params.lead, params.length);
|
|
496
|
+
} else {
|
|
497
|
+
priceUsd = subtype.price(params.diameter, params.length);
|
|
498
|
+
}
|
|
499
|
+
} else if (params.diameter) {
|
|
500
|
+
weight = subtype.weight(params.diameter);
|
|
501
|
+
priceUsd = subtype.price(params.diameter);
|
|
502
|
+
} else if (params.size) {
|
|
503
|
+
weight = subtype.weight(params.size);
|
|
504
|
+
priceUsd = subtype.price(params.size);
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
const priceTokens = Math.round(priceUsd * 1.5); // Convert USD to estimated $CYCLE tokens
|
|
508
|
+
|
|
509
|
+
return {
|
|
510
|
+
misumiPN: partNumber,
|
|
511
|
+
name: comp.name,
|
|
512
|
+
subtype: subtype.label,
|
|
513
|
+
material: subtype.material,
|
|
514
|
+
finish: subtype.finish || 'Standard',
|
|
515
|
+
tolerance: subtype.tolerance || 'Standard',
|
|
516
|
+
specifications: params,
|
|
517
|
+
weight: parseFloat(weight.toFixed(2)),
|
|
518
|
+
priceUSD: parseFloat(priceUsd.toFixed(2)),
|
|
519
|
+
priceTokens: priceTokens,
|
|
520
|
+
misumiUrl: `https://us.misumi-ec.com/vona2/detail/${partNumber.replace('{', '').replace('}', '')}`,
|
|
521
|
+
image: subtype.image
|
|
522
|
+
};
|
|
523
|
+
},
|
|
524
|
+
|
|
525
|
+
// Search across all components
|
|
526
|
+
search(query, filters = {}) {
|
|
527
|
+
const results = [];
|
|
528
|
+
const lowerQuery = query.toLowerCase();
|
|
529
|
+
|
|
530
|
+
for (const [catKey, catVal] of Object.entries(COMPONENT_DB)) {
|
|
531
|
+
for (const [typeKey, typeVal] of Object.entries(catVal)) {
|
|
532
|
+
// Match on name, description, or type
|
|
533
|
+
const matchScore =
|
|
534
|
+
(typeVal.name.toLowerCase().includes(lowerQuery) ? 3 : 0) +
|
|
535
|
+
(typeVal.description.toLowerCase().includes(lowerQuery) ? 2 : 0) +
|
|
536
|
+
(typeKey.toLowerCase().includes(lowerQuery) ? 1 : 0);
|
|
537
|
+
|
|
538
|
+
if (matchScore > 0) {
|
|
539
|
+
// Apply filters
|
|
540
|
+
if (filters.category && catKey !== filters.category) continue;
|
|
541
|
+
if (filters.material && typeVal.subtypes) {
|
|
542
|
+
const subtypesMatching = Object.entries(typeVal.subtypes).filter(
|
|
543
|
+
([, st]) => !filters.material || (st.material && st.material.includes(filters.material))
|
|
544
|
+
);
|
|
545
|
+
if (subtypesMatching.length === 0) continue;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
results.push({
|
|
549
|
+
category: catKey,
|
|
550
|
+
type: typeKey,
|
|
551
|
+
name: typeVal.name,
|
|
552
|
+
description: typeVal.description,
|
|
553
|
+
score: matchScore,
|
|
554
|
+
subtypes: Object.keys(typeVal.subtypes)
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
return results.sort((a, b) => b.score - a.score);
|
|
561
|
+
},
|
|
562
|
+
|
|
563
|
+
// Compare multiple parts
|
|
564
|
+
compare(partNumbers) {
|
|
565
|
+
const specs = partNumbers.map(pn => {
|
|
566
|
+
// Extract config from part number (simplified)
|
|
567
|
+
return {
|
|
568
|
+
misumiPN: pn,
|
|
569
|
+
url: `https://us.misumi-ec.com/vona2/detail/${pn}`
|
|
570
|
+
};
|
|
571
|
+
});
|
|
572
|
+
|
|
573
|
+
return {
|
|
574
|
+
parts: specs,
|
|
575
|
+
comparisonUrl: `https://us.misumi-ec.com/vona2/mcs/Item?SORL=0${specs.map(s => `&ML=${encodeURIComponent(s.misumiPN)}`).join('')}`
|
|
576
|
+
};
|
|
577
|
+
},
|
|
578
|
+
|
|
579
|
+
// BOM management
|
|
580
|
+
getBOM() {
|
|
581
|
+
const bom = JSON.parse(localStorage.getItem('cyclecad_misumi_bom') || '[]');
|
|
582
|
+
return bom;
|
|
583
|
+
},
|
|
584
|
+
|
|
585
|
+
addToBOM(partNumber, quantity = 1) {
|
|
586
|
+
const bom = this.getBOM();
|
|
587
|
+
const existing = bom.find(item => item.misumiPN === partNumber);
|
|
588
|
+
if (existing) {
|
|
589
|
+
existing.quantity += quantity;
|
|
590
|
+
} else {
|
|
591
|
+
bom.push({ misumiPN: partNumber, quantity, added: new Date().toISOString() });
|
|
592
|
+
}
|
|
593
|
+
localStorage.setItem('cyclecad_misumi_bom', JSON.stringify(bom));
|
|
594
|
+
return bom;
|
|
595
|
+
},
|
|
596
|
+
|
|
597
|
+
removeFromBOM(partNumber) {
|
|
598
|
+
const bom = this.getBOM().filter(item => item.misumiPN !== partNumber);
|
|
599
|
+
localStorage.setItem('cyclecad_misumi_bom', JSON.stringify(bom));
|
|
600
|
+
return bom;
|
|
601
|
+
},
|
|
602
|
+
|
|
603
|
+
clearBOM() {
|
|
604
|
+
localStorage.setItem('cyclecad_misumi_bom', '[]');
|
|
605
|
+
},
|
|
606
|
+
|
|
607
|
+
getBOMTotal() {
|
|
608
|
+
// Simplified: sum of estimated prices
|
|
609
|
+
// In real implementation, would fetch live prices from MISUMI API
|
|
610
|
+
return {
|
|
611
|
+
itemCount: this.getBOM().reduce((sum, item) => sum + item.quantity, 0),
|
|
612
|
+
estimatedUSD: this.getBOM().reduce((sum, item) => sum + 50, 0), // Placeholder
|
|
613
|
+
estimatedTokens: this.getBOM().length * 75
|
|
614
|
+
};
|
|
615
|
+
},
|
|
616
|
+
|
|
617
|
+
exportBOM(format = 'csv') {
|
|
618
|
+
const bom = this.getBOM();
|
|
619
|
+
if (format === 'csv') {
|
|
620
|
+
const header = 'MISUMI PN,Quantity,Unit Price (USD),Total,MISUMI URL';
|
|
621
|
+
const rows = bom.map(item =>
|
|
622
|
+
`${item.misumiPN},${item.quantity},50.00,${item.quantity * 50},${ encodeURIComponent(item.misumiPN)}`
|
|
623
|
+
);
|
|
624
|
+
return header + '\n' + rows.join('\n');
|
|
625
|
+
} else if (format === 'html') {
|
|
626
|
+
let html = '<table border="1"><tr><th>MISUMI PN</th><th>Quantity</th><th>Price</th><th>Link</th></tr>';
|
|
627
|
+
bom.forEach(item => {
|
|
628
|
+
html += `<tr><td>${item.misumiPN}</td><td>${item.quantity}</td><td>$50</td>`;
|
|
629
|
+
html += `<td><a href="https://us.misumi-ec.com/vona2/detail/${item.misumiPN}" target="_blank">MISUMI</a></td></tr>`;
|
|
630
|
+
});
|
|
631
|
+
html += '</table>';
|
|
632
|
+
return html;
|
|
633
|
+
}
|
|
634
|
+
return null;
|
|
635
|
+
},
|
|
636
|
+
|
|
637
|
+
// Quick 3D geometry generation
|
|
638
|
+
insertComponent(partNumber, position = [0, 0, 0]) {
|
|
639
|
+
// Simplified: return basic geometry for visualization
|
|
640
|
+
// In full implementation, would return proper Three.js geometry
|
|
641
|
+
const geom = {
|
|
642
|
+
type: 'cylinder', // or 'box', 'torus', etc.
|
|
643
|
+
params: {
|
|
644
|
+
radiusTop: 5,
|
|
645
|
+
radiusBottom: 5,
|
|
646
|
+
height: 50,
|
|
647
|
+
segments: 16
|
|
648
|
+
},
|
|
649
|
+
position,
|
|
650
|
+
misumiPN: partNumber
|
|
651
|
+
};
|
|
652
|
+
return geom;
|
|
653
|
+
},
|
|
654
|
+
|
|
655
|
+
// UI generation
|
|
656
|
+
getUI() {
|
|
657
|
+
return `
|
|
658
|
+
<div id="misumi-panel" class="misumi-panel" style="
|
|
659
|
+
position: fixed;
|
|
660
|
+
right: 0;
|
|
661
|
+
top: 44px;
|
|
662
|
+
width: 400px;
|
|
663
|
+
height: calc(100vh - 44px);
|
|
664
|
+
background: #1e1e1e;
|
|
665
|
+
border-left: 1px solid #333;
|
|
666
|
+
color: #e0e0e0;
|
|
667
|
+
font-family: Calibri, sans-serif;
|
|
668
|
+
font-size: 13px;
|
|
669
|
+
z-index: 999;
|
|
670
|
+
display: flex;
|
|
671
|
+
flex-direction: column;
|
|
672
|
+
">
|
|
673
|
+
<div class="misumi-tabs" style="
|
|
674
|
+
display: flex;
|
|
675
|
+
border-bottom: 1px solid #333;
|
|
676
|
+
background: #252525;
|
|
677
|
+
">
|
|
678
|
+
<button class="tab-btn active" data-tab="browse" style="
|
|
679
|
+
flex: 1;
|
|
680
|
+
padding: 10px;
|
|
681
|
+
border: none;
|
|
682
|
+
background: #252525;
|
|
683
|
+
color: #58a6ff;
|
|
684
|
+
cursor: pointer;
|
|
685
|
+
border-bottom: 2px solid #58a6ff;
|
|
686
|
+
font-weight: bold;
|
|
687
|
+
">Browse</button>
|
|
688
|
+
<button class="tab-btn" data-tab="configure" style="
|
|
689
|
+
flex: 1;
|
|
690
|
+
padding: 10px;
|
|
691
|
+
border: none;
|
|
692
|
+
background: #252525;
|
|
693
|
+
color: #888;
|
|
694
|
+
cursor: pointer;
|
|
695
|
+
font-weight: bold;
|
|
696
|
+
">Configure</button>
|
|
697
|
+
<button class="tab-btn" data-tab="search" style="
|
|
698
|
+
flex: 1;
|
|
699
|
+
padding: 10px;
|
|
700
|
+
border: none;
|
|
701
|
+
background: #252525;
|
|
702
|
+
color: #888;
|
|
703
|
+
cursor: pointer;
|
|
704
|
+
font-weight: bold;
|
|
705
|
+
">Search</button>
|
|
706
|
+
<button class="tab-btn" data-tab="bom" style="
|
|
707
|
+
flex: 1;
|
|
708
|
+
padding: 10px;
|
|
709
|
+
border: none;
|
|
710
|
+
background: #252525;
|
|
711
|
+
color: #888;
|
|
712
|
+
cursor: pointer;
|
|
713
|
+
font-weight: bold;
|
|
714
|
+
">BOM</button>
|
|
715
|
+
</div>
|
|
716
|
+
|
|
717
|
+
<div class="misumi-content" style="
|
|
718
|
+
flex: 1;
|
|
719
|
+
overflow-y: auto;
|
|
720
|
+
padding: 12px;
|
|
721
|
+
min-height: 0;
|
|
722
|
+
">
|
|
723
|
+
<!-- Browse Tab -->
|
|
724
|
+
<div class="tab-content browse active" style="display: block;">
|
|
725
|
+
<div style="font-weight: bold; margin-bottom: 10px; color: #58a6ff;">Component Categories</div>
|
|
726
|
+
<div id="misumi-categories" style="
|
|
727
|
+
display: grid;
|
|
728
|
+
grid-template-columns: 1fr 1fr;
|
|
729
|
+
gap: 8px;
|
|
730
|
+
">
|
|
731
|
+
<button style="padding: 12px; background: #2d2d2d; border: 1px solid #444; color: #e0e0e0; cursor: pointer; border-radius: 4px; font-size: 11px;" onclick="window.cycleCAD.misumi._expandCategory('linearMotion')">Linear Motion</button>
|
|
732
|
+
<button style="padding: 12px; background: #2d2d2d; border: 1px solid #444; color: #e0e0e0; cursor: pointer; border-radius: 4px; font-size: 11px;" onclick="window.cycleCAD.misumi._expandCategory('fasteners')">Fasteners</button>
|
|
733
|
+
<button style="padding: 12px; background: #2d2d2d; border: 1px solid #444; color: #e0e0e0; cursor: pointer; border-radius: 4px; font-size: 11px;" onclick="window.cycleCAD.misumi._expandCategory('springs')">Springs</button>
|
|
734
|
+
<button style="padding: 12px; background: #2d2d2d; border: 1px solid #444; color: #e0e0e0; cursor: pointer; border-radius: 4px; font-size: 11px;" onclick="window.cycleCAD.misumi._expandCategory('shaftsAndCouplings')">Couplings</button>
|
|
735
|
+
<button style="padding: 12px; background: #2d2d2d; border: 1px solid #444; color: #e0e0e0; cursor: pointer; border-radius: 4px; font-size: 11px;" onclick="window.cycleCAD.misumi._expandCategory('positioning')">Positioning</button>
|
|
736
|
+
</div>
|
|
737
|
+
<div id="misumi-category-items" style="margin-top: 12px;"></div>
|
|
738
|
+
</div>
|
|
739
|
+
|
|
740
|
+
<!-- Configure Tab -->
|
|
741
|
+
<div class="tab-content configure" style="display: none;">
|
|
742
|
+
<div style="font-weight: bold; margin-bottom: 10px; color: #58a6ff;">Parametric Configurator</div>
|
|
743
|
+
<label style="display: block; margin-bottom: 8px;">
|
|
744
|
+
Category:
|
|
745
|
+
<select id="misumi-cat-sel" style="width: 100%; padding: 6px; background: #2d2d2d; color: #e0e0e0; border: 1px solid #444; border-radius: 4px; margin-top: 4px;">
|
|
746
|
+
<option value="">-- Select --</option>
|
|
747
|
+
<option value="linearMotion">Linear Motion</option>
|
|
748
|
+
<option value="fasteners">Fasteners</option>
|
|
749
|
+
<option value="springs">Springs</option>
|
|
750
|
+
<option value="shaftsAndCouplings">Shafts & Couplings</option>
|
|
751
|
+
<option value="positioning">Positioning</option>
|
|
752
|
+
</select>
|
|
753
|
+
</label>
|
|
754
|
+
<label style="display: block; margin-bottom: 8px;">
|
|
755
|
+
Type:
|
|
756
|
+
<select id="misumi-type-sel" style="width: 100%; padding: 6px; background: #2d2d2d; color: #e0e0e0; border: 1px solid #444; border-radius: 4px; margin-top: 4px;">
|
|
757
|
+
<option value="">-- Select --</option>
|
|
758
|
+
</select>
|
|
759
|
+
</label>
|
|
760
|
+
<div id="misumi-params" style="margin-top: 12px;"></div>
|
|
761
|
+
<button onclick="window.cycleCAD.misumi._executeConfig()" style="
|
|
762
|
+
width: 100%;
|
|
763
|
+
padding: 10px;
|
|
764
|
+
background: #58a6ff;
|
|
765
|
+
color: #1e1e1e;
|
|
766
|
+
border: none;
|
|
767
|
+
border-radius: 4px;
|
|
768
|
+
cursor: pointer;
|
|
769
|
+
font-weight: bold;
|
|
770
|
+
margin-top: 12px;
|
|
771
|
+
">Configure & Add to BOM</button>
|
|
772
|
+
<div id="misumi-config-result" style="margin-top: 12px; padding: 8px; background: #2d2d2d; border-left: 3px solid #58a6ff; border-radius: 4px; display: none;"></div>
|
|
773
|
+
</div>
|
|
774
|
+
|
|
775
|
+
<!-- Search Tab -->
|
|
776
|
+
<div class="tab-content search" style="display: none;">
|
|
777
|
+
<div style="font-weight: bold; margin-bottom: 10px; color: #58a6ff;">Search Components</div>
|
|
778
|
+
<input type="text" id="misumi-search-input" placeholder="Search..." style="
|
|
779
|
+
width: 100%;
|
|
780
|
+
padding: 8px;
|
|
781
|
+
background: #2d2d2d;
|
|
782
|
+
color: #e0e0e0;
|
|
783
|
+
border: 1px solid #444;
|
|
784
|
+
border-radius: 4px;
|
|
785
|
+
margin-bottom: 10px;
|
|
786
|
+
">
|
|
787
|
+
<div id="misumi-search-results" style="margin-top: 8px;"></div>
|
|
788
|
+
</div>
|
|
789
|
+
|
|
790
|
+
<!-- BOM Tab -->
|
|
791
|
+
<div class="tab-content bom" style="display: none;">
|
|
792
|
+
<div style="font-weight: bold; margin-bottom: 10px; color: #58a6ff;">Bill of Materials</div>
|
|
793
|
+
<div id="misumi-bom-items" style="margin-bottom: 12px;"></div>
|
|
794
|
+
<div style="background: #2d2d2d; padding: 8px; border-radius: 4px; margin-bottom: 10px;">
|
|
795
|
+
<div>Items: <span id="misumi-bom-count">0</span></div>
|
|
796
|
+
<div>Est. Cost: <span id="misumi-bom-total">$0</span></div>
|
|
797
|
+
</div>
|
|
798
|
+
<button onclick="window.cycleCAD.misumi._exportBOM('csv')" style="
|
|
799
|
+
width: 100%;
|
|
800
|
+
padding: 8px;
|
|
801
|
+
background: #444;
|
|
802
|
+
color: #e0e0e0;
|
|
803
|
+
border: none;
|
|
804
|
+
border-radius: 4px;
|
|
805
|
+
cursor: pointer;
|
|
806
|
+
margin-bottom: 6px;
|
|
807
|
+
">Export CSV</button>
|
|
808
|
+
<button onclick="window.cycleCAD.misumi._clearBOM()" style="
|
|
809
|
+
width: 100%;
|
|
810
|
+
padding: 8px;
|
|
811
|
+
background: #333;
|
|
812
|
+
color: #e0e0e0;
|
|
813
|
+
border: none;
|
|
814
|
+
border-radius: 4px;
|
|
815
|
+
cursor: pointer;
|
|
816
|
+
">Clear BOM</button>
|
|
817
|
+
</div>
|
|
818
|
+
</div>
|
|
819
|
+
</div>
|
|
820
|
+
`;
|
|
821
|
+
},
|
|
822
|
+
|
|
823
|
+
// Internal UI helpers
|
|
824
|
+
_expandCategory(catName) {
|
|
825
|
+
const cat = COMPONENT_DB[catName];
|
|
826
|
+
if (!cat) return;
|
|
827
|
+
const container = document.getElementById('misumi-category-items');
|
|
828
|
+
container.innerHTML = '';
|
|
829
|
+
for (const [typeKey, typeVal] of Object.entries(cat)) {
|
|
830
|
+
const card = document.createElement('div');
|
|
831
|
+
card.style.cssText = 'padding: 10px; background: #2d2d2d; border: 1px solid #444; border-radius: 4px; margin-bottom: 8px; cursor: pointer;';
|
|
832
|
+
card.innerHTML = `
|
|
833
|
+
<div style="font-weight: bold; color: #58a6ff;">${typeVal.name}</div>
|
|
834
|
+
<div style="font-size: 11px; color: #888; margin-top: 4px;">${typeVal.description}</div>
|
|
835
|
+
`;
|
|
836
|
+
card.onclick = () => alert(`${typeVal.name}: ${typeVal.description}\n\nSubtypes: ${Object.keys(typeVal.subtypes).join(', ')}`);
|
|
837
|
+
container.appendChild(card);
|
|
838
|
+
}
|
|
839
|
+
},
|
|
840
|
+
|
|
841
|
+
_executeConfig() {
|
|
842
|
+
const cat = document.getElementById('misumi-cat-sel')?.value;
|
|
843
|
+
const type = document.getElementById('misumi-type-sel')?.value;
|
|
844
|
+
if (!cat || !type) return alert('Please select category and type');
|
|
845
|
+
|
|
846
|
+
const result = this.configure(cat, type, { diameter: 10, length: 100, subtype: Object.keys(COMPONENT_DB[cat]?.[type]?.subtypes || {})[0] });
|
|
847
|
+
if (result) {
|
|
848
|
+
this.addToBOM(result.misumiPN, 1);
|
|
849
|
+
const resultDiv = document.getElementById('misumi-config-result');
|
|
850
|
+
resultDiv.style.display = 'block';
|
|
851
|
+
resultDiv.innerHTML = `<strong>${result.misumiPN}</strong><br>$${result.priceUSD} (${result.priceTokens} tokens)<br><a href="${result.misumiUrl}" target="_blank" style="color: #58a6ff; text-decoration: none;">View on MISUMI</a>`;
|
|
852
|
+
}
|
|
853
|
+
},
|
|
854
|
+
|
|
855
|
+
_exportBOM(format) {
|
|
856
|
+
const csv = this.exportBOM(format);
|
|
857
|
+
const blob = new Blob([csv], { type: 'text/csv' });
|
|
858
|
+
const url = URL.createObjectURL(blob);
|
|
859
|
+
const a = document.createElement('a');
|
|
860
|
+
a.href = url;
|
|
861
|
+
a.download = `cyclecad-bom-${new Date().toISOString().split('T')[0]}.${format}`;
|
|
862
|
+
a.click();
|
|
863
|
+
},
|
|
864
|
+
|
|
865
|
+
_clearBOM() {
|
|
866
|
+
if (confirm('Clear entire BOM?')) {
|
|
867
|
+
this.clearBOM();
|
|
868
|
+
this._updateBOMUI();
|
|
869
|
+
}
|
|
870
|
+
},
|
|
871
|
+
|
|
872
|
+
_updateBOMUI() {
|
|
873
|
+
const bom = this.getBOM();
|
|
874
|
+
const total = this.getBOMTotal();
|
|
875
|
+
document.getElementById('misumi-bom-count').textContent = total.itemCount;
|
|
876
|
+
document.getElementById('misumi-bom-total').textContent = `$${total.estimatedUSD}`;
|
|
877
|
+
|
|
878
|
+
const itemsDiv = document.getElementById('misumi-bom-items');
|
|
879
|
+
itemsDiv.innerHTML = bom.map(item => `
|
|
880
|
+
<div style="padding: 8px; background: #2d2d2d; border-radius: 4px; margin-bottom: 6px; display: flex; justify-content: space-between; align-items: center;">
|
|
881
|
+
<div>
|
|
882
|
+
<div style="font-weight: bold;">${item.misumiPN}</div>
|
|
883
|
+
<div style="font-size: 11px; color: #888;">Qty: ${item.quantity}</div>
|
|
884
|
+
</div>
|
|
885
|
+
<button onclick="window.cycleCAD.misumi.removeFromBOM('${item.misumiPN}'); window.cycleCAD.misumi._updateBOMUI();" style="
|
|
886
|
+
padding: 4px 8px;
|
|
887
|
+
background: #444;
|
|
888
|
+
color: #e0e0e0;
|
|
889
|
+
border: none;
|
|
890
|
+
border-radius: 3px;
|
|
891
|
+
cursor: pointer;
|
|
892
|
+
font-size: 11px;
|
|
893
|
+
">Remove</button>
|
|
894
|
+
</div>
|
|
895
|
+
`).join('');
|
|
896
|
+
}
|
|
897
|
+
};
|
|
898
|
+
|
|
899
|
+
// Register as window.cycleCAD.misumi
|
|
900
|
+
if (!window.cycleCAD) window.cycleCAD = {};
|
|
901
|
+
window.cycleCAD.misumi = MisumiCatalog;
|
|
902
|
+
|
|
903
|
+
console.log('[MISUMI Catalog] Loaded. Use window.cycleCAD.misumi.configure(...) to get started.');
|
|
904
|
+
})();
|