@tscircuit/circuit-json-util 0.0.47 → 0.0.48
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/dist/index.js +21 -20
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
// lib/cju.ts
|
|
2
2
|
import * as Soup from "circuit-json";
|
|
3
|
-
var cju = (
|
|
4
|
-
|
|
3
|
+
var cju = (circuitJsonInput, options = {}) => {
|
|
4
|
+
const circuitJson = circuitJsonInput;
|
|
5
|
+
let internalStore = circuitJson._internal_store;
|
|
5
6
|
if (!internalStore) {
|
|
6
7
|
internalStore = {
|
|
7
8
|
counts: {},
|
|
8
9
|
editCount: 0
|
|
9
10
|
};
|
|
10
|
-
|
|
11
|
-
for (const elm of
|
|
11
|
+
circuitJson._internal_store = internalStore;
|
|
12
|
+
for (const elm of circuitJson) {
|
|
12
13
|
const type = elm.type;
|
|
13
14
|
const idVal = elm[`${type}_id`];
|
|
14
15
|
if (!idVal)
|
|
@@ -29,8 +30,8 @@ var cju = (soup, options = {}) => {
|
|
|
29
30
|
if (prop === "toArray") {
|
|
30
31
|
return () => {
|
|
31
32
|
;
|
|
32
|
-
|
|
33
|
-
return
|
|
33
|
+
circuitJson.editCount = internalStore.editCount;
|
|
34
|
+
return circuitJson;
|
|
34
35
|
};
|
|
35
36
|
}
|
|
36
37
|
if (prop === "editCount") {
|
|
@@ -38,7 +39,7 @@ var cju = (soup, options = {}) => {
|
|
|
38
39
|
}
|
|
39
40
|
const component_type = prop;
|
|
40
41
|
return {
|
|
41
|
-
get: (id) =>
|
|
42
|
+
get: (id) => circuitJson.find(
|
|
42
43
|
(e) => e.type === component_type && e[`${component_type}_id`] === id
|
|
43
44
|
),
|
|
44
45
|
getUsing: (using) => {
|
|
@@ -50,24 +51,24 @@ var cju = (soup, options = {}) => {
|
|
|
50
51
|
}
|
|
51
52
|
const join_key = keys[0];
|
|
52
53
|
const join_type = join_key.replace("_id", "");
|
|
53
|
-
const joiner =
|
|
54
|
+
const joiner = circuitJson.find(
|
|
54
55
|
(e) => e.type === join_type && e[join_key] === using[join_key]
|
|
55
56
|
);
|
|
56
57
|
if (!joiner)
|
|
57
58
|
return null;
|
|
58
|
-
return
|
|
59
|
+
return circuitJson.find(
|
|
59
60
|
(e) => e.type === component_type && e[`${component_type}_id`] === joiner[`${component_type}_id`]
|
|
60
61
|
);
|
|
61
62
|
},
|
|
62
63
|
getWhere: (where) => {
|
|
63
64
|
const keys = Object.keys(where);
|
|
64
|
-
return
|
|
65
|
+
return circuitJson.find(
|
|
65
66
|
(e) => e.type === component_type && keys.every((key) => e[key] === where[key])
|
|
66
67
|
);
|
|
67
68
|
},
|
|
68
69
|
list: (where) => {
|
|
69
70
|
const keys = !where ? [] : Object.keys(where);
|
|
70
|
-
return
|
|
71
|
+
return circuitJson.filter(
|
|
71
72
|
(e) => e.type === component_type && keys.every((key) => e[key] === where[key])
|
|
72
73
|
);
|
|
73
74
|
},
|
|
@@ -84,21 +85,21 @@ var cju = (soup, options = {}) => {
|
|
|
84
85
|
const parser = Soup[component_type] ?? Soup.any_soup_element;
|
|
85
86
|
parser.parse(newElm);
|
|
86
87
|
}
|
|
87
|
-
|
|
88
|
+
circuitJson.push(newElm);
|
|
88
89
|
internalStore.editCount++;
|
|
89
90
|
return newElm;
|
|
90
91
|
},
|
|
91
92
|
delete: (id) => {
|
|
92
|
-
const elm =
|
|
93
|
+
const elm = circuitJson.find(
|
|
93
94
|
(e) => e[`${component_type}_id`] === id
|
|
94
95
|
);
|
|
95
96
|
if (!elm)
|
|
96
97
|
return;
|
|
97
|
-
|
|
98
|
+
circuitJson.splice(circuitJson.indexOf(elm), 1);
|
|
98
99
|
internalStore.editCount++;
|
|
99
100
|
},
|
|
100
101
|
update: (id, newProps) => {
|
|
101
|
-
const elm =
|
|
102
|
+
const elm = circuitJson.find(
|
|
102
103
|
(e) => e.type === component_type && e[`${component_type}_id`] === id
|
|
103
104
|
);
|
|
104
105
|
if (!elm)
|
|
@@ -109,17 +110,17 @@ var cju = (soup, options = {}) => {
|
|
|
109
110
|
},
|
|
110
111
|
select: (selector) => {
|
|
111
112
|
if (component_type === "source_component") {
|
|
112
|
-
return
|
|
113
|
+
return circuitJson.find(
|
|
113
114
|
(e) => e.type === "source_component" && e.name === selector.replace(/\./g, "")
|
|
114
115
|
);
|
|
115
116
|
} else if (component_type === "pcb_port" || component_type === "source_port" || component_type === "schematic_port") {
|
|
116
117
|
const [component_name, port_selector] = selector.replace(/\./g, "").split(/[\s\>]+/);
|
|
117
|
-
const source_component =
|
|
118
|
+
const source_component = circuitJson.find(
|
|
118
119
|
(e) => e.type === "source_component" && e.name === component_name
|
|
119
120
|
);
|
|
120
121
|
if (!source_component)
|
|
121
122
|
return null;
|
|
122
|
-
const source_port =
|
|
123
|
+
const source_port = circuitJson.find(
|
|
123
124
|
(e) => e.type === "source_port" && e.source_component_id === source_component.source_component_id && (e.name === port_selector || (e.port_hints ?? []).includes(port_selector))
|
|
124
125
|
);
|
|
125
126
|
if (!source_port)
|
|
@@ -127,11 +128,11 @@ var cju = (soup, options = {}) => {
|
|
|
127
128
|
if (component_type === "source_port")
|
|
128
129
|
return source_port;
|
|
129
130
|
if (component_type === "pcb_port") {
|
|
130
|
-
return
|
|
131
|
+
return circuitJson.find(
|
|
131
132
|
(e) => e.type === "pcb_port" && e.source_port_id === source_port.source_port_id
|
|
132
133
|
);
|
|
133
134
|
} else if (component_type === "schematic_port") {
|
|
134
|
-
return
|
|
135
|
+
return circuitJson.find(
|
|
135
136
|
(e) => e.type === "schematic_port" && e.source_port_id === source_port.source_port_id
|
|
136
137
|
);
|
|
137
138
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../lib/cju.ts","../lib/cju-indexed.ts","../lib/transform-soup-elements.ts","../lib/direction-to-vec.ts","../lib/apply-selector.ts","../lib/convert-abbreviation-to-soup-element-type.ts","../lib/get-element-id.ts","../lib/get-element-by-id.ts","../lib/readable-name-functions/get-readable-name-for-pcb-trace.ts","../lib/readable-name-functions/get-readable-name-for-pcb-port.ts","../lib/readable-name-functions/get-readable-name-for-pcb-smtpad.ts","../lib/readable-name-functions/get-readable-name-for-element.ts","../lib/get-bounds-of-pcb-elements.ts","../lib/utils/string-hash.ts","../lib/utils/get-layout-debug-object.ts","../lib/utils/is-truthy.ts","../lib/find-bounds-and-center.ts","../lib/get-primary-id.ts"],"sourcesContent":["import type {\n AnyCircuitElement,\n AnyCircuitElementInput,\n SourceComponentBase,\n SourcePort,\n} from \"circuit-json\"\nimport * as Soup from \"circuit-json\"\n\nexport type CircuitJsonOps<\n K extends AnyCircuitElement[\"type\"],\n T extends AnyCircuitElement | AnyCircuitElementInput,\n> = {\n get: (id: string) => Extract<T, { type: K }> | null\n select: (selector: string) => Extract<T, { type: K }> | null\n getWhere: (where: any) => Extract<T, { type: K }> | null\n getUsing: (using: {\n [key: `${string}_id`]: string\n }) => Extract<T, { type: K }> | null\n insert: (\n elm: Omit<Extract<T, { type: K }>, \"type\" | `${K}_id`>,\n ) => Extract<T, { type: K }>\n update: (\n id: string,\n newProps: Partial<Extract<T, { type: K }>>,\n ) => Extract<T, { type: K }>\n delete: (id: string) => void\n list: (where?: any) => Extract<T, { type: K }>[]\n}\n\nexport type CircuitJsonUtilObjects = {\n [K in AnyCircuitElement[\"type\"]]: CircuitJsonOps<K, AnyCircuitElement>\n} & {\n toArray: () => AnyCircuitElement[]\n editCount: number\n}\nexport type CircuitJsonInputUtilObjects = {\n [K in AnyCircuitElementInput[\"type\"]]: CircuitJsonOps<\n K,\n AnyCircuitElementInput\n >\n}\n\nexport type CircuitJsonUtilOptions = {\n validateInserts?: boolean\n}\n\nexport type GetCircuitJsonUtilFn = ((\n soup: AnyCircuitElement[],\n options?: CircuitJsonUtilOptions,\n) => CircuitJsonUtilObjects) & {\n unparsed: (soup: AnyCircuitElementInput[]) => CircuitJsonInputUtilObjects\n}\n\ninterface InternalStore {\n counts: Record<string, number>\n editCount: number\n}\n\nexport const cju: GetCircuitJsonUtilFn = ((\n soup: AnyCircuitElement[],\n options: CircuitJsonUtilOptions = {},\n) => {\n let internalStore: InternalStore = (soup as any)._internal_store\n if (!internalStore) {\n internalStore = {\n counts: {},\n editCount: 0,\n } as InternalStore\n ;(soup as any)._internal_store = internalStore\n\n // Initialize counts\n for (const elm of soup) {\n const type = elm.type\n const idVal = (elm as any)[`${type}_id`]\n if (!idVal) continue\n const idNum = Number.parseInt(idVal.split(\"_\").pop())\n if (!Number.isNaN(idNum)) {\n internalStore.counts[type] = Math.max(\n internalStore.counts[type] ?? 0,\n idNum,\n )\n }\n }\n }\n const su = new Proxy(\n {},\n {\n get: (proxy_target: any, prop: string) => {\n if (prop === \"toArray\") {\n return () => {\n ;(soup as any).editCount = internalStore.editCount\n return soup\n }\n }\n if (prop === \"editCount\") {\n return internalStore.editCount\n }\n\n const component_type = prop\n\n return {\n get: (id: string) =>\n soup.find(\n (e: any) =>\n e.type === component_type && e[`${component_type}_id`] === id,\n ),\n getUsing: (using: any) => {\n const keys = Object.keys(using)\n if (keys.length !== 1) {\n throw new Error(\n \"getUsing requires exactly one key, e.g. { pcb_component_id }\",\n )\n }\n const join_key = keys[0] as string\n const join_type = join_key.replace(\"_id\", \"\")\n const joiner: any = soup.find(\n (e: any) =>\n e.type === join_type && e[join_key] === using[join_key],\n )\n if (!joiner) return null\n return soup.find(\n (e: any) =>\n e.type === component_type &&\n e[`${component_type}_id`] === joiner[`${component_type}_id`],\n )\n },\n getWhere: (where: any) => {\n const keys = Object.keys(where)\n return soup.find(\n (e: any) =>\n e.type === component_type &&\n keys.every((key) => e[key] === where[key]),\n )\n },\n list: (where?: any) => {\n const keys = !where ? [] : Object.keys(where)\n return soup.filter(\n (e: any) =>\n e.type === component_type &&\n keys.every((key) => e[key] === where[key]),\n )\n },\n insert: (elm: any) => {\n internalStore.counts[component_type] ??= -1\n internalStore.counts[component_type]++\n const index = internalStore.counts[component_type]\n const newElm = {\n type: component_type,\n [`${component_type}_id`]: `${component_type}_${index}`,\n ...elm,\n }\n\n if (options.validateInserts) {\n const parser =\n (Soup as any)[component_type] ?? Soup.any_soup_element\n parser.parse(newElm)\n }\n\n soup.push(newElm)\n internalStore.editCount++\n return newElm\n },\n delete: (id: string) => {\n const elm = soup.find(\n (e) => (e as any)[`${component_type}_id`] === id,\n )\n if (!elm) return\n soup.splice(soup.indexOf(elm), 1)\n internalStore.editCount++\n },\n update: (id: string, newProps: any) => {\n const elm = soup.find(\n (e) =>\n e.type === component_type &&\n (e as any)[`${component_type}_id`] === id,\n )\n if (!elm) return null\n Object.assign(elm, newProps)\n internalStore.editCount++\n return elm\n },\n select: (selector: string) => {\n // TODO when applySelector is isolated we can use it, until then we\n // do a poor man's selector implementation for two common cases\n if (component_type === \"source_component\") {\n return soup.find(\n (e) =>\n e.type === \"source_component\" &&\n e.name === selector.replace(/\\./g, \"\"),\n )\n } else if (\n component_type === \"pcb_port\" ||\n component_type === \"source_port\" ||\n component_type === \"schematic_port\"\n ) {\n const [component_name, port_selector] = selector\n .replace(/\\./g, \"\")\n .split(/[\\s\\>]+/)\n const source_component = soup.find(\n (e) =>\n e.type === \"source_component\" && e.name === component_name,\n ) as SourceComponentBase\n if (!source_component) return null\n const source_port = soup.find(\n (e) =>\n e.type === \"source_port\" &&\n e.source_component_id ===\n source_component.source_component_id &&\n (e.name === port_selector ||\n (e.port_hints ?? []).includes(port_selector!)),\n ) as SourcePort\n if (!source_port) return null\n if (component_type === \"source_port\") return source_port\n\n if (component_type === \"pcb_port\") {\n return soup.find(\n (e) =>\n e.type === \"pcb_port\" &&\n e.source_port_id === source_port.source_port_id,\n )\n } else if (component_type === \"schematic_port\") {\n return soup.find(\n (e) =>\n e.type === \"schematic_port\" &&\n e.source_port_id === source_port.source_port_id,\n )\n }\n }\n },\n }\n },\n },\n )\n\n return su\n}) as any\ncju.unparsed = cju as any\n\nexport const su = cju\n\nexport default cju\n","import type {\n AnyCircuitElement,\n AnyCircuitElementInput,\n SourceComponentBase,\n SourcePort,\n} from \"circuit-json\"\nimport * as Soup from \"circuit-json\"\nimport type {\n CircuitJsonOps,\n CircuitJsonUtilObjects as CircuitJsonUtilObjects,\n CircuitJsonInputUtilObjects as CircuitJsonInputUtilObjects,\n} from \"./cju\"\n\nexport type IndexedCircuitJsonUtilOptions = {\n validateInserts?: boolean\n indexConfig?: {\n // Enable specific indexes for faster lookups\n byId?: boolean\n byType?: boolean\n byRelation?: boolean\n bySubcircuit?: boolean\n byCustomField?: string[]\n }\n}\n\nexport type GetIndexedCircuitJsonUtilFn = ((\n soup: AnyCircuitElement[],\n options?: IndexedCircuitJsonUtilOptions,\n) => CircuitJsonUtilObjects) & {\n unparsed: (soup: AnyCircuitElementInput[]) => CircuitJsonInputUtilObjects\n}\n\ninterface InternalStore {\n counts: Record<string, number>\n editCount: number\n // Indexes for faster lookups\n indexes: {\n byId?: Map<string, AnyCircuitElement>\n byType?: Map<string, AnyCircuitElement[]>\n // Maps relation fields (like component_id) to elements\n byRelation?: Map<string, Map<string, AnyCircuitElement[]>>\n // Maps subcircuit_id to elements\n bySubcircuit?: Map<string, AnyCircuitElement[]>\n // Custom field indexes\n byCustomField?: Map<string, Map<string, AnyCircuitElement[]>>\n }\n}\n\n// Creates a unique key for the ID index\nfunction createIdKey(element: AnyCircuitElement): string {\n const type = element.type\n return `${type}:${(element as any)[`${type}_id`]}`\n}\n\nexport const cjuIndexed: GetIndexedCircuitJsonUtilFn = ((\n soup: AnyCircuitElement[],\n options: IndexedCircuitJsonUtilOptions = {},\n) => {\n let internalStore: InternalStore = (soup as any)._internal_store_indexed\n\n if (!internalStore) {\n internalStore = {\n counts: {},\n editCount: 0,\n indexes: {},\n } as InternalStore\n\n // Initialize counts\n for (const elm of soup) {\n const type = elm.type\n const idVal = (elm as any)[`${type}_id`]\n if (!idVal) continue\n const idNum = Number.parseInt(idVal.split(\"_\").pop() || \"\")\n if (!Number.isNaN(idNum)) {\n internalStore.counts[type] = Math.max(\n internalStore.counts[type] ?? 0,\n idNum,\n )\n }\n }\n\n // Build indexes\n const indexConfig = options.indexConfig || {}\n const indexes = internalStore.indexes\n\n // Reset indexes before rebuilding\n if (indexConfig.byId) {\n indexes.byId = new Map()\n }\n\n if (indexConfig.byType) {\n indexes.byType = new Map()\n }\n\n if (indexConfig.byRelation) {\n indexes.byRelation = new Map()\n }\n\n if (indexConfig.bySubcircuit) {\n indexes.bySubcircuit = new Map()\n }\n\n if (indexConfig.byCustomField && indexConfig.byCustomField.length > 0) {\n indexes.byCustomField = new Map()\n for (const field of indexConfig.byCustomField) {\n indexes.byCustomField.set(field, new Map())\n }\n }\n\n // Build indexes\n for (const element of soup) {\n // Index by ID\n if (indexConfig.byId) {\n const idKey = createIdKey(element)\n indexes.byId!.set(idKey, element)\n }\n\n // Index by type\n if (indexConfig.byType) {\n const elementsOfType = indexes.byType!.get(element.type) || []\n elementsOfType.push(element)\n indexes.byType!.set(element.type, elementsOfType)\n }\n\n // Index by relation fields (fields ending with _id)\n if (indexConfig.byRelation) {\n const elementEntries = Object.entries(element)\n for (const [key, value] of elementEntries) {\n if (\n key.endsWith(\"_id\") &&\n key !== `${element.type}_id` &&\n typeof value === \"string\"\n ) {\n const relationTypeMap = indexes.byRelation!.get(key) || new Map()\n const relatedElements = relationTypeMap.get(value as string) || []\n relatedElements.push(element)\n relationTypeMap.set(value as string, relatedElements)\n indexes.byRelation!.set(key, relationTypeMap)\n }\n }\n }\n\n // Index by subcircuit_id\n if (indexConfig.bySubcircuit && \"subcircuit_id\" in element) {\n const subcircuitId = (element as any).subcircuit_id\n if (subcircuitId && typeof subcircuitId === \"string\") {\n const subcircuitElements =\n indexes.bySubcircuit!.get(subcircuitId) || []\n subcircuitElements.push(element)\n indexes.bySubcircuit!.set(subcircuitId, subcircuitElements)\n }\n }\n\n // Index by custom fields\n if (indexConfig.byCustomField && indexes.byCustomField) {\n for (const field of indexConfig.byCustomField) {\n if (field in element) {\n const fieldValue = (element as any)[field]\n if (\n fieldValue !== undefined &&\n (typeof fieldValue === \"string\" || typeof fieldValue === \"number\")\n ) {\n const fieldValueStr = String(fieldValue)\n const fieldMap = indexes.byCustomField.get(field)!\n const elementsWithFieldValue = fieldMap.get(fieldValueStr) || []\n elementsWithFieldValue.push(element)\n fieldMap.set(fieldValueStr, elementsWithFieldValue)\n }\n }\n }\n }\n }\n // Store internal state\n ;(soup as any)._internal_store_indexed = internalStore\n }\n\n const suIndexed = new Proxy(\n {},\n {\n get: (proxy_target: any, prop: string) => {\n if (prop === \"toArray\") {\n return () => {\n ;(soup as any).editCount = internalStore.editCount\n return soup\n }\n }\n if (prop === \"editCount\") {\n return internalStore.editCount\n }\n\n const component_type = prop\n\n return {\n get: (id: string) => {\n const indexConfig = options.indexConfig || {}\n\n // Use ID index if available\n if (indexConfig.byId && internalStore.indexes.byId) {\n return (\n (internalStore.indexes.byId.get(\n `${component_type}:${id}`,\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n }\n\n // Use type index if available\n if (indexConfig.byType && internalStore.indexes.byType) {\n const elementsOfType =\n internalStore.indexes.byType.get(component_type) || []\n return (\n (elementsOfType.find(\n (e: any) => e[`${component_type}_id`] === id,\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n }\n\n // Fallback to regular search\n return (\n (soup.find(\n (e: any) =>\n e.type === component_type && e[`${component_type}_id`] === id,\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n },\n\n getUsing: (using: any) => {\n const indexConfig = options.indexConfig || {}\n const keys = Object.keys(using)\n\n if (keys.length !== 1) {\n throw new Error(\n \"getUsing requires exactly one key, e.g. { pcb_component_id }\",\n )\n }\n\n const join_key = keys[0] as string\n const join_type = join_key.replace(\"_id\", \"\")\n\n // Use relation index if available\n if (indexConfig.byRelation && internalStore.indexes.byRelation) {\n const relationMap = internalStore.indexes.byRelation.get(join_key)\n if (relationMap) {\n const relatedElements = relationMap.get(using[join_key]) || []\n const joiner = relatedElements.find((e) => e.type === join_type)\n\n if (!joiner) return null\n\n // Now find the element of component_type with matching ID\n const joinerId =\n joiner[`${component_type}_id` as keyof typeof joiner]\n\n if (indexConfig.byId && internalStore.indexes.byId) {\n return (\n (internalStore.indexes.byId.get(\n `${component_type}:${joinerId}`,\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n }\n\n if (indexConfig.byType && internalStore.indexes.byType) {\n const elementsOfType =\n internalStore.indexes.byType.get(component_type) || []\n return (\n (elementsOfType.find(\n (e: any) => e[`${component_type}_id`] === joinerId,\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n }\n\n return (\n (soup.find(\n (e: any) =>\n e.type === component_type &&\n e[`${component_type}_id`] === joinerId,\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n }\n }\n\n // Fallback to regular approach\n const joiner: any = soup.find(\n (e: any) =>\n e.type === join_type && e[join_key] === using[join_key],\n )\n\n if (!joiner) return null\n\n return (\n (soup.find(\n (e: any) =>\n e.type === component_type &&\n e[`${component_type}_id`] === joiner[`${component_type}_id`],\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n },\n\n getWhere: (where: any) => {\n const indexConfig = options.indexConfig || {}\n const keys = Object.keys(where)\n\n // If we're looking by a single property and it's indexed as a custom field\n if (\n keys.length === 1 &&\n indexConfig.byCustomField &&\n internalStore.indexes.byCustomField\n ) {\n const field = keys[0]\n const fieldMap = internalStore.indexes.byCustomField.get(field!)\n\n if (fieldMap) {\n const fieldValue = String(where[field!])\n const elementsWithFieldValue = fieldMap.get(fieldValue) || []\n\n return (\n (elementsWithFieldValue.find(\n (e: any) => e.type === component_type,\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n }\n }\n\n // If we're looking by subcircuit_id and it's indexed\n if (\n \"subcircuit_id\" in where &&\n indexConfig.bySubcircuit &&\n internalStore.indexes.bySubcircuit\n ) {\n const subcircuitId = where.subcircuit_id\n const subcircuitElements =\n internalStore.indexes.bySubcircuit.get(subcircuitId) || []\n\n return (\n (subcircuitElements.find(\n (e: any) =>\n e.type === component_type &&\n keys.every((key) => e[key] === where[key]),\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n }\n\n // Use type index if available to reduce search space\n if (indexConfig.byType && internalStore.indexes.byType) {\n const elementsOfType =\n internalStore.indexes.byType.get(component_type) || []\n\n return (\n (elementsOfType.find((e: any) =>\n keys.every((key) => e[key] === where[key]),\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n }\n\n // Fallback to regular approach\n return (\n (soup.find(\n (e: any) =>\n e.type === component_type &&\n keys.every((key) => e[key] === where[key]),\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n },\n\n list: (where?: any) => {\n const indexConfig = options.indexConfig || {}\n const keys = !where ? [] : Object.keys(where)\n\n // If no filters, just return all elements of this type using the type index\n if (\n keys.length === 0 &&\n indexConfig.byType &&\n internalStore.indexes.byType\n ) {\n return (internalStore.indexes.byType.get(component_type) ||\n []) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >[]\n }\n\n // If filtering by subcircuit_id and it's the only filter\n if (\n keys.length === 1 &&\n keys[0] === \"subcircuit_id\" &&\n indexConfig.bySubcircuit &&\n internalStore.indexes.bySubcircuit\n ) {\n const subcircuitId = where.subcircuit_id\n const subcircuitElements =\n internalStore.indexes.bySubcircuit.get(subcircuitId) || []\n\n return subcircuitElements.filter(\n (e: any) => e.type === component_type,\n ) as Extract<AnyCircuitElement, { type: typeof component_type }>[]\n }\n\n // Start with all elements of this type to reduce search space\n let elementsToFilter: AnyCircuitElement[]\n\n if (indexConfig.byType && internalStore.indexes.byType) {\n elementsToFilter =\n internalStore.indexes.byType.get(component_type) || []\n } else {\n elementsToFilter = soup.filter((e) => e.type === component_type)\n }\n\n // Apply remaining filters\n if (keys.length > 0) {\n return elementsToFilter.filter((e: any) =>\n keys.every((key) => e[key] === where[key]),\n ) as Extract<AnyCircuitElement, { type: typeof component_type }>[]\n }\n\n return elementsToFilter as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >[]\n },\n\n insert: (elm: any) => {\n internalStore.counts[component_type] ??= -1\n internalStore.counts[component_type]++\n const index = internalStore.counts[component_type]\n const newElm = {\n type: component_type,\n [`${component_type}_id`]: `${component_type}_${index}`,\n ...elm,\n }\n\n if (options.validateInserts) {\n const parser =\n (Soup as any)[component_type] ?? Soup.any_soup_element\n parser.parse(newElm)\n }\n\n soup.push(newElm)\n internalStore.editCount++\n\n // Update indexes with the new element\n const indexConfig = options.indexConfig || {}\n\n // Update ID index\n if (indexConfig.byId && internalStore.indexes.byId) {\n const idKey = createIdKey(newElm)\n internalStore.indexes.byId.set(idKey, newElm)\n }\n\n // Update type index\n if (indexConfig.byType && internalStore.indexes.byType) {\n const elementsOfType =\n internalStore.indexes.byType.get(component_type) || []\n elementsOfType.push(newElm)\n internalStore.indexes.byType.set(component_type, elementsOfType)\n }\n\n // Update relation index\n if (indexConfig.byRelation && internalStore.indexes.byRelation) {\n const elementEntries = Object.entries(newElm)\n for (const [key, value] of elementEntries) {\n if (\n key.endsWith(\"_id\") &&\n key !== `${newElm.type}_id` &&\n typeof value === \"string\"\n ) {\n const relationTypeMap =\n internalStore.indexes.byRelation.get(key) || new Map()\n const relatedElements =\n relationTypeMap.get(value as string) || []\n relatedElements.push(newElm)\n relationTypeMap.set(value as string, relatedElements)\n internalStore.indexes.byRelation.set(key, relationTypeMap)\n }\n }\n }\n\n // Update subcircuit index\n if (\n indexConfig.bySubcircuit &&\n internalStore.indexes.bySubcircuit &&\n \"subcircuit_id\" in newElm\n ) {\n const subcircuitId = (newElm as any).subcircuit_id\n if (subcircuitId && typeof subcircuitId === \"string\") {\n const subcircuitElements =\n internalStore.indexes.bySubcircuit.get(subcircuitId) || []\n subcircuitElements.push(newElm)\n internalStore.indexes.bySubcircuit.set(\n subcircuitId,\n subcircuitElements,\n )\n }\n }\n\n // Update custom field indexes\n if (\n indexConfig.byCustomField &&\n internalStore.indexes.byCustomField\n ) {\n for (const field of indexConfig.byCustomField) {\n if (field in newElm) {\n const fieldValue = (newElm as any)[field]\n if (\n fieldValue !== undefined &&\n (typeof fieldValue === \"string\" ||\n typeof fieldValue === \"number\")\n ) {\n const fieldValueStr = String(fieldValue)\n const fieldMap =\n internalStore.indexes.byCustomField.get(field)!\n const elementsWithFieldValue =\n fieldMap.get(fieldValueStr) || []\n elementsWithFieldValue.push(newElm)\n fieldMap.set(fieldValueStr, elementsWithFieldValue)\n }\n }\n }\n }\n\n return newElm\n },\n\n delete: (id: string) => {\n const indexConfig = options.indexConfig || {}\n let elm: AnyCircuitElement | undefined\n\n // Find the element to delete\n if (indexConfig.byId && internalStore.indexes.byId) {\n elm = internalStore.indexes.byId.get(`${component_type}:${id}`)\n } else if (indexConfig.byType && internalStore.indexes.byType) {\n const elementsOfType =\n internalStore.indexes.byType.get(component_type) || []\n elm = elementsOfType.find(\n (e: any) => e[`${component_type}_id`] === id,\n )\n } else {\n elm = soup.find((e) => (e as any)[`${component_type}_id`] === id)\n }\n\n if (!elm) return\n\n // Remove from array\n const elmIndex = soup.indexOf(elm)\n if (elmIndex >= 0) {\n soup.splice(elmIndex, 1)\n internalStore.editCount++\n }\n\n // Remove from indexes\n if (indexConfig.byId && internalStore.indexes.byId) {\n const idKey = createIdKey(elm)\n internalStore.indexes.byId.delete(idKey)\n }\n\n if (indexConfig.byType && internalStore.indexes.byType) {\n const elementsOfType =\n internalStore.indexes.byType.get(component_type) || []\n const filteredElements = elementsOfType.filter(\n (e: any) => e[`${component_type}_id`] !== id,\n )\n internalStore.indexes.byType.set(component_type, filteredElements)\n }\n\n if (indexConfig.byRelation && internalStore.indexes.byRelation) {\n // This is more complex - we need to find and remove from all relation maps\n // where this element appears\n for (const [\n relationKey,\n relationMap,\n ] of internalStore.indexes.byRelation.entries()) {\n for (const [relationValue, elements] of relationMap.entries()) {\n const updatedElements = elements.filter((e) => e !== elm)\n\n if (updatedElements.length === 0) {\n relationMap.delete(relationValue)\n } else {\n relationMap.set(relationValue, updatedElements)\n }\n }\n }\n }\n\n if (\n indexConfig.bySubcircuit &&\n internalStore.indexes.bySubcircuit &&\n \"subcircuit_id\" in elm\n ) {\n const subcircuitId = (elm as any).subcircuit_id\n if (subcircuitId) {\n const subcircuitElements =\n internalStore.indexes.bySubcircuit.get(subcircuitId) || []\n const updatedElements = subcircuitElements.filter(\n (e) => e !== elm,\n )\n\n if (updatedElements.length === 0) {\n internalStore.indexes.bySubcircuit.delete(subcircuitId)\n } else {\n internalStore.indexes.bySubcircuit.set(\n subcircuitId,\n updatedElements,\n )\n }\n }\n }\n\n if (\n indexConfig.byCustomField &&\n internalStore.indexes.byCustomField\n ) {\n for (const fieldMap of internalStore.indexes.byCustomField.values()) {\n for (const [fieldValue, elements] of fieldMap.entries()) {\n const updatedElements = elements.filter((e) => e !== elm)\n\n if (updatedElements.length === 0) {\n fieldMap.delete(fieldValue)\n } else {\n fieldMap.set(fieldValue, updatedElements)\n }\n }\n }\n }\n },\n\n update: (id: string, newProps: any) => {\n const indexConfig = options.indexConfig || {}\n let elm: AnyCircuitElement | undefined | null\n\n // Find the element to update\n if (indexConfig.byId && internalStore.indexes.byId) {\n elm = internalStore.indexes.byId.get(`${component_type}:${id}`)\n } else if (indexConfig.byType && internalStore.indexes.byType) {\n const elementsOfType =\n internalStore.indexes.byType.get(component_type) || []\n elm = elementsOfType.find(\n (e: any) => e[`${component_type}_id`] === id,\n )\n } else {\n elm = soup.find(\n (e) =>\n e.type === component_type &&\n (e as any)[`${component_type}_id`] === id,\n )\n }\n\n if (!elm) return null\n\n // Need to remove from indexes before updating\n if (indexConfig.byRelation && internalStore.indexes.byRelation) {\n // Remove from relation indexes\n const elementEntries = Object.entries(elm)\n for (const [key, value] of elementEntries) {\n if (\n key.endsWith(\"_id\") &&\n key !== `${elm.type}_id` &&\n typeof value === \"string\"\n ) {\n if (key in newProps && newProps[key] !== value) {\n const relationTypeMap =\n internalStore.indexes.byRelation.get(key)\n if (relationTypeMap) {\n const relatedElements =\n relationTypeMap.get(value as string) || []\n const updatedElements = relatedElements.filter(\n (e) => e !== elm,\n )\n\n if (updatedElements.length === 0) {\n relationTypeMap.delete(value as string)\n } else {\n relationTypeMap.set(value as string, updatedElements)\n }\n }\n }\n }\n }\n }\n\n if (\n indexConfig.bySubcircuit &&\n internalStore.indexes.bySubcircuit &&\n \"subcircuit_id\" in elm &&\n \"subcircuit_id\" in newProps\n ) {\n const oldSubcircuitId = (elm as any).subcircuit_id\n const newSubcircuitId = newProps.subcircuit_id\n\n if (oldSubcircuitId !== newSubcircuitId) {\n // Remove from old subcircuit index\n const subcircuitElements =\n internalStore.indexes.bySubcircuit.get(oldSubcircuitId) || []\n const updatedElements = subcircuitElements.filter(\n (e) => e !== elm,\n )\n\n if (updatedElements.length === 0) {\n internalStore.indexes.bySubcircuit.delete(oldSubcircuitId)\n } else {\n internalStore.indexes.bySubcircuit.set(\n oldSubcircuitId,\n updatedElements,\n )\n }\n }\n }\n\n if (\n indexConfig.byCustomField &&\n internalStore.indexes.byCustomField\n ) {\n for (const field of indexConfig.byCustomField) {\n if (\n field in elm &&\n field in newProps &&\n (elm as any)[field] !== newProps[field]\n ) {\n const fieldMap =\n internalStore.indexes.byCustomField.get(field)\n if (fieldMap) {\n const oldValue = String((elm as any)[field])\n const elements = fieldMap.get(oldValue) || []\n const updatedElements = elements.filter((e) => e !== elm)\n\n if (updatedElements.length === 0) {\n fieldMap.delete(oldValue)\n } else {\n fieldMap.set(oldValue, updatedElements)\n }\n }\n }\n }\n }\n\n // Update the element\n Object.assign(elm, newProps)\n internalStore.editCount++\n\n // Add to indexes with updated values\n if (indexConfig.byRelation && internalStore.indexes.byRelation) {\n const elementEntries = Object.entries(elm)\n for (const [key, value] of elementEntries) {\n if (\n key.endsWith(\"_id\") &&\n key !== `${elm.type}_id` &&\n typeof value === \"string\"\n ) {\n if (key in newProps) {\n const relationTypeMap: any =\n internalStore.indexes.byRelation.get(key) || new Map()\n const relatedElements: any =\n relationTypeMap.get(value as string) || []\n\n if (!relatedElements.includes(elm)) {\n relatedElements.push(elm)\n relationTypeMap.set(value as string, relatedElements)\n internalStore.indexes.byRelation.set(key, relationTypeMap)\n }\n }\n }\n }\n }\n\n if (\n indexConfig.bySubcircuit &&\n internalStore.indexes.bySubcircuit &&\n \"subcircuit_id\" in elm &&\n \"subcircuit_id\" in newProps\n ) {\n const subcircuitId = (elm as any).subcircuit_id\n if (subcircuitId && typeof subcircuitId === \"string\") {\n const subcircuitElements =\n internalStore.indexes.bySubcircuit.get(subcircuitId) || []\n\n if (!subcircuitElements.includes(elm)) {\n subcircuitElements.push(elm)\n internalStore.indexes.bySubcircuit.set(\n subcircuitId,\n subcircuitElements,\n )\n }\n }\n }\n\n if (\n indexConfig.byCustomField &&\n internalStore.indexes.byCustomField\n ) {\n for (const field of indexConfig.byCustomField) {\n if (field in elm && field in newProps) {\n const fieldValue: any = (elm as any)[field]\n if (\n fieldValue !== undefined &&\n (typeof fieldValue === \"string\" ||\n typeof fieldValue === \"number\")\n ) {\n const fieldValueStr = String(fieldValue)\n const fieldMap =\n internalStore.indexes.byCustomField.get(field)!\n const elementsWithFieldValue =\n fieldMap.get(fieldValueStr) || []\n\n if (!elementsWithFieldValue.includes(elm)) {\n elementsWithFieldValue.push(elm)\n fieldMap.set(fieldValueStr, elementsWithFieldValue)\n }\n }\n }\n }\n }\n\n return elm as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >\n },\n\n select: (selector: string) => {\n // Selection by selector is specialized enough that we don't use indexes here\n // TODO when applySelector is isolated we can use it, until then we\n // do a poor man's selector implementation for two common cases\n if (component_type === \"source_component\") {\n return (\n (soup.find(\n (e) =>\n e.type === \"source_component\" &&\n e.name === selector.replace(/\\./g, \"\"),\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n } else if (\n component_type === \"pcb_port\" ||\n component_type === \"source_port\" ||\n component_type === \"schematic_port\"\n ) {\n const [component_name, port_selector] = selector\n .replace(/\\./g, \"\")\n .split(/[\\s\\>]+/)\n const source_component = soup.find(\n (e) =>\n e.type === \"source_component\" && e.name === component_name,\n ) as SourceComponentBase\n if (!source_component) return null\n const source_port = soup.find(\n (e) =>\n e.type === \"source_port\" &&\n e.source_component_id ===\n source_component.source_component_id &&\n (e.name === port_selector ||\n (e.port_hints ?? []).includes(port_selector!)),\n ) as SourcePort\n if (!source_port) return null\n if (component_type === \"source_port\")\n return source_port as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >\n\n if (component_type === \"pcb_port\") {\n return (\n (soup.find(\n (e) =>\n e.type === \"pcb_port\" &&\n e.source_port_id === source_port.source_port_id,\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n } else if (component_type === \"schematic_port\") {\n return (\n (soup.find(\n (e) =>\n e.type === \"schematic_port\" &&\n e.source_port_id === source_port.source_port_id,\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n }\n }\n\n return null\n },\n }\n },\n },\n )\n\n return suIndexed\n}) as any\n\ncjuIndexed.unparsed = cjuIndexed as any\n\nexport default cjuIndexed\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { type Matrix, applyToPoint, decomposeTSR } from \"transformation-matrix\"\nimport {\n directionToVec,\n rotateDirection,\n vecToDirection,\n} from \"./direction-to-vec\"\n\nexport const transformSchematicElement = (\n elm: AnyCircuitElement,\n matrix: Matrix,\n) => {\n if (elm.type === \"schematic_component\") {\n // TODO handle rotation\n elm.center = applyToPoint(matrix, elm.center)\n } else if (elm.type === \"schematic_port\") {\n elm.center = applyToPoint(matrix, elm.center)\n\n if (elm.facing_direction) {\n elm.facing_direction = rotateDirection(\n elm.facing_direction,\n -(Math.atan2(matrix.b, matrix.a) / Math.PI) * 2,\n )\n }\n } else if (elm.type === \"schematic_text\") {\n elm.position = applyToPoint(matrix, elm.position)\n // } else if (elm.type === \"schematic_group\") {\n // elm.center = applyToPoint(matrix, elm.center)\n } else if (elm.type === \"schematic_trace\") {\n } else if (elm.type === \"schematic_box\") {\n const { x, y } = applyToPoint(matrix, { x: elm.x, y: elm.y })\n elm.x = x\n elm.y = y\n } else if (elm.type === \"schematic_line\") {\n const { x: x1, y: y1 } = applyToPoint(matrix, { x: elm.x1, y: elm.y1 })\n const { x: x2, y: y2 } = applyToPoint(matrix, { x: elm.x2, y: elm.y2 })\n elm.x1 = x1\n elm.y1 = y1\n elm.x2 = x2\n elm.y2 = y2\n }\n return elm\n}\n\nexport const transformSchematicElements = (\n elms: AnyCircuitElement[],\n matrix: Matrix,\n) => {\n return elms.map((elm) => transformSchematicElement(elm, matrix))\n}\n\nexport const transformPCBElement = (elm: AnyCircuitElement, matrix: Matrix) => {\n if (\n elm.type === \"pcb_plated_hole\" ||\n elm.type === \"pcb_hole\" ||\n elm.type === \"pcb_via\" ||\n elm.type === \"pcb_smtpad\" ||\n elm.type === \"pcb_port\"\n ) {\n const { x, y } = applyToPoint(matrix, { x: elm.x, y: elm.y })\n elm.x = x\n elm.y = y\n } else if (elm.type === \"pcb_keepout\" || elm.type === \"pcb_board\") {\n // TODO adjust size/rotation\n elm.center = applyToPoint(matrix, elm.center)\n } else if (\n elm.type === \"pcb_silkscreen_text\" ||\n elm.type === \"pcb_fabrication_note_text\"\n ) {\n elm.anchor_position = applyToPoint(matrix, elm.anchor_position)\n } else if (\n elm.type === \"pcb_silkscreen_circle\" ||\n elm.type === \"pcb_silkscreen_rect\" ||\n elm.type === \"pcb_component\"\n ) {\n elm.center = applyToPoint(matrix, elm.center)\n } else if (\n elm.type === \"pcb_silkscreen_path\" ||\n elm.type === \"pcb_trace\" ||\n elm.type === \"pcb_fabrication_note_path\"\n ) {\n elm.route = elm.route.map((rp) => {\n const tp = applyToPoint(matrix, rp) as { x: number; y: number }\n rp.x = tp.x\n rp.y = tp.y\n return rp\n })\n } else if (elm.type === \"pcb_silkscreen_line\") {\n const p1 = { x: elm.x1, y: elm.y1 }\n const p2 = { x: elm.x2, y: elm.y2 }\n const p1t = applyToPoint(matrix, p1)\n const p2t = applyToPoint(matrix, p2)\n elm.x1 = p1t.x\n elm.y1 = p1t.y\n elm.x2 = p2t.x\n elm.y2 = p2t.y\n } else if (elm.type === \"cad_component\") {\n const newPos = applyToPoint(matrix, {\n x: elm.position.x,\n y: elm.position.y,\n })\n elm.position.x = newPos.x\n elm.position.y = newPos.y\n }\n return elm\n}\n\nexport const transformPCBElements = (\n elms: AnyCircuitElement[],\n matrix: Matrix,\n) => {\n const tsr = decomposeTSR(matrix)\n const flipPadWidthHeight =\n Math.round(tsr.rotation.angle / (Math.PI / 2)) % 2 === 1\n let transformedElms = elms.map((elm) => transformPCBElement(elm, matrix))\n if (flipPadWidthHeight) {\n transformedElms = transformedElms.map((elm) => {\n if (elm.type === \"pcb_smtpad\" && elm.shape === \"rect\") {\n ;[elm.width, elm.height] = [elm.height, elm.width]\n }\n return elm\n })\n }\n return transformedElms\n}\n","export const directionToVec = (direction: \"up\" | \"down\" | \"left\" | \"right\") => {\n if (direction === \"up\") return { x: 0, y: 1 }\n else if (direction === \"down\") return { x: 0, y: -1 }\n else if (direction === \"left\") return { x: -1, y: 0 }\n else if (direction === \"right\") return { x: 1, y: 0 }\n else throw new Error(\"Invalid direction\")\n}\n\nexport const vecToDirection = ({ x, y }: { x: number; y: number }) => {\n if (x > y) y = 0\n if (y > x) x = 0\n if (x > 0 && y === 0) return \"right\"\n else if (x < 0 && y === 0) return \"left\"\n else if (x === 0 && y > 0) return \"up\"\n else if (x === 0 && y < 0) return \"down\"\n else throw new Error(`Invalid vector for direction conversion (${x}, ${y})`)\n}\n\nexport const rotateClockwise = (\n direction: \"up\" | \"down\" | \"left\" | \"right\"\n) => {\n if (direction === \"up\") return \"right\"\n else if (direction === \"right\") return \"down\"\n else if (direction === \"down\") return \"left\"\n else if (direction === \"left\") return \"up\"\n throw new Error(`Invalid direction: ${direction}`)\n}\n\nexport const rotateCounterClockwise = (\n direction: \"up\" | \"down\" | \"left\" | \"right\"\n) => {\n if (direction === \"up\") return \"left\"\n else if (direction === \"left\") return \"down\"\n else if (direction === \"down\") return \"right\"\n else if (direction === \"right\") return \"up\"\n throw new Error(`Invalid direction: ${direction}`)\n}\n\nexport const rotateDirection = (\n direction: \"up\" | \"down\" | \"left\" | \"right\",\n num90DegreeClockwiseTurns: number\n) => {\n while (num90DegreeClockwiseTurns > 0) {\n direction = rotateClockwise(direction)\n num90DegreeClockwiseTurns--\n }\n while (num90DegreeClockwiseTurns < 0) {\n direction = rotateCounterClockwise(direction)\n num90DegreeClockwiseTurns++\n }\n return direction\n}\n\nexport const oppositeDirection = (\n direction: \"up\" | \"down\" | \"left\" | \"right\"\n) => {\n if (direction === \"up\") return \"down\"\n else if (direction === \"down\") return \"up\"\n else if (direction === \"left\") return \"right\"\n else if (direction === \"right\") return \"left\"\n throw new Error(`Invalid direction: ${direction}`)\n}\n\nexport const oppositeSide = (\n sideOrDir: \"up\" | \"down\" | \"top\" | \"bottom\" | \"left\" | \"right\"\n) => {\n if (sideOrDir === \"top\" || sideOrDir === \"up\") return \"bottom\"\n else if (sideOrDir === \"bottom\" || sideOrDir === \"down\") return \"top\"\n else if (sideOrDir === \"left\") return \"right\"\n else if (sideOrDir === \"right\") return \"left\"\n throw new Error(`Invalid sideOrDir: ${sideOrDir}`)\n}\n","import * as parsel from \"parsel-js\"\nimport { convertAbbrToType } from \"./convert-abbreviation-to-soup-element-type\"\nimport type { AnyCircuitElement } from \"circuit-json\"\n\nconst filterByType = (\n elements: AnyCircuitElement[],\n type: string\n): AnyCircuitElement[] => {\n type = convertAbbrToType(type)\n return elements.filter(\n (elm) => (\"ftype\" in elm && elm.ftype === type) || elm.type === type\n )\n}\n\n/**\n * Filter elements to match the selector, e.g. to access the left port of a\n * resistor you can do \".R1 > port.left\"\n */\nexport const applySelector = (\n elements: AnyCircuitElement[],\n selectorRaw: string\n): AnyCircuitElement[] => {\n const selectorAST = parsel.parse(selectorRaw)\n return applySelectorAST(elements, selectorAST!)\n}\n\nconst doesElmMatchClassName = (elm: AnyCircuitElement, className: string) =>\n (\"name\" in elm && elm.name === className) ||\n (\"port_hints\" in elm && elm.port_hints?.includes(className))\n\nexport const applySelectorAST = (\n elements: AnyCircuitElement[],\n selectorAST: parsel.AST\n): AnyCircuitElement[] => {\n switch (selectorAST.type) {\n case \"complex\": {\n switch (selectorAST.combinator) {\n case \" \": // TODO technically should do a deep search\n case \">\": {\n const { left, right } = selectorAST\n if (left.type === \"class\" || left.type === \"type\") {\n // TODO should also check if content matches any element tags\n let matchElms: AnyCircuitElement[]\n if (left.type === \"class\") {\n matchElms = elements.filter((elm) =>\n doesElmMatchClassName(elm, left.name)\n )\n } else if (left.type === \"type\") {\n matchElms = filterByType(elements, left.name)\n } else {\n matchElms = []\n }\n\n const childrenOfMatchingElms = matchElms.flatMap((matchElm) =>\n elements.filter(\n (elm: any) =>\n elm[`${matchElm.type}_id`] ===\n (matchElm as any)[`${matchElm.type}_id`] && elm !== matchElm\n )\n )\n return applySelectorAST(childrenOfMatchingElms, right)\n } else {\n throw new Error(`unsupported selector type \"${left.type}\" `)\n }\n }\n default: {\n throw new Error(\n `Couldn't apply selector AST for complex combinator \"${selectorAST.combinator}\"`\n )\n }\n }\n return []\n }\n case \"compound\": {\n const conditionsToMatch = selectorAST.list.map((part) => {\n switch (part.type) {\n case \"class\": {\n return (elm: any) => doesElmMatchClassName(elm, part.name)\n }\n case \"type\": {\n const name = convertAbbrToType(part.name)\n return (elm: any) => elm.type === name\n }\n }\n })\n\n return elements.filter((elm) =>\n conditionsToMatch.every((condFn) => condFn?.(elm))\n )\n }\n case \"type\": {\n return filterByType(elements, selectorAST.name) as AnyCircuitElement[]\n }\n case \"class\": {\n return elements.filter((elm) =>\n doesElmMatchClassName(elm, selectorAST.name)\n )\n }\n default: {\n throw new Error(\n `Couldn't apply selector AST for type: \"${\n selectorAST.type\n }\" ${JSON.stringify(selectorAST, null, \" \")}`\n )\n }\n }\n}\n","export const convertAbbrToType = (abbr: string): string => {\n switch (abbr) {\n case \"port\":\n return \"source_port\"\n case \"net\":\n return \"source_net\"\n case \"power\":\n return \"simple_power_source\"\n }\n return abbr\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\n\nexport const getElementId = (elm: AnyCircuitElement): string => {\n const type = elm.type\n const id = (elm as any)[`${type}_id`]\n return id\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { getElementId } from \"./get-element-id\"\n\nexport const getElementById = (\n soup: AnyCircuitElement[],\n id: string,\n): AnyCircuitElement | null => {\n return soup.find((elm) => getElementId(elm) === id) ?? null\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { cju } from \"../cju\"\n\nexport function getReadableNameForPcbTrace(\n soup: AnyCircuitElement[],\n pcb_trace_id: string,\n) {\n // Find the pcb_trace object\n const pcbTrace = cju(soup).pcb_trace.get(pcb_trace_id)\n\n if (!pcbTrace) {\n return `trace[${pcb_trace_id}]`\n }\n\n // Get the connected ports\n const connectedPcbPortIds: string[] = pcbTrace.route\n .flatMap((point: any) => [point.start_pcb_port_id, point.end_pcb_port_id])\n .filter(Boolean)\n\n if (connectedPcbPortIds.length === 0) {\n return `trace[${pcb_trace_id}]`\n }\n\n // Function to get component name and port hint\n function getComponentAndPortInfo(pcb_port_id: string) {\n const pcbPort = cju(soup).pcb_port.get(pcb_port_id)\n if (!pcbPort) return null\n\n const pcbComponent = cju(soup).pcb_component.get(pcbPort.pcb_component_id)\n if (!pcbComponent) return null\n const sourceComponent = cju(soup).source_component.get(\n pcbComponent.source_component_id,\n )\n if (!sourceComponent) return null\n\n const sourcePort = cju(soup).source_port.get(pcbPort.source_port_id)\n const portHint = sourcePort?.port_hints ? sourcePort.port_hints[1] : \"\"\n\n return {\n componentName: sourceComponent.name,\n portHint: portHint,\n }\n }\n\n // Generate the readable selector\n const selectorParts = connectedPcbPortIds.map((portId) => {\n const info = getComponentAndPortInfo(portId)\n if (info) {\n return `.${info.componentName} > port.${info.portHint}`\n }\n return `port[${portId}]`\n })\n\n return `trace[${selectorParts.join(\", \")}]`\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { cju } from \"../cju\"\n\nexport const getReadableNameForPcbPort = (\n soup: AnyCircuitElement[],\n pcb_port_id: string,\n): string => {\n const pcbPort = cju(soup).pcb_port.get(pcb_port_id)\n if (!pcbPort) {\n return `pcb_port[#${pcb_port_id}]`\n }\n\n // Get the component information\n const pcbComponent = cju(soup).pcb_component.get(pcbPort?.pcb_component_id)\n\n if (!pcbComponent) {\n return `pcb_port[#${pcb_port_id}]`\n }\n\n // Get the source component information\n const sourceComponent = cju(soup).source_component.get(\n pcbComponent.source_component_id,\n )\n\n if (!sourceComponent) {\n return `pcb_port[#${pcb_port_id}]`\n }\n\n // Get the source port information\n const sourcePort = cju(soup).source_port.get(pcbPort.source_port_id)\n\n if (!sourcePort) {\n return `pcb_port[#${pcb_port_id}]`\n }\n\n // Determine the pad number or hint\n let padIdentifier: string\n if (sourcePort?.port_hints && sourcePort.port_hints.length > 0) {\n padIdentifier = sourcePort.port_hints[0]!\n } else if (sourcePort.port_hints && sourcePort.port_hints.length > 0) {\n padIdentifier = sourcePort.port_hints[0]!\n } else {\n padIdentifier = pcb_port_id\n }\n\n return `pcb_port[.${sourceComponent.name} > .${padIdentifier}]`\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { cju } from \"../cju\"\nimport { getReadableNameForPcbPort } from \"./get-readable-name-for-pcb-port\"\n\nexport function getReadableNameForPcbSmtpad(\n soup: AnyCircuitElement[],\n pcb_smtpad_id: string,\n): string {\n // Find the pcb_smtpad object\n const pcbSmtpad = cju(soup).pcb_smtpad.get(pcb_smtpad_id)\n\n if (!pcbSmtpad || !pcbSmtpad.pcb_port_id) {\n return `smtpad[${pcb_smtpad_id}]`\n }\n\n return getReadableNameForPcbPort(soup, pcbSmtpad.pcb_port_id)\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { getReadableNameForPcbTrace } from \"./get-readable-name-for-pcb-trace\"\nimport { getReadableNameForPcbSmtpad } from \"./get-readable-name-for-pcb-smtpad\"\nimport { getReadableNameForPcbPort } from \"./get-readable-name-for-pcb-port\"\nimport { getElementById } from \"lib/get-element-by-id\"\nimport { getElementId } from \"lib/get-element-id\"\n\nexport const getReadableNameForElement = (\n soup: AnyCircuitElement[],\n elm: AnyCircuitElement | string,\n): string => {\n if (typeof elm === \"string\") {\n const elmObj = getElementById(soup, elm)\n if (!elmObj) `unknown (could not find element with id ${elm})`\n return getReadableNameForElement(soup, elmObj as any)\n }\n switch (elm.type) {\n case \"pcb_port\":\n return getReadableNameForPcbPort(soup, elm.pcb_port_id)\n case \"pcb_smtpad\":\n return getReadableNameForPcbSmtpad(soup, elm.pcb_smtpad_id)\n case \"pcb_trace\":\n return getReadableNameForPcbTrace(soup, elm.pcb_trace_id)\n case \"source_component\":\n return `source_component[${elm.name}]`\n default:\n return `${elm.type}[#${getElementId(elm)}]`\n }\n}\n\nexport {\n getReadableNameForPcbPort,\n getReadableNameForPcbSmtpad,\n getReadableNameForPcbTrace,\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\n\nexport const getBoundsOfPcbElements = (\n elements: AnyCircuitElement[],\n): { minX: number; minY: number; maxX: number; maxY: number } => {\n let minX = Number.POSITIVE_INFINITY\n let minY = Number.POSITIVE_INFINITY\n let maxX = Number.NEGATIVE_INFINITY\n let maxY = Number.NEGATIVE_INFINITY\n\n for (const elm of elements) {\n if (!elm.type.startsWith(\"pcb_\")) continue\n\n let centerX: number | undefined\n let centerY: number | undefined\n\n let width: number | undefined\n let height: number | undefined\n\n if (\"x\" in elm && \"y\" in elm) {\n centerX = elm.x\n centerY = elm.y\n }\n\n if (\"outer_diameter\" in elm) {\n width = elm.outer_diameter\n height = elm.outer_diameter\n }\n\n if (\"width\" in elm) {\n width = elm.width\n }\n\n if (\"height\" in elm) {\n height = elm.height\n }\n\n if (\"center\" in elm) {\n // @ts-ignore\n centerX = elm.center.x\n // @ts-ignore\n centerY = elm.center.y\n }\n\n if (centerX !== undefined && centerY !== undefined) {\n minX = Math.min(minX, centerX)\n minY = Math.min(minY, centerY)\n maxX = Math.max(maxX, centerX)\n maxY = Math.max(maxY, centerY)\n\n if (width !== undefined && height !== undefined) {\n minX = Math.min(minX, centerX - width / 2)\n minY = Math.min(minY, centerY - height / 2)\n maxX = Math.max(maxX, centerX + width / 2)\n maxY = Math.max(maxY, centerY + height / 2)\n }\n\n if (\"radius\" in elm) {\n minX = Math.min(minX, centerX - elm.radius)\n minY = Math.min(minY, centerY - elm.radius)\n maxX = Math.max(maxX, centerX + elm.radius)\n maxY = Math.max(maxY, centerY + elm.radius)\n }\n } else if (elm.type === \"pcb_trace\") {\n for (const point of elm.route) {\n // TODO add trace thickness support\n minX = Math.min(minX, point.x)\n minY = Math.min(minY, point.y)\n maxX = Math.max(maxX, point.x)\n maxY = Math.max(maxY, point.y)\n }\n }\n }\n\n return { minX, minY, maxX, maxY }\n}\n","export function stringHash(str: string) {\n let hash = 0\n if (str.length == 0) return hash\n for (var i = 0; i < str.length; i++) {\n var char = str.charCodeAt(i)\n hash = (hash << 5) - hash + char\n hash = hash & hash // Convert to 32bit integer\n }\n return Math.abs(hash)\n}\n","import { stringHash } from \"./string-hash\"\n\nexport type LayoutDebugObject = {\n x: number\n y: number\n width: number\n height: number\n bg_color: string\n title: string\n content: Object\n secondary?: boolean\n}\n\n/**\n * Vendored from \"nice-color-palettes\" package\n */\nconst nice_color_palettes = [\n [\"#69d2e7\", \"#a7dbd8\", \"#e0e4cc\", \"#f38630\", \"#fa6900\"],\n [\"#fe4365\", \"#fc9d9a\", \"#f9cdad\", \"#c8c8a9\", \"#83af9b\"],\n [\"#ecd078\", \"#d95b43\", \"#c02942\", \"#542437\", \"#53777a\"],\n [\"#556270\", \"#4ecdc4\", \"#c7f464\", \"#ff6b6b\", \"#c44d58\"],\n [\"#774f38\", \"#e08e79\", \"#f1d4af\", \"#ece5ce\", \"#c5e0dc\"],\n [\"#e8ddcb\", \"#cdb380\", \"#036564\", \"#033649\", \"#031634\"],\n [\"#490a3d\", \"#bd1550\", \"#e97f02\", \"#f8ca00\", \"#8a9b0f\"],\n [\"#594f4f\", \"#547980\", \"#45ada8\", \"#9de0ad\", \"#e5fcc2\"],\n [\"#00a0b0\", \"#6a4a3c\", \"#cc333f\", \"#eb6841\", \"#edc951\"],\n [\"#e94e77\", \"#d68189\", \"#c6a49a\", \"#c6e5d9\", \"#f4ead5\"],\n [\"#3fb8af\", \"#7fc7af\", \"#dad8a7\", \"#ff9e9d\", \"#ff3d7f\"],\n [\"#d9ceb2\", \"#948c75\", \"#d5ded9\", \"#7a6a53\", \"#99b2b7\"],\n [\"#ffffff\", \"#cbe86b\", \"#f2e9e1\", \"#1c140d\", \"#cbe86b\"],\n [\"#efffcd\", \"#dce9be\", \"#555152\", \"#2e2633\", \"#99173c\"],\n [\"#343838\", \"#005f6b\", \"#008c9e\", \"#00b4cc\", \"#00dffc\"],\n [\"#413e4a\", \"#73626e\", \"#b38184\", \"#f0b49e\", \"#f7e4be\"],\n [\"#ff4e50\", \"#fc913a\", \"#f9d423\", \"#ede574\", \"#e1f5c4\"],\n [\"#99b898\", \"#fecea8\", \"#ff847c\", \"#e84a5f\", \"#2a363b\"],\n [\"#655643\", \"#80bca3\", \"#f6f7bd\", \"#e6ac27\", \"#bf4d28\"],\n [\"#00a8c6\", \"#40c0cb\", \"#f9f2e7\", \"#aee239\", \"#8fbe00\"],\n [\"#351330\", \"#424254\", \"#64908a\", \"#e8caa4\", \"#cc2a41\"],\n [\"#554236\", \"#f77825\", \"#d3ce3d\", \"#f1efa5\", \"#60b99a\"],\n [\"#5d4157\", \"#838689\", \"#a8caba\", \"#cad7b2\", \"#ebe3aa\"],\n [\"#8c2318\", \"#5e8c6a\", \"#88a65e\", \"#bfb35a\", \"#f2c45a\"],\n [\"#fad089\", \"#ff9c5b\", \"#f5634a\", \"#ed303c\", \"#3b8183\"],\n [\"#ff4242\", \"#f4fad2\", \"#d4ee5e\", \"#e1edb9\", \"#f0f2eb\"],\n [\"#f8b195\", \"#f67280\", \"#c06c84\", \"#6c5b7b\", \"#355c7d\"],\n [\"#d1e751\", \"#ffffff\", \"#000000\", \"#4dbce9\", \"#26ade4\"],\n [\"#1b676b\", \"#519548\", \"#88c425\", \"#bef202\", \"#eafde6\"],\n [\"#5e412f\", \"#fcebb6\", \"#78c0a8\", \"#f07818\", \"#f0a830\"],\n [\"#bcbdac\", \"#cfbe27\", \"#f27435\", \"#f02475\", \"#3b2d38\"],\n [\"#452632\", \"#91204d\", \"#e4844a\", \"#e8bf56\", \"#e2f7ce\"],\n [\"#eee6ab\", \"#c5bc8e\", \"#696758\", \"#45484b\", \"#36393b\"],\n [\"#f0d8a8\", \"#3d1c00\", \"#86b8b1\", \"#f2d694\", \"#fa2a00\"],\n [\"#2a044a\", \"#0b2e59\", \"#0d6759\", \"#7ab317\", \"#a0c55f\"],\n [\"#f04155\", \"#ff823a\", \"#f2f26f\", \"#fff7bd\", \"#95cfb7\"],\n [\"#b9d7d9\", \"#668284\", \"#2a2829\", \"#493736\", \"#7b3b3b\"],\n [\"#bbbb88\", \"#ccc68d\", \"#eedd99\", \"#eec290\", \"#eeaa88\"],\n [\"#b3cc57\", \"#ecf081\", \"#ffbe40\", \"#ef746f\", \"#ab3e5b\"],\n [\"#a3a948\", \"#edb92e\", \"#f85931\", \"#ce1836\", \"#009989\"],\n [\"#300030\", \"#480048\", \"#601848\", \"#c04848\", \"#f07241\"],\n [\"#67917a\", \"#170409\", \"#b8af03\", \"#ccbf82\", \"#e33258\"],\n [\"#aab3ab\", \"#c4cbb7\", \"#ebefc9\", \"#eee0b7\", \"#e8caaf\"],\n [\"#e8d5b7\", \"#0e2430\", \"#fc3a51\", \"#f5b349\", \"#e8d5b9\"],\n [\"#ab526b\", \"#bca297\", \"#c5ceae\", \"#f0e2a4\", \"#f4ebc3\"],\n [\"#607848\", \"#789048\", \"#c0d860\", \"#f0f0d8\", \"#604848\"],\n [\"#b6d8c0\", \"#c8d9bf\", \"#dadabd\", \"#ecdbbc\", \"#fedcba\"],\n [\"#a8e6ce\", \"#dcedc2\", \"#ffd3b5\", \"#ffaaa6\", \"#ff8c94\"],\n [\"#3e4147\", \"#fffedf\", \"#dfba69\", \"#5a2e2e\", \"#2a2c31\"],\n [\"#fc354c\", \"#29221f\", \"#13747d\", \"#0abfbc\", \"#fcf7c5\"],\n [\"#cc0c39\", \"#e6781e\", \"#c8cf02\", \"#f8fcc1\", \"#1693a7\"],\n [\"#1c2130\", \"#028f76\", \"#b3e099\", \"#ffeaad\", \"#d14334\"],\n [\"#a7c5bd\", \"#e5ddcb\", \"#eb7b59\", \"#cf4647\", \"#524656\"],\n [\"#dad6ca\", \"#1bb0ce\", \"#4f8699\", \"#6a5e72\", \"#563444\"],\n [\"#5c323e\", \"#a82743\", \"#e15e32\", \"#c0d23e\", \"#e5f04c\"],\n [\"#edebe6\", \"#d6e1c7\", \"#94c7b6\", \"#403b33\", \"#d3643b\"],\n [\"#fdf1cc\", \"#c6d6b8\", \"#987f69\", \"#e3ad40\", \"#fcd036\"],\n [\"#230f2b\", \"#f21d41\", \"#ebebbc\", \"#bce3c5\", \"#82b3ae\"],\n [\"#b9d3b0\", \"#81bda4\", \"#b28774\", \"#f88f79\", \"#f6aa93\"],\n [\"#3a111c\", \"#574951\", \"#83988e\", \"#bcdea5\", \"#e6f9bc\"],\n [\"#5e3929\", \"#cd8c52\", \"#b7d1a3\", \"#dee8be\", \"#fcf7d3\"],\n [\"#1c0113\", \"#6b0103\", \"#a30006\", \"#c21a01\", \"#f03c02\"],\n [\"#000000\", \"#9f111b\", \"#b11623\", \"#292c37\", \"#cccccc\"],\n [\"#382f32\", \"#ffeaf2\", \"#fcd9e5\", \"#fbc5d8\", \"#f1396d\"],\n [\"#e3dfba\", \"#c8d6bf\", \"#93ccc6\", \"#6cbdb5\", \"#1a1f1e\"],\n [\"#f6f6f6\", \"#e8e8e8\", \"#333333\", \"#990100\", \"#b90504\"],\n [\"#1b325f\", \"#9cc4e4\", \"#e9f2f9\", \"#3a89c9\", \"#f26c4f\"],\n [\"#a1dbb2\", \"#fee5ad\", \"#faca66\", \"#f7a541\", \"#f45d4c\"],\n [\"#c1b398\", \"#605951\", \"#fbeec2\", \"#61a6ab\", \"#accec0\"],\n [\"#5e9fa3\", \"#dcd1b4\", \"#fab87f\", \"#f87e7b\", \"#b05574\"],\n [\"#951f2b\", \"#f5f4d7\", \"#e0dfb1\", \"#a5a36c\", \"#535233\"],\n [\"#8dccad\", \"#988864\", \"#fea6a2\", \"#f9d6ac\", \"#ffe9af\"],\n [\"#2d2d29\", \"#215a6d\", \"#3ca2a2\", \"#92c7a3\", \"#dfece6\"],\n [\"#413d3d\", \"#040004\", \"#c8ff00\", \"#fa023c\", \"#4b000f\"],\n [\"#eff3cd\", \"#b2d5ba\", \"#61ada0\", \"#248f8d\", \"#605063\"],\n [\"#ffefd3\", \"#fffee4\", \"#d0ecea\", \"#9fd6d2\", \"#8b7a5e\"],\n [\"#cfffdd\", \"#b4dec1\", \"#5c5863\", \"#a85163\", \"#ff1f4c\"],\n [\"#9dc9ac\", \"#fffec7\", \"#f56218\", \"#ff9d2e\", \"#919167\"],\n [\"#4e395d\", \"#827085\", \"#8ebe94\", \"#ccfc8e\", \"#dc5b3e\"],\n [\"#a8a7a7\", \"#cc527a\", \"#e8175d\", \"#474747\", \"#363636\"],\n [\"#f8edd1\", \"#d88a8a\", \"#474843\", \"#9d9d93\", \"#c5cfc6\"],\n [\"#046d8b\", \"#309292\", \"#2fb8ac\", \"#93a42a\", \"#ecbe13\"],\n [\"#f38a8a\", \"#55443d\", \"#a0cab5\", \"#cde9ca\", \"#f1edd0\"],\n [\"#a70267\", \"#f10c49\", \"#fb6b41\", \"#f6d86b\", \"#339194\"],\n [\"#ff003c\", \"#ff8a00\", \"#fabe28\", \"#88c100\", \"#00c176\"],\n [\"#ffedbf\", \"#f7803c\", \"#f54828\", \"#2e0d23\", \"#f8e4c1\"],\n [\"#4e4d4a\", \"#353432\", \"#94ba65\", \"#2790b0\", \"#2b4e72\"],\n [\"#0ca5b0\", \"#4e3f30\", \"#fefeeb\", \"#f8f4e4\", \"#a5b3aa\"],\n [\"#4d3b3b\", \"#de6262\", \"#ffb88c\", \"#ffd0b3\", \"#f5e0d3\"],\n [\"#fffbb7\", \"#a6f6af\", \"#66b6ab\", \"#5b7c8d\", \"#4f2958\"],\n [\"#edf6ee\", \"#d1c089\", \"#b3204d\", \"#412e28\", \"#151101\"],\n [\"#9d7e79\", \"#ccac95\", \"#9a947c\", \"#748b83\", \"#5b756c\"],\n [\"#fcfef5\", \"#e9ffe1\", \"#cdcfb7\", \"#d6e6c3\", \"#fafbe3\"],\n [\"#9cddc8\", \"#bfd8ad\", \"#ddd9ab\", \"#f7af63\", \"#633d2e\"],\n [\"#30261c\", \"#403831\", \"#36544f\", \"#1f5f61\", \"#0b8185\"],\n [\"#aaff00\", \"#ffaa00\", \"#ff00aa\", \"#aa00ff\", \"#00aaff\"],\n [\"#d1313d\", \"#e5625c\", \"#f9bf76\", \"#8eb2c5\", \"#615375\"],\n [\"#ffe181\", \"#eee9e5\", \"#fad3b2\", \"#ffba7f\", \"#ff9c97\"],\n [\"#73c8a9\", \"#dee1b6\", \"#e1b866\", \"#bd5532\", \"#373b44\"],\n [\"#805841\", \"#dcf7f3\", \"#fffcdd\", \"#ffd8d8\", \"#f5a2a2\"],\n]\n\nexport const getDebugLayoutObject = (lo: any): LayoutDebugObject | null => {\n let {\n x,\n y,\n width,\n height,\n }: { x: number; y: number; width?: number; height?: number } = {\n ...lo,\n ...(lo as any).size,\n ...(lo as any).center,\n ...(lo as any).position,\n }\n\n if (\n lo.x1 !== undefined &&\n lo.x2 !== undefined &&\n lo.y1 !== undefined &&\n lo.y2 !== undefined\n ) {\n x = (lo.x1 + lo.x2) / 2\n y = (lo.y1 + lo.y2) / 2\n width = Math.abs(lo.x1 - lo.x2)\n height = Math.abs(lo.y1 - lo.y2)\n }\n\n const title = lo.text || lo.name || lo.source?.text || lo.source?.name || \"?\"\n const content = lo\n\n if (x === undefined || y === undefined) return null\n\n if (width === undefined) {\n if (\"outer_diameter\" in lo) {\n width = lo.outer_diameter\n height = lo.outer_diameter\n }\n }\n\n if (width === undefined || height === undefined) {\n width = 0.1\n height = 0.1\n }\n\n return {\n x,\n y,\n width,\n height,\n title,\n content,\n bg_color:\n nice_color_palettes[\n stringHash((lo as any).type || title) % nice_color_palettes.length\n ]?.[4] ?? \"#f00\",\n }\n}\n","export const isTruthy = <T>(value: T): value is NonNullable<T> => Boolean(value)\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { getDebugLayoutObject } from \"./utils/get-layout-debug-object\"\nimport { isTruthy } from \"./utils/is-truthy\"\n\nexport const findBoundsAndCenter = (\n elements: AnyCircuitElement[],\n): { center: { x: number; y: number }; width: number; height: number } => {\n const debugObjects = elements\n .filter((elm) => elm.type.startsWith(\"pcb_\"))\n .concat(\n elements\n .filter((elm) => elm.type === \"pcb_trace\")\n // @ts-ignore\n .flatMap((elm: PcbTrace) => elm.route),\n )\n .map((elm) => getDebugLayoutObject(elm))\n .filter(isTruthy)\n\n if (debugObjects.length === 0)\n return { center: { x: 0, y: 0 }, width: 0, height: 0 }\n\n let minX = debugObjects[0]!.x - debugObjects[0]!.width / 2\n let maxX = debugObjects[0]!.x + debugObjects[0]!.width / 2\n let minY = debugObjects[0]!.y - debugObjects[0]!.height / 2\n let maxY = debugObjects[0]!.y + debugObjects[0]!.height / 2\n\n for (const obj of debugObjects.slice(1)) {\n minX = Math.min(minX, obj.x - obj.width / 2)\n maxX = Math.max(maxX, obj.x + obj.width / 2)\n minY = Math.min(minY, obj.y - obj.height / 2)\n maxY = Math.max(maxY, obj.y + obj.height / 2)\n }\n\n const width = maxX - minX\n const height = maxY - minY\n const center = { x: minX + width / 2, y: minY + height / 2 }\n\n return { center, width, height }\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\n\nexport const getPrimaryId = (element: AnyCircuitElement): string => {\n // @ts-ignore\n return element[`${element.type}_id`]\n}\n"],"mappings":"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AW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AACxD;AAEO,IAAM,uBAAuB,CAAC,OAAsC;AACzE,MAAI;AAAA,IACF;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAA+D;AAAA,IAC7D,GAAG;AAAA,IACH,GAAI,GAAW;AAAA,IACf,GAAI,GAAW;AAAA,IACf,GAAI,GAAW;AAAA,EACjB;AAEA,MACE,GAAG,OAAO,UACV,GAAG,OAAO,UACV,GAAG,OAAO,UACV,GAAG,OAAO,QACV;AACA,SAAK,GAAG,KAAK,GAAG,MAAM;AACtB,SAAK,GAAG,KAAK,GAAG,MAAM;AACtB,YAAQ,KAAK,IAAI,GAAG,KAAK,GAAG,EAAE;AAC9B,aAAS,KAAK,IAAI,GAAG,KAAK,GAAG,EAAE;AAAA,EACjC;AAEA,QAAM,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,QAAQ,GAAG,QAAQ,QAAQ;AAC1E,QAAM,UAAU;AAEhB,MAAI,MAAM,UAAa,MAAM;AAAW,WAAO;AAE/C,MAAI,UAAU,QAAW;AACvB,QAAI,oBAAoB,IAAI;AAC1B,cAAQ,GAAG;AACX,eAAS,GAAG;AAAA,IACd;AAAA,EACF;AAEA,MAAI,UAAU,UAAa,WAAW,QAAW;AAC/C,YAAQ;AACR,aAAS;AAAA,EACX;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UACE,oBACE,WAAY,GAAW,QAAQ,KAAK,IAAI,oBAAoB,MAC9D,IAAI,CAAC,KAAK;AAAA,EACd;AACF;;;AC7KO,IAAM,WAAW,CAAI,UAAsC,QAAQ,KAAK;;;ACIxE,IAAM,sBAAsB,CACjC,aACwE;AACxE,QAAM,eAAe,SAClB,OAAO,CAAC,QAAQ,IAAI,KAAK,WAAW,MAAM,CAAC,EAC3C;AAAA,IACC,SACG,OAAO,CAAC,QAAQ,IAAI,SAAS,WAAW,EAExC,QAAQ,CAAC,QAAkB,IAAI,KAAK;AAAA,EACzC,EACC,IAAI,CAAC,QAAQ,qBAAqB,GAAG,CAAC,EACtC,OAAO,QAAQ;AAElB,MAAI,aAAa,WAAW;AAC1B,WAAO,EAAE,QAAQ,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,OAAO,GAAG,QAAQ,EAAE;AAEvD,MAAI,OAAO,aAAa,CAAC,EAAG,IAAI,aAAa,CAAC,EAAG,QAAQ;AACzD,MAAI,OAAO,aAAa,CAAC,EAAG,IAAI,aAAa,CAAC,EAAG,QAAQ;AACzD,MAAI,OAAO,aAAa,CAAC,EAAG,IAAI,aAAa,CAAC,EAAG,SAAS;AAC1D,MAAI,OAAO,aAAa,CAAC,EAAG,IAAI,aAAa,CAAC,EAAG,SAAS;AAE1D,aAAW,OAAO,aAAa,MAAM,CAAC,GAAG;AACvC,WAAO,KAAK,IAAI,MAAM,IAAI,IAAI,IAAI,QAAQ,CAAC;AAC3C,WAAO,KAAK,IAAI,MAAM,IAAI,IAAI,IAAI,QAAQ,CAAC;AAC3C,WAAO,KAAK,IAAI,MAAM,IAAI,IAAI,IAAI,SAAS,CAAC;AAC5C,WAAO,KAAK,IAAI,MAAM,IAAI,IAAI,IAAI,SAAS,CAAC;AAAA,EAC9C;AAEA,QAAM,QAAQ,OAAO;AACrB,QAAM,SAAS,OAAO;AACtB,QAAM,SAAS,EAAE,GAAG,OAAO,QAAQ,GAAG,GAAG,OAAO,SAAS,EAAE;AAE3D,SAAO,EAAE,QAAQ,OAAO,OAAO;AACjC;;;ACpCO,IAAM,eAAe,CAAC,YAAuC;AAElE,SAAO,QAAQ,GAAG,QAAQ,IAAI,KAAK;AACrC;","names":["su","Soup","joiner"]}
|
|
1
|
+
{"version":3,"sources":["../lib/cju.ts","../lib/cju-indexed.ts","../lib/transform-soup-elements.ts","../lib/direction-to-vec.ts","../lib/apply-selector.ts","../lib/convert-abbreviation-to-soup-element-type.ts","../lib/get-element-id.ts","../lib/get-element-by-id.ts","../lib/readable-name-functions/get-readable-name-for-pcb-trace.ts","../lib/readable-name-functions/get-readable-name-for-pcb-port.ts","../lib/readable-name-functions/get-readable-name-for-pcb-smtpad.ts","../lib/readable-name-functions/get-readable-name-for-element.ts","../lib/get-bounds-of-pcb-elements.ts","../lib/utils/string-hash.ts","../lib/utils/get-layout-debug-object.ts","../lib/utils/is-truthy.ts","../lib/find-bounds-and-center.ts","../lib/get-primary-id.ts"],"sourcesContent":["import type {\n AnyCircuitElement,\n AnyCircuitElementInput,\n SourceComponentBase,\n SourcePort,\n} from \"circuit-json\"\nimport * as Soup from \"circuit-json\"\n\nexport type CircuitJsonOps<\n K extends AnyCircuitElement[\"type\"],\n T extends AnyCircuitElement | AnyCircuitElementInput,\n> = {\n get: (id: string) => Extract<T, { type: K }> | null\n select: (selector: string) => Extract<T, { type: K }> | null\n getWhere: (where: any) => Extract<T, { type: K }> | null\n getUsing: (using: {\n [key: `${string}_id`]: string\n }) => Extract<T, { type: K }> | null\n insert: (\n elm: Omit<Extract<T, { type: K }>, \"type\" | `${K}_id`>,\n ) => Extract<T, { type: K }>\n update: (\n id: string,\n newProps: Partial<Extract<T, { type: K }>>,\n ) => Extract<T, { type: K }>\n delete: (id: string) => void\n list: (where?: any) => Extract<T, { type: K }>[]\n}\n\nexport type CircuitJsonUtilObjects = {\n [K in AnyCircuitElement[\"type\"]]: CircuitJsonOps<K, AnyCircuitElement>\n} & {\n toArray: () => AnyCircuitElement[]\n editCount: number\n}\nexport type CircuitJsonInputUtilObjects = {\n [K in AnyCircuitElementInput[\"type\"]]: CircuitJsonOps<\n K,\n AnyCircuitElementInput\n >\n}\n\nexport type CircuitJsonUtilOptions = {\n validateInserts?: boolean\n}\n\nexport type GetCircuitJsonUtilFn = ((\n soup: AnyCircuitElement[],\n options?: CircuitJsonUtilOptions,\n) => CircuitJsonUtilObjects) & {\n unparsed: (soup: AnyCircuitElementInput[]) => CircuitJsonInputUtilObjects\n}\n\ninterface InternalStore {\n counts: Record<string, number>\n editCount: number\n}\n\nexport const cju: GetCircuitJsonUtilFn = ((\n circuitJsonInput: any[],\n options: CircuitJsonUtilOptions = {},\n) => {\n const circuitJson = circuitJsonInput as AnyCircuitElement[]\n let internalStore: InternalStore = (circuitJson as any)._internal_store\n if (!internalStore) {\n internalStore = {\n counts: {},\n editCount: 0,\n } as InternalStore\n ;(circuitJson as any)._internal_store = internalStore\n\n // Initialize counts\n for (const elm of circuitJson) {\n const type = elm.type\n const idVal = (elm as any)[`${type}_id`]\n if (!idVal) continue\n const idNum = Number.parseInt(idVal.split(\"_\").pop())\n if (!Number.isNaN(idNum)) {\n internalStore.counts[type] = Math.max(\n internalStore.counts[type] ?? 0,\n idNum,\n )\n }\n }\n }\n const su = new Proxy(\n {},\n {\n get: (proxy_target: any, prop: string) => {\n if (prop === \"toArray\") {\n return () => {\n ;(circuitJson as any).editCount = internalStore.editCount\n return circuitJson\n }\n }\n if (prop === \"editCount\") {\n return internalStore.editCount\n }\n\n const component_type = prop\n\n return {\n get: (id: string) =>\n circuitJson.find(\n (e: any) =>\n e.type === component_type && e[`${component_type}_id`] === id,\n ),\n getUsing: (using: any) => {\n const keys = Object.keys(using)\n if (keys.length !== 1) {\n throw new Error(\n \"getUsing requires exactly one key, e.g. { pcb_component_id }\",\n )\n }\n const join_key = keys[0] as string\n const join_type = join_key.replace(\"_id\", \"\")\n const joiner: any = circuitJson.find(\n (e: any) =>\n e.type === join_type && e[join_key] === using[join_key],\n )\n if (!joiner) return null\n return circuitJson.find(\n (e: any) =>\n e.type === component_type &&\n e[`${component_type}_id`] === joiner[`${component_type}_id`],\n )\n },\n getWhere: (where: any) => {\n const keys = Object.keys(where)\n return circuitJson.find(\n (e: any) =>\n e.type === component_type &&\n keys.every((key) => e[key] === where[key]),\n )\n },\n list: (where?: any) => {\n const keys = !where ? [] : Object.keys(where)\n return circuitJson.filter(\n (e: any) =>\n e.type === component_type &&\n keys.every((key) => e[key] === where[key]),\n )\n },\n insert: (elm: any) => {\n internalStore.counts[component_type] ??= -1\n internalStore.counts[component_type]++\n const index = internalStore.counts[component_type]\n const newElm = {\n type: component_type,\n [`${component_type}_id`]: `${component_type}_${index}`,\n ...elm,\n }\n\n if (options.validateInserts) {\n const parser =\n (Soup as any)[component_type] ?? Soup.any_soup_element\n parser.parse(newElm)\n }\n\n circuitJson.push(newElm)\n internalStore.editCount++\n return newElm\n },\n delete: (id: string) => {\n const elm = circuitJson.find(\n (e) => (e as any)[`${component_type}_id`] === id,\n )\n if (!elm) return\n circuitJson.splice(circuitJson.indexOf(elm), 1)\n internalStore.editCount++\n },\n update: (id: string, newProps: any) => {\n const elm = circuitJson.find(\n (e) =>\n e.type === component_type &&\n (e as any)[`${component_type}_id`] === id,\n )\n if (!elm) return null\n Object.assign(elm, newProps)\n internalStore.editCount++\n return elm\n },\n select: (selector: string) => {\n // TODO when applySelector is isolated we can use it, until then we\n // do a poor man's selector implementation for two common cases\n if (component_type === \"source_component\") {\n return circuitJson.find(\n (e) =>\n e.type === \"source_component\" &&\n e.name === selector.replace(/\\./g, \"\"),\n )\n } else if (\n component_type === \"pcb_port\" ||\n component_type === \"source_port\" ||\n component_type === \"schematic_port\"\n ) {\n const [component_name, port_selector] = selector\n .replace(/\\./g, \"\")\n .split(/[\\s\\>]+/)\n const source_component = circuitJson.find(\n (e) =>\n e.type === \"source_component\" && e.name === component_name,\n ) as SourceComponentBase\n if (!source_component) return null\n const source_port = circuitJson.find(\n (e) =>\n e.type === \"source_port\" &&\n e.source_component_id ===\n source_component.source_component_id &&\n (e.name === port_selector ||\n (e.port_hints ?? []).includes(port_selector!)),\n ) as SourcePort\n if (!source_port) return null\n if (component_type === \"source_port\") return source_port\n\n if (component_type === \"pcb_port\") {\n return circuitJson.find(\n (e) =>\n e.type === \"pcb_port\" &&\n e.source_port_id === source_port.source_port_id,\n )\n } else if (component_type === \"schematic_port\") {\n return circuitJson.find(\n (e) =>\n e.type === \"schematic_port\" &&\n e.source_port_id === source_port.source_port_id,\n )\n }\n }\n },\n }\n },\n },\n )\n\n return su\n}) as any\ncju.unparsed = cju as any\n\nexport const su = cju\n\nexport default cju\n","import type {\n AnyCircuitElement,\n AnyCircuitElementInput,\n SourceComponentBase,\n SourcePort,\n} from \"circuit-json\"\nimport * as Soup from \"circuit-json\"\nimport type {\n CircuitJsonOps,\n CircuitJsonUtilObjects as CircuitJsonUtilObjects,\n CircuitJsonInputUtilObjects as CircuitJsonInputUtilObjects,\n} from \"./cju\"\n\nexport type IndexedCircuitJsonUtilOptions = {\n validateInserts?: boolean\n indexConfig?: {\n // Enable specific indexes for faster lookups\n byId?: boolean\n byType?: boolean\n byRelation?: boolean\n bySubcircuit?: boolean\n byCustomField?: string[]\n }\n}\n\nexport type GetIndexedCircuitJsonUtilFn = ((\n soup: AnyCircuitElement[],\n options?: IndexedCircuitJsonUtilOptions,\n) => CircuitJsonUtilObjects) & {\n unparsed: (soup: AnyCircuitElementInput[]) => CircuitJsonInputUtilObjects\n}\n\ninterface InternalStore {\n counts: Record<string, number>\n editCount: number\n // Indexes for faster lookups\n indexes: {\n byId?: Map<string, AnyCircuitElement>\n byType?: Map<string, AnyCircuitElement[]>\n // Maps relation fields (like component_id) to elements\n byRelation?: Map<string, Map<string, AnyCircuitElement[]>>\n // Maps subcircuit_id to elements\n bySubcircuit?: Map<string, AnyCircuitElement[]>\n // Custom field indexes\n byCustomField?: Map<string, Map<string, AnyCircuitElement[]>>\n }\n}\n\n// Creates a unique key for the ID index\nfunction createIdKey(element: AnyCircuitElement): string {\n const type = element.type\n return `${type}:${(element as any)[`${type}_id`]}`\n}\n\nexport const cjuIndexed: GetIndexedCircuitJsonUtilFn = ((\n soup: AnyCircuitElement[],\n options: IndexedCircuitJsonUtilOptions = {},\n) => {\n let internalStore: InternalStore = (soup as any)._internal_store_indexed\n\n if (!internalStore) {\n internalStore = {\n counts: {},\n editCount: 0,\n indexes: {},\n } as InternalStore\n\n // Initialize counts\n for (const elm of soup) {\n const type = elm.type\n const idVal = (elm as any)[`${type}_id`]\n if (!idVal) continue\n const idNum = Number.parseInt(idVal.split(\"_\").pop() || \"\")\n if (!Number.isNaN(idNum)) {\n internalStore.counts[type] = Math.max(\n internalStore.counts[type] ?? 0,\n idNum,\n )\n }\n }\n\n // Build indexes\n const indexConfig = options.indexConfig || {}\n const indexes = internalStore.indexes\n\n // Reset indexes before rebuilding\n if (indexConfig.byId) {\n indexes.byId = new Map()\n }\n\n if (indexConfig.byType) {\n indexes.byType = new Map()\n }\n\n if (indexConfig.byRelation) {\n indexes.byRelation = new Map()\n }\n\n if (indexConfig.bySubcircuit) {\n indexes.bySubcircuit = new Map()\n }\n\n if (indexConfig.byCustomField && indexConfig.byCustomField.length > 0) {\n indexes.byCustomField = new Map()\n for (const field of indexConfig.byCustomField) {\n indexes.byCustomField.set(field, new Map())\n }\n }\n\n // Build indexes\n for (const element of soup) {\n // Index by ID\n if (indexConfig.byId) {\n const idKey = createIdKey(element)\n indexes.byId!.set(idKey, element)\n }\n\n // Index by type\n if (indexConfig.byType) {\n const elementsOfType = indexes.byType!.get(element.type) || []\n elementsOfType.push(element)\n indexes.byType!.set(element.type, elementsOfType)\n }\n\n // Index by relation fields (fields ending with _id)\n if (indexConfig.byRelation) {\n const elementEntries = Object.entries(element)\n for (const [key, value] of elementEntries) {\n if (\n key.endsWith(\"_id\") &&\n key !== `${element.type}_id` &&\n typeof value === \"string\"\n ) {\n const relationTypeMap = indexes.byRelation!.get(key) || new Map()\n const relatedElements = relationTypeMap.get(value as string) || []\n relatedElements.push(element)\n relationTypeMap.set(value as string, relatedElements)\n indexes.byRelation!.set(key, relationTypeMap)\n }\n }\n }\n\n // Index by subcircuit_id\n if (indexConfig.bySubcircuit && \"subcircuit_id\" in element) {\n const subcircuitId = (element as any).subcircuit_id\n if (subcircuitId && typeof subcircuitId === \"string\") {\n const subcircuitElements =\n indexes.bySubcircuit!.get(subcircuitId) || []\n subcircuitElements.push(element)\n indexes.bySubcircuit!.set(subcircuitId, subcircuitElements)\n }\n }\n\n // Index by custom fields\n if (indexConfig.byCustomField && indexes.byCustomField) {\n for (const field of indexConfig.byCustomField) {\n if (field in element) {\n const fieldValue = (element as any)[field]\n if (\n fieldValue !== undefined &&\n (typeof fieldValue === \"string\" || typeof fieldValue === \"number\")\n ) {\n const fieldValueStr = String(fieldValue)\n const fieldMap = indexes.byCustomField.get(field)!\n const elementsWithFieldValue = fieldMap.get(fieldValueStr) || []\n elementsWithFieldValue.push(element)\n fieldMap.set(fieldValueStr, elementsWithFieldValue)\n }\n }\n }\n }\n }\n // Store internal state\n ;(soup as any)._internal_store_indexed = internalStore\n }\n\n const suIndexed = new Proxy(\n {},\n {\n get: (proxy_target: any, prop: string) => {\n if (prop === \"toArray\") {\n return () => {\n ;(soup as any).editCount = internalStore.editCount\n return soup\n }\n }\n if (prop === \"editCount\") {\n return internalStore.editCount\n }\n\n const component_type = prop\n\n return {\n get: (id: string) => {\n const indexConfig = options.indexConfig || {}\n\n // Use ID index if available\n if (indexConfig.byId && internalStore.indexes.byId) {\n return (\n (internalStore.indexes.byId.get(\n `${component_type}:${id}`,\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n }\n\n // Use type index if available\n if (indexConfig.byType && internalStore.indexes.byType) {\n const elementsOfType =\n internalStore.indexes.byType.get(component_type) || []\n return (\n (elementsOfType.find(\n (e: any) => e[`${component_type}_id`] === id,\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n }\n\n // Fallback to regular search\n return (\n (soup.find(\n (e: any) =>\n e.type === component_type && e[`${component_type}_id`] === id,\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n },\n\n getUsing: (using: any) => {\n const indexConfig = options.indexConfig || {}\n const keys = Object.keys(using)\n\n if (keys.length !== 1) {\n throw new Error(\n \"getUsing requires exactly one key, e.g. { pcb_component_id }\",\n )\n }\n\n const join_key = keys[0] as string\n const join_type = join_key.replace(\"_id\", \"\")\n\n // Use relation index if available\n if (indexConfig.byRelation && internalStore.indexes.byRelation) {\n const relationMap = internalStore.indexes.byRelation.get(join_key)\n if (relationMap) {\n const relatedElements = relationMap.get(using[join_key]) || []\n const joiner = relatedElements.find((e) => e.type === join_type)\n\n if (!joiner) return null\n\n // Now find the element of component_type with matching ID\n const joinerId =\n joiner[`${component_type}_id` as keyof typeof joiner]\n\n if (indexConfig.byId && internalStore.indexes.byId) {\n return (\n (internalStore.indexes.byId.get(\n `${component_type}:${joinerId}`,\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n }\n\n if (indexConfig.byType && internalStore.indexes.byType) {\n const elementsOfType =\n internalStore.indexes.byType.get(component_type) || []\n return (\n (elementsOfType.find(\n (e: any) => e[`${component_type}_id`] === joinerId,\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n }\n\n return (\n (soup.find(\n (e: any) =>\n e.type === component_type &&\n e[`${component_type}_id`] === joinerId,\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n }\n }\n\n // Fallback to regular approach\n const joiner: any = soup.find(\n (e: any) =>\n e.type === join_type && e[join_key] === using[join_key],\n )\n\n if (!joiner) return null\n\n return (\n (soup.find(\n (e: any) =>\n e.type === component_type &&\n e[`${component_type}_id`] === joiner[`${component_type}_id`],\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n },\n\n getWhere: (where: any) => {\n const indexConfig = options.indexConfig || {}\n const keys = Object.keys(where)\n\n // If we're looking by a single property and it's indexed as a custom field\n if (\n keys.length === 1 &&\n indexConfig.byCustomField &&\n internalStore.indexes.byCustomField\n ) {\n const field = keys[0]\n const fieldMap = internalStore.indexes.byCustomField.get(field!)\n\n if (fieldMap) {\n const fieldValue = String(where[field!])\n const elementsWithFieldValue = fieldMap.get(fieldValue) || []\n\n return (\n (elementsWithFieldValue.find(\n (e: any) => e.type === component_type,\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n }\n }\n\n // If we're looking by subcircuit_id and it's indexed\n if (\n \"subcircuit_id\" in where &&\n indexConfig.bySubcircuit &&\n internalStore.indexes.bySubcircuit\n ) {\n const subcircuitId = where.subcircuit_id\n const subcircuitElements =\n internalStore.indexes.bySubcircuit.get(subcircuitId) || []\n\n return (\n (subcircuitElements.find(\n (e: any) =>\n e.type === component_type &&\n keys.every((key) => e[key] === where[key]),\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n }\n\n // Use type index if available to reduce search space\n if (indexConfig.byType && internalStore.indexes.byType) {\n const elementsOfType =\n internalStore.indexes.byType.get(component_type) || []\n\n return (\n (elementsOfType.find((e: any) =>\n keys.every((key) => e[key] === where[key]),\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n }\n\n // Fallback to regular approach\n return (\n (soup.find(\n (e: any) =>\n e.type === component_type &&\n keys.every((key) => e[key] === where[key]),\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n },\n\n list: (where?: any) => {\n const indexConfig = options.indexConfig || {}\n const keys = !where ? [] : Object.keys(where)\n\n // If no filters, just return all elements of this type using the type index\n if (\n keys.length === 0 &&\n indexConfig.byType &&\n internalStore.indexes.byType\n ) {\n return (internalStore.indexes.byType.get(component_type) ||\n []) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >[]\n }\n\n // If filtering by subcircuit_id and it's the only filter\n if (\n keys.length === 1 &&\n keys[0] === \"subcircuit_id\" &&\n indexConfig.bySubcircuit &&\n internalStore.indexes.bySubcircuit\n ) {\n const subcircuitId = where.subcircuit_id\n const subcircuitElements =\n internalStore.indexes.bySubcircuit.get(subcircuitId) || []\n\n return subcircuitElements.filter(\n (e: any) => e.type === component_type,\n ) as Extract<AnyCircuitElement, { type: typeof component_type }>[]\n }\n\n // Start with all elements of this type to reduce search space\n let elementsToFilter: AnyCircuitElement[]\n\n if (indexConfig.byType && internalStore.indexes.byType) {\n elementsToFilter =\n internalStore.indexes.byType.get(component_type) || []\n } else {\n elementsToFilter = soup.filter((e) => e.type === component_type)\n }\n\n // Apply remaining filters\n if (keys.length > 0) {\n return elementsToFilter.filter((e: any) =>\n keys.every((key) => e[key] === where[key]),\n ) as Extract<AnyCircuitElement, { type: typeof component_type }>[]\n }\n\n return elementsToFilter as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >[]\n },\n\n insert: (elm: any) => {\n internalStore.counts[component_type] ??= -1\n internalStore.counts[component_type]++\n const index = internalStore.counts[component_type]\n const newElm = {\n type: component_type,\n [`${component_type}_id`]: `${component_type}_${index}`,\n ...elm,\n }\n\n if (options.validateInserts) {\n const parser =\n (Soup as any)[component_type] ?? Soup.any_soup_element\n parser.parse(newElm)\n }\n\n soup.push(newElm)\n internalStore.editCount++\n\n // Update indexes with the new element\n const indexConfig = options.indexConfig || {}\n\n // Update ID index\n if (indexConfig.byId && internalStore.indexes.byId) {\n const idKey = createIdKey(newElm)\n internalStore.indexes.byId.set(idKey, newElm)\n }\n\n // Update type index\n if (indexConfig.byType && internalStore.indexes.byType) {\n const elementsOfType =\n internalStore.indexes.byType.get(component_type) || []\n elementsOfType.push(newElm)\n internalStore.indexes.byType.set(component_type, elementsOfType)\n }\n\n // Update relation index\n if (indexConfig.byRelation && internalStore.indexes.byRelation) {\n const elementEntries = Object.entries(newElm)\n for (const [key, value] of elementEntries) {\n if (\n key.endsWith(\"_id\") &&\n key !== `${newElm.type}_id` &&\n typeof value === \"string\"\n ) {\n const relationTypeMap =\n internalStore.indexes.byRelation.get(key) || new Map()\n const relatedElements =\n relationTypeMap.get(value as string) || []\n relatedElements.push(newElm)\n relationTypeMap.set(value as string, relatedElements)\n internalStore.indexes.byRelation.set(key, relationTypeMap)\n }\n }\n }\n\n // Update subcircuit index\n if (\n indexConfig.bySubcircuit &&\n internalStore.indexes.bySubcircuit &&\n \"subcircuit_id\" in newElm\n ) {\n const subcircuitId = (newElm as any).subcircuit_id\n if (subcircuitId && typeof subcircuitId === \"string\") {\n const subcircuitElements =\n internalStore.indexes.bySubcircuit.get(subcircuitId) || []\n subcircuitElements.push(newElm)\n internalStore.indexes.bySubcircuit.set(\n subcircuitId,\n subcircuitElements,\n )\n }\n }\n\n // Update custom field indexes\n if (\n indexConfig.byCustomField &&\n internalStore.indexes.byCustomField\n ) {\n for (const field of indexConfig.byCustomField) {\n if (field in newElm) {\n const fieldValue = (newElm as any)[field]\n if (\n fieldValue !== undefined &&\n (typeof fieldValue === \"string\" ||\n typeof fieldValue === \"number\")\n ) {\n const fieldValueStr = String(fieldValue)\n const fieldMap =\n internalStore.indexes.byCustomField.get(field)!\n const elementsWithFieldValue =\n fieldMap.get(fieldValueStr) || []\n elementsWithFieldValue.push(newElm)\n fieldMap.set(fieldValueStr, elementsWithFieldValue)\n }\n }\n }\n }\n\n return newElm\n },\n\n delete: (id: string) => {\n const indexConfig = options.indexConfig || {}\n let elm: AnyCircuitElement | undefined\n\n // Find the element to delete\n if (indexConfig.byId && internalStore.indexes.byId) {\n elm = internalStore.indexes.byId.get(`${component_type}:${id}`)\n } else if (indexConfig.byType && internalStore.indexes.byType) {\n const elementsOfType =\n internalStore.indexes.byType.get(component_type) || []\n elm = elementsOfType.find(\n (e: any) => e[`${component_type}_id`] === id,\n )\n } else {\n elm = soup.find((e) => (e as any)[`${component_type}_id`] === id)\n }\n\n if (!elm) return\n\n // Remove from array\n const elmIndex = soup.indexOf(elm)\n if (elmIndex >= 0) {\n soup.splice(elmIndex, 1)\n internalStore.editCount++\n }\n\n // Remove from indexes\n if (indexConfig.byId && internalStore.indexes.byId) {\n const idKey = createIdKey(elm)\n internalStore.indexes.byId.delete(idKey)\n }\n\n if (indexConfig.byType && internalStore.indexes.byType) {\n const elementsOfType =\n internalStore.indexes.byType.get(component_type) || []\n const filteredElements = elementsOfType.filter(\n (e: any) => e[`${component_type}_id`] !== id,\n )\n internalStore.indexes.byType.set(component_type, filteredElements)\n }\n\n if (indexConfig.byRelation && internalStore.indexes.byRelation) {\n // This is more complex - we need to find and remove from all relation maps\n // where this element appears\n for (const [\n relationKey,\n relationMap,\n ] of internalStore.indexes.byRelation.entries()) {\n for (const [relationValue, elements] of relationMap.entries()) {\n const updatedElements = elements.filter((e) => e !== elm)\n\n if (updatedElements.length === 0) {\n relationMap.delete(relationValue)\n } else {\n relationMap.set(relationValue, updatedElements)\n }\n }\n }\n }\n\n if (\n indexConfig.bySubcircuit &&\n internalStore.indexes.bySubcircuit &&\n \"subcircuit_id\" in elm\n ) {\n const subcircuitId = (elm as any).subcircuit_id\n if (subcircuitId) {\n const subcircuitElements =\n internalStore.indexes.bySubcircuit.get(subcircuitId) || []\n const updatedElements = subcircuitElements.filter(\n (e) => e !== elm,\n )\n\n if (updatedElements.length === 0) {\n internalStore.indexes.bySubcircuit.delete(subcircuitId)\n } else {\n internalStore.indexes.bySubcircuit.set(\n subcircuitId,\n updatedElements,\n )\n }\n }\n }\n\n if (\n indexConfig.byCustomField &&\n internalStore.indexes.byCustomField\n ) {\n for (const fieldMap of internalStore.indexes.byCustomField.values()) {\n for (const [fieldValue, elements] of fieldMap.entries()) {\n const updatedElements = elements.filter((e) => e !== elm)\n\n if (updatedElements.length === 0) {\n fieldMap.delete(fieldValue)\n } else {\n fieldMap.set(fieldValue, updatedElements)\n }\n }\n }\n }\n },\n\n update: (id: string, newProps: any) => {\n const indexConfig = options.indexConfig || {}\n let elm: AnyCircuitElement | undefined | null\n\n // Find the element to update\n if (indexConfig.byId && internalStore.indexes.byId) {\n elm = internalStore.indexes.byId.get(`${component_type}:${id}`)\n } else if (indexConfig.byType && internalStore.indexes.byType) {\n const elementsOfType =\n internalStore.indexes.byType.get(component_type) || []\n elm = elementsOfType.find(\n (e: any) => e[`${component_type}_id`] === id,\n )\n } else {\n elm = soup.find(\n (e) =>\n e.type === component_type &&\n (e as any)[`${component_type}_id`] === id,\n )\n }\n\n if (!elm) return null\n\n // Need to remove from indexes before updating\n if (indexConfig.byRelation && internalStore.indexes.byRelation) {\n // Remove from relation indexes\n const elementEntries = Object.entries(elm)\n for (const [key, value] of elementEntries) {\n if (\n key.endsWith(\"_id\") &&\n key !== `${elm.type}_id` &&\n typeof value === \"string\"\n ) {\n if (key in newProps && newProps[key] !== value) {\n const relationTypeMap =\n internalStore.indexes.byRelation.get(key)\n if (relationTypeMap) {\n const relatedElements =\n relationTypeMap.get(value as string) || []\n const updatedElements = relatedElements.filter(\n (e) => e !== elm,\n )\n\n if (updatedElements.length === 0) {\n relationTypeMap.delete(value as string)\n } else {\n relationTypeMap.set(value as string, updatedElements)\n }\n }\n }\n }\n }\n }\n\n if (\n indexConfig.bySubcircuit &&\n internalStore.indexes.bySubcircuit &&\n \"subcircuit_id\" in elm &&\n \"subcircuit_id\" in newProps\n ) {\n const oldSubcircuitId = (elm as any).subcircuit_id\n const newSubcircuitId = newProps.subcircuit_id\n\n if (oldSubcircuitId !== newSubcircuitId) {\n // Remove from old subcircuit index\n const subcircuitElements =\n internalStore.indexes.bySubcircuit.get(oldSubcircuitId) || []\n const updatedElements = subcircuitElements.filter(\n (e) => e !== elm,\n )\n\n if (updatedElements.length === 0) {\n internalStore.indexes.bySubcircuit.delete(oldSubcircuitId)\n } else {\n internalStore.indexes.bySubcircuit.set(\n oldSubcircuitId,\n updatedElements,\n )\n }\n }\n }\n\n if (\n indexConfig.byCustomField &&\n internalStore.indexes.byCustomField\n ) {\n for (const field of indexConfig.byCustomField) {\n if (\n field in elm &&\n field in newProps &&\n (elm as any)[field] !== newProps[field]\n ) {\n const fieldMap =\n internalStore.indexes.byCustomField.get(field)\n if (fieldMap) {\n const oldValue = String((elm as any)[field])\n const elements = fieldMap.get(oldValue) || []\n const updatedElements = elements.filter((e) => e !== elm)\n\n if (updatedElements.length === 0) {\n fieldMap.delete(oldValue)\n } else {\n fieldMap.set(oldValue, updatedElements)\n }\n }\n }\n }\n }\n\n // Update the element\n Object.assign(elm, newProps)\n internalStore.editCount++\n\n // Add to indexes with updated values\n if (indexConfig.byRelation && internalStore.indexes.byRelation) {\n const elementEntries = Object.entries(elm)\n for (const [key, value] of elementEntries) {\n if (\n key.endsWith(\"_id\") &&\n key !== `${elm.type}_id` &&\n typeof value === \"string\"\n ) {\n if (key in newProps) {\n const relationTypeMap: any =\n internalStore.indexes.byRelation.get(key) || new Map()\n const relatedElements: any =\n relationTypeMap.get(value as string) || []\n\n if (!relatedElements.includes(elm)) {\n relatedElements.push(elm)\n relationTypeMap.set(value as string, relatedElements)\n internalStore.indexes.byRelation.set(key, relationTypeMap)\n }\n }\n }\n }\n }\n\n if (\n indexConfig.bySubcircuit &&\n internalStore.indexes.bySubcircuit &&\n \"subcircuit_id\" in elm &&\n \"subcircuit_id\" in newProps\n ) {\n const subcircuitId = (elm as any).subcircuit_id\n if (subcircuitId && typeof subcircuitId === \"string\") {\n const subcircuitElements =\n internalStore.indexes.bySubcircuit.get(subcircuitId) || []\n\n if (!subcircuitElements.includes(elm)) {\n subcircuitElements.push(elm)\n internalStore.indexes.bySubcircuit.set(\n subcircuitId,\n subcircuitElements,\n )\n }\n }\n }\n\n if (\n indexConfig.byCustomField &&\n internalStore.indexes.byCustomField\n ) {\n for (const field of indexConfig.byCustomField) {\n if (field in elm && field in newProps) {\n const fieldValue: any = (elm as any)[field]\n if (\n fieldValue !== undefined &&\n (typeof fieldValue === \"string\" ||\n typeof fieldValue === \"number\")\n ) {\n const fieldValueStr = String(fieldValue)\n const fieldMap =\n internalStore.indexes.byCustomField.get(field)!\n const elementsWithFieldValue =\n fieldMap.get(fieldValueStr) || []\n\n if (!elementsWithFieldValue.includes(elm)) {\n elementsWithFieldValue.push(elm)\n fieldMap.set(fieldValueStr, elementsWithFieldValue)\n }\n }\n }\n }\n }\n\n return elm as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >\n },\n\n select: (selector: string) => {\n // Selection by selector is specialized enough that we don't use indexes here\n // TODO when applySelector is isolated we can use it, until then we\n // do a poor man's selector implementation for two common cases\n if (component_type === \"source_component\") {\n return (\n (soup.find(\n (e) =>\n e.type === \"source_component\" &&\n e.name === selector.replace(/\\./g, \"\"),\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n } else if (\n component_type === \"pcb_port\" ||\n component_type === \"source_port\" ||\n component_type === \"schematic_port\"\n ) {\n const [component_name, port_selector] = selector\n .replace(/\\./g, \"\")\n .split(/[\\s\\>]+/)\n const source_component = soup.find(\n (e) =>\n e.type === \"source_component\" && e.name === component_name,\n ) as SourceComponentBase\n if (!source_component) return null\n const source_port = soup.find(\n (e) =>\n e.type === \"source_port\" &&\n e.source_component_id ===\n source_component.source_component_id &&\n (e.name === port_selector ||\n (e.port_hints ?? []).includes(port_selector!)),\n ) as SourcePort\n if (!source_port) return null\n if (component_type === \"source_port\")\n return source_port as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >\n\n if (component_type === \"pcb_port\") {\n return (\n (soup.find(\n (e) =>\n e.type === \"pcb_port\" &&\n e.source_port_id === source_port.source_port_id,\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n } else if (component_type === \"schematic_port\") {\n return (\n (soup.find(\n (e) =>\n e.type === \"schematic_port\" &&\n e.source_port_id === source_port.source_port_id,\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n }\n }\n\n return null\n },\n }\n },\n },\n )\n\n return suIndexed\n}) as any\n\ncjuIndexed.unparsed = cjuIndexed as any\n\nexport default cjuIndexed\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { type Matrix, applyToPoint, decomposeTSR } from \"transformation-matrix\"\nimport {\n directionToVec,\n rotateDirection,\n vecToDirection,\n} from \"./direction-to-vec\"\n\nexport const transformSchematicElement = (\n elm: AnyCircuitElement,\n matrix: Matrix,\n) => {\n if (elm.type === \"schematic_component\") {\n // TODO handle rotation\n elm.center = applyToPoint(matrix, elm.center)\n } else if (elm.type === \"schematic_port\") {\n elm.center = applyToPoint(matrix, elm.center)\n\n if (elm.facing_direction) {\n elm.facing_direction = rotateDirection(\n elm.facing_direction,\n -(Math.atan2(matrix.b, matrix.a) / Math.PI) * 2,\n )\n }\n } else if (elm.type === \"schematic_text\") {\n elm.position = applyToPoint(matrix, elm.position)\n // } else if (elm.type === \"schematic_group\") {\n // elm.center = applyToPoint(matrix, elm.center)\n } else if (elm.type === \"schematic_trace\") {\n } else if (elm.type === \"schematic_box\") {\n const { x, y } = applyToPoint(matrix, { x: elm.x, y: elm.y })\n elm.x = x\n elm.y = y\n } else if (elm.type === \"schematic_line\") {\n const { x: x1, y: y1 } = applyToPoint(matrix, { x: elm.x1, y: elm.y1 })\n const { x: x2, y: y2 } = applyToPoint(matrix, { x: elm.x2, y: elm.y2 })\n elm.x1 = x1\n elm.y1 = y1\n elm.x2 = x2\n elm.y2 = y2\n }\n return elm\n}\n\nexport const transformSchematicElements = (\n elms: AnyCircuitElement[],\n matrix: Matrix,\n) => {\n return elms.map((elm) => transformSchematicElement(elm, matrix))\n}\n\nexport const transformPCBElement = (elm: AnyCircuitElement, matrix: Matrix) => {\n if (\n elm.type === \"pcb_plated_hole\" ||\n elm.type === \"pcb_hole\" ||\n elm.type === \"pcb_via\" ||\n elm.type === \"pcb_smtpad\" ||\n elm.type === \"pcb_port\"\n ) {\n const { x, y } = applyToPoint(matrix, { x: elm.x, y: elm.y })\n elm.x = x\n elm.y = y\n } else if (elm.type === \"pcb_keepout\" || elm.type === \"pcb_board\") {\n // TODO adjust size/rotation\n elm.center = applyToPoint(matrix, elm.center)\n } else if (\n elm.type === \"pcb_silkscreen_text\" ||\n elm.type === \"pcb_fabrication_note_text\"\n ) {\n elm.anchor_position = applyToPoint(matrix, elm.anchor_position)\n } else if (\n elm.type === \"pcb_silkscreen_circle\" ||\n elm.type === \"pcb_silkscreen_rect\" ||\n elm.type === \"pcb_component\"\n ) {\n elm.center = applyToPoint(matrix, elm.center)\n } else if (\n elm.type === \"pcb_silkscreen_path\" ||\n elm.type === \"pcb_trace\" ||\n elm.type === \"pcb_fabrication_note_path\"\n ) {\n elm.route = elm.route.map((rp) => {\n const tp = applyToPoint(matrix, rp) as { x: number; y: number }\n rp.x = tp.x\n rp.y = tp.y\n return rp\n })\n } else if (elm.type === \"pcb_silkscreen_line\") {\n const p1 = { x: elm.x1, y: elm.y1 }\n const p2 = { x: elm.x2, y: elm.y2 }\n const p1t = applyToPoint(matrix, p1)\n const p2t = applyToPoint(matrix, p2)\n elm.x1 = p1t.x\n elm.y1 = p1t.y\n elm.x2 = p2t.x\n elm.y2 = p2t.y\n } else if (elm.type === \"cad_component\") {\n const newPos = applyToPoint(matrix, {\n x: elm.position.x,\n y: elm.position.y,\n })\n elm.position.x = newPos.x\n elm.position.y = newPos.y\n }\n return elm\n}\n\nexport const transformPCBElements = (\n elms: AnyCircuitElement[],\n matrix: Matrix,\n) => {\n const tsr = decomposeTSR(matrix)\n const flipPadWidthHeight =\n Math.round(tsr.rotation.angle / (Math.PI / 2)) % 2 === 1\n let transformedElms = elms.map((elm) => transformPCBElement(elm, matrix))\n if (flipPadWidthHeight) {\n transformedElms = transformedElms.map((elm) => {\n if (elm.type === \"pcb_smtpad\" && elm.shape === \"rect\") {\n ;[elm.width, elm.height] = [elm.height, elm.width]\n }\n return elm\n })\n }\n return transformedElms\n}\n","export const directionToVec = (direction: \"up\" | \"down\" | \"left\" | \"right\") => {\n if (direction === \"up\") return { x: 0, y: 1 }\n else if (direction === \"down\") return { x: 0, y: -1 }\n else if (direction === \"left\") return { x: -1, y: 0 }\n else if (direction === \"right\") return { x: 1, y: 0 }\n else throw new Error(\"Invalid direction\")\n}\n\nexport const vecToDirection = ({ x, y }: { x: number; y: number }) => {\n if (x > y) y = 0\n if (y > x) x = 0\n if (x > 0 && y === 0) return \"right\"\n else if (x < 0 && y === 0) return \"left\"\n else if (x === 0 && y > 0) return \"up\"\n else if (x === 0 && y < 0) return \"down\"\n else throw new Error(`Invalid vector for direction conversion (${x}, ${y})`)\n}\n\nexport const rotateClockwise = (\n direction: \"up\" | \"down\" | \"left\" | \"right\"\n) => {\n if (direction === \"up\") return \"right\"\n else if (direction === \"right\") return \"down\"\n else if (direction === \"down\") return \"left\"\n else if (direction === \"left\") return \"up\"\n throw new Error(`Invalid direction: ${direction}`)\n}\n\nexport const rotateCounterClockwise = (\n direction: \"up\" | \"down\" | \"left\" | \"right\"\n) => {\n if (direction === \"up\") return \"left\"\n else if (direction === \"left\") return \"down\"\n else if (direction === \"down\") return \"right\"\n else if (direction === \"right\") return \"up\"\n throw new Error(`Invalid direction: ${direction}`)\n}\n\nexport const rotateDirection = (\n direction: \"up\" | \"down\" | \"left\" | \"right\",\n num90DegreeClockwiseTurns: number\n) => {\n while (num90DegreeClockwiseTurns > 0) {\n direction = rotateClockwise(direction)\n num90DegreeClockwiseTurns--\n }\n while (num90DegreeClockwiseTurns < 0) {\n direction = rotateCounterClockwise(direction)\n num90DegreeClockwiseTurns++\n }\n return direction\n}\n\nexport const oppositeDirection = (\n direction: \"up\" | \"down\" | \"left\" | \"right\"\n) => {\n if (direction === \"up\") return \"down\"\n else if (direction === \"down\") return \"up\"\n else if (direction === \"left\") return \"right\"\n else if (direction === \"right\") return \"left\"\n throw new Error(`Invalid direction: ${direction}`)\n}\n\nexport const oppositeSide = (\n sideOrDir: \"up\" | \"down\" | \"top\" | \"bottom\" | \"left\" | \"right\"\n) => {\n if (sideOrDir === \"top\" || sideOrDir === \"up\") return \"bottom\"\n else if (sideOrDir === \"bottom\" || sideOrDir === \"down\") return \"top\"\n else if (sideOrDir === \"left\") return \"right\"\n else if (sideOrDir === \"right\") return \"left\"\n throw new Error(`Invalid sideOrDir: ${sideOrDir}`)\n}\n","import * as parsel from \"parsel-js\"\nimport { convertAbbrToType } from \"./convert-abbreviation-to-soup-element-type\"\nimport type { AnyCircuitElement } from \"circuit-json\"\n\nconst filterByType = (\n elements: AnyCircuitElement[],\n type: string\n): AnyCircuitElement[] => {\n type = convertAbbrToType(type)\n return elements.filter(\n (elm) => (\"ftype\" in elm && elm.ftype === type) || elm.type === type\n )\n}\n\n/**\n * Filter elements to match the selector, e.g. to access the left port of a\n * resistor you can do \".R1 > port.left\"\n */\nexport const applySelector = (\n elements: AnyCircuitElement[],\n selectorRaw: string\n): AnyCircuitElement[] => {\n const selectorAST = parsel.parse(selectorRaw)\n return applySelectorAST(elements, selectorAST!)\n}\n\nconst doesElmMatchClassName = (elm: AnyCircuitElement, className: string) =>\n (\"name\" in elm && elm.name === className) ||\n (\"port_hints\" in elm && elm.port_hints?.includes(className))\n\nexport const applySelectorAST = (\n elements: AnyCircuitElement[],\n selectorAST: parsel.AST\n): AnyCircuitElement[] => {\n switch (selectorAST.type) {\n case \"complex\": {\n switch (selectorAST.combinator) {\n case \" \": // TODO technically should do a deep search\n case \">\": {\n const { left, right } = selectorAST\n if (left.type === \"class\" || left.type === \"type\") {\n // TODO should also check if content matches any element tags\n let matchElms: AnyCircuitElement[]\n if (left.type === \"class\") {\n matchElms = elements.filter((elm) =>\n doesElmMatchClassName(elm, left.name)\n )\n } else if (left.type === \"type\") {\n matchElms = filterByType(elements, left.name)\n } else {\n matchElms = []\n }\n\n const childrenOfMatchingElms = matchElms.flatMap((matchElm) =>\n elements.filter(\n (elm: any) =>\n elm[`${matchElm.type}_id`] ===\n (matchElm as any)[`${matchElm.type}_id`] && elm !== matchElm\n )\n )\n return applySelectorAST(childrenOfMatchingElms, right)\n } else {\n throw new Error(`unsupported selector type \"${left.type}\" `)\n }\n }\n default: {\n throw new Error(\n `Couldn't apply selector AST for complex combinator \"${selectorAST.combinator}\"`\n )\n }\n }\n return []\n }\n case \"compound\": {\n const conditionsToMatch = selectorAST.list.map((part) => {\n switch (part.type) {\n case \"class\": {\n return (elm: any) => doesElmMatchClassName(elm, part.name)\n }\n case \"type\": {\n const name = convertAbbrToType(part.name)\n return (elm: any) => elm.type === name\n }\n }\n })\n\n return elements.filter((elm) =>\n conditionsToMatch.every((condFn) => condFn?.(elm))\n )\n }\n case \"type\": {\n return filterByType(elements, selectorAST.name) as AnyCircuitElement[]\n }\n case \"class\": {\n return elements.filter((elm) =>\n doesElmMatchClassName(elm, selectorAST.name)\n )\n }\n default: {\n throw new Error(\n `Couldn't apply selector AST for type: \"${\n selectorAST.type\n }\" ${JSON.stringify(selectorAST, null, \" \")}`\n )\n }\n }\n}\n","export const convertAbbrToType = (abbr: string): string => {\n switch (abbr) {\n case \"port\":\n return \"source_port\"\n case \"net\":\n return \"source_net\"\n case \"power\":\n return \"simple_power_source\"\n }\n return abbr\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\n\nexport const getElementId = (elm: AnyCircuitElement): string => {\n const type = elm.type\n const id = (elm as any)[`${type}_id`]\n return id\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { getElementId } from \"./get-element-id\"\n\nexport const getElementById = (\n soup: AnyCircuitElement[],\n id: string,\n): AnyCircuitElement | null => {\n return soup.find((elm) => getElementId(elm) === id) ?? null\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { cju } from \"../cju\"\n\nexport function getReadableNameForPcbTrace(\n soup: AnyCircuitElement[],\n pcb_trace_id: string,\n) {\n // Find the pcb_trace object\n const pcbTrace = cju(soup).pcb_trace.get(pcb_trace_id)\n\n if (!pcbTrace) {\n return `trace[${pcb_trace_id}]`\n }\n\n // Get the connected ports\n const connectedPcbPortIds: string[] = pcbTrace.route\n .flatMap((point: any) => [point.start_pcb_port_id, point.end_pcb_port_id])\n .filter(Boolean)\n\n if (connectedPcbPortIds.length === 0) {\n return `trace[${pcb_trace_id}]`\n }\n\n // Function to get component name and port hint\n function getComponentAndPortInfo(pcb_port_id: string) {\n const pcbPort = cju(soup).pcb_port.get(pcb_port_id)\n if (!pcbPort) return null\n\n const pcbComponent = cju(soup).pcb_component.get(pcbPort.pcb_component_id)\n if (!pcbComponent) return null\n const sourceComponent = cju(soup).source_component.get(\n pcbComponent.source_component_id,\n )\n if (!sourceComponent) return null\n\n const sourcePort = cju(soup).source_port.get(pcbPort.source_port_id)\n const portHint = sourcePort?.port_hints ? sourcePort.port_hints[1] : \"\"\n\n return {\n componentName: sourceComponent.name,\n portHint: portHint,\n }\n }\n\n // Generate the readable selector\n const selectorParts = connectedPcbPortIds.map((portId) => {\n const info = getComponentAndPortInfo(portId)\n if (info) {\n return `.${info.componentName} > port.${info.portHint}`\n }\n return `port[${portId}]`\n })\n\n return `trace[${selectorParts.join(\", \")}]`\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { cju } from \"../cju\"\n\nexport const getReadableNameForPcbPort = (\n soup: AnyCircuitElement[],\n pcb_port_id: string,\n): string => {\n const pcbPort = cju(soup).pcb_port.get(pcb_port_id)\n if (!pcbPort) {\n return `pcb_port[#${pcb_port_id}]`\n }\n\n // Get the component information\n const pcbComponent = cju(soup).pcb_component.get(pcbPort?.pcb_component_id)\n\n if (!pcbComponent) {\n return `pcb_port[#${pcb_port_id}]`\n }\n\n // Get the source component information\n const sourceComponent = cju(soup).source_component.get(\n pcbComponent.source_component_id,\n )\n\n if (!sourceComponent) {\n return `pcb_port[#${pcb_port_id}]`\n }\n\n // Get the source port information\n const sourcePort = cju(soup).source_port.get(pcbPort.source_port_id)\n\n if (!sourcePort) {\n return `pcb_port[#${pcb_port_id}]`\n }\n\n // Determine the pad number or hint\n let padIdentifier: string\n if (sourcePort?.port_hints && sourcePort.port_hints.length > 0) {\n padIdentifier = sourcePort.port_hints[0]!\n } else if (sourcePort.port_hints && sourcePort.port_hints.length > 0) {\n padIdentifier = sourcePort.port_hints[0]!\n } else {\n padIdentifier = pcb_port_id\n }\n\n return `pcb_port[.${sourceComponent.name} > .${padIdentifier}]`\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { cju } from \"../cju\"\nimport { getReadableNameForPcbPort } from \"./get-readable-name-for-pcb-port\"\n\nexport function getReadableNameForPcbSmtpad(\n soup: AnyCircuitElement[],\n pcb_smtpad_id: string,\n): string {\n // Find the pcb_smtpad object\n const pcbSmtpad = cju(soup).pcb_smtpad.get(pcb_smtpad_id)\n\n if (!pcbSmtpad || !pcbSmtpad.pcb_port_id) {\n return `smtpad[${pcb_smtpad_id}]`\n }\n\n return getReadableNameForPcbPort(soup, pcbSmtpad.pcb_port_id)\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { getReadableNameForPcbTrace } from \"./get-readable-name-for-pcb-trace\"\nimport { getReadableNameForPcbSmtpad } from \"./get-readable-name-for-pcb-smtpad\"\nimport { getReadableNameForPcbPort } from \"./get-readable-name-for-pcb-port\"\nimport { getElementById } from \"lib/get-element-by-id\"\nimport { getElementId } from \"lib/get-element-id\"\n\nexport const getReadableNameForElement = (\n soup: AnyCircuitElement[],\n elm: AnyCircuitElement | string,\n): string => {\n if (typeof elm === \"string\") {\n const elmObj = getElementById(soup, elm)\n if (!elmObj) `unknown (could not find element with id ${elm})`\n return getReadableNameForElement(soup, elmObj as any)\n }\n switch (elm.type) {\n case \"pcb_port\":\n return getReadableNameForPcbPort(soup, elm.pcb_port_id)\n case \"pcb_smtpad\":\n return getReadableNameForPcbSmtpad(soup, elm.pcb_smtpad_id)\n case \"pcb_trace\":\n return getReadableNameForPcbTrace(soup, elm.pcb_trace_id)\n case \"source_component\":\n return `source_component[${elm.name}]`\n default:\n return `${elm.type}[#${getElementId(elm)}]`\n }\n}\n\nexport {\n getReadableNameForPcbPort,\n getReadableNameForPcbSmtpad,\n getReadableNameForPcbTrace,\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\n\nexport const getBoundsOfPcbElements = (\n elements: AnyCircuitElement[],\n): { minX: number; minY: number; maxX: number; maxY: number } => {\n let minX = Number.POSITIVE_INFINITY\n let minY = Number.POSITIVE_INFINITY\n let maxX = Number.NEGATIVE_INFINITY\n let maxY = Number.NEGATIVE_INFINITY\n\n for (const elm of elements) {\n if (!elm.type.startsWith(\"pcb_\")) continue\n\n let centerX: number | undefined\n let centerY: number | undefined\n\n let width: number | undefined\n let height: number | undefined\n\n if (\"x\" in elm && \"y\" in elm) {\n centerX = elm.x\n centerY = elm.y\n }\n\n if (\"outer_diameter\" in elm) {\n width = elm.outer_diameter\n height = elm.outer_diameter\n }\n\n if (\"width\" in elm) {\n width = elm.width\n }\n\n if (\"height\" in elm) {\n height = elm.height\n }\n\n if (\"center\" in elm) {\n // @ts-ignore\n centerX = elm.center.x\n // @ts-ignore\n centerY = elm.center.y\n }\n\n if (centerX !== undefined && centerY !== undefined) {\n minX = Math.min(minX, centerX)\n minY = Math.min(minY, centerY)\n maxX = Math.max(maxX, centerX)\n maxY = Math.max(maxY, centerY)\n\n if (width !== undefined && height !== undefined) {\n minX = Math.min(minX, centerX - width / 2)\n minY = Math.min(minY, centerY - height / 2)\n maxX = Math.max(maxX, centerX + width / 2)\n maxY = Math.max(maxY, centerY + height / 2)\n }\n\n if (\"radius\" in elm) {\n minX = Math.min(minX, centerX - elm.radius)\n minY = Math.min(minY, centerY - elm.radius)\n maxX = Math.max(maxX, centerX + elm.radius)\n maxY = Math.max(maxY, centerY + elm.radius)\n }\n } else if (elm.type === \"pcb_trace\") {\n for (const point of elm.route) {\n // TODO add trace thickness support\n minX = Math.min(minX, point.x)\n minY = Math.min(minY, point.y)\n maxX = Math.max(maxX, point.x)\n maxY = Math.max(maxY, point.y)\n }\n }\n }\n\n return { minX, minY, maxX, maxY }\n}\n","export function stringHash(str: string) {\n let hash = 0\n if (str.length == 0) return hash\n for (var i = 0; i < str.length; i++) {\n var char = str.charCodeAt(i)\n hash = (hash << 5) - hash + char\n hash = hash & hash // Convert to 32bit integer\n }\n return Math.abs(hash)\n}\n","import { stringHash } from \"./string-hash\"\n\nexport type LayoutDebugObject = {\n x: number\n y: number\n width: number\n height: number\n bg_color: string\n title: string\n content: Object\n secondary?: boolean\n}\n\n/**\n * Vendored from \"nice-color-palettes\" package\n */\nconst nice_color_palettes = [\n [\"#69d2e7\", \"#a7dbd8\", \"#e0e4cc\", \"#f38630\", \"#fa6900\"],\n [\"#fe4365\", \"#fc9d9a\", \"#f9cdad\", \"#c8c8a9\", \"#83af9b\"],\n [\"#ecd078\", \"#d95b43\", \"#c02942\", \"#542437\", \"#53777a\"],\n [\"#556270\", \"#4ecdc4\", \"#c7f464\", \"#ff6b6b\", \"#c44d58\"],\n [\"#774f38\", \"#e08e79\", \"#f1d4af\", \"#ece5ce\", \"#c5e0dc\"],\n [\"#e8ddcb\", \"#cdb380\", \"#036564\", \"#033649\", \"#031634\"],\n [\"#490a3d\", \"#bd1550\", \"#e97f02\", \"#f8ca00\", \"#8a9b0f\"],\n [\"#594f4f\", \"#547980\", \"#45ada8\", \"#9de0ad\", \"#e5fcc2\"],\n [\"#00a0b0\", \"#6a4a3c\", \"#cc333f\", \"#eb6841\", \"#edc951\"],\n [\"#e94e77\", \"#d68189\", \"#c6a49a\", \"#c6e5d9\", \"#f4ead5\"],\n [\"#3fb8af\", \"#7fc7af\", \"#dad8a7\", \"#ff9e9d\", \"#ff3d7f\"],\n [\"#d9ceb2\", \"#948c75\", \"#d5ded9\", \"#7a6a53\", \"#99b2b7\"],\n [\"#ffffff\", \"#cbe86b\", \"#f2e9e1\", \"#1c140d\", \"#cbe86b\"],\n [\"#efffcd\", \"#dce9be\", \"#555152\", \"#2e2633\", \"#99173c\"],\n [\"#343838\", \"#005f6b\", \"#008c9e\", \"#00b4cc\", \"#00dffc\"],\n [\"#413e4a\", \"#73626e\", \"#b38184\", \"#f0b49e\", \"#f7e4be\"],\n [\"#ff4e50\", \"#fc913a\", \"#f9d423\", \"#ede574\", \"#e1f5c4\"],\n [\"#99b898\", \"#fecea8\", \"#ff847c\", \"#e84a5f\", \"#2a363b\"],\n [\"#655643\", \"#80bca3\", \"#f6f7bd\", \"#e6ac27\", \"#bf4d28\"],\n [\"#00a8c6\", \"#40c0cb\", \"#f9f2e7\", \"#aee239\", \"#8fbe00\"],\n [\"#351330\", \"#424254\", \"#64908a\", \"#e8caa4\", \"#cc2a41\"],\n [\"#554236\", \"#f77825\", \"#d3ce3d\", \"#f1efa5\", \"#60b99a\"],\n [\"#5d4157\", \"#838689\", \"#a8caba\", \"#cad7b2\", \"#ebe3aa\"],\n [\"#8c2318\", \"#5e8c6a\", \"#88a65e\", \"#bfb35a\", \"#f2c45a\"],\n [\"#fad089\", \"#ff9c5b\", \"#f5634a\", \"#ed303c\", \"#3b8183\"],\n [\"#ff4242\", \"#f4fad2\", \"#d4ee5e\", \"#e1edb9\", \"#f0f2eb\"],\n [\"#f8b195\", \"#f67280\", \"#c06c84\", \"#6c5b7b\", \"#355c7d\"],\n [\"#d1e751\", \"#ffffff\", \"#000000\", \"#4dbce9\", \"#26ade4\"],\n [\"#1b676b\", \"#519548\", \"#88c425\", \"#bef202\", \"#eafde6\"],\n [\"#5e412f\", \"#fcebb6\", \"#78c0a8\", \"#f07818\", \"#f0a830\"],\n [\"#bcbdac\", \"#cfbe27\", \"#f27435\", \"#f02475\", \"#3b2d38\"],\n [\"#452632\", \"#91204d\", \"#e4844a\", \"#e8bf56\", \"#e2f7ce\"],\n [\"#eee6ab\", \"#c5bc8e\", \"#696758\", \"#45484b\", \"#36393b\"],\n [\"#f0d8a8\", \"#3d1c00\", \"#86b8b1\", \"#f2d694\", \"#fa2a00\"],\n [\"#2a044a\", \"#0b2e59\", \"#0d6759\", \"#7ab317\", \"#a0c55f\"],\n [\"#f04155\", \"#ff823a\", \"#f2f26f\", \"#fff7bd\", \"#95cfb7\"],\n [\"#b9d7d9\", \"#668284\", \"#2a2829\", \"#493736\", \"#7b3b3b\"],\n [\"#bbbb88\", \"#ccc68d\", \"#eedd99\", \"#eec290\", \"#eeaa88\"],\n [\"#b3cc57\", \"#ecf081\", \"#ffbe40\", \"#ef746f\", \"#ab3e5b\"],\n [\"#a3a948\", \"#edb92e\", \"#f85931\", \"#ce1836\", \"#009989\"],\n [\"#300030\", \"#480048\", \"#601848\", \"#c04848\", \"#f07241\"],\n [\"#67917a\", \"#170409\", \"#b8af03\", \"#ccbf82\", \"#e33258\"],\n [\"#aab3ab\", \"#c4cbb7\", \"#ebefc9\", \"#eee0b7\", \"#e8caaf\"],\n [\"#e8d5b7\", \"#0e2430\", \"#fc3a51\", \"#f5b349\", \"#e8d5b9\"],\n [\"#ab526b\", \"#bca297\", \"#c5ceae\", \"#f0e2a4\", \"#f4ebc3\"],\n [\"#607848\", \"#789048\", \"#c0d860\", \"#f0f0d8\", \"#604848\"],\n [\"#b6d8c0\", \"#c8d9bf\", \"#dadabd\", \"#ecdbbc\", \"#fedcba\"],\n [\"#a8e6ce\", \"#dcedc2\", \"#ffd3b5\", \"#ffaaa6\", \"#ff8c94\"],\n [\"#3e4147\", \"#fffedf\", \"#dfba69\", \"#5a2e2e\", \"#2a2c31\"],\n [\"#fc354c\", \"#29221f\", \"#13747d\", \"#0abfbc\", \"#fcf7c5\"],\n [\"#cc0c39\", \"#e6781e\", \"#c8cf02\", \"#f8fcc1\", \"#1693a7\"],\n [\"#1c2130\", \"#028f76\", \"#b3e099\", \"#ffeaad\", \"#d14334\"],\n [\"#a7c5bd\", \"#e5ddcb\", \"#eb7b59\", \"#cf4647\", \"#524656\"],\n [\"#dad6ca\", \"#1bb0ce\", \"#4f8699\", \"#6a5e72\", \"#563444\"],\n [\"#5c323e\", \"#a82743\", \"#e15e32\", \"#c0d23e\", \"#e5f04c\"],\n [\"#edebe6\", \"#d6e1c7\", \"#94c7b6\", \"#403b33\", \"#d3643b\"],\n [\"#fdf1cc\", \"#c6d6b8\", \"#987f69\", \"#e3ad40\", \"#fcd036\"],\n [\"#230f2b\", \"#f21d41\", \"#ebebbc\", \"#bce3c5\", \"#82b3ae\"],\n [\"#b9d3b0\", \"#81bda4\", \"#b28774\", \"#f88f79\", \"#f6aa93\"],\n [\"#3a111c\", \"#574951\", \"#83988e\", \"#bcdea5\", \"#e6f9bc\"],\n [\"#5e3929\", \"#cd8c52\", \"#b7d1a3\", \"#dee8be\", \"#fcf7d3\"],\n [\"#1c0113\", \"#6b0103\", \"#a30006\", \"#c21a01\", \"#f03c02\"],\n [\"#000000\", \"#9f111b\", \"#b11623\", \"#292c37\", \"#cccccc\"],\n [\"#382f32\", \"#ffeaf2\", \"#fcd9e5\", \"#fbc5d8\", \"#f1396d\"],\n [\"#e3dfba\", \"#c8d6bf\", \"#93ccc6\", \"#6cbdb5\", \"#1a1f1e\"],\n [\"#f6f6f6\", \"#e8e8e8\", \"#333333\", \"#990100\", \"#b90504\"],\n [\"#1b325f\", \"#9cc4e4\", \"#e9f2f9\", \"#3a89c9\", \"#f26c4f\"],\n [\"#a1dbb2\", \"#fee5ad\", \"#faca66\", \"#f7a541\", \"#f45d4c\"],\n [\"#c1b398\", \"#605951\", \"#fbeec2\", \"#61a6ab\", \"#accec0\"],\n [\"#5e9fa3\", \"#dcd1b4\", \"#fab87f\", \"#f87e7b\", \"#b05574\"],\n [\"#951f2b\", \"#f5f4d7\", \"#e0dfb1\", \"#a5a36c\", \"#535233\"],\n [\"#8dccad\", \"#988864\", \"#fea6a2\", \"#f9d6ac\", \"#ffe9af\"],\n [\"#2d2d29\", \"#215a6d\", \"#3ca2a2\", \"#92c7a3\", \"#dfece6\"],\n [\"#413d3d\", \"#040004\", \"#c8ff00\", \"#fa023c\", \"#4b000f\"],\n [\"#eff3cd\", \"#b2d5ba\", \"#61ada0\", \"#248f8d\", \"#605063\"],\n [\"#ffefd3\", \"#fffee4\", \"#d0ecea\", \"#9fd6d2\", \"#8b7a5e\"],\n [\"#cfffdd\", \"#b4dec1\", \"#5c5863\", \"#a85163\", \"#ff1f4c\"],\n [\"#9dc9ac\", \"#fffec7\", \"#f56218\", \"#ff9d2e\", \"#919167\"],\n [\"#4e395d\", \"#827085\", \"#8ebe94\", \"#ccfc8e\", \"#dc5b3e\"],\n [\"#a8a7a7\", \"#cc527a\", \"#e8175d\", \"#474747\", \"#363636\"],\n [\"#f8edd1\", \"#d88a8a\", \"#474843\", \"#9d9d93\", \"#c5cfc6\"],\n [\"#046d8b\", \"#309292\", \"#2fb8ac\", \"#93a42a\", \"#ecbe13\"],\n [\"#f38a8a\", \"#55443d\", \"#a0cab5\", \"#cde9ca\", \"#f1edd0\"],\n [\"#a70267\", \"#f10c49\", \"#fb6b41\", \"#f6d86b\", \"#339194\"],\n [\"#ff003c\", \"#ff8a00\", \"#fabe28\", \"#88c100\", \"#00c176\"],\n [\"#ffedbf\", \"#f7803c\", \"#f54828\", \"#2e0d23\", \"#f8e4c1\"],\n [\"#4e4d4a\", \"#353432\", \"#94ba65\", \"#2790b0\", \"#2b4e72\"],\n [\"#0ca5b0\", \"#4e3f30\", \"#fefeeb\", \"#f8f4e4\", \"#a5b3aa\"],\n [\"#4d3b3b\", \"#de6262\", \"#ffb88c\", \"#ffd0b3\", \"#f5e0d3\"],\n [\"#fffbb7\", \"#a6f6af\", \"#66b6ab\", \"#5b7c8d\", \"#4f2958\"],\n [\"#edf6ee\", \"#d1c089\", \"#b3204d\", \"#412e28\", \"#151101\"],\n [\"#9d7e79\", \"#ccac95\", \"#9a947c\", \"#748b83\", \"#5b756c\"],\n [\"#fcfef5\", \"#e9ffe1\", \"#cdcfb7\", \"#d6e6c3\", \"#fafbe3\"],\n [\"#9cddc8\", \"#bfd8ad\", \"#ddd9ab\", \"#f7af63\", \"#633d2e\"],\n [\"#30261c\", \"#403831\", \"#36544f\", \"#1f5f61\", \"#0b8185\"],\n [\"#aaff00\", \"#ffaa00\", \"#ff00aa\", \"#aa00ff\", \"#00aaff\"],\n [\"#d1313d\", \"#e5625c\", \"#f9bf76\", \"#8eb2c5\", \"#615375\"],\n [\"#ffe181\", \"#eee9e5\", \"#fad3b2\", \"#ffba7f\", \"#ff9c97\"],\n [\"#73c8a9\", \"#dee1b6\", \"#e1b866\", \"#bd5532\", \"#373b44\"],\n [\"#805841\", \"#dcf7f3\", \"#fffcdd\", \"#ffd8d8\", \"#f5a2a2\"],\n]\n\nexport const getDebugLayoutObject = (lo: any): LayoutDebugObject | null => {\n let {\n x,\n y,\n width,\n height,\n }: { x: number; y: number; width?: number; height?: number } = {\n ...lo,\n ...(lo as any).size,\n ...(lo as any).center,\n ...(lo as any).position,\n }\n\n if (\n lo.x1 !== undefined &&\n lo.x2 !== undefined &&\n lo.y1 !== undefined &&\n lo.y2 !== undefined\n ) {\n x = (lo.x1 + lo.x2) / 2\n y = (lo.y1 + lo.y2) / 2\n width = Math.abs(lo.x1 - lo.x2)\n height = Math.abs(lo.y1 - lo.y2)\n }\n\n const title = lo.text || lo.name || lo.source?.text || lo.source?.name || \"?\"\n const content = lo\n\n if (x === undefined || y === undefined) return null\n\n if (width === undefined) {\n if (\"outer_diameter\" in lo) {\n width = lo.outer_diameter\n height = lo.outer_diameter\n }\n }\n\n if (width === undefined || height === undefined) {\n width = 0.1\n height = 0.1\n }\n\n return {\n x,\n y,\n width,\n height,\n title,\n content,\n bg_color:\n nice_color_palettes[\n stringHash((lo as any).type || title) % nice_color_palettes.length\n ]?.[4] ?? \"#f00\",\n }\n}\n","export const isTruthy = <T>(value: T): value is NonNullable<T> => Boolean(value)\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { getDebugLayoutObject } from \"./utils/get-layout-debug-object\"\nimport { isTruthy } from \"./utils/is-truthy\"\n\nexport const findBoundsAndCenter = (\n elements: AnyCircuitElement[],\n): { center: { x: number; y: number }; width: number; height: number } => {\n const debugObjects = elements\n .filter((elm) => elm.type.startsWith(\"pcb_\"))\n .concat(\n elements\n .filter((elm) => elm.type === \"pcb_trace\")\n // @ts-ignore\n .flatMap((elm: PcbTrace) => elm.route),\n )\n .map((elm) => getDebugLayoutObject(elm))\n .filter(isTruthy)\n\n if (debugObjects.length === 0)\n return { center: { x: 0, y: 0 }, width: 0, height: 0 }\n\n let minX = debugObjects[0]!.x - debugObjects[0]!.width / 2\n let maxX = debugObjects[0]!.x + debugObjects[0]!.width / 2\n let minY = debugObjects[0]!.y - debugObjects[0]!.height / 2\n let maxY = debugObjects[0]!.y + debugObjects[0]!.height / 2\n\n for (const obj of debugObjects.slice(1)) {\n minX = Math.min(minX, obj.x - obj.width / 2)\n maxX = Math.max(maxX, obj.x + obj.width / 2)\n minY = Math.min(minY, obj.y - obj.height / 2)\n maxY = Math.max(maxY, obj.y + obj.height / 2)\n }\n\n const width = maxX - minX\n const height = maxY - minY\n const center = { x: minX + width / 2, y: minY + height / 2 }\n\n return { center, width, height }\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\n\nexport const getPrimaryId = (element: AnyCircuitElement): string => {\n // @ts-ignore\n return element[`${element.type}_id`]\n}\n"],"mappings":"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EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AACxD;AAEO,IAAM,uBAAuB,CAAC,OAAsC;AACzE,MAAI;AAAA,IACF;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAA+D;AAAA,IAC7D,GAAG;AAAA,IACH,GAAI,GAAW;AAAA,IACf,GAAI,GAAW;AAAA,IACf,GAAI,GAAW;AAAA,EACjB;AAEA,MACE,GAAG,OAAO,UACV,GAAG,OAAO,UACV,GAAG,OAAO,UACV,GAAG,OAAO,QACV;AACA,SAAK,GAAG,KAAK,GAAG,MAAM;AACtB,SAAK,GAAG,KAAK,GAAG,MAAM;AACtB,YAAQ,KAAK,IAAI,GAAG,KAAK,GAAG,EAAE;AAC9B,aAAS,KAAK,IAAI,GAAG,KAAK,GAAG,EAAE;AAAA,EACjC;AAEA,QAAM,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,QAAQ,GAAG,QAAQ,QAAQ;AAC1E,QAAM,UAAU;AAEhB,MAAI,MAAM,UAAa,MAAM;AAAW,WAAO;AAE/C,MAAI,UAAU,QAAW;AACvB,QAAI,oBAAoB,IAAI;AAC1B,cAAQ,GAAG;AACX,eAAS,GAAG;AAAA,IACd;AAAA,EACF;AAEA,MAAI,UAAU,UAAa,WAAW,QAAW;AAC/C,YAAQ;AACR,aAAS;AAAA,EACX;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UACE,oBACE,WAAY,GAAW,QAAQ,KAAK,IAAI,oBAAoB,MAC9D,IAAI,CAAC,KAAK;AAAA,EACd;AACF;;;AC7KO,IAAM,WAAW,CAAI,UAAsC,QAAQ,KAAK;;;ACIxE,IAAM,sBAAsB,CACjC,aACwE;AACxE,QAAM,eAAe,SAClB,OAAO,CAAC,QAAQ,IAAI,KAAK,WAAW,MAAM,CAAC,EAC3C;AAAA,IACC,SACG,OAAO,CAAC,QAAQ,IAAI,SAAS,WAAW,EAExC,QAAQ,CAAC,QAAkB,IAAI,KAAK;AAAA,EACzC,EACC,IAAI,CAAC,QAAQ,qBAAqB,GAAG,CAAC,EACtC,OAAO,QAAQ;AAElB,MAAI,aAAa,WAAW;AAC1B,WAAO,EAAE,QAAQ,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,OAAO,GAAG,QAAQ,EAAE;AAEvD,MAAI,OAAO,aAAa,CAAC,EAAG,IAAI,aAAa,CAAC,EAAG,QAAQ;AACzD,MAAI,OAAO,aAAa,CAAC,EAAG,IAAI,aAAa,CAAC,EAAG,QAAQ;AACzD,MAAI,OAAO,aAAa,CAAC,EAAG,IAAI,aAAa,CAAC,EAAG,SAAS;AAC1D,MAAI,OAAO,aAAa,CAAC,EAAG,IAAI,aAAa,CAAC,EAAG,SAAS;AAE1D,aAAW,OAAO,aAAa,MAAM,CAAC,GAAG;AACvC,WAAO,KAAK,IAAI,MAAM,IAAI,IAAI,IAAI,QAAQ,CAAC;AAC3C,WAAO,KAAK,IAAI,MAAM,IAAI,IAAI,IAAI,QAAQ,CAAC;AAC3C,WAAO,KAAK,IAAI,MAAM,IAAI,IAAI,IAAI,SAAS,CAAC;AAC5C,WAAO,KAAK,IAAI,MAAM,IAAI,IAAI,IAAI,SAAS,CAAC;AAAA,EAC9C;AAEA,QAAM,QAAQ,OAAO;AACrB,QAAM,SAAS,OAAO;AACtB,QAAM,SAAS,EAAE,GAAG,OAAO,QAAQ,GAAG,GAAG,OAAO,SAAS,EAAE;AAE3D,SAAO,EAAE,QAAQ,OAAO,OAAO;AACjC;;;ACpCO,IAAM,eAAe,CAAC,YAAuC;AAElE,SAAO,QAAQ,GAAG,QAAQ,IAAI,KAAK;AACrC;","names":["su","Soup","joiner"]}
|