@tscircuit/circuit-json-util 0.0.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +64 -0
- package/dist/index.cjs +636 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +2368 -0
- package/dist/index.d.ts +2413 -0
- package/dist/index.js +1286 -0
- package/dist/index.js.map +1 -0
- package/package.json +37 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1286 @@
|
|
|
1
|
+
// lib/cju.ts
|
|
2
|
+
import * as Soup from "circuit-json";
|
|
3
|
+
var cju = (soup, options = {}) => {
|
|
4
|
+
let internalStore = soup._internal_store;
|
|
5
|
+
if (!internalStore) {
|
|
6
|
+
internalStore = {
|
|
7
|
+
counts: {}
|
|
8
|
+
};
|
|
9
|
+
soup._internal_store = internalStore;
|
|
10
|
+
for (const elm of soup) {
|
|
11
|
+
const type = elm.type;
|
|
12
|
+
const idVal = elm[`${type}_id`];
|
|
13
|
+
if (!idVal)
|
|
14
|
+
continue;
|
|
15
|
+
const idNum = Number.parseInt(idVal.split("_").pop());
|
|
16
|
+
if (!Number.isNaN(idNum)) {
|
|
17
|
+
internalStore.counts[type] = Math.max(
|
|
18
|
+
internalStore.counts[type] ?? 0,
|
|
19
|
+
idNum
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const su2 = new Proxy(
|
|
25
|
+
{},
|
|
26
|
+
{
|
|
27
|
+
get: (proxy_target, component_type) => {
|
|
28
|
+
if (component_type === "toArray") {
|
|
29
|
+
return () => soup;
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
get: (id) => soup.find(
|
|
33
|
+
(e) => e.type === component_type && e[`${component_type}_id`] === id
|
|
34
|
+
),
|
|
35
|
+
getUsing: (using) => {
|
|
36
|
+
const keys = Object.keys(using);
|
|
37
|
+
if (keys.length !== 1) {
|
|
38
|
+
throw new Error(
|
|
39
|
+
"getUsing requires exactly one key, e.g. { pcb_component_id }"
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
const join_key = keys[0];
|
|
43
|
+
const join_type = join_key.replace("_id", "");
|
|
44
|
+
const joiner = soup.find(
|
|
45
|
+
(e) => e.type === join_type && e[join_key] === using[join_key]
|
|
46
|
+
);
|
|
47
|
+
if (!joiner)
|
|
48
|
+
return null;
|
|
49
|
+
return soup.find(
|
|
50
|
+
(e) => e.type === component_type && e[`${component_type}_id`] === joiner[`${component_type}_id`]
|
|
51
|
+
);
|
|
52
|
+
},
|
|
53
|
+
getWhere: (where) => {
|
|
54
|
+
const keys = Object.keys(where);
|
|
55
|
+
return soup.find(
|
|
56
|
+
(e) => e.type === component_type && keys.every((key) => e[key] === where[key])
|
|
57
|
+
);
|
|
58
|
+
},
|
|
59
|
+
list: (where) => {
|
|
60
|
+
const keys = !where ? [] : Object.keys(where);
|
|
61
|
+
return soup.filter(
|
|
62
|
+
(e) => e.type === component_type && keys.every((key) => e[key] === where[key])
|
|
63
|
+
);
|
|
64
|
+
},
|
|
65
|
+
insert: (elm) => {
|
|
66
|
+
internalStore.counts[component_type] ??= -1;
|
|
67
|
+
internalStore.counts[component_type]++;
|
|
68
|
+
const index = internalStore.counts[component_type];
|
|
69
|
+
const newElm = {
|
|
70
|
+
type: component_type,
|
|
71
|
+
[`${component_type}_id`]: `${component_type}_${index}`,
|
|
72
|
+
...elm
|
|
73
|
+
};
|
|
74
|
+
if (options.validateInserts) {
|
|
75
|
+
const parser = Soup[component_type] ?? Soup.any_soup_element;
|
|
76
|
+
parser.parse(newElm);
|
|
77
|
+
}
|
|
78
|
+
soup.push(newElm);
|
|
79
|
+
return newElm;
|
|
80
|
+
},
|
|
81
|
+
delete: (id) => {
|
|
82
|
+
const elm = soup.find(
|
|
83
|
+
(e) => e[`${component_type}_id`] === id
|
|
84
|
+
);
|
|
85
|
+
if (!elm)
|
|
86
|
+
return;
|
|
87
|
+
soup.splice(soup.indexOf(elm), 1);
|
|
88
|
+
},
|
|
89
|
+
update: (id, newProps) => {
|
|
90
|
+
const elm = soup.find(
|
|
91
|
+
(e) => e.type === component_type && e[`${component_type}_id`] === id
|
|
92
|
+
);
|
|
93
|
+
if (!elm)
|
|
94
|
+
return;
|
|
95
|
+
Object.assign(elm, newProps);
|
|
96
|
+
return elm;
|
|
97
|
+
},
|
|
98
|
+
select: (selector) => {
|
|
99
|
+
if (component_type === "source_component") {
|
|
100
|
+
return soup.find(
|
|
101
|
+
(e) => e.type === "source_component" && e.name === selector.replace(/\./g, "")
|
|
102
|
+
);
|
|
103
|
+
} else if (component_type === "pcb_port" || component_type === "source_port" || component_type === "schematic_port") {
|
|
104
|
+
const [component_name, port_selector] = selector.replace(/\./g, "").split(/[\s\>]+/);
|
|
105
|
+
const source_component = soup.find(
|
|
106
|
+
(e) => e.type === "source_component" && e.name === component_name
|
|
107
|
+
);
|
|
108
|
+
if (!source_component)
|
|
109
|
+
return null;
|
|
110
|
+
const source_port = soup.find(
|
|
111
|
+
(e) => e.type === "source_port" && e.source_component_id === source_component.source_component_id && (e.name === port_selector || (e.port_hints ?? []).includes(port_selector))
|
|
112
|
+
);
|
|
113
|
+
if (!source_port)
|
|
114
|
+
return null;
|
|
115
|
+
if (component_type === "source_port")
|
|
116
|
+
return source_port;
|
|
117
|
+
if (component_type === "pcb_port") {
|
|
118
|
+
return soup.find(
|
|
119
|
+
(e) => e.type === "pcb_port" && e.source_port_id === source_port.source_port_id
|
|
120
|
+
);
|
|
121
|
+
} else if (component_type === "schematic_port") {
|
|
122
|
+
return soup.find(
|
|
123
|
+
(e) => e.type === "schematic_port" && e.source_port_id === source_port.source_port_id
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
);
|
|
132
|
+
return su2;
|
|
133
|
+
};
|
|
134
|
+
cju.unparsed = cju;
|
|
135
|
+
var su = cju;
|
|
136
|
+
var cju_default = cju;
|
|
137
|
+
|
|
138
|
+
// lib/cju-indexed.ts
|
|
139
|
+
import * as Soup2 from "circuit-json";
|
|
140
|
+
function createIdKey(element) {
|
|
141
|
+
const type = element.type;
|
|
142
|
+
return `${type}:${element[`${type}_id`]}`;
|
|
143
|
+
}
|
|
144
|
+
var cjuIndexed = (soup, options = {}) => {
|
|
145
|
+
let internalStore = soup._internal_store_indexed;
|
|
146
|
+
if (!internalStore) {
|
|
147
|
+
internalStore = {
|
|
148
|
+
counts: {},
|
|
149
|
+
indexes: {}
|
|
150
|
+
};
|
|
151
|
+
for (const elm of soup) {
|
|
152
|
+
const type = elm.type;
|
|
153
|
+
const idVal = elm[`${type}_id`];
|
|
154
|
+
if (!idVal)
|
|
155
|
+
continue;
|
|
156
|
+
const idNum = Number.parseInt(idVal.split("_").pop() || "");
|
|
157
|
+
if (!Number.isNaN(idNum)) {
|
|
158
|
+
internalStore.counts[type] = Math.max(
|
|
159
|
+
internalStore.counts[type] ?? 0,
|
|
160
|
+
idNum
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
const indexConfig = options.indexConfig || {};
|
|
165
|
+
const indexes = internalStore.indexes;
|
|
166
|
+
if (indexConfig.byId) {
|
|
167
|
+
indexes.byId = /* @__PURE__ */ new Map();
|
|
168
|
+
}
|
|
169
|
+
if (indexConfig.byType) {
|
|
170
|
+
indexes.byType = /* @__PURE__ */ new Map();
|
|
171
|
+
}
|
|
172
|
+
if (indexConfig.byRelation) {
|
|
173
|
+
indexes.byRelation = /* @__PURE__ */ new Map();
|
|
174
|
+
}
|
|
175
|
+
if (indexConfig.bySubcircuit) {
|
|
176
|
+
indexes.bySubcircuit = /* @__PURE__ */ new Map();
|
|
177
|
+
}
|
|
178
|
+
if (indexConfig.byCustomField && indexConfig.byCustomField.length > 0) {
|
|
179
|
+
indexes.byCustomField = /* @__PURE__ */ new Map();
|
|
180
|
+
for (const field of indexConfig.byCustomField) {
|
|
181
|
+
indexes.byCustomField.set(field, /* @__PURE__ */ new Map());
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
for (const element of soup) {
|
|
185
|
+
if (indexConfig.byId) {
|
|
186
|
+
const idKey = createIdKey(element);
|
|
187
|
+
indexes.byId.set(idKey, element);
|
|
188
|
+
}
|
|
189
|
+
if (indexConfig.byType) {
|
|
190
|
+
const elementsOfType = indexes.byType.get(element.type) || [];
|
|
191
|
+
elementsOfType.push(element);
|
|
192
|
+
indexes.byType.set(element.type, elementsOfType);
|
|
193
|
+
}
|
|
194
|
+
if (indexConfig.byRelation) {
|
|
195
|
+
const elementEntries = Object.entries(element);
|
|
196
|
+
for (const [key, value] of elementEntries) {
|
|
197
|
+
if (key.endsWith("_id") && key !== `${element.type}_id` && typeof value === "string") {
|
|
198
|
+
const relationTypeMap = indexes.byRelation.get(key) || /* @__PURE__ */ new Map();
|
|
199
|
+
const relatedElements = relationTypeMap.get(value) || [];
|
|
200
|
+
relatedElements.push(element);
|
|
201
|
+
relationTypeMap.set(value, relatedElements);
|
|
202
|
+
indexes.byRelation.set(key, relationTypeMap);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
if (indexConfig.bySubcircuit && "subcircuit_id" in element) {
|
|
207
|
+
const subcircuitId = element.subcircuit_id;
|
|
208
|
+
if (subcircuitId && typeof subcircuitId === "string") {
|
|
209
|
+
const subcircuitElements = indexes.bySubcircuit.get(subcircuitId) || [];
|
|
210
|
+
subcircuitElements.push(element);
|
|
211
|
+
indexes.bySubcircuit.set(subcircuitId, subcircuitElements);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (indexConfig.byCustomField && indexes.byCustomField) {
|
|
215
|
+
for (const field of indexConfig.byCustomField) {
|
|
216
|
+
if (field in element) {
|
|
217
|
+
const fieldValue = element[field];
|
|
218
|
+
if (fieldValue !== void 0 && (typeof fieldValue === "string" || typeof fieldValue === "number")) {
|
|
219
|
+
const fieldValueStr = String(fieldValue);
|
|
220
|
+
const fieldMap = indexes.byCustomField.get(field);
|
|
221
|
+
const elementsWithFieldValue = fieldMap.get(fieldValueStr) || [];
|
|
222
|
+
elementsWithFieldValue.push(element);
|
|
223
|
+
fieldMap.set(fieldValueStr, elementsWithFieldValue);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
;
|
|
230
|
+
soup._internal_store_indexed = internalStore;
|
|
231
|
+
}
|
|
232
|
+
const suIndexed = new Proxy(
|
|
233
|
+
{},
|
|
234
|
+
{
|
|
235
|
+
get: (proxy_target, component_type) => {
|
|
236
|
+
if (component_type === "toArray") {
|
|
237
|
+
return () => soup;
|
|
238
|
+
}
|
|
239
|
+
return {
|
|
240
|
+
get: (id) => {
|
|
241
|
+
const indexConfig = options.indexConfig || {};
|
|
242
|
+
if (indexConfig.byId && internalStore.indexes.byId) {
|
|
243
|
+
return internalStore.indexes.byId.get(
|
|
244
|
+
`${component_type}:${id}`
|
|
245
|
+
) || null;
|
|
246
|
+
}
|
|
247
|
+
if (indexConfig.byType && internalStore.indexes.byType) {
|
|
248
|
+
const elementsOfType = internalStore.indexes.byType.get(component_type) || [];
|
|
249
|
+
return elementsOfType.find(
|
|
250
|
+
(e) => e[`${component_type}_id`] === id
|
|
251
|
+
) || null;
|
|
252
|
+
}
|
|
253
|
+
return soup.find(
|
|
254
|
+
(e) => e.type === component_type && e[`${component_type}_id`] === id
|
|
255
|
+
) || null;
|
|
256
|
+
},
|
|
257
|
+
getUsing: (using) => {
|
|
258
|
+
const indexConfig = options.indexConfig || {};
|
|
259
|
+
const keys = Object.keys(using);
|
|
260
|
+
if (keys.length !== 1) {
|
|
261
|
+
throw new Error(
|
|
262
|
+
"getUsing requires exactly one key, e.g. { pcb_component_id }"
|
|
263
|
+
);
|
|
264
|
+
}
|
|
265
|
+
const join_key = keys[0];
|
|
266
|
+
const join_type = join_key.replace("_id", "");
|
|
267
|
+
if (indexConfig.byRelation && internalStore.indexes.byRelation) {
|
|
268
|
+
const relationMap = internalStore.indexes.byRelation.get(join_key);
|
|
269
|
+
if (relationMap) {
|
|
270
|
+
const relatedElements = relationMap.get(using[join_key]) || [];
|
|
271
|
+
const joiner2 = relatedElements.find((e) => e.type === join_type);
|
|
272
|
+
if (!joiner2)
|
|
273
|
+
return null;
|
|
274
|
+
const joinerId = joiner2[`${component_type}_id`];
|
|
275
|
+
if (indexConfig.byId && internalStore.indexes.byId) {
|
|
276
|
+
return internalStore.indexes.byId.get(
|
|
277
|
+
`${component_type}:${joinerId}`
|
|
278
|
+
) || null;
|
|
279
|
+
}
|
|
280
|
+
if (indexConfig.byType && internalStore.indexes.byType) {
|
|
281
|
+
const elementsOfType = internalStore.indexes.byType.get(component_type) || [];
|
|
282
|
+
return elementsOfType.find(
|
|
283
|
+
(e) => e[`${component_type}_id`] === joinerId
|
|
284
|
+
) || null;
|
|
285
|
+
}
|
|
286
|
+
return soup.find(
|
|
287
|
+
(e) => e.type === component_type && e[`${component_type}_id`] === joinerId
|
|
288
|
+
) || null;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
const joiner = soup.find(
|
|
292
|
+
(e) => e.type === join_type && e[join_key] === using[join_key]
|
|
293
|
+
);
|
|
294
|
+
if (!joiner)
|
|
295
|
+
return null;
|
|
296
|
+
return soup.find(
|
|
297
|
+
(e) => e.type === component_type && e[`${component_type}_id`] === joiner[`${component_type}_id`]
|
|
298
|
+
) || null;
|
|
299
|
+
},
|
|
300
|
+
getWhere: (where) => {
|
|
301
|
+
const indexConfig = options.indexConfig || {};
|
|
302
|
+
const keys = Object.keys(where);
|
|
303
|
+
if (keys.length === 1 && indexConfig.byCustomField && internalStore.indexes.byCustomField) {
|
|
304
|
+
const field = keys[0];
|
|
305
|
+
const fieldMap = internalStore.indexes.byCustomField.get(field);
|
|
306
|
+
if (fieldMap) {
|
|
307
|
+
const fieldValue = String(where[field]);
|
|
308
|
+
const elementsWithFieldValue = fieldMap.get(fieldValue) || [];
|
|
309
|
+
return elementsWithFieldValue.find(
|
|
310
|
+
(e) => e.type === component_type
|
|
311
|
+
) || null;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
if ("subcircuit_id" in where && indexConfig.bySubcircuit && internalStore.indexes.bySubcircuit) {
|
|
315
|
+
const subcircuitId = where.subcircuit_id;
|
|
316
|
+
const subcircuitElements = internalStore.indexes.bySubcircuit.get(subcircuitId) || [];
|
|
317
|
+
return subcircuitElements.find(
|
|
318
|
+
(e) => e.type === component_type && keys.every((key) => e[key] === where[key])
|
|
319
|
+
) || null;
|
|
320
|
+
}
|
|
321
|
+
if (indexConfig.byType && internalStore.indexes.byType) {
|
|
322
|
+
const elementsOfType = internalStore.indexes.byType.get(component_type) || [];
|
|
323
|
+
return elementsOfType.find(
|
|
324
|
+
(e) => keys.every((key) => e[key] === where[key])
|
|
325
|
+
) || null;
|
|
326
|
+
}
|
|
327
|
+
return soup.find(
|
|
328
|
+
(e) => e.type === component_type && keys.every((key) => e[key] === where[key])
|
|
329
|
+
) || null;
|
|
330
|
+
},
|
|
331
|
+
list: (where) => {
|
|
332
|
+
const indexConfig = options.indexConfig || {};
|
|
333
|
+
const keys = !where ? [] : Object.keys(where);
|
|
334
|
+
if (keys.length === 0 && indexConfig.byType && internalStore.indexes.byType) {
|
|
335
|
+
return internalStore.indexes.byType.get(component_type) || [];
|
|
336
|
+
}
|
|
337
|
+
if (keys.length === 1 && keys[0] === "subcircuit_id" && indexConfig.bySubcircuit && internalStore.indexes.bySubcircuit) {
|
|
338
|
+
const subcircuitId = where.subcircuit_id;
|
|
339
|
+
const subcircuitElements = internalStore.indexes.bySubcircuit.get(subcircuitId) || [];
|
|
340
|
+
return subcircuitElements.filter(
|
|
341
|
+
(e) => e.type === component_type
|
|
342
|
+
);
|
|
343
|
+
}
|
|
344
|
+
let elementsToFilter;
|
|
345
|
+
if (indexConfig.byType && internalStore.indexes.byType) {
|
|
346
|
+
elementsToFilter = internalStore.indexes.byType.get(component_type) || [];
|
|
347
|
+
} else {
|
|
348
|
+
elementsToFilter = soup.filter((e) => e.type === component_type);
|
|
349
|
+
}
|
|
350
|
+
if (keys.length > 0) {
|
|
351
|
+
return elementsToFilter.filter(
|
|
352
|
+
(e) => keys.every((key) => e[key] === where[key])
|
|
353
|
+
);
|
|
354
|
+
}
|
|
355
|
+
return elementsToFilter;
|
|
356
|
+
},
|
|
357
|
+
insert: (elm) => {
|
|
358
|
+
internalStore.counts[component_type] ??= -1;
|
|
359
|
+
internalStore.counts[component_type]++;
|
|
360
|
+
const index = internalStore.counts[component_type];
|
|
361
|
+
const newElm = {
|
|
362
|
+
type: component_type,
|
|
363
|
+
[`${component_type}_id`]: `${component_type}_${index}`,
|
|
364
|
+
...elm
|
|
365
|
+
};
|
|
366
|
+
if (options.validateInserts) {
|
|
367
|
+
const parser = Soup2[component_type] ?? Soup2.any_soup_element;
|
|
368
|
+
parser.parse(newElm);
|
|
369
|
+
}
|
|
370
|
+
soup.push(newElm);
|
|
371
|
+
const indexConfig = options.indexConfig || {};
|
|
372
|
+
if (indexConfig.byId && internalStore.indexes.byId) {
|
|
373
|
+
const idKey = createIdKey(newElm);
|
|
374
|
+
internalStore.indexes.byId.set(idKey, newElm);
|
|
375
|
+
}
|
|
376
|
+
if (indexConfig.byType && internalStore.indexes.byType) {
|
|
377
|
+
const elementsOfType = internalStore.indexes.byType.get(component_type) || [];
|
|
378
|
+
elementsOfType.push(newElm);
|
|
379
|
+
internalStore.indexes.byType.set(component_type, elementsOfType);
|
|
380
|
+
}
|
|
381
|
+
if (indexConfig.byRelation && internalStore.indexes.byRelation) {
|
|
382
|
+
const elementEntries = Object.entries(newElm);
|
|
383
|
+
for (const [key, value] of elementEntries) {
|
|
384
|
+
if (key.endsWith("_id") && key !== `${newElm.type}_id` && typeof value === "string") {
|
|
385
|
+
const relationTypeMap = internalStore.indexes.byRelation.get(key) || /* @__PURE__ */ new Map();
|
|
386
|
+
const relatedElements = relationTypeMap.get(value) || [];
|
|
387
|
+
relatedElements.push(newElm);
|
|
388
|
+
relationTypeMap.set(value, relatedElements);
|
|
389
|
+
internalStore.indexes.byRelation.set(key, relationTypeMap);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
if (indexConfig.bySubcircuit && internalStore.indexes.bySubcircuit && "subcircuit_id" in newElm) {
|
|
394
|
+
const subcircuitId = newElm.subcircuit_id;
|
|
395
|
+
if (subcircuitId && typeof subcircuitId === "string") {
|
|
396
|
+
const subcircuitElements = internalStore.indexes.bySubcircuit.get(subcircuitId) || [];
|
|
397
|
+
subcircuitElements.push(newElm);
|
|
398
|
+
internalStore.indexes.bySubcircuit.set(
|
|
399
|
+
subcircuitId,
|
|
400
|
+
subcircuitElements
|
|
401
|
+
);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
if (indexConfig.byCustomField && internalStore.indexes.byCustomField) {
|
|
405
|
+
for (const field of indexConfig.byCustomField) {
|
|
406
|
+
if (field in newElm) {
|
|
407
|
+
const fieldValue = newElm[field];
|
|
408
|
+
if (fieldValue !== void 0 && (typeof fieldValue === "string" || typeof fieldValue === "number")) {
|
|
409
|
+
const fieldValueStr = String(fieldValue);
|
|
410
|
+
const fieldMap = internalStore.indexes.byCustomField.get(field);
|
|
411
|
+
const elementsWithFieldValue = fieldMap.get(fieldValueStr) || [];
|
|
412
|
+
elementsWithFieldValue.push(newElm);
|
|
413
|
+
fieldMap.set(fieldValueStr, elementsWithFieldValue);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
return newElm;
|
|
419
|
+
},
|
|
420
|
+
delete: (id) => {
|
|
421
|
+
const indexConfig = options.indexConfig || {};
|
|
422
|
+
let elm;
|
|
423
|
+
if (indexConfig.byId && internalStore.indexes.byId) {
|
|
424
|
+
elm = internalStore.indexes.byId.get(`${component_type}:${id}`);
|
|
425
|
+
} else if (indexConfig.byType && internalStore.indexes.byType) {
|
|
426
|
+
const elementsOfType = internalStore.indexes.byType.get(component_type) || [];
|
|
427
|
+
elm = elementsOfType.find(
|
|
428
|
+
(e) => e[`${component_type}_id`] === id
|
|
429
|
+
);
|
|
430
|
+
} else {
|
|
431
|
+
elm = soup.find((e) => e[`${component_type}_id`] === id);
|
|
432
|
+
}
|
|
433
|
+
if (!elm)
|
|
434
|
+
return;
|
|
435
|
+
const elmIndex = soup.indexOf(elm);
|
|
436
|
+
if (elmIndex >= 0) {
|
|
437
|
+
soup.splice(elmIndex, 1);
|
|
438
|
+
}
|
|
439
|
+
if (indexConfig.byId && internalStore.indexes.byId) {
|
|
440
|
+
const idKey = createIdKey(elm);
|
|
441
|
+
internalStore.indexes.byId.delete(idKey);
|
|
442
|
+
}
|
|
443
|
+
if (indexConfig.byType && internalStore.indexes.byType) {
|
|
444
|
+
const elementsOfType = internalStore.indexes.byType.get(component_type) || [];
|
|
445
|
+
const filteredElements = elementsOfType.filter(
|
|
446
|
+
(e) => e[`${component_type}_id`] !== id
|
|
447
|
+
);
|
|
448
|
+
internalStore.indexes.byType.set(component_type, filteredElements);
|
|
449
|
+
}
|
|
450
|
+
if (indexConfig.byRelation && internalStore.indexes.byRelation) {
|
|
451
|
+
for (const [
|
|
452
|
+
relationKey,
|
|
453
|
+
relationMap
|
|
454
|
+
] of internalStore.indexes.byRelation.entries()) {
|
|
455
|
+
for (const [relationValue, elements] of relationMap.entries()) {
|
|
456
|
+
const updatedElements = elements.filter((e) => e !== elm);
|
|
457
|
+
if (updatedElements.length === 0) {
|
|
458
|
+
relationMap.delete(relationValue);
|
|
459
|
+
} else {
|
|
460
|
+
relationMap.set(relationValue, updatedElements);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
if (indexConfig.bySubcircuit && internalStore.indexes.bySubcircuit && "subcircuit_id" in elm) {
|
|
466
|
+
const subcircuitId = elm.subcircuit_id;
|
|
467
|
+
if (subcircuitId) {
|
|
468
|
+
const subcircuitElements = internalStore.indexes.bySubcircuit.get(subcircuitId) || [];
|
|
469
|
+
const updatedElements = subcircuitElements.filter(
|
|
470
|
+
(e) => e !== elm
|
|
471
|
+
);
|
|
472
|
+
if (updatedElements.length === 0) {
|
|
473
|
+
internalStore.indexes.bySubcircuit.delete(subcircuitId);
|
|
474
|
+
} else {
|
|
475
|
+
internalStore.indexes.bySubcircuit.set(
|
|
476
|
+
subcircuitId,
|
|
477
|
+
updatedElements
|
|
478
|
+
);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
if (indexConfig.byCustomField && internalStore.indexes.byCustomField) {
|
|
483
|
+
for (const fieldMap of internalStore.indexes.byCustomField.values()) {
|
|
484
|
+
for (const [fieldValue, elements] of fieldMap.entries()) {
|
|
485
|
+
const updatedElements = elements.filter((e) => e !== elm);
|
|
486
|
+
if (updatedElements.length === 0) {
|
|
487
|
+
fieldMap.delete(fieldValue);
|
|
488
|
+
} else {
|
|
489
|
+
fieldMap.set(fieldValue, updatedElements);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
},
|
|
495
|
+
update: (id, newProps) => {
|
|
496
|
+
const indexConfig = options.indexConfig || {};
|
|
497
|
+
let elm;
|
|
498
|
+
if (indexConfig.byId && internalStore.indexes.byId) {
|
|
499
|
+
elm = internalStore.indexes.byId.get(`${component_type}:${id}`);
|
|
500
|
+
} else if (indexConfig.byType && internalStore.indexes.byType) {
|
|
501
|
+
const elementsOfType = internalStore.indexes.byType.get(component_type) || [];
|
|
502
|
+
elm = elementsOfType.find(
|
|
503
|
+
(e) => e[`${component_type}_id`] === id
|
|
504
|
+
);
|
|
505
|
+
} else {
|
|
506
|
+
elm = soup.find(
|
|
507
|
+
(e) => e.type === component_type && e[`${component_type}_id`] === id
|
|
508
|
+
);
|
|
509
|
+
}
|
|
510
|
+
if (!elm)
|
|
511
|
+
return null;
|
|
512
|
+
if (indexConfig.byRelation && internalStore.indexes.byRelation) {
|
|
513
|
+
const elementEntries = Object.entries(elm);
|
|
514
|
+
for (const [key, value] of elementEntries) {
|
|
515
|
+
if (key.endsWith("_id") && key !== `${elm.type}_id` && typeof value === "string") {
|
|
516
|
+
if (key in newProps && newProps[key] !== value) {
|
|
517
|
+
const relationTypeMap = internalStore.indexes.byRelation.get(key);
|
|
518
|
+
if (relationTypeMap) {
|
|
519
|
+
const relatedElements = relationTypeMap.get(value) || [];
|
|
520
|
+
const updatedElements = relatedElements.filter(
|
|
521
|
+
(e) => e !== elm
|
|
522
|
+
);
|
|
523
|
+
if (updatedElements.length === 0) {
|
|
524
|
+
relationTypeMap.delete(value);
|
|
525
|
+
} else {
|
|
526
|
+
relationTypeMap.set(value, updatedElements);
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
if (indexConfig.bySubcircuit && internalStore.indexes.bySubcircuit && "subcircuit_id" in elm && "subcircuit_id" in newProps) {
|
|
534
|
+
const oldSubcircuitId = elm.subcircuit_id;
|
|
535
|
+
const newSubcircuitId = newProps.subcircuit_id;
|
|
536
|
+
if (oldSubcircuitId !== newSubcircuitId) {
|
|
537
|
+
const subcircuitElements = internalStore.indexes.bySubcircuit.get(oldSubcircuitId) || [];
|
|
538
|
+
const updatedElements = subcircuitElements.filter(
|
|
539
|
+
(e) => e !== elm
|
|
540
|
+
);
|
|
541
|
+
if (updatedElements.length === 0) {
|
|
542
|
+
internalStore.indexes.bySubcircuit.delete(oldSubcircuitId);
|
|
543
|
+
} else {
|
|
544
|
+
internalStore.indexes.bySubcircuit.set(
|
|
545
|
+
oldSubcircuitId,
|
|
546
|
+
updatedElements
|
|
547
|
+
);
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
if (indexConfig.byCustomField && internalStore.indexes.byCustomField) {
|
|
552
|
+
for (const field of indexConfig.byCustomField) {
|
|
553
|
+
if (field in elm && field in newProps && elm[field] !== newProps[field]) {
|
|
554
|
+
const fieldMap = internalStore.indexes.byCustomField.get(field);
|
|
555
|
+
if (fieldMap) {
|
|
556
|
+
const oldValue = String(elm[field]);
|
|
557
|
+
const elements = fieldMap.get(oldValue) || [];
|
|
558
|
+
const updatedElements = elements.filter((e) => e !== elm);
|
|
559
|
+
if (updatedElements.length === 0) {
|
|
560
|
+
fieldMap.delete(oldValue);
|
|
561
|
+
} else {
|
|
562
|
+
fieldMap.set(oldValue, updatedElements);
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
Object.assign(elm, newProps);
|
|
569
|
+
if (indexConfig.byRelation && internalStore.indexes.byRelation) {
|
|
570
|
+
const elementEntries = Object.entries(elm);
|
|
571
|
+
for (const [key, value] of elementEntries) {
|
|
572
|
+
if (key.endsWith("_id") && key !== `${elm.type}_id` && typeof value === "string") {
|
|
573
|
+
if (key in newProps) {
|
|
574
|
+
const relationTypeMap = internalStore.indexes.byRelation.get(key) || /* @__PURE__ */ new Map();
|
|
575
|
+
const relatedElements = relationTypeMap.get(value) || [];
|
|
576
|
+
if (!relatedElements.includes(elm)) {
|
|
577
|
+
relatedElements.push(elm);
|
|
578
|
+
relationTypeMap.set(value, relatedElements);
|
|
579
|
+
internalStore.indexes.byRelation.set(key, relationTypeMap);
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
if (indexConfig.bySubcircuit && internalStore.indexes.bySubcircuit && "subcircuit_id" in elm && "subcircuit_id" in newProps) {
|
|
586
|
+
const subcircuitId = elm.subcircuit_id;
|
|
587
|
+
if (subcircuitId && typeof subcircuitId === "string") {
|
|
588
|
+
const subcircuitElements = internalStore.indexes.bySubcircuit.get(subcircuitId) || [];
|
|
589
|
+
if (!subcircuitElements.includes(elm)) {
|
|
590
|
+
subcircuitElements.push(elm);
|
|
591
|
+
internalStore.indexes.bySubcircuit.set(
|
|
592
|
+
subcircuitId,
|
|
593
|
+
subcircuitElements
|
|
594
|
+
);
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
if (indexConfig.byCustomField && internalStore.indexes.byCustomField) {
|
|
599
|
+
for (const field of indexConfig.byCustomField) {
|
|
600
|
+
if (field in elm && field in newProps) {
|
|
601
|
+
const fieldValue = elm[field];
|
|
602
|
+
if (fieldValue !== void 0 && (typeof fieldValue === "string" || typeof fieldValue === "number")) {
|
|
603
|
+
const fieldValueStr = String(fieldValue);
|
|
604
|
+
const fieldMap = internalStore.indexes.byCustomField.get(field);
|
|
605
|
+
const elementsWithFieldValue = fieldMap.get(fieldValueStr) || [];
|
|
606
|
+
if (!elementsWithFieldValue.includes(elm)) {
|
|
607
|
+
elementsWithFieldValue.push(elm);
|
|
608
|
+
fieldMap.set(fieldValueStr, elementsWithFieldValue);
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
return elm;
|
|
615
|
+
},
|
|
616
|
+
select: (selector) => {
|
|
617
|
+
if (component_type === "source_component") {
|
|
618
|
+
return soup.find(
|
|
619
|
+
(e) => e.type === "source_component" && e.name === selector.replace(/\./g, "")
|
|
620
|
+
) || null;
|
|
621
|
+
} else if (component_type === "pcb_port" || component_type === "source_port" || component_type === "schematic_port") {
|
|
622
|
+
const [component_name, port_selector] = selector.replace(/\./g, "").split(/[\s\>]+/);
|
|
623
|
+
const source_component = soup.find(
|
|
624
|
+
(e) => e.type === "source_component" && e.name === component_name
|
|
625
|
+
);
|
|
626
|
+
if (!source_component)
|
|
627
|
+
return null;
|
|
628
|
+
const source_port = soup.find(
|
|
629
|
+
(e) => e.type === "source_port" && e.source_component_id === source_component.source_component_id && (e.name === port_selector || (e.port_hints ?? []).includes(port_selector))
|
|
630
|
+
);
|
|
631
|
+
if (!source_port)
|
|
632
|
+
return null;
|
|
633
|
+
if (component_type === "source_port")
|
|
634
|
+
return source_port;
|
|
635
|
+
if (component_type === "pcb_port") {
|
|
636
|
+
return soup.find(
|
|
637
|
+
(e) => e.type === "pcb_port" && e.source_port_id === source_port.source_port_id
|
|
638
|
+
) || null;
|
|
639
|
+
} else if (component_type === "schematic_port") {
|
|
640
|
+
return soup.find(
|
|
641
|
+
(e) => e.type === "schematic_port" && e.source_port_id === source_port.source_port_id
|
|
642
|
+
) || null;
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
return null;
|
|
646
|
+
}
|
|
647
|
+
};
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
);
|
|
651
|
+
return suIndexed;
|
|
652
|
+
};
|
|
653
|
+
cjuIndexed.unparsed = cjuIndexed;
|
|
654
|
+
var cju_indexed_default = cjuIndexed;
|
|
655
|
+
|
|
656
|
+
// lib/transform-soup-elements.ts
|
|
657
|
+
import { applyToPoint, decomposeTSR } from "transformation-matrix";
|
|
658
|
+
|
|
659
|
+
// lib/direction-to-vec.ts
|
|
660
|
+
var directionToVec = (direction) => {
|
|
661
|
+
if (direction === "up")
|
|
662
|
+
return { x: 0, y: 1 };
|
|
663
|
+
else if (direction === "down")
|
|
664
|
+
return { x: 0, y: -1 };
|
|
665
|
+
else if (direction === "left")
|
|
666
|
+
return { x: -1, y: 0 };
|
|
667
|
+
else if (direction === "right")
|
|
668
|
+
return { x: 1, y: 0 };
|
|
669
|
+
else
|
|
670
|
+
throw new Error("Invalid direction");
|
|
671
|
+
};
|
|
672
|
+
var vecToDirection = ({ x, y }) => {
|
|
673
|
+
if (x > y)
|
|
674
|
+
y = 0;
|
|
675
|
+
if (y > x)
|
|
676
|
+
x = 0;
|
|
677
|
+
if (x > 0 && y === 0)
|
|
678
|
+
return "right";
|
|
679
|
+
else if (x < 0 && y === 0)
|
|
680
|
+
return "left";
|
|
681
|
+
else if (x === 0 && y > 0)
|
|
682
|
+
return "up";
|
|
683
|
+
else if (x === 0 && y < 0)
|
|
684
|
+
return "down";
|
|
685
|
+
else
|
|
686
|
+
throw new Error(`Invalid vector for direction conversion (${x}, ${y})`);
|
|
687
|
+
};
|
|
688
|
+
var rotateClockwise = (direction) => {
|
|
689
|
+
if (direction === "up")
|
|
690
|
+
return "right";
|
|
691
|
+
else if (direction === "right")
|
|
692
|
+
return "down";
|
|
693
|
+
else if (direction === "down")
|
|
694
|
+
return "left";
|
|
695
|
+
else if (direction === "left")
|
|
696
|
+
return "up";
|
|
697
|
+
throw new Error(`Invalid direction: ${direction}`);
|
|
698
|
+
};
|
|
699
|
+
var rotateCounterClockwise = (direction) => {
|
|
700
|
+
if (direction === "up")
|
|
701
|
+
return "left";
|
|
702
|
+
else if (direction === "left")
|
|
703
|
+
return "down";
|
|
704
|
+
else if (direction === "down")
|
|
705
|
+
return "right";
|
|
706
|
+
else if (direction === "right")
|
|
707
|
+
return "up";
|
|
708
|
+
throw new Error(`Invalid direction: ${direction}`);
|
|
709
|
+
};
|
|
710
|
+
var rotateDirection = (direction, num90DegreeClockwiseTurns) => {
|
|
711
|
+
while (num90DegreeClockwiseTurns > 0) {
|
|
712
|
+
direction = rotateClockwise(direction);
|
|
713
|
+
num90DegreeClockwiseTurns--;
|
|
714
|
+
}
|
|
715
|
+
while (num90DegreeClockwiseTurns < 0) {
|
|
716
|
+
direction = rotateCounterClockwise(direction);
|
|
717
|
+
num90DegreeClockwiseTurns++;
|
|
718
|
+
}
|
|
719
|
+
return direction;
|
|
720
|
+
};
|
|
721
|
+
var oppositeDirection = (direction) => {
|
|
722
|
+
if (direction === "up")
|
|
723
|
+
return "down";
|
|
724
|
+
else if (direction === "down")
|
|
725
|
+
return "up";
|
|
726
|
+
else if (direction === "left")
|
|
727
|
+
return "right";
|
|
728
|
+
else if (direction === "right")
|
|
729
|
+
return "left";
|
|
730
|
+
throw new Error(`Invalid direction: ${direction}`);
|
|
731
|
+
};
|
|
732
|
+
var oppositeSide = (sideOrDir) => {
|
|
733
|
+
if (sideOrDir === "top" || sideOrDir === "up")
|
|
734
|
+
return "bottom";
|
|
735
|
+
else if (sideOrDir === "bottom" || sideOrDir === "down")
|
|
736
|
+
return "top";
|
|
737
|
+
else if (sideOrDir === "left")
|
|
738
|
+
return "right";
|
|
739
|
+
else if (sideOrDir === "right")
|
|
740
|
+
return "left";
|
|
741
|
+
throw new Error(`Invalid sideOrDir: ${sideOrDir}`);
|
|
742
|
+
};
|
|
743
|
+
|
|
744
|
+
// lib/transform-soup-elements.ts
|
|
745
|
+
var transformSchematicElement = (elm, matrix) => {
|
|
746
|
+
if (elm.type === "schematic_component") {
|
|
747
|
+
elm.center = applyToPoint(matrix, elm.center);
|
|
748
|
+
} else if (elm.type === "schematic_port") {
|
|
749
|
+
elm.center = applyToPoint(matrix, elm.center);
|
|
750
|
+
if (elm.facing_direction) {
|
|
751
|
+
elm.facing_direction = rotateDirection(
|
|
752
|
+
elm.facing_direction,
|
|
753
|
+
-(Math.atan2(matrix.b, matrix.a) / Math.PI) * 2
|
|
754
|
+
);
|
|
755
|
+
}
|
|
756
|
+
} else if (elm.type === "schematic_text") {
|
|
757
|
+
elm.position = applyToPoint(matrix, elm.position);
|
|
758
|
+
} else if (elm.type === "schematic_trace") {
|
|
759
|
+
} else if (elm.type === "schematic_box") {
|
|
760
|
+
const { x, y } = applyToPoint(matrix, { x: elm.x, y: elm.y });
|
|
761
|
+
elm.x = x;
|
|
762
|
+
elm.y = y;
|
|
763
|
+
} else if (elm.type === "schematic_line") {
|
|
764
|
+
const { x: x1, y: y1 } = applyToPoint(matrix, { x: elm.x1, y: elm.y1 });
|
|
765
|
+
const { x: x2, y: y2 } = applyToPoint(matrix, { x: elm.x2, y: elm.y2 });
|
|
766
|
+
elm.x1 = x1;
|
|
767
|
+
elm.y1 = y1;
|
|
768
|
+
elm.x2 = x2;
|
|
769
|
+
elm.y2 = y2;
|
|
770
|
+
}
|
|
771
|
+
return elm;
|
|
772
|
+
};
|
|
773
|
+
var transformSchematicElements = (elms, matrix) => {
|
|
774
|
+
return elms.map((elm) => transformSchematicElement(elm, matrix));
|
|
775
|
+
};
|
|
776
|
+
var transformPCBElement = (elm, matrix) => {
|
|
777
|
+
if (elm.type === "pcb_plated_hole" || elm.type === "pcb_hole" || elm.type === "pcb_via" || elm.type === "pcb_smtpad" || elm.type === "pcb_port") {
|
|
778
|
+
const { x, y } = applyToPoint(matrix, { x: elm.x, y: elm.y });
|
|
779
|
+
elm.x = x;
|
|
780
|
+
elm.y = y;
|
|
781
|
+
} else if (elm.type === "pcb_keepout" || elm.type === "pcb_board") {
|
|
782
|
+
elm.center = applyToPoint(matrix, elm.center);
|
|
783
|
+
} else if (elm.type === "pcb_silkscreen_text" || elm.type === "pcb_fabrication_note_text") {
|
|
784
|
+
elm.anchor_position = applyToPoint(matrix, elm.anchor_position);
|
|
785
|
+
} else if (elm.type === "pcb_silkscreen_circle" || elm.type === "pcb_silkscreen_rect" || elm.type === "pcb_component") {
|
|
786
|
+
elm.center = applyToPoint(matrix, elm.center);
|
|
787
|
+
} else if (elm.type === "pcb_silkscreen_path" || elm.type === "pcb_trace" || elm.type === "pcb_fabrication_note_path") {
|
|
788
|
+
elm.route = elm.route.map((rp) => {
|
|
789
|
+
const tp = applyToPoint(matrix, rp);
|
|
790
|
+
rp.x = tp.x;
|
|
791
|
+
rp.y = tp.y;
|
|
792
|
+
return rp;
|
|
793
|
+
});
|
|
794
|
+
} else if (elm.type === "pcb_silkscreen_line") {
|
|
795
|
+
const p1 = { x: elm.x1, y: elm.y1 };
|
|
796
|
+
const p2 = { x: elm.x2, y: elm.y2 };
|
|
797
|
+
const p1t = applyToPoint(matrix, p1);
|
|
798
|
+
const p2t = applyToPoint(matrix, p2);
|
|
799
|
+
elm.x1 = p1t.x;
|
|
800
|
+
elm.y1 = p1t.y;
|
|
801
|
+
elm.x2 = p2t.x;
|
|
802
|
+
elm.y2 = p2t.y;
|
|
803
|
+
} else if (elm.type === "cad_component") {
|
|
804
|
+
const newPos = applyToPoint(matrix, {
|
|
805
|
+
x: elm.position.x,
|
|
806
|
+
y: elm.position.y
|
|
807
|
+
});
|
|
808
|
+
elm.position.x = newPos.x;
|
|
809
|
+
elm.position.y = newPos.y;
|
|
810
|
+
}
|
|
811
|
+
return elm;
|
|
812
|
+
};
|
|
813
|
+
var transformPCBElements = (elms, matrix) => {
|
|
814
|
+
const tsr = decomposeTSR(matrix);
|
|
815
|
+
const flipPadWidthHeight = Math.round(tsr.rotation.angle / (Math.PI / 2)) % 2 === 1;
|
|
816
|
+
let transformedElms = elms.map((elm) => transformPCBElement(elm, matrix));
|
|
817
|
+
if (flipPadWidthHeight) {
|
|
818
|
+
transformedElms = transformedElms.map((elm) => {
|
|
819
|
+
if (elm.type === "pcb_smtpad" && elm.shape === "rect") {
|
|
820
|
+
;
|
|
821
|
+
[elm.width, elm.height] = [elm.height, elm.width];
|
|
822
|
+
}
|
|
823
|
+
return elm;
|
|
824
|
+
});
|
|
825
|
+
}
|
|
826
|
+
return transformedElms;
|
|
827
|
+
};
|
|
828
|
+
|
|
829
|
+
// lib/apply-selector.ts
|
|
830
|
+
import * as parsel from "parsel-js";
|
|
831
|
+
|
|
832
|
+
// lib/convert-abbreviation-to-soup-element-type.ts
|
|
833
|
+
var convertAbbrToType = (abbr) => {
|
|
834
|
+
switch (abbr) {
|
|
835
|
+
case "port":
|
|
836
|
+
return "source_port";
|
|
837
|
+
case "net":
|
|
838
|
+
return "source_net";
|
|
839
|
+
case "power":
|
|
840
|
+
return "simple_power_source";
|
|
841
|
+
}
|
|
842
|
+
return abbr;
|
|
843
|
+
};
|
|
844
|
+
|
|
845
|
+
// lib/apply-selector.ts
|
|
846
|
+
var filterByType = (elements, type) => {
|
|
847
|
+
type = convertAbbrToType(type);
|
|
848
|
+
return elements.filter(
|
|
849
|
+
(elm) => "ftype" in elm && elm.ftype === type || elm.type === type
|
|
850
|
+
);
|
|
851
|
+
};
|
|
852
|
+
var applySelector = (elements, selectorRaw) => {
|
|
853
|
+
const selectorAST = parsel.parse(selectorRaw);
|
|
854
|
+
return applySelectorAST(elements, selectorAST);
|
|
855
|
+
};
|
|
856
|
+
var doesElmMatchClassName = (elm, className) => "name" in elm && elm.name === className || "port_hints" in elm && elm.port_hints?.includes(className);
|
|
857
|
+
var applySelectorAST = (elements, selectorAST) => {
|
|
858
|
+
switch (selectorAST.type) {
|
|
859
|
+
case "complex": {
|
|
860
|
+
switch (selectorAST.combinator) {
|
|
861
|
+
case " ":
|
|
862
|
+
case ">": {
|
|
863
|
+
const { left, right } = selectorAST;
|
|
864
|
+
if (left.type === "class" || left.type === "type") {
|
|
865
|
+
let matchElms;
|
|
866
|
+
if (left.type === "class") {
|
|
867
|
+
matchElms = elements.filter(
|
|
868
|
+
(elm) => doesElmMatchClassName(elm, left.name)
|
|
869
|
+
);
|
|
870
|
+
} else if (left.type === "type") {
|
|
871
|
+
matchElms = filterByType(elements, left.name);
|
|
872
|
+
} else {
|
|
873
|
+
matchElms = [];
|
|
874
|
+
}
|
|
875
|
+
const childrenOfMatchingElms = matchElms.flatMap(
|
|
876
|
+
(matchElm) => elements.filter(
|
|
877
|
+
(elm) => elm[`${matchElm.type}_id`] === matchElm[`${matchElm.type}_id`] && elm !== matchElm
|
|
878
|
+
)
|
|
879
|
+
);
|
|
880
|
+
return applySelectorAST(childrenOfMatchingElms, right);
|
|
881
|
+
} else {
|
|
882
|
+
throw new Error(`unsupported selector type "${left.type}" `);
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
default: {
|
|
886
|
+
throw new Error(
|
|
887
|
+
`Couldn't apply selector AST for complex combinator "${selectorAST.combinator}"`
|
|
888
|
+
);
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
return [];
|
|
892
|
+
}
|
|
893
|
+
case "compound": {
|
|
894
|
+
const conditionsToMatch = selectorAST.list.map((part) => {
|
|
895
|
+
switch (part.type) {
|
|
896
|
+
case "class": {
|
|
897
|
+
return (elm) => doesElmMatchClassName(elm, part.name);
|
|
898
|
+
}
|
|
899
|
+
case "type": {
|
|
900
|
+
const name = convertAbbrToType(part.name);
|
|
901
|
+
return (elm) => elm.type === name;
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
});
|
|
905
|
+
return elements.filter(
|
|
906
|
+
(elm) => conditionsToMatch.every((condFn) => condFn?.(elm))
|
|
907
|
+
);
|
|
908
|
+
}
|
|
909
|
+
case "type": {
|
|
910
|
+
return filterByType(elements, selectorAST.name);
|
|
911
|
+
}
|
|
912
|
+
case "class": {
|
|
913
|
+
return elements.filter(
|
|
914
|
+
(elm) => doesElmMatchClassName(elm, selectorAST.name)
|
|
915
|
+
);
|
|
916
|
+
}
|
|
917
|
+
default: {
|
|
918
|
+
throw new Error(
|
|
919
|
+
`Couldn't apply selector AST for type: "${selectorAST.type}" ${JSON.stringify(selectorAST, null, " ")}`
|
|
920
|
+
);
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
};
|
|
924
|
+
|
|
925
|
+
// lib/get-element-id.ts
|
|
926
|
+
var getElementId = (elm) => {
|
|
927
|
+
const type = elm.type;
|
|
928
|
+
const id = elm[`${type}_id`];
|
|
929
|
+
return id;
|
|
930
|
+
};
|
|
931
|
+
|
|
932
|
+
// lib/get-element-by-id.ts
|
|
933
|
+
var getElementById = (soup, id) => {
|
|
934
|
+
return soup.find((elm) => getElementId(elm) === id) ?? null;
|
|
935
|
+
};
|
|
936
|
+
|
|
937
|
+
// lib/readable-name-functions/get-readable-name-for-pcb-trace.ts
|
|
938
|
+
function getReadableNameForPcbTrace(soup, pcb_trace_id) {
|
|
939
|
+
const pcbTrace = cju(soup).pcb_trace.get(pcb_trace_id);
|
|
940
|
+
if (!pcbTrace) {
|
|
941
|
+
return `trace[${pcb_trace_id}]`;
|
|
942
|
+
}
|
|
943
|
+
const connectedPcbPortIds = pcbTrace.route.flatMap((point) => [point.start_pcb_port_id, point.end_pcb_port_id]).filter(Boolean);
|
|
944
|
+
if (connectedPcbPortIds.length === 0) {
|
|
945
|
+
return `trace[${pcb_trace_id}]`;
|
|
946
|
+
}
|
|
947
|
+
function getComponentAndPortInfo(pcb_port_id) {
|
|
948
|
+
const pcbPort = cju(soup).pcb_port.get(pcb_port_id);
|
|
949
|
+
if (!pcbPort)
|
|
950
|
+
return null;
|
|
951
|
+
const pcbComponent = cju(soup).pcb_component.get(pcbPort.pcb_component_id);
|
|
952
|
+
if (!pcbComponent)
|
|
953
|
+
return null;
|
|
954
|
+
const sourceComponent = cju(soup).source_component.get(
|
|
955
|
+
pcbComponent.source_component_id
|
|
956
|
+
);
|
|
957
|
+
if (!sourceComponent)
|
|
958
|
+
return null;
|
|
959
|
+
const sourcePort = cju(soup).source_port.get(pcbPort.source_port_id);
|
|
960
|
+
const portHint = sourcePort?.port_hints ? sourcePort.port_hints[1] : "";
|
|
961
|
+
return {
|
|
962
|
+
componentName: sourceComponent.name,
|
|
963
|
+
portHint
|
|
964
|
+
};
|
|
965
|
+
}
|
|
966
|
+
const selectorParts = connectedPcbPortIds.map((portId) => {
|
|
967
|
+
const info = getComponentAndPortInfo(portId);
|
|
968
|
+
if (info) {
|
|
969
|
+
return `.${info.componentName} > port.${info.portHint}`;
|
|
970
|
+
}
|
|
971
|
+
return `port[${portId}]`;
|
|
972
|
+
});
|
|
973
|
+
return `trace[${selectorParts.join(", ")}]`;
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
// lib/readable-name-functions/get-readable-name-for-pcb-port.ts
|
|
977
|
+
var getReadableNameForPcbPort = (soup, pcb_port_id) => {
|
|
978
|
+
const pcbPort = cju(soup).pcb_port.get(pcb_port_id);
|
|
979
|
+
if (!pcbPort) {
|
|
980
|
+
return `pcb_port[#${pcb_port_id}]`;
|
|
981
|
+
}
|
|
982
|
+
const pcbComponent = cju(soup).pcb_component.get(pcbPort?.pcb_component_id);
|
|
983
|
+
if (!pcbComponent) {
|
|
984
|
+
return `pcb_port[#${pcb_port_id}]`;
|
|
985
|
+
}
|
|
986
|
+
const sourceComponent = cju(soup).source_component.get(
|
|
987
|
+
pcbComponent.source_component_id
|
|
988
|
+
);
|
|
989
|
+
if (!sourceComponent) {
|
|
990
|
+
return `pcb_port[#${pcb_port_id}]`;
|
|
991
|
+
}
|
|
992
|
+
const sourcePort = cju(soup).source_port.get(pcbPort.source_port_id);
|
|
993
|
+
if (!sourcePort) {
|
|
994
|
+
return `pcb_port[#${pcb_port_id}]`;
|
|
995
|
+
}
|
|
996
|
+
let padIdentifier;
|
|
997
|
+
if (sourcePort?.port_hints && sourcePort.port_hints.length > 0) {
|
|
998
|
+
padIdentifier = sourcePort.port_hints[0];
|
|
999
|
+
} else if (sourcePort.port_hints && sourcePort.port_hints.length > 0) {
|
|
1000
|
+
padIdentifier = sourcePort.port_hints[0];
|
|
1001
|
+
} else {
|
|
1002
|
+
padIdentifier = pcb_port_id;
|
|
1003
|
+
}
|
|
1004
|
+
return `pcb_port[.${sourceComponent.name} > .${padIdentifier}]`;
|
|
1005
|
+
};
|
|
1006
|
+
|
|
1007
|
+
// lib/readable-name-functions/get-readable-name-for-pcb-smtpad.ts
|
|
1008
|
+
function getReadableNameForPcbSmtpad(soup, pcb_smtpad_id) {
|
|
1009
|
+
const pcbSmtpad = cju(soup).pcb_smtpad.get(pcb_smtpad_id);
|
|
1010
|
+
if (!pcbSmtpad || !pcbSmtpad.pcb_port_id) {
|
|
1011
|
+
return `smtpad[${pcb_smtpad_id}]`;
|
|
1012
|
+
}
|
|
1013
|
+
return getReadableNameForPcbPort(soup, pcbSmtpad.pcb_port_id);
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
// lib/readable-name-functions/get-readable-name-for-element.ts
|
|
1017
|
+
var getReadableNameForElement = (soup, elm) => {
|
|
1018
|
+
if (typeof elm === "string") {
|
|
1019
|
+
const elmObj = getElementById(soup, elm);
|
|
1020
|
+
if (!elmObj)
|
|
1021
|
+
`unknown (could not find element with id ${elm})`;
|
|
1022
|
+
return getReadableNameForElement(soup, elmObj);
|
|
1023
|
+
}
|
|
1024
|
+
switch (elm.type) {
|
|
1025
|
+
case "pcb_port":
|
|
1026
|
+
return getReadableNameForPcbPort(soup, elm.pcb_port_id);
|
|
1027
|
+
case "pcb_smtpad":
|
|
1028
|
+
return getReadableNameForPcbSmtpad(soup, elm.pcb_smtpad_id);
|
|
1029
|
+
case "pcb_trace":
|
|
1030
|
+
return getReadableNameForPcbTrace(soup, elm.pcb_trace_id);
|
|
1031
|
+
case "source_component":
|
|
1032
|
+
return `source_component[${elm.name}]`;
|
|
1033
|
+
default:
|
|
1034
|
+
return `${elm.type}[#${getElementId(elm)}]`;
|
|
1035
|
+
}
|
|
1036
|
+
};
|
|
1037
|
+
|
|
1038
|
+
// lib/get-bounds-of-pcb-elements.ts
|
|
1039
|
+
var getBoundsOfPcbElements = (elements) => {
|
|
1040
|
+
let minX = Number.POSITIVE_INFINITY;
|
|
1041
|
+
let minY = Number.POSITIVE_INFINITY;
|
|
1042
|
+
let maxX = Number.NEGATIVE_INFINITY;
|
|
1043
|
+
let maxY = Number.NEGATIVE_INFINITY;
|
|
1044
|
+
for (const elm of elements) {
|
|
1045
|
+
if (!elm.type.startsWith("pcb_"))
|
|
1046
|
+
continue;
|
|
1047
|
+
if ("x" in elm && "y" in elm) {
|
|
1048
|
+
minX = Math.min(minX, elm.x);
|
|
1049
|
+
minY = Math.min(minY, elm.y);
|
|
1050
|
+
maxX = Math.max(maxX, elm.x);
|
|
1051
|
+
maxY = Math.max(maxY, elm.y);
|
|
1052
|
+
if ("width" in elm) {
|
|
1053
|
+
maxX = Math.max(maxX, elm.x + elm.width);
|
|
1054
|
+
}
|
|
1055
|
+
if ("height" in elm) {
|
|
1056
|
+
maxY = Math.max(maxY, elm.y + elm.height);
|
|
1057
|
+
}
|
|
1058
|
+
if ("radius" in elm) {
|
|
1059
|
+
minX = Math.min(minX, elm.x - elm.radius);
|
|
1060
|
+
minY = Math.min(minY, elm.y - elm.radius);
|
|
1061
|
+
maxX = Math.max(maxX, elm.x + elm.radius);
|
|
1062
|
+
maxY = Math.max(maxY, elm.y + elm.radius);
|
|
1063
|
+
}
|
|
1064
|
+
} else if (elm.type === "pcb_trace") {
|
|
1065
|
+
for (const point of elm.route) {
|
|
1066
|
+
minX = Math.min(minX, point.x);
|
|
1067
|
+
minY = Math.min(minY, point.y);
|
|
1068
|
+
maxX = Math.max(maxX, point.x);
|
|
1069
|
+
maxY = Math.max(maxY, point.y);
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
return { minX, minY, maxX, maxY };
|
|
1074
|
+
};
|
|
1075
|
+
|
|
1076
|
+
// lib/utils/string-hash.ts
|
|
1077
|
+
function stringHash(str) {
|
|
1078
|
+
let hash = 0;
|
|
1079
|
+
if (str.length == 0)
|
|
1080
|
+
return hash;
|
|
1081
|
+
for (var i = 0; i < str.length; i++) {
|
|
1082
|
+
var char = str.charCodeAt(i);
|
|
1083
|
+
hash = (hash << 5) - hash + char;
|
|
1084
|
+
hash = hash & hash;
|
|
1085
|
+
}
|
|
1086
|
+
return Math.abs(hash);
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
// lib/utils/get-layout-debug-object.ts
|
|
1090
|
+
var nice_color_palettes = [
|
|
1091
|
+
["#69d2e7", "#a7dbd8", "#e0e4cc", "#f38630", "#fa6900"],
|
|
1092
|
+
["#fe4365", "#fc9d9a", "#f9cdad", "#c8c8a9", "#83af9b"],
|
|
1093
|
+
["#ecd078", "#d95b43", "#c02942", "#542437", "#53777a"],
|
|
1094
|
+
["#556270", "#4ecdc4", "#c7f464", "#ff6b6b", "#c44d58"],
|
|
1095
|
+
["#774f38", "#e08e79", "#f1d4af", "#ece5ce", "#c5e0dc"],
|
|
1096
|
+
["#e8ddcb", "#cdb380", "#036564", "#033649", "#031634"],
|
|
1097
|
+
["#490a3d", "#bd1550", "#e97f02", "#f8ca00", "#8a9b0f"],
|
|
1098
|
+
["#594f4f", "#547980", "#45ada8", "#9de0ad", "#e5fcc2"],
|
|
1099
|
+
["#00a0b0", "#6a4a3c", "#cc333f", "#eb6841", "#edc951"],
|
|
1100
|
+
["#e94e77", "#d68189", "#c6a49a", "#c6e5d9", "#f4ead5"],
|
|
1101
|
+
["#3fb8af", "#7fc7af", "#dad8a7", "#ff9e9d", "#ff3d7f"],
|
|
1102
|
+
["#d9ceb2", "#948c75", "#d5ded9", "#7a6a53", "#99b2b7"],
|
|
1103
|
+
["#ffffff", "#cbe86b", "#f2e9e1", "#1c140d", "#cbe86b"],
|
|
1104
|
+
["#efffcd", "#dce9be", "#555152", "#2e2633", "#99173c"],
|
|
1105
|
+
["#343838", "#005f6b", "#008c9e", "#00b4cc", "#00dffc"],
|
|
1106
|
+
["#413e4a", "#73626e", "#b38184", "#f0b49e", "#f7e4be"],
|
|
1107
|
+
["#ff4e50", "#fc913a", "#f9d423", "#ede574", "#e1f5c4"],
|
|
1108
|
+
["#99b898", "#fecea8", "#ff847c", "#e84a5f", "#2a363b"],
|
|
1109
|
+
["#655643", "#80bca3", "#f6f7bd", "#e6ac27", "#bf4d28"],
|
|
1110
|
+
["#00a8c6", "#40c0cb", "#f9f2e7", "#aee239", "#8fbe00"],
|
|
1111
|
+
["#351330", "#424254", "#64908a", "#e8caa4", "#cc2a41"],
|
|
1112
|
+
["#554236", "#f77825", "#d3ce3d", "#f1efa5", "#60b99a"],
|
|
1113
|
+
["#5d4157", "#838689", "#a8caba", "#cad7b2", "#ebe3aa"],
|
|
1114
|
+
["#8c2318", "#5e8c6a", "#88a65e", "#bfb35a", "#f2c45a"],
|
|
1115
|
+
["#fad089", "#ff9c5b", "#f5634a", "#ed303c", "#3b8183"],
|
|
1116
|
+
["#ff4242", "#f4fad2", "#d4ee5e", "#e1edb9", "#f0f2eb"],
|
|
1117
|
+
["#f8b195", "#f67280", "#c06c84", "#6c5b7b", "#355c7d"],
|
|
1118
|
+
["#d1e751", "#ffffff", "#000000", "#4dbce9", "#26ade4"],
|
|
1119
|
+
["#1b676b", "#519548", "#88c425", "#bef202", "#eafde6"],
|
|
1120
|
+
["#5e412f", "#fcebb6", "#78c0a8", "#f07818", "#f0a830"],
|
|
1121
|
+
["#bcbdac", "#cfbe27", "#f27435", "#f02475", "#3b2d38"],
|
|
1122
|
+
["#452632", "#91204d", "#e4844a", "#e8bf56", "#e2f7ce"],
|
|
1123
|
+
["#eee6ab", "#c5bc8e", "#696758", "#45484b", "#36393b"],
|
|
1124
|
+
["#f0d8a8", "#3d1c00", "#86b8b1", "#f2d694", "#fa2a00"],
|
|
1125
|
+
["#2a044a", "#0b2e59", "#0d6759", "#7ab317", "#a0c55f"],
|
|
1126
|
+
["#f04155", "#ff823a", "#f2f26f", "#fff7bd", "#95cfb7"],
|
|
1127
|
+
["#b9d7d9", "#668284", "#2a2829", "#493736", "#7b3b3b"],
|
|
1128
|
+
["#bbbb88", "#ccc68d", "#eedd99", "#eec290", "#eeaa88"],
|
|
1129
|
+
["#b3cc57", "#ecf081", "#ffbe40", "#ef746f", "#ab3e5b"],
|
|
1130
|
+
["#a3a948", "#edb92e", "#f85931", "#ce1836", "#009989"],
|
|
1131
|
+
["#300030", "#480048", "#601848", "#c04848", "#f07241"],
|
|
1132
|
+
["#67917a", "#170409", "#b8af03", "#ccbf82", "#e33258"],
|
|
1133
|
+
["#aab3ab", "#c4cbb7", "#ebefc9", "#eee0b7", "#e8caaf"],
|
|
1134
|
+
["#e8d5b7", "#0e2430", "#fc3a51", "#f5b349", "#e8d5b9"],
|
|
1135
|
+
["#ab526b", "#bca297", "#c5ceae", "#f0e2a4", "#f4ebc3"],
|
|
1136
|
+
["#607848", "#789048", "#c0d860", "#f0f0d8", "#604848"],
|
|
1137
|
+
["#b6d8c0", "#c8d9bf", "#dadabd", "#ecdbbc", "#fedcba"],
|
|
1138
|
+
["#a8e6ce", "#dcedc2", "#ffd3b5", "#ffaaa6", "#ff8c94"],
|
|
1139
|
+
["#3e4147", "#fffedf", "#dfba69", "#5a2e2e", "#2a2c31"],
|
|
1140
|
+
["#fc354c", "#29221f", "#13747d", "#0abfbc", "#fcf7c5"],
|
|
1141
|
+
["#cc0c39", "#e6781e", "#c8cf02", "#f8fcc1", "#1693a7"],
|
|
1142
|
+
["#1c2130", "#028f76", "#b3e099", "#ffeaad", "#d14334"],
|
|
1143
|
+
["#a7c5bd", "#e5ddcb", "#eb7b59", "#cf4647", "#524656"],
|
|
1144
|
+
["#dad6ca", "#1bb0ce", "#4f8699", "#6a5e72", "#563444"],
|
|
1145
|
+
["#5c323e", "#a82743", "#e15e32", "#c0d23e", "#e5f04c"],
|
|
1146
|
+
["#edebe6", "#d6e1c7", "#94c7b6", "#403b33", "#d3643b"],
|
|
1147
|
+
["#fdf1cc", "#c6d6b8", "#987f69", "#e3ad40", "#fcd036"],
|
|
1148
|
+
["#230f2b", "#f21d41", "#ebebbc", "#bce3c5", "#82b3ae"],
|
|
1149
|
+
["#b9d3b0", "#81bda4", "#b28774", "#f88f79", "#f6aa93"],
|
|
1150
|
+
["#3a111c", "#574951", "#83988e", "#bcdea5", "#e6f9bc"],
|
|
1151
|
+
["#5e3929", "#cd8c52", "#b7d1a3", "#dee8be", "#fcf7d3"],
|
|
1152
|
+
["#1c0113", "#6b0103", "#a30006", "#c21a01", "#f03c02"],
|
|
1153
|
+
["#000000", "#9f111b", "#b11623", "#292c37", "#cccccc"],
|
|
1154
|
+
["#382f32", "#ffeaf2", "#fcd9e5", "#fbc5d8", "#f1396d"],
|
|
1155
|
+
["#e3dfba", "#c8d6bf", "#93ccc6", "#6cbdb5", "#1a1f1e"],
|
|
1156
|
+
["#f6f6f6", "#e8e8e8", "#333333", "#990100", "#b90504"],
|
|
1157
|
+
["#1b325f", "#9cc4e4", "#e9f2f9", "#3a89c9", "#f26c4f"],
|
|
1158
|
+
["#a1dbb2", "#fee5ad", "#faca66", "#f7a541", "#f45d4c"],
|
|
1159
|
+
["#c1b398", "#605951", "#fbeec2", "#61a6ab", "#accec0"],
|
|
1160
|
+
["#5e9fa3", "#dcd1b4", "#fab87f", "#f87e7b", "#b05574"],
|
|
1161
|
+
["#951f2b", "#f5f4d7", "#e0dfb1", "#a5a36c", "#535233"],
|
|
1162
|
+
["#8dccad", "#988864", "#fea6a2", "#f9d6ac", "#ffe9af"],
|
|
1163
|
+
["#2d2d29", "#215a6d", "#3ca2a2", "#92c7a3", "#dfece6"],
|
|
1164
|
+
["#413d3d", "#040004", "#c8ff00", "#fa023c", "#4b000f"],
|
|
1165
|
+
["#eff3cd", "#b2d5ba", "#61ada0", "#248f8d", "#605063"],
|
|
1166
|
+
["#ffefd3", "#fffee4", "#d0ecea", "#9fd6d2", "#8b7a5e"],
|
|
1167
|
+
["#cfffdd", "#b4dec1", "#5c5863", "#a85163", "#ff1f4c"],
|
|
1168
|
+
["#9dc9ac", "#fffec7", "#f56218", "#ff9d2e", "#919167"],
|
|
1169
|
+
["#4e395d", "#827085", "#8ebe94", "#ccfc8e", "#dc5b3e"],
|
|
1170
|
+
["#a8a7a7", "#cc527a", "#e8175d", "#474747", "#363636"],
|
|
1171
|
+
["#f8edd1", "#d88a8a", "#474843", "#9d9d93", "#c5cfc6"],
|
|
1172
|
+
["#046d8b", "#309292", "#2fb8ac", "#93a42a", "#ecbe13"],
|
|
1173
|
+
["#f38a8a", "#55443d", "#a0cab5", "#cde9ca", "#f1edd0"],
|
|
1174
|
+
["#a70267", "#f10c49", "#fb6b41", "#f6d86b", "#339194"],
|
|
1175
|
+
["#ff003c", "#ff8a00", "#fabe28", "#88c100", "#00c176"],
|
|
1176
|
+
["#ffedbf", "#f7803c", "#f54828", "#2e0d23", "#f8e4c1"],
|
|
1177
|
+
["#4e4d4a", "#353432", "#94ba65", "#2790b0", "#2b4e72"],
|
|
1178
|
+
["#0ca5b0", "#4e3f30", "#fefeeb", "#f8f4e4", "#a5b3aa"],
|
|
1179
|
+
["#4d3b3b", "#de6262", "#ffb88c", "#ffd0b3", "#f5e0d3"],
|
|
1180
|
+
["#fffbb7", "#a6f6af", "#66b6ab", "#5b7c8d", "#4f2958"],
|
|
1181
|
+
["#edf6ee", "#d1c089", "#b3204d", "#412e28", "#151101"],
|
|
1182
|
+
["#9d7e79", "#ccac95", "#9a947c", "#748b83", "#5b756c"],
|
|
1183
|
+
["#fcfef5", "#e9ffe1", "#cdcfb7", "#d6e6c3", "#fafbe3"],
|
|
1184
|
+
["#9cddc8", "#bfd8ad", "#ddd9ab", "#f7af63", "#633d2e"],
|
|
1185
|
+
["#30261c", "#403831", "#36544f", "#1f5f61", "#0b8185"],
|
|
1186
|
+
["#aaff00", "#ffaa00", "#ff00aa", "#aa00ff", "#00aaff"],
|
|
1187
|
+
["#d1313d", "#e5625c", "#f9bf76", "#8eb2c5", "#615375"],
|
|
1188
|
+
["#ffe181", "#eee9e5", "#fad3b2", "#ffba7f", "#ff9c97"],
|
|
1189
|
+
["#73c8a9", "#dee1b6", "#e1b866", "#bd5532", "#373b44"],
|
|
1190
|
+
["#805841", "#dcf7f3", "#fffcdd", "#ffd8d8", "#f5a2a2"]
|
|
1191
|
+
];
|
|
1192
|
+
var getDebugLayoutObject = (lo) => {
|
|
1193
|
+
let {
|
|
1194
|
+
x,
|
|
1195
|
+
y,
|
|
1196
|
+
width,
|
|
1197
|
+
height
|
|
1198
|
+
} = {
|
|
1199
|
+
...lo,
|
|
1200
|
+
...lo.size,
|
|
1201
|
+
...lo.center,
|
|
1202
|
+
...lo.position
|
|
1203
|
+
};
|
|
1204
|
+
if (lo.x1 !== void 0 && lo.x2 !== void 0 && lo.y1 !== void 0 && lo.y2 !== void 0) {
|
|
1205
|
+
x = (lo.x1 + lo.x2) / 2;
|
|
1206
|
+
y = (lo.y1 + lo.y2) / 2;
|
|
1207
|
+
width = Math.abs(lo.x1 - lo.x2);
|
|
1208
|
+
height = Math.abs(lo.y1 - lo.y2);
|
|
1209
|
+
}
|
|
1210
|
+
const title = lo.text || lo.name || lo.source?.text || lo.source?.name || "?";
|
|
1211
|
+
const content = lo;
|
|
1212
|
+
if (x === void 0 || y === void 0)
|
|
1213
|
+
return null;
|
|
1214
|
+
if (width === void 0) {
|
|
1215
|
+
if ("outer_diameter" in lo) {
|
|
1216
|
+
width = lo.outer_diameter;
|
|
1217
|
+
height = lo.outer_diameter;
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
if (width === void 0 || height === void 0) {
|
|
1221
|
+
width = 0.1;
|
|
1222
|
+
height = 0.1;
|
|
1223
|
+
}
|
|
1224
|
+
return {
|
|
1225
|
+
x,
|
|
1226
|
+
y,
|
|
1227
|
+
width,
|
|
1228
|
+
height,
|
|
1229
|
+
title,
|
|
1230
|
+
content,
|
|
1231
|
+
bg_color: nice_color_palettes[stringHash(lo.type || title) % nice_color_palettes.length]?.[4] ?? "#f00"
|
|
1232
|
+
};
|
|
1233
|
+
};
|
|
1234
|
+
|
|
1235
|
+
// lib/utils/is-truthy.ts
|
|
1236
|
+
var isTruthy = (value) => Boolean(value);
|
|
1237
|
+
|
|
1238
|
+
// lib/find-bounds-and-center.ts
|
|
1239
|
+
var findBoundsAndCenter = (elements) => {
|
|
1240
|
+
const debugObjects = elements.filter((elm) => elm.type.startsWith("pcb_")).concat(
|
|
1241
|
+
elements.filter((elm) => elm.type === "pcb_trace").flatMap((elm) => elm.route)
|
|
1242
|
+
).map((elm) => getDebugLayoutObject(elm)).filter(isTruthy);
|
|
1243
|
+
if (debugObjects.length === 0)
|
|
1244
|
+
return { center: { x: 0, y: 0 }, width: 0, height: 0 };
|
|
1245
|
+
let minX = debugObjects[0].x - debugObjects[0].width / 2;
|
|
1246
|
+
let maxX = debugObjects[0].x + debugObjects[0].width / 2;
|
|
1247
|
+
let minY = debugObjects[0].y - debugObjects[0].height / 2;
|
|
1248
|
+
let maxY = debugObjects[0].y + debugObjects[0].height / 2;
|
|
1249
|
+
for (const obj of debugObjects.slice(1)) {
|
|
1250
|
+
minX = Math.min(minX, obj.x - obj.width / 2);
|
|
1251
|
+
maxX = Math.max(maxX, obj.x + obj.width / 2);
|
|
1252
|
+
minY = Math.min(minY, obj.y - obj.height / 2);
|
|
1253
|
+
maxY = Math.max(maxY, obj.y + obj.height / 2);
|
|
1254
|
+
}
|
|
1255
|
+
const width = maxX - minX;
|
|
1256
|
+
const height = maxY - minY;
|
|
1257
|
+
const center = { x: minX + width / 2, y: minY + height / 2 };
|
|
1258
|
+
return { center, width, height };
|
|
1259
|
+
};
|
|
1260
|
+
export {
|
|
1261
|
+
applySelector,
|
|
1262
|
+
applySelectorAST,
|
|
1263
|
+
cju_default as cju,
|
|
1264
|
+
cju_indexed_default as cjuIndexed,
|
|
1265
|
+
directionToVec,
|
|
1266
|
+
findBoundsAndCenter,
|
|
1267
|
+
getBoundsOfPcbElements,
|
|
1268
|
+
getElementById,
|
|
1269
|
+
getElementId,
|
|
1270
|
+
getReadableNameForElement,
|
|
1271
|
+
getReadableNameForPcbPort,
|
|
1272
|
+
getReadableNameForPcbSmtpad,
|
|
1273
|
+
getReadableNameForPcbTrace,
|
|
1274
|
+
oppositeDirection,
|
|
1275
|
+
oppositeSide,
|
|
1276
|
+
rotateClockwise,
|
|
1277
|
+
rotateCounterClockwise,
|
|
1278
|
+
rotateDirection,
|
|
1279
|
+
su,
|
|
1280
|
+
transformPCBElement,
|
|
1281
|
+
transformPCBElements,
|
|
1282
|
+
transformSchematicElement,
|
|
1283
|
+
transformSchematicElements,
|
|
1284
|
+
vecToDirection
|
|
1285
|
+
};
|
|
1286
|
+
//# sourceMappingURL=index.js.map
|