circuitscript 0.1.31 → 0.1.33

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.
Files changed (58) hide show
  1. package/dist/cjs/BaseVisitor.js +37 -3
  2. package/dist/cjs/RefdesAnnotationVisitor.js +27 -10
  3. package/dist/cjs/antlr/CircuitScriptParser.js +990 -831
  4. package/dist/cjs/draw_symbols.js +38 -34
  5. package/dist/cjs/environment.js +24 -4
  6. package/dist/cjs/execute.js +107 -68
  7. package/dist/cjs/globals.js +4 -2
  8. package/dist/cjs/graph.js +14 -12
  9. package/dist/cjs/helpers.js +85 -16
  10. package/dist/cjs/layout.js +50 -25
  11. package/dist/cjs/main.js +16 -18
  12. package/dist/cjs/objects/ClassComponent.js +199 -30
  13. package/dist/cjs/objects/types.js +5 -1
  14. package/dist/cjs/regenerate-tests.js +3 -3
  15. package/dist/cjs/render.js +5 -3
  16. package/dist/cjs/rules-check/no-connect-on-connected-pin.js +9 -8
  17. package/dist/cjs/rules-check/rules.js +7 -2
  18. package/dist/cjs/rules-check/unconnected-pins.js +10 -8
  19. package/dist/cjs/utils.js +2 -1
  20. package/dist/cjs/validate/SymbolValidatorVisitor.js +0 -10
  21. package/dist/cjs/visitor.js +284 -191
  22. package/dist/esm/BaseVisitor.js +37 -3
  23. package/dist/esm/RefdesAnnotationVisitor.js +27 -10
  24. package/dist/esm/antlr/CircuitScriptParser.js +989 -830
  25. package/dist/esm/antlr/CircuitScriptVisitor.js +1 -0
  26. package/dist/esm/draw_symbols.js +38 -34
  27. package/dist/esm/environment.js +21 -1
  28. package/dist/esm/execute.js +108 -69
  29. package/dist/esm/globals.js +2 -0
  30. package/dist/esm/graph.js +14 -12
  31. package/dist/esm/helpers.js +86 -17
  32. package/dist/esm/layout.js +51 -26
  33. package/dist/esm/main.js +16 -18
  34. package/dist/esm/objects/ClassComponent.js +201 -30
  35. package/dist/esm/objects/types.js +7 -1
  36. package/dist/esm/regenerate-tests.js +3 -3
  37. package/dist/esm/render.js +5 -3
  38. package/dist/esm/rules-check/no-connect-on-connected-pin.js +9 -8
  39. package/dist/esm/rules-check/rules.js +7 -2
  40. package/dist/esm/rules-check/unconnected-pins.js +10 -8
  41. package/dist/esm/utils.js +2 -1
  42. package/dist/esm/validate/SymbolValidatorVisitor.js +0 -10
  43. package/dist/esm/visitor.js +185 -92
  44. package/dist/types/BaseVisitor.d.ts +15 -5
  45. package/dist/types/RefdesAnnotationVisitor.d.ts +2 -0
  46. package/dist/types/antlr/CircuitScriptParser.d.ts +32 -14
  47. package/dist/types/antlr/CircuitScriptVisitor.d.ts +2 -0
  48. package/dist/types/environment.d.ts +7 -1
  49. package/dist/types/execute.d.ts +4 -1
  50. package/dist/types/globals.d.ts +2 -0
  51. package/dist/types/graph.d.ts +2 -2
  52. package/dist/types/helpers.d.ts +2 -1
  53. package/dist/types/layout.d.ts +5 -4
  54. package/dist/types/objects/ClassComponent.d.ts +34 -9
  55. package/dist/types/objects/types.d.ts +19 -3
  56. package/dist/types/validate/SymbolValidatorVisitor.d.ts +0 -4
  57. package/dist/types/visitor.d.ts +7 -1
  58. package/package.json +1 -1
@@ -135,7 +135,7 @@ class SymbolGraphic {
135
135
  }
136
136
  drawLabels(group) {
137
137
  const labels = this.drawing.getLabels();
138
- labels.forEach(label => {
138
+ for (const label of labels) {
139
139
  const tmpLabel = label;
140
140
  const { fontSize = (0, ParamDefinition_js_1.numeric)(50), anchor = geometry_js_1.HorizontalAlign.Left, vanchor = geometry_js_1.VerticalAlign.Bottom, fontWeight = 'regular', angle: tmpLabelAngle = (0, ParamDefinition_js_1.numeric)(0), textColor = "#333", } = tmpLabel.style ?? {};
141
141
  const labelAngle = tmpLabelAngle.toNumber();
@@ -148,31 +148,35 @@ class SymbolGraphic {
148
148
  useAnchor = this.flipTextAnchor(anchor);
149
149
  useDominantBaseline = this.flipDominantBaseline(vanchor);
150
150
  }
151
- switch (useAnchor) {
152
- case geometry_js_1.HorizontalAlign.Left:
153
- anchorStyle = (this.flipX === 0)
154
- ? geometry_js_1.HorizontalAlignProp.Start : geometry_js_1.HorizontalAlignProp.End;
155
- break;
156
- case geometry_js_1.HorizontalAlign.Middle:
157
- anchorStyle = geometry_js_1.HorizontalAlignProp.Middle;
158
- break;
159
- case geometry_js_1.HorizontalAlign.Right:
160
- anchorStyle = (this.flipX === 0)
161
- ? geometry_js_1.HorizontalAlignProp.End : geometry_js_1.HorizontalAlignProp.Start;
162
- break;
151
+ const isHorizontalLabel = labelAngle === 0 || labelAngle === 180;
152
+ const isVerticalLabel = labelAngle === 90 || labelAngle === -90;
153
+ if (useAnchor === geometry_js_1.HorizontalAlign.Middle) {
154
+ anchorStyle = geometry_js_1.HorizontalAlignProp.Middle;
163
155
  }
164
- switch (useDominantBaseline) {
165
- case geometry_js_1.VerticalAlign.Top:
166
- dominantBaseline = (this.flipY === 0)
167
- ? geometry_js_1.VerticalAlignProp.Hanging : geometry_js_1.VerticalAlignProp.TextTop;
168
- break;
169
- case geometry_js_1.VerticalAlign.Middle:
170
- dominantBaseline = geometry_js_1.VerticalAlignProp.Central;
171
- break;
172
- case geometry_js_1.VerticalAlign.Bottom:
173
- dominantBaseline = (this.flipY === 0)
174
- ? geometry_js_1.VerticalAlignProp.TextTop : geometry_js_1.VerticalAlignProp.Hanging;
175
- break;
156
+ else if (useAnchor === geometry_js_1.HorizontalAlign.Left) {
157
+ anchorStyle = geometry_js_1.HorizontalAlignProp.Start;
158
+ }
159
+ else if (useAnchor === geometry_js_1.HorizontalAlign.Right) {
160
+ anchorStyle = geometry_js_1.HorizontalAlignProp.End;
161
+ }
162
+ if (useDominantBaseline === geometry_js_1.VerticalAlign.Middle) {
163
+ dominantBaseline = geometry_js_1.VerticalAlignProp.Central;
164
+ }
165
+ else if (useDominantBaseline === geometry_js_1.VerticalAlign.Top) {
166
+ dominantBaseline = geometry_js_1.VerticalAlignProp.Hanging;
167
+ }
168
+ else if (useDominantBaseline === geometry_js_1.VerticalAlign.Bottom) {
169
+ dominantBaseline = geometry_js_1.VerticalAlignProp.TextTop;
170
+ }
171
+ if (anchorStyle !== geometry_js_1.HorizontalAlignProp.Middle &&
172
+ ((isHorizontalLabel && this.flipX === 1) || (isVerticalLabel && this.flipY === 1))) {
173
+ anchorStyle = (anchorStyle === geometry_js_1.HorizontalAlignProp.Start)
174
+ ? geometry_js_1.HorizontalAlignProp.End : geometry_js_1.HorizontalAlignProp.Start;
175
+ }
176
+ if (dominantBaseline !== geometry_js_1.VerticalAlignProp.Central &&
177
+ ((isHorizontalLabel && this.flipY === 1) || (isVerticalLabel && this.flipX === 1))) {
178
+ dominantBaseline = (dominantBaseline === geometry_js_1.VerticalAlignProp.Hanging)
179
+ ? geometry_js_1.VerticalAlignProp.TextTop : geometry_js_1.VerticalAlignProp.Hanging;
176
180
  }
177
181
  const position = tmpLabel.getLabelPosition();
178
182
  if (this.flipX !== 0) {
@@ -316,7 +320,7 @@ class SymbolGraphic {
316
320
  .translate(-originSize / 2, -originSize / 2)
317
321
  .fill('green');
318
322
  }
319
- });
323
+ }
320
324
  }
321
325
  flipTextAnchor(value) {
322
326
  if (value === geometry_js_1.HorizontalAlign.Left) {
@@ -712,7 +716,7 @@ class SymbolCustom extends SymbolGraphic {
712
716
  const pinStartY = bodyHeightMM.neg().half();
713
717
  const pinStartX = bodyWidthMM.neg().half();
714
718
  const tmpPinSpacing = this.pinSpacing.toNumber();
715
- leftPins.forEach(pin => {
719
+ for (const pin of leftPins) {
716
720
  const position = pin.position;
717
721
  const pinY = pinStartY.add((position + 1) * tmpPinSpacing);
718
722
  drawing.addPinMM(pin.pinId, leftPinStart.sub(this.pinLength), pinY, leftPinStart, pinY, defaultLineColor);
@@ -728,8 +732,8 @@ class SymbolCustom extends SymbolGraphic {
728
732
  vanchor: geometry_js_1.VerticalAlign.Bottom,
729
733
  textColor: defaultLineColor
730
734
  });
731
- });
732
- rightPins.forEach(pin => {
735
+ }
736
+ for (const pin of rightPins) {
733
737
  const position = pin.position;
734
738
  const pinY = pinStartY.add((position + 1) * tmpPinSpacing);
735
739
  drawing.addPinMM(pin.pinId, rightPinStart.add(this.pinLength), pinY, rightPinStart, pinY, defaultLineColor);
@@ -745,8 +749,8 @@ class SymbolCustom extends SymbolGraphic {
745
749
  vanchor: geometry_js_1.VerticalAlign.Bottom,
746
750
  textColor: defaultLineColor
747
751
  });
748
- });
749
- topPins.forEach(pin => {
752
+ }
753
+ for (const pin of topPins) {
750
754
  const position = pin.position;
751
755
  const pinX = pinStartX.add((position + 1) * tmpPinSpacing);
752
756
  drawing.addPinMM(pin.pinId, pinX, topPinStart.sub(this.pinLength), pinX, topPinStart, defaultLineColor);
@@ -764,8 +768,8 @@ class SymbolCustom extends SymbolGraphic {
764
768
  textColor: defaultLineColor,
765
769
  angle: (0, ParamDefinition_js_1.numeric)(-90),
766
770
  });
767
- });
768
- bottomPins.forEach(pin => {
771
+ }
772
+ for (const pin of bottomPins) {
769
773
  const position = pin.position;
770
774
  const pinX = pinStartX.add((position + 1) * tmpPinSpacing);
771
775
  drawing.addPinMM(pin.pinId, pinX, bottomPinStart.add(this.pinLength), pinX, bottomPinStart, defaultLineColor);
@@ -783,7 +787,7 @@ class SymbolCustom extends SymbolGraphic {
783
787
  textColor: defaultLineColor,
784
788
  angle: (0, ParamDefinition_js_1.numeric)(-90)
785
789
  });
786
- });
790
+ }
787
791
  const instanceName = drawing.variables.get('refdes');
788
792
  instanceName && drawing.addLabel(bodyWidthMM.neg().half(), bodyHeightMM.neg().half().sub((0, helpers_js_1.milsToMM)(20)), instanceName, {
789
793
  fontSize: (0, ParamDefinition_js_1.numeric)(globals_js_1.CustomSymbolRefDesSize),
@@ -5,7 +5,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.NodeScriptEnvironment = void 0;
7
7
  const svg_js_1 = require("@svgdotjs/svg.js");
8
- const fs_1 = __importDefault(require("fs"));
8
+ const fs_1 = require("fs");
9
+ const fs_2 = __importDefault(require("fs"));
9
10
  const path_1 = __importDefault(require("path"));
10
11
  const crypto_js_1 = __importDefault(require("crypto-js"));
11
12
  const globals_js_1 = require("./globals.js");
@@ -39,7 +40,7 @@ class NodeScriptEnvironment {
39
40
  }
40
41
  try {
41
42
  const packageJsonPath = path_1.default.join(this.getToolsPath(), '../', 'package.json');
42
- const packageJsonContent = fs_1.default.readFileSync(packageJsonPath, 'utf-8');
43
+ const packageJsonContent = fs_2.default.readFileSync(packageJsonPath, 'utf-8');
43
44
  const packageJson = JSON.parse(packageJsonContent);
44
45
  this.cachedVersion = packageJson.version || globals_js_1.TOOL_VERSION;
45
46
  return this.cachedVersion;
@@ -118,7 +119,11 @@ class NodeScriptEnvironment {
118
119
  return this.prepareSVGEnvironmentInternal(this.getFontsPath());
119
120
  }
120
121
  async readFile(path, options) {
121
- return fs_1.default.promises.readFile(path, options);
122
+ options = options ?? { encoding: 'utf8' };
123
+ return fs_2.default.promises.readFile(path, options);
124
+ }
125
+ writeFileSync(path, data) {
126
+ return (0, fs_1.writeFileSync)(path, data);
122
127
  }
123
128
  getAbsolutePath(filePath) {
124
129
  return path_1.default.resolve(filePath);
@@ -138,7 +143,7 @@ class NodeScriptEnvironment {
138
143
  }
139
144
  async exists(path) {
140
145
  try {
141
- fs_1.default.promises.access(path, fs_1.default.constants.F_OK);
146
+ await fs_2.default.promises.access(path, fs_2.default.constants.F_OK);
142
147
  return true;
143
148
  }
144
149
  catch (err) {
@@ -148,6 +153,21 @@ class NodeScriptEnvironment {
148
153
  hashStringSHA256(value) {
149
154
  return crypto_js_1.default.SHA256(value).toString();
150
155
  }
156
+ dirname(filePath) {
157
+ return path_1.default.dirname(filePath);
158
+ }
159
+ extname(filePath) {
160
+ return path_1.default.extname(filePath);
161
+ }
162
+ basename(filePath, ext) {
163
+ return path_1.default.basename(filePath, ext);
164
+ }
165
+ join(...paths) {
166
+ return path_1.default.join(...paths);
167
+ }
168
+ relative(from, to) {
169
+ return path_1.default.relative(from, to);
170
+ }
151
171
  }
152
172
  exports.NodeScriptEnvironment = NodeScriptEnvironment;
153
173
  NodeScriptEnvironment._instance = null;
@@ -60,7 +60,7 @@ class ExecutionContext {
60
60
  setupRoot() {
61
61
  const componentRoot = ClassComponent_js_1.ClassComponent.simple(globals_js_1.GlobalNames.__root, 1);
62
62
  componentRoot.typeProp = globals_js_1.ComponentTypes.net;
63
- componentRoot.displayProp = this.getPointSymbol();
63
+ componentRoot.addDefaultUnit(this.getPointSymbol());
64
64
  this.scope.instances.set(globals_js_1.GlobalNames.__root, componentRoot);
65
65
  this.scope.setCurrent(componentRoot);
66
66
  this.scope.componentRoot = componentRoot;
@@ -126,49 +126,13 @@ class ExecutionContext {
126
126
  }
127
127
  createComponent(instanceName, pins, params, props, isModule = false) {
128
128
  const className = isModule ? ClassComponent_js_1.ModuleComponent : ClassComponent_js_1.ClassComponent;
129
+ pins = this.extractPinsFromUnits(props.units);
129
130
  const component = new className(instanceName, pins.length);
130
131
  pins.forEach((pin) => {
131
132
  component.pins.set(pin.id, pin);
132
133
  });
133
- component.displayProp = props.display ?? null;
134
- component.widthProp = props.width ?? null;
135
- component.heightProp = props.height ?? null;
136
134
  component.typeProp = props.type ?? null;
137
135
  component.copyProp = props.copy ?? false;
138
- let useAngle = null;
139
- if (props.angle) {
140
- useAngle = props.angle.toNumber() % 360;
141
- if (useAngle < 0) {
142
- useAngle += 360;
143
- }
144
- }
145
- if (props.display === null && props.arrange === null) {
146
- const tmpArrangeLeft = [];
147
- const tmpArrangeRight = [];
148
- pins.forEach((pin, index) => {
149
- const useArray = (index % 2 === 0) ? tmpArrangeLeft : tmpArrangeRight;
150
- useArray.push(pin.id);
151
- });
152
- const arrangeProp = new Map([
153
- [globals_js_1.SymbolPinSide.Left, tmpArrangeLeft],
154
- [globals_js_1.SymbolPinSide.Right, tmpArrangeRight]
155
- ]);
156
- props.arrange = arrangeProp;
157
- }
158
- if (props.arrange !== null) {
159
- component.arrangeProps = this.removeArrangePropDuplicates(props.arrange);
160
- const arrangePropPins = this.getArrangePropPins(component.arrangeProps);
161
- pins.forEach(pin => {
162
- if (arrangePropPins.find(id => id.equals(pin.id)) === undefined) {
163
- this.logWarning(`Pin ${pin.id} is not specified in arrange property`);
164
- }
165
- });
166
- }
167
- else {
168
- component.arrangeProps = null;
169
- }
170
- component.angleProp = useAngle ?? 0;
171
- component.followWireOrientationProp = props.followWireOrientation;
172
136
  const paramsMap = new Map();
173
137
  params.forEach((param) => {
174
138
  component.parameters.set(param.paramName, param.paramValue);
@@ -195,27 +159,91 @@ class ExecutionContext {
195
159
  this.scope.setNet(component, defaultPin, tmpNet);
196
160
  this.log('set net', netName, 'component', component, defaultPin);
197
161
  }
198
- const { pins: pinSides, maxPositions } = getPortSide(component.pins, component.arrangeProps);
199
- component.pinsMaxPositions = maxPositions;
200
- const pinIdKeys = Array.from(component.pins.keys());
201
- pinSides.forEach(({ pinId, side, position }) => {
202
- const matchedPinId = pinIdKeys.find(id => id.equals(pinId));
203
- if (matchedPinId) {
204
- const tmpPin = component.pins.get(matchedPinId);
205
- tmpPin.side = side;
206
- tmpPin.position = position;
207
- }
208
- else {
209
- throw 'Not found!';
210
- }
211
- });
212
162
  this.scope.instances.set(instanceName, component);
213
163
  const pinsOutput = pins.map((pin) => {
214
164
  return pin.id + ':' + pin.name;
215
165
  });
216
166
  this.log('add symbol', instanceName, '[' + pinsOutput.join(', ') + ']');
167
+ component.units = this.generateComponentUnits(props.units, component);
168
+ component.refreshPinUnitMap();
217
169
  return component;
218
170
  }
171
+ extractPinsFromUnits(units) {
172
+ const pins = [];
173
+ units.forEach(([, definition]) => {
174
+ pins.push(...definition.pins);
175
+ });
176
+ return pins;
177
+ }
178
+ generateComponentUnits(units, parent) {
179
+ return units.map(([key, unitDef]) => {
180
+ unitDef = { ...unitDef };
181
+ let useAngle = null;
182
+ const { pins } = unitDef;
183
+ const pinsMap = new Map();
184
+ pins.forEach(pin => {
185
+ pinsMap.set(pin.id, pin);
186
+ });
187
+ if (unitDef.angle) {
188
+ useAngle = unitDef.angle.toNumber() % 360;
189
+ if (useAngle < 0) {
190
+ useAngle += 360;
191
+ }
192
+ }
193
+ if (unitDef.display === null && unitDef.arrange === null) {
194
+ const tmpArrangeLeft = [];
195
+ const tmpArrangeRight = [];
196
+ pins.forEach((pin, index) => {
197
+ const useArray = (index % 2 === 0) ? tmpArrangeLeft : tmpArrangeRight;
198
+ useArray.push(pin.id);
199
+ });
200
+ const arrangeProp = new Map([
201
+ [globals_js_1.SymbolPinSide.Left, tmpArrangeLeft],
202
+ [globals_js_1.SymbolPinSide.Right, tmpArrangeRight]
203
+ ]);
204
+ unitDef.arrange = arrangeProp;
205
+ }
206
+ if (unitDef.arrange !== null) {
207
+ unitDef.arrange = this.removeArrangePropDuplicates(unitDef.arrange);
208
+ const arrangePropPins = this.getArrangePropPins(unitDef.arrange);
209
+ pins.forEach(pin => {
210
+ if (arrangePropPins.find(id => id.equals(pin.id)) === undefined) {
211
+ this.logWarning(`Pin ${pin.id} is not specified in arrange property`);
212
+ }
213
+ });
214
+ }
215
+ else {
216
+ unitDef.arrange = null;
217
+ }
218
+ unitDef.angle = useAngle ?? 0;
219
+ const { pins: pinSides, maxPositions } = getPortSide(pinsMap, unitDef.arrange);
220
+ const pinIdKeys = Array.from(pinsMap.keys());
221
+ pinSides.forEach(({ pinId, side, position }) => {
222
+ const matchedPinId = pinIdKeys.find(id => id.equals(pinId));
223
+ if (matchedPinId) {
224
+ const tmpPin = pinsMap.get(matchedPinId);
225
+ tmpPin.side = side;
226
+ tmpPin.position = position;
227
+ }
228
+ else {
229
+ throw 'Not found!';
230
+ }
231
+ });
232
+ const componentUnit = new ClassComponent_js_1.ComponentUnit(key, parent);
233
+ componentUnit.widthProp = unitDef.width;
234
+ componentUnit.heightProp = unitDef.height;
235
+ componentUnit.angleProp = unitDef.angle;
236
+ componentUnit.followWireOrientationProp = unitDef.followWireOrientation;
237
+ componentUnit.pins = pinsMap;
238
+ componentUnit.pinsFlat = pins;
239
+ componentUnit.numPins = unitDef.pins.length;
240
+ componentUnit.pinsMaxPositions = maxPositions;
241
+ componentUnit.displayProp = unitDef.display;
242
+ componentUnit.arrangeProps = unitDef.arrange;
243
+ componentUnit.suffix = unitDef.suffix ?? null;
244
+ return componentUnit;
245
+ });
246
+ }
219
247
  removeArrangePropDuplicates(arrangeProp) {
220
248
  const sides = [
221
249
  globals_js_1.SymbolPinSide.Left,
@@ -881,9 +909,10 @@ class ExecutionContext {
881
909
  this.scope.setActive(ExecutionScope_js_1.ActiveObject.Wire, wireId);
882
910
  this.scope.sequence.push([ExecutionScope_js_1.SequenceAction.Wire, wireId, tmp, newWire]);
883
911
  this.scope.currentComponent.pinWires.set(this.scope.currentPin, tmp);
884
- if (!this.scope.currentComponent.didSetWireOrientationAngle) {
912
+ const currentUnit = this.scope.currentComponent.getUnitForPin(this.scope.currentPin);
913
+ if (!currentUnit.didSetWireOrientationAngle) {
885
914
  this.applyComponentAngleFromWire(this.scope.currentComponent, this.scope.currentPin, true);
886
- this.scope.currentComponent.didSetWireOrientationAngle = true;
915
+ currentUnit.didSetWireOrientationAngle = true;
887
916
  }
888
917
  return newWire;
889
918
  }
@@ -893,7 +922,6 @@ class ExecutionContext {
893
922
  }
894
923
  const useName = userDefined ? 'point.' + pointId : pointId;
895
924
  const componentPoint = ClassComponent_js_1.ClassComponent.simple(useName, 1);
896
- componentPoint.displayProp = this.getPointSymbol(useName);
897
925
  componentPoint.typeProp = globals_js_1.ComponentTypes.net;
898
926
  let usePointLinkComponent = null;
899
927
  if (this.scope.currentComponent._pointLinkComponent) {
@@ -903,6 +931,7 @@ class ExecutionContext {
903
931
  usePointLinkComponent = this.scope.currentComponent;
904
932
  }
905
933
  componentPoint._pointLinkComponent = usePointLinkComponent;
934
+ componentPoint.addDefaultUnit(this.getPointSymbol(useName));
906
935
  this.scope.instances.set(pointId, componentPoint);
907
936
  this.toComponent(componentPoint, 1, { addSequence: true });
908
937
  return this.getCurrentPoint();
@@ -976,6 +1005,15 @@ class ExecutionContext {
976
1005
  if (this.scope.instances.has(idName)) {
977
1006
  const component = this.scope.instances.get(idName);
978
1007
  component.setParam(paramName, value);
1008
+ const unitModifiers = [
1009
+ globals_js_1.ParamKeys.angle,
1010
+ globals_js_1.ParamKeys.flip,
1011
+ globals_js_1.ParamKeys.flipX,
1012
+ globals_js_1.ParamKeys.flipY,
1013
+ ];
1014
+ if (unitModifiers.indexOf(paramName) !== -1) {
1015
+ component.getUnit().setParam(paramName, value);
1016
+ }
979
1017
  }
980
1018
  else if (this.scope.variables.has(idName)) {
981
1019
  throw "Not implemented yet!";
@@ -986,17 +1024,18 @@ class ExecutionContext {
986
1024
  }
987
1025
  }
988
1026
  applyComponentAngleFromWire(component, pin, opposite = false) {
1027
+ const targetUnit = component.getUnitForPin(pin);
989
1028
  if (this.componentAngleFollowsWire
990
- && component.followWireOrientationProp
991
- && component.useWireOrientationAngle
992
- && !component.didSetWireOrientationAngle
1029
+ && targetUnit.followWireOrientationProp
1030
+ && targetUnit.useWireOrientationAngle
1031
+ && !targetUnit.didSetWireOrientationAngle
993
1032
  && this.scope.currentWireId !== -1) {
994
1033
  const currentWire = this.scope.wires[this.scope.currentWireId];
995
1034
  let useSegment = currentWire.path[currentWire.path.length - 1];
996
1035
  if (opposite) {
997
1036
  useSegment = currentWire.path[0];
998
1037
  }
999
- const pinPositions = (0, layout_js_1.CalculatePinPositions)(component);
1038
+ const pinPositions = (0, layout_js_1.CalculatePinPositions)(targetUnit);
1000
1039
  if (pinPositions.has(pin)) {
1001
1040
  const connectedPinPos = pinPositions.get(pin);
1002
1041
  let targetAngle = null;
@@ -1034,27 +1073,27 @@ class ExecutionContext {
1034
1073
  if (targetAngle === null) {
1035
1074
  return;
1036
1075
  }
1037
- this.log('set component angle from wire, target angle:', targetAngle, ', component angle:', component.angleProp, 'pin angle:', connectedPinPos.angle);
1076
+ this.log('set component unit angle from wire, target angle:', targetAngle, ', component unit angle:', targetUnit.angleProp, 'pin angle:', connectedPinPos.angle);
1038
1077
  let useAngle = (targetAngle - connectedPinPos.angle.toNumber()) % 360;
1039
1078
  if (useAngle < 0) {
1040
1079
  useAngle += 360;
1041
1080
  }
1042
1081
  if (useAngle === 90) {
1043
- component.setParam(globals_js_1.ParamKeys.angle, (0, ParamDefinition_js_1.numeric)(90));
1082
+ targetUnit.setParam(globals_js_1.ParamKeys.angle, (0, ParamDefinition_js_1.numeric)(90));
1044
1083
  }
1045
1084
  else if (useAngle === 180) {
1046
- if (component.angleProp === 0 || component.angleProp === 180) {
1047
- component.setParam(globals_js_1.ParamKeys.flipX, 1);
1085
+ if (targetUnit.angleProp === 0 || targetUnit.angleProp === 180) {
1086
+ targetUnit.setParam(globals_js_1.ParamKeys.flipX, (0, ParamDefinition_js_1.numeric)(1));
1048
1087
  }
1049
- else if (component.angleProp === 90 || component.angleProp === 270) {
1050
- component.setParam(globals_js_1.ParamKeys.flipY, 1);
1088
+ else if (targetUnit.angleProp === 90 || targetUnit.angleProp === 270) {
1089
+ targetUnit.setParam(globals_js_1.ParamKeys.flipY, (0, ParamDefinition_js_1.numeric)(1));
1051
1090
  }
1052
1091
  }
1053
1092
  else if (useAngle === 270) {
1054
- component.setParam(globals_js_1.ParamKeys.angle, (0, ParamDefinition_js_1.numeric)(270));
1093
+ targetUnit.setParam(globals_js_1.ParamKeys.angle, (0, ParamDefinition_js_1.numeric)(270));
1055
1094
  }
1056
- component.wireOrientationAngle = useAngle;
1057
- component.didSetWireOrientationAngle = true;
1095
+ targetUnit.wireOrientationAngle = useAngle;
1096
+ targetUnit.didSetWireOrientationAngle = true;
1058
1097
  }
1059
1098
  }
1060
1099
  }
@@ -1,12 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SymbolValidatorContext = exports.RenderFlags = exports.GlobalDocumentName = exports.ModuleContainsKeyword = exports.FrameType = exports.NetGraphicsParams = exports.BlockTypes = exports.ReferenceTypes = exports.ComponentTypes = exports.ColorScheme = exports.PortPaddingVertical = exports.PortPaddingHorizontal = exports.PortArrowSize = exports.junctionSize = exports.defaultFontSize = exports.defaultFontBold = exports.defaultFont = exports.displayUnits = exports.defaultFrameTitleTextSize = exports.CustomSymbolParamTextSize = exports.CustomSymbolRefDesSize = exports.CustomSymbolPinIdSize = exports.CustomSymbolPinTextSize = exports.defaultPageSpacingMM = exports.defaultPageMarginMM = exports.defaultPinIdTextSize = exports.defaultPinNameTextSize = exports.defaultWireLineWidth = exports.defaultSymbolLineWidth = exports.fontDisplayScale = exports.defaultZoomScale = exports.defaultGridSizeUnits = exports.portHeight = exports.portWidth = exports.PxToMM = exports.MMToPt = exports.MMToPx = exports.MilsToMM = exports.WireAutoDirection = exports.LengthUnit = exports.ValidPinSides = exports.SymbolPinSide = exports.LayoutDirection = exports.ParamKeys = exports.NoNetText = exports.GlobalNames = exports.BaseNamespace = exports.DoubleDelimiter1 = exports.Delimiter1 = exports.TOOL_VERSION = void 0;
4
- exports.TrailerArrayIndex = void 0;
3
+ exports.RenderFlags = exports.GlobalDocumentName = exports.ModuleContainsKeyword = exports.FrameType = exports.NetGraphicsParams = exports.BlockTypes = exports.ReferenceTypes = exports.ComponentTypes = exports.ColorScheme = exports.PortPaddingVertical = exports.PortPaddingHorizontal = exports.PortArrowSize = exports.junctionSize = exports.defaultFontSize = exports.defaultFontBold = exports.defaultFont = exports.displayUnits = exports.defaultFrameTitleTextSize = exports.CustomSymbolParamTextSize = exports.CustomSymbolRefDesSize = exports.CustomSymbolPinIdSize = exports.CustomSymbolPinTextSize = exports.defaultPageSpacingMM = exports.defaultPageMarginMM = exports.defaultPinIdTextSize = exports.defaultPinNameTextSize = exports.defaultWireLineWidth = exports.defaultSymbolLineWidth = exports.fontDisplayScale = exports.defaultZoomScale = exports.defaultGridSizeUnits = exports.portHeight = exports.portWidth = exports.PxToMM = exports.MMToPt = exports.MMToPx = exports.MilsToMM = exports.WireAutoDirection = exports.LengthUnit = exports.ValidPinSides = exports.SymbolPinSide = exports.LayoutDirection = exports.ParamKeys = exports.NoNetText = exports.GlobalNames = exports.RefdesFileSuffix = exports.BaseNamespace = exports.DoubleDelimiter1 = exports.Delimiter1 = exports.TOOL_VERSION = void 0;
4
+ exports.DefaultComponentUnit = exports.TrailerArrayIndex = exports.SymbolValidatorContext = void 0;
5
5
  const ParamDefinition_js_1 = require("./objects/ParamDefinition.js");
6
6
  exports.TOOL_VERSION = '0.1.5';
7
7
  exports.Delimiter1 = '-';
8
8
  exports.DoubleDelimiter1 = `${exports.Delimiter1}${exports.Delimiter1}`;
9
9
  exports.BaseNamespace = `${exports.DoubleDelimiter1}.`;
10
+ exports.RefdesFileSuffix = '.refdes.json';
10
11
  var GlobalNames;
11
12
  (function (GlobalNames) {
12
13
  GlobalNames["__root"] = "--root";
@@ -132,3 +133,4 @@ exports.RenderFlags = {
132
133
  };
133
134
  exports.SymbolValidatorContext = '_sym';
134
135
  exports.TrailerArrayIndex = 'index';
136
+ exports.DefaultComponentUnit = '__default';
package/dist/cjs/graph.js CHANGED
@@ -60,32 +60,33 @@ class NetGraph {
60
60
  case ExecutionScope_js_1.SequenceAction.At: {
61
61
  this.print(...sequenceStep);
62
62
  const [, component, pin] = sequenceStep;
63
- const tmpInstanceName = component.instanceName;
63
+ const componentUnit = component.getUnitForPin(pin);
64
+ const tmpInstanceName = componentUnit.instanceName;
64
65
  if (action === ExecutionScope_js_1.SequenceAction.At) {
65
66
  previousNode = null;
66
67
  previousPin = null;
67
68
  }
68
69
  if (!graph.hasNode(tmpInstanceName)) {
69
70
  this.print('create instance', tmpInstanceName);
70
- const { displayProp = null } = component;
71
+ const { displayProp = null } = componentUnit;
71
72
  let tmpSymbol;
72
73
  if (displayProp instanceof draw_symbols_js_1.SymbolDrawing) {
73
74
  tmpSymbol = new draw_symbols_js_1.SymbolPlaceholder(displayProp);
74
75
  tmpSymbol.drawing.logger = this.logger;
75
76
  }
76
77
  else {
77
- const symbolPinDefinitions = generateLayoutPinDefinition(component);
78
+ const symbolPinDefinitions = generateLayoutPinDefinition(componentUnit);
78
79
  if (component.typeProp === globals_js_1.ComponentTypes.module) {
79
- tmpSymbol = new draw_symbols_js_1.SymbolCustomModule(symbolPinDefinitions, component.pinsMaxPositions);
80
+ tmpSymbol = new draw_symbols_js_1.SymbolCustomModule(symbolPinDefinitions, componentUnit.pinsMaxPositions);
80
81
  }
81
82
  else {
82
- tmpSymbol = new draw_symbols_js_1.SymbolCustom(symbolPinDefinitions, component.pinsMaxPositions);
83
+ tmpSymbol = new draw_symbols_js_1.SymbolCustom(symbolPinDefinitions, componentUnit.pinsMaxPositions);
83
84
  }
84
85
  }
85
- (0, layout_js_1.applyComponentParamsToSymbol)(component, tmpSymbol);
86
+ (0, layout_js_1.applyComponentParamsToSymbol)(componentUnit, tmpSymbol);
86
87
  tmpSymbol.refreshDrawing();
87
88
  const { width: useWidth, height: useHeight } = tmpSymbol.size();
88
- tmpComponent = new layout_js_1.RenderComponent(component, useWidth, useHeight);
89
+ tmpComponent = new layout_js_1.RenderComponent(component, componentUnit.unitId, useWidth, useHeight);
89
90
  tmpComponent.symbol = tmpSymbol;
90
91
  graph.setNode(tmpInstanceName, [RenderItemType.Component, tmpComponent, index]);
91
92
  let useFrame = frameStack[frameStack.length - 1];
@@ -113,7 +114,8 @@ class NetGraph {
113
114
  const [prevNodeType, prevNodeItem] = graph.node(previousNode);
114
115
  if (prevNodeType === RenderItemType.Component) {
115
116
  const matchingItem = nets.find(([comp, pin]) => {
116
- return comp.instanceName === previousNode
117
+ const unit = comp.getUnitForPin(pin);
118
+ return unit.instanceName === previousNode
117
119
  && pin.equals(previousPin);
118
120
  });
119
121
  if (matchingItem !== undefined) {
@@ -348,11 +350,11 @@ function getWireName(wireId) {
348
350
  return 'wire:' + wireId;
349
351
  }
350
352
  exports.getWireName = getWireName;
351
- function generateLayoutPinDefinition(component) {
352
- const pins = component.pins;
353
+ function generateLayoutPinDefinition(componentUnit) {
354
+ const pins = componentUnit.pins;
353
355
  const symbolPinDefinitions = [];
354
356
  const existingPinIds = Array.from(pins.keys());
355
- const arrangeProps = component.arrangeProps ?? [];
357
+ const arrangeProps = componentUnit.arrangeProps ?? [];
356
358
  const addedPins = [];
357
359
  for (const [key, items] of arrangeProps) {
358
360
  let useItems;
@@ -381,7 +383,7 @@ function generateLayoutPinDefinition(component) {
381
383
  return addedPins.find(id => id.equals(pinId)) === undefined;
382
384
  });
383
385
  if (unplacedPins.length > 0) {
384
- component._unplacedPins = unplacedPins;
386
+ componentUnit._unplacedPins = unplacedPins;
385
387
  console.warn("Warning: There are unplaced pins: " + unplacedPins);
386
388
  }
387
389
  return symbolPinDefinitions;