@design-core/core 0.0.7 → 51.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/.github/workflows/DesignCoreQA.yml +3 -0
  2. package/core/designCore.js +1 -1
  3. package/core/dimensions/alignedDimension.js +7 -7
  4. package/core/dimensions/angularDimension.js +32 -32
  5. package/core/dimensions/{baseCircularDimension.js → circularDimensionBase.js} +19 -19
  6. package/core/dimensions/diametricDimension.js +10 -10
  7. package/core/dimensions/dimension.js +42 -42
  8. package/core/dimensions/{baseDimension.js → dimensionBase.js} +17 -17
  9. package/core/dimensions/{baseLinearDimension.js → linearDimensionBase.js} +9 -9
  10. package/core/dimensions/radialDimension.js +8 -8
  11. package/core/dimensions/rotatedDimension.js +8 -8
  12. package/core/entities/arc.js +22 -22
  13. package/core/entities/arctext.js +13 -13
  14. package/core/entities/circle.js +7 -7
  15. package/core/entities/hatch.js +210 -40
  16. package/core/entities/insert.js +11 -6
  17. package/core/entities/point.js +19 -19
  18. package/core/entities/polyline.js +3 -3
  19. package/core/entities/{basePolyline.js → polylineBase.js} +18 -18
  20. package/core/entities/text.js +4 -4
  21. package/core/lib/boundingBox.js +11 -11
  22. package/core/lib/canvas.js +13 -6
  23. package/core/lib/clipboard.js +2 -2
  24. package/core/lib/dxf/dxf.js +11 -11
  25. package/core/lib/dxf/dxfIterator.js +2 -2
  26. package/core/lib/entityManager.js +19 -19
  27. package/core/lib/inputManager.js +1 -1
  28. package/core/lib/matrix.js +1 -1
  29. package/core/lib/patterns.js +1 -1
  30. package/core/lib/polylineUtils.js +9 -9
  31. package/core/lib/renderers/cairoRenderer.js +5 -5
  32. package/core/lib/renderers/canvasRenderer.js +4 -4
  33. package/core/lib/renderers/pdfRenderer.js +7 -7
  34. package/core/lib/renderers/rendererBase.js +1 -1
  35. package/core/lib/scene.js +1 -1
  36. package/core/lib/selectionManager.js +18 -18
  37. package/core/lib/utils.js +5 -5
  38. package/core/properties/entityProperties.js +2 -1
  39. package/core/properties/flags.js +12 -0
  40. package/core/properties/property.js +8 -3
  41. package/core/properties/propertyManager.js +52 -37
  42. package/core/tables/block.js +50 -46
  43. package/core/tables/dimStyle.js +5 -5
  44. package/core/tables/ltypeManager.js +1 -1
  45. package/core/tables/vport.js +2 -2
  46. package/core/tools/chamfer.js +6 -6
  47. package/core/tools/chamferFilletBase.js +4 -4
  48. package/core/tools/copy.js +8 -8
  49. package/core/tools/copybase.js +3 -3
  50. package/core/tools/copyclip.js +3 -3
  51. package/core/tools/cornerEntity.js +2 -2
  52. package/core/tools/cutclip.js +3 -3
  53. package/core/tools/explode.js +6 -6
  54. package/core/tools/extend.js +13 -13
  55. package/core/tools/fillet.js +6 -6
  56. package/core/tools/matchProp.js +1 -1
  57. package/core/tools/mirror.js +11 -11
  58. package/core/tools/move.js +5 -5
  59. package/core/tools/offset.js +29 -29
  60. package/core/tools/purge.js +10 -10
  61. package/core/tools/rotate.js +16 -16
  62. package/core/tools/scale.js +6 -6
  63. package/core/tools/trim.js +15 -15
  64. package/cspell.json +323 -0
  65. package/package.json +1 -1
  66. package/test/dimensions/alignedDimension.test.js +3 -3
  67. package/test/dimensions/angularDimension.test.js +7 -7
  68. package/test/dimensions/diametricDimension.test.js +9 -9
  69. package/test/dimensions/dimension.test.js +12 -12
  70. package/test/dimensions/{baseDimension.test.js → dimensionBase.test.js} +12 -12
  71. package/test/dimensions/{baseLinearDimension.test.js → linearDimensionBase.test.js} +7 -7
  72. package/test/dimensions/radialDimension.test.js +9 -9
  73. package/test/dimensions/rotatedDimension.test.js +4 -4
  74. package/test/entities/arc.test.js +10 -10
  75. package/test/entities/arctext.test.js +6 -6
  76. package/test/entities/circle.test.js +18 -18
  77. package/test/entities/hatch.test.js +362 -39
  78. package/test/entities/insert.test.js +9 -9
  79. package/test/entities/point.test.js +3 -3
  80. package/test/entities/{basePolyline.test.js → polylineBase.test.js} +131 -62
  81. package/test/entities/text.test.js +19 -19
  82. package/test/integration/exportIntegration.test.js +3 -3
  83. package/test/integration/userInputIntegration.test.js +5 -5
  84. package/test/lib/boundingBox.test.js +3 -3
  85. package/test/lib/canvas.test.js +9 -9
  86. package/test/lib/clipboard.test.js +73 -0
  87. package/test/lib/inputManager.test.js +4 -4
  88. package/test/lib/scene.test.js +9 -9
  89. package/test/lib/selectionManager.test.js +3 -3
  90. package/test/lib/snapping.test.js +1 -1
  91. package/test/properties/flags.test.js +24 -0
  92. package/test/properties/propertyManager.test.js +93 -22
  93. package/test/renderers/pdfRenderer.test.js +2 -2
  94. package/test/tables/block.test.js +63 -14
  95. package/test/tables/layerManager.test.js +2 -2
  96. package/test/test-helpers/hatchGridRenderer.js +3 -3
  97. package/test/test-helpers/test-helpers.js +6 -6
  98. package/test/tools/chamfer.test.js +60 -60
  99. package/test/tools/chamferFilletBase.test.js +36 -36
  100. package/test/tools/copy.test.js +6 -6
  101. package/test/tools/copybase.test.js +2 -2
  102. package/test/tools/copyclip.test.js +2 -2
  103. package/test/tools/cornerEntity.test.js +8 -8
  104. package/test/tools/cutclip.test.js +2 -2
  105. package/test/tools/erase.test.js +6 -6
  106. package/test/tools/explode.test.js +2 -2
  107. package/test/tools/extend.test.js +84 -84
  108. package/test/tools/fillet.test.js +62 -62
  109. package/test/tools/matchProp.test.js +6 -6
  110. package/test/tools/mirror.test.js +26 -26
  111. package/test/tools/move.test.js +7 -7
  112. package/test/tools/offset.test.js +65 -65
  113. package/test/tools/purge.test.js +4 -4
  114. package/test/tools/rotate.test.js +10 -10
  115. package/test/tools/scale.test.js +28 -28
  116. package/test/tools/trim.test.js +109 -109
  117. package/test/tools/zoom.test.js +15 -17
@@ -24,9 +24,9 @@ test.each(inputScenarios)('Trim.execute handles $desc', async (scenario) => {
24
24
  // clear all scene entities
25
25
  core.scene.clear();
26
26
  // create line
27
- core.scene.addItem('Line', { points: [new Point(), new Point(10, 0)] });
27
+ core.scene.addEntity('Line', { points: [new Point(), new Point(10, 0)] });
28
28
  // create circle
29
- core.scene.addItem('Circle', { points: [new Point(), new Point(10, 0)] });
29
+ core.scene.addEntity('Circle', { points: [new Point(), new Point(10, 0)] });
30
30
  // select line
31
31
  core.scene.selectionManager.selectionSet.selectionSet.push(0);
32
32
 
@@ -35,7 +35,7 @@ test.each(inputScenarios)('Trim.execute handles $desc', async (scenario) => {
35
35
  await extend.execute();
36
36
 
37
37
  expect(extend.selectedBoundaryItems[0]).toEqual(core.scene.entities.get(0));
38
- expect(extend.selectedItem).toBe(core.scene.entities.get(1));
38
+ expect(extend.selectedEntity).toBe(core.scene.entities.get(1));
39
39
  expect(actionSpy).toHaveBeenCalled();
40
40
  }, { extraMethods: { actionCommand: () => actionSpy() } });
41
41
  });
@@ -63,12 +63,12 @@ test('Test Extend.action', () => {
63
63
  // clear all scene entities
64
64
  core.scene.clear();
65
65
  // Add items to scene
66
- core.scene.addItem('Line', { points: [lineOneStart, lineOneEnd] });
67
- core.scene.addItem('Line', { points: [lineTwoStart, lineTwoEnd] });
66
+ core.scene.addEntity('Line', { points: [lineOneStart, lineOneEnd] });
67
+ core.scene.addEntity('Line', { points: [lineTwoStart, lineTwoEnd] });
68
68
  // Select boundary item
69
69
  extend.selectedBoundaryItems = [core.scene.entities.get(0)];
70
70
  // select item to trim
71
- extend.selectedItem = core.scene.entities.get(1);
71
+ extend.selectedEntity = core.scene.entities.get(1);
72
72
  // set mouse location - required for Extend
73
73
  core.mouse.setPosFromScenePoint(new Point(40, 50));
74
74
  // Perform Extend
@@ -95,12 +95,12 @@ test('Test Extend.action', () => {
95
95
  // clear scene items
96
96
  core.scene.clear();
97
97
  // Add items to scene
98
- core.scene.addItem('Line', { points: [lineTwoStart, lineTwoEnd] });
99
- core.scene.addItem('Line', { points: [lineThreeStart, lineThreeEnd] });
98
+ core.scene.addEntity('Line', { points: [lineTwoStart, lineTwoEnd] });
99
+ core.scene.addEntity('Line', { points: [lineThreeStart, lineThreeEnd] });
100
100
  // Select boundary item
101
101
  extend.selectedBoundaryItems = [core.scene.entities.get(0)];
102
102
  // select item to extend
103
- extend.selectedItem = core.scene.entities.get(1);
103
+ extend.selectedEntity = core.scene.entities.get(1);
104
104
  // set mouse location - required for Extend
105
105
  core.mouse.setPosFromScenePoint(new Point(0, 20));
106
106
  // Perform Extend
@@ -126,12 +126,12 @@ test('Test Extend.action', () => {
126
126
  // clear scene items
127
127
  core.scene.clear();
128
128
  // Add items to scene
129
- core.scene.addItem('Line', { points: [lineOneStart, lineOneEnd] });
130
- core.scene.addItem('Line', { points: [crossingLineStart, crossingLineEnd] });
129
+ core.scene.addEntity('Line', { points: [lineOneStart, lineOneEnd] });
130
+ core.scene.addEntity('Line', { points: [crossingLineStart, crossingLineEnd] });
131
131
  // Select boundary item
132
132
  extend.selectedBoundaryItems = [core.scene.entities.get(0)];
133
133
  // select item to extend
134
- extend.selectedItem = core.scene.entities.get(1);
134
+ extend.selectedEntity = core.scene.entities.get(1);
135
135
  // set mouse location - required for Extend
136
136
  core.mouse.setPosFromScenePoint(new Point(35, 35));
137
137
  // Perform Extend
@@ -158,8 +158,8 @@ test('Test Extend.action line - endpoint coincident with intersection', () => {
158
158
  const extend = new Extend();
159
159
  core.scene.clear();
160
160
 
161
- core.scene.addItem('Line', { points: [new Point(0, 50), new Point(25, 50)] });
162
- core.scene.addItem('Lwpolyline', { points: [
161
+ core.scene.addEntity('Line', { points: [new Point(0, 50), new Point(25, 50)] });
162
+ core.scene.addEntity('Lwpolyline', { points: [
163
163
  new Point(50, 0), new Point(50, 100), new Point(100, 100),
164
164
  new Point(100, 0), new Point(150, 0), new Point(150, 100),
165
165
  new Point(200, 100), new Point(200, 0),
@@ -171,7 +171,7 @@ test('Test Extend.action line - endpoint coincident with intersection', () => {
171
171
  const expected = [50, 100, 150, 200];
172
172
  for (const ex of expected) {
173
173
  extend.selectedBoundaryItems = [boundary];
174
- extend.selectedItem = line;
174
+ extend.selectedEntity = line;
175
175
  core.mouse.setPosFromScenePoint(new Point(line.points[1].x - 5, 50));
176
176
  extend.action();
177
177
  expect(line.points[1].x).toBe(ex);
@@ -188,11 +188,11 @@ test('Test Extend.action polyline - endpoint coincident with intersection', () =
188
188
  const extend = new Extend();
189
189
  core.scene.clear();
190
190
 
191
- core.scene.addItem('Lwpolyline', { points: [new Point(0, 0), new Point(50, 50)] });
192
- core.scene.addItem('Line', { points: [new Point(100, 0), new Point(100, 100)] });
191
+ core.scene.addEntity('Lwpolyline', { points: [new Point(0, 0), new Point(50, 50)] });
192
+ core.scene.addEntity('Line', { points: [new Point(100, 0), new Point(100, 100)] });
193
193
 
194
194
  extend.selectedBoundaryItems = [core.scene.entities.get(1)];
195
- extend.selectedItem = core.scene.entities.get(0);
195
+ extend.selectedEntity = core.scene.entities.get(0);
196
196
  core.mouse.setPosFromScenePoint(new Point(45, 45));
197
197
  extend.action();
198
198
 
@@ -210,11 +210,11 @@ test('Test Extend.action polyline - 2-point polyline extend start', () => {
210
210
  const extend = new Extend();
211
211
  core.scene.clear();
212
212
 
213
- core.scene.addItem('Lwpolyline', { points: [new Point(50, 0), new Point(100, 0)] });
214
- core.scene.addItem('Line', { points: [new Point(0, -50), new Point(0, 50)] });
213
+ core.scene.addEntity('Lwpolyline', { points: [new Point(50, 0), new Point(100, 0)] });
214
+ core.scene.addEntity('Line', { points: [new Point(0, -50), new Point(0, 50)] });
215
215
 
216
216
  extend.selectedBoundaryItems = [core.scene.entities.get(1)];
217
- extend.selectedItem = core.scene.entities.get(0);
217
+ extend.selectedEntity = core.scene.entities.get(0);
218
218
  core.mouse.setPosFromScenePoint(new Point(55, 0));
219
219
  extend.action();
220
220
 
@@ -234,11 +234,11 @@ test('Test Extend.action polyline - extend end segment', () => {
234
234
  const extend = new Extend();
235
235
  core.scene.clear();
236
236
 
237
- core.scene.addItem('Lwpolyline', { points: [new Point(0, 0), new Point(50, 0), new Point(75, 0)] });
238
- core.scene.addItem('Line', { points: [new Point(100, -50), new Point(100, 50)] });
237
+ core.scene.addEntity('Lwpolyline', { points: [new Point(0, 0), new Point(50, 0), new Point(75, 0)] });
238
+ core.scene.addEntity('Line', { points: [new Point(100, -50), new Point(100, 50)] });
239
239
 
240
240
  extend.selectedBoundaryItems = [core.scene.entities.get(1)];
241
- extend.selectedItem = core.scene.entities.get(0);
241
+ extend.selectedEntity = core.scene.entities.get(0);
242
242
  core.mouse.setPosFromScenePoint(new Point(80, 0));
243
243
  extend.action();
244
244
 
@@ -261,11 +261,11 @@ test('Test Extend.action polyline - extend start segment', () => {
261
261
  const extend = new Extend();
262
262
  core.scene.clear();
263
263
 
264
- core.scene.addItem('Lwpolyline', { points: [new Point(25, 0), new Point(50, 0), new Point(100, 0)] });
265
- core.scene.addItem('Line', { points: [new Point(0, -50), new Point(0, 50)] });
264
+ core.scene.addEntity('Lwpolyline', { points: [new Point(25, 0), new Point(50, 0), new Point(100, 0)] });
265
+ core.scene.addEntity('Line', { points: [new Point(0, -50), new Point(0, 50)] });
266
266
 
267
267
  extend.selectedBoundaryItems = [core.scene.entities.get(1)];
268
- extend.selectedItem = core.scene.entities.get(0);
268
+ extend.selectedEntity = core.scene.entities.get(0);
269
269
  core.mouse.setPosFromScenePoint(new Point(20, 0));
270
270
  extend.action();
271
271
 
@@ -288,11 +288,11 @@ test('Test Extend.action polyline - reject arc end segment', () => {
288
288
  const extend = new Extend();
289
289
  core.scene.clear();
290
290
 
291
- core.scene.addItem('Lwpolyline', { points: [new Point(0, 0), new Point(50, 0, 1), new Point(100, 0)] });
292
- core.scene.addItem('Line', { points: [new Point(125, -50), new Point(125, 50)] });
291
+ core.scene.addEntity('Lwpolyline', { points: [new Point(0, 0), new Point(50, 0, 1), new Point(100, 0)] });
292
+ core.scene.addEntity('Line', { points: [new Point(125, -50), new Point(125, 50)] });
293
293
 
294
294
  extend.selectedBoundaryItems = [core.scene.entities.get(1)];
295
- extend.selectedItem = core.scene.entities.get(0);
295
+ extend.selectedEntity = core.scene.entities.get(0);
296
296
  core.mouse.setPosFromScenePoint(new Point(100, 0));
297
297
  extend.action();
298
298
 
@@ -316,11 +316,11 @@ test('Test Extend.action polyline - reject intersection behind endpoint', () =>
316
316
  const extend = new Extend();
317
317
  core.scene.clear();
318
318
 
319
- core.scene.addItem('Lwpolyline', { points: [new Point(50, 0), new Point(75, 0), new Point(100, 0)] });
320
- core.scene.addItem('Line', { points: [new Point(25, -50), new Point(25, 50)] });
319
+ core.scene.addEntity('Lwpolyline', { points: [new Point(50, 0), new Point(75, 0), new Point(100, 0)] });
320
+ core.scene.addEntity('Line', { points: [new Point(25, -50), new Point(25, 50)] });
321
321
 
322
322
  extend.selectedBoundaryItems = [core.scene.entities.get(1)];
323
- extend.selectedItem = core.scene.entities.get(0);
323
+ extend.selectedEntity = core.scene.entities.get(0);
324
324
  core.mouse.setPosFromScenePoint(new Point(95, 0));
325
325
  extend.action();
326
326
 
@@ -339,11 +339,11 @@ test('Test Extend.action polyline - reject shortening intersection', () => {
339
339
  const extend = new Extend();
340
340
  core.scene.clear();
341
341
 
342
- core.scene.addItem('Lwpolyline', { points: [new Point(0, 0), new Point(50, 0), new Point(100, 0)] });
343
- core.scene.addItem('Line', { points: [new Point(75, -50), new Point(75, 50)] });
342
+ core.scene.addEntity('Lwpolyline', { points: [new Point(0, 0), new Point(50, 0), new Point(100, 0)] });
343
+ core.scene.addEntity('Line', { points: [new Point(75, -50), new Point(75, 50)] });
344
344
 
345
345
  extend.selectedBoundaryItems = [core.scene.entities.get(1)];
346
- extend.selectedItem = core.scene.entities.get(0);
346
+ extend.selectedEntity = core.scene.entities.get(0);
347
347
  core.mouse.setPosFromScenePoint(new Point(95, 0));
348
348
  extend.action();
349
349
 
@@ -362,11 +362,11 @@ test('Test Extend.action polyline - extend with arc start segment', () => {
362
362
  const extend = new Extend();
363
363
  core.scene.clear();
364
364
 
365
- core.scene.addItem('Lwpolyline', { points: [new Point(0, 0, 1), new Point(50, 0), new Point(100, 0)] });
366
- core.scene.addItem('Line', { points: [new Point(125, -50), new Point(125, 50)] });
365
+ core.scene.addEntity('Lwpolyline', { points: [new Point(0, 0, 1), new Point(50, 0), new Point(100, 0)] });
366
+ core.scene.addEntity('Line', { points: [new Point(125, -50), new Point(125, 50)] });
367
367
 
368
368
  extend.selectedBoundaryItems = [core.scene.entities.get(1)];
369
- extend.selectedItem = core.scene.entities.get(0);
369
+ extend.selectedEntity = core.scene.entities.get(0);
370
370
  core.mouse.setPosFromScenePoint(new Point(110, 0));
371
371
  extend.action();
372
372
 
@@ -383,11 +383,11 @@ test('Test Extend.action polyline - no intersections', () => {
383
383
  const extend = new Extend();
384
384
  core.scene.clear();
385
385
 
386
- core.scene.addItem('Lwpolyline', { points: [new Point(0, 0), new Point(50, 0)] });
387
- core.scene.addItem('Line', { points: [new Point(0, 50), new Point(100, 50)] });
386
+ core.scene.addEntity('Lwpolyline', { points: [new Point(0, 0), new Point(50, 0)] });
387
+ core.scene.addEntity('Line', { points: [new Point(0, 50), new Point(100, 50)] });
388
388
 
389
389
  extend.selectedBoundaryItems = [core.scene.entities.get(1)];
390
- extend.selectedItem = core.scene.entities.get(0);
390
+ extend.selectedEntity = core.scene.entities.get(0);
391
391
  core.mouse.setPosFromScenePoint(new Point(45, 0));
392
392
  extend.action();
393
393
 
@@ -410,7 +410,7 @@ test('Extend.preview does not throw', () => {
410
410
 
411
411
  test('Extend.preview returns early when no boundary items set', () => {
412
412
  core.scene.clear();
413
- core.scene.addItem('Line', { points: [new Point(100, -10), new Point(100, 10)] });
413
+ core.scene.addEntity('Line', { points: [new Point(100, -10), new Point(100, 10)] });
414
414
  DesignCore.Scene.previewEntities.clear();
415
415
 
416
416
  const extend = new Extend();
@@ -422,8 +422,8 @@ test('Extend.preview returns early when no boundary items set', () => {
422
422
 
423
423
  test('Extend.preview returns early when findClosestItem returns undefined', () => {
424
424
  core.scene.clear();
425
- core.scene.addItem('Line', { points: [new Point(100, -10), new Point(100, 10)] });
426
- core.scene.addItem('Line', { points: [new Point(0, 0), new Point(50, 0)] });
425
+ core.scene.addEntity('Line', { points: [new Point(100, -10), new Point(100, 10)] });
426
+ core.scene.addEntity('Line', { points: [new Point(0, 0), new Point(50, 0)] });
427
427
  DesignCore.Scene.previewEntities.clear();
428
428
 
429
429
  const extend = new Extend();
@@ -439,8 +439,8 @@ test('Extend.preview returns early when findClosestItem returns undefined', () =
439
439
  test('Extend.preview returns early when hovered entity does not implement extend', () => {
440
440
  // Circle does not override Entity.extend() — preview must not emit a notification.
441
441
  core.scene.clear();
442
- core.scene.addItem('Line', { points: [new Point(100, -10), new Point(100, 10)] }); // boundary
443
- core.scene.addItem('Circle', { points: [new Point(0, 0), new Point(5, 0)] }); // unsupported
442
+ core.scene.addEntity('Line', { points: [new Point(100, -10), new Point(100, 10)] }); // boundary
443
+ core.scene.addEntity('Circle', { points: [new Point(0, 0), new Point(5, 0)] }); // unsupported
444
444
  DesignCore.Scene.previewEntities.clear();
445
445
 
446
446
  const notifySpy = jest.spyOn(core, 'notify');
@@ -460,8 +460,8 @@ test('Extend.preview returns early when hovered entity does not implement extend
460
460
  test('Extend.preview returns early when hovered entity has no valid extension', () => {
461
461
  // Hovered line is parallel to the boundary — no intersection ahead of its endpoint.
462
462
  core.scene.clear();
463
- core.scene.addItem('Line', { points: [new Point(0, 50), new Point(100, 50)] }); // boundary (horizontal)
464
- core.scene.addItem('Line', { points: [new Point(0, 0), new Point(50, 0)] }); // hovered (parallel, y=0)
463
+ core.scene.addEntity('Line', { points: [new Point(0, 50), new Point(100, 50)] }); // boundary (horizontal)
464
+ core.scene.addEntity('Line', { points: [new Point(0, 0), new Point(50, 0)] }); // hovered (parallel, y=0)
465
465
  DesignCore.Scene.previewEntities.clear();
466
466
 
467
467
  const extend = new Extend();
@@ -479,8 +479,8 @@ test('Extend.preview populates previewEntities when entity can be extended', ()
479
479
  // Vertical boundary at x=100; short horizontal line from (0,0) to (50,0).
480
480
  // Mouse near end (45,0) → end extends to (100,0).
481
481
  core.scene.clear();
482
- core.scene.addItem('Line', { points: [new Point(100, -10), new Point(100, 10)] }); // boundary
483
- core.scene.addItem('Line', { points: [new Point(0, 0), new Point(50, 0)] }); // hovered
482
+ core.scene.addEntity('Line', { points: [new Point(100, -10), new Point(100, 10)] }); // boundary
483
+ core.scene.addEntity('Line', { points: [new Point(0, 0), new Point(50, 0)] }); // hovered
484
484
  DesignCore.Scene.previewEntities.clear();
485
485
 
486
486
  const extend = new Extend();
@@ -502,7 +502,7 @@ test('Extend.preview populates previewEntities when entity can be extended', ()
502
502
  test('Extend.execute returns early when boundary input is undefined', async () => {
503
503
  core.scene.clear();
504
504
  core.scene.selectionManager.reset();
505
- core.scene.addItem('Line', { points: [new Point(), new Point(10, 0)] });
505
+ core.scene.addEntity('Line', { points: [new Point(), new Point(10, 0)] });
506
506
 
507
507
  await withMockInput(core.scene, [undefined], async () => {
508
508
  const extend = new Extend();
@@ -514,8 +514,8 @@ test('Extend.execute returns early when boundary input is undefined', async () =
514
514
  test('Extend.execute exits selection loop when selection input is undefined', async () => {
515
515
  core.scene.clear();
516
516
  core.scene.selectionManager.reset();
517
- core.scene.addItem('Line', { points: [new Point(100, -10), new Point(100, 10)] });
518
- core.scene.addItem('Line', { points: [new Point(0, 0), new Point(50, 0)] });
517
+ core.scene.addEntity('Line', { points: [new Point(100, -10), new Point(100, 10)] });
518
+ core.scene.addEntity('Line', { points: [new Point(0, 0), new Point(50, 0)] });
519
519
  core.scene.selectionManager.selectionSet.selectionSet.push(0);
520
520
 
521
521
  const executeCommandSpy = jest.fn();
@@ -530,9 +530,9 @@ test('Extend.execute exits selection loop when selection input is undefined', as
530
530
  test('Extend.execute calls actionCommand once per extend selection', async () => {
531
531
  core.scene.clear();
532
532
  core.scene.selectionManager.reset();
533
- core.scene.addItem('Line', { points: [new Point(100, -10), new Point(100, 10)] });
534
- core.scene.addItem('Line', { points: [new Point(0, 0), new Point(50, 0)] });
535
- core.scene.addItem('Line', { points: [new Point(0, 5), new Point(50, 5)] });
533
+ core.scene.addEntity('Line', { points: [new Point(100, -10), new Point(100, 10)] });
534
+ core.scene.addEntity('Line', { points: [new Point(0, 0), new Point(50, 0)] });
535
+ core.scene.addEntity('Line', { points: [new Point(0, 5), new Point(50, 5)] });
536
536
  core.scene.selectionManager.selectionSet.selectionSet.push(0);
537
537
 
538
538
  const actionSpy = jest.fn();
@@ -548,11 +548,11 @@ test('Extend.execute calls actionCommand once per extend selection', async () =>
548
548
  );
549
549
  });
550
550
 
551
- test('Extend.action does nothing when selectedItem is null', () => {
551
+ test('Extend.action does nothing when selectedEntity is null', () => {
552
552
  core.scene.clear();
553
- core.scene.addItem('Line', { points: [new Point(), new Point(10, 0)] });
553
+ core.scene.addEntity('Line', { points: [new Point(), new Point(10, 0)] });
554
554
  const extend = new Extend();
555
- extend.selectedItem = null;
555
+ extend.selectedEntity = null;
556
556
  extend.selectedBoundaryItems = [core.scene.entities.get(0)];
557
557
 
558
558
  expect(() => extend.action()).not.toThrow();
@@ -560,24 +560,24 @@ test('Extend.action does nothing when selectedItem is null', () => {
560
560
 
561
561
  test('Extend.action does nothing when selectedBoundaryItems is empty', () => {
562
562
  core.scene.clear();
563
- core.scene.addItem('Line', { points: [new Point(), new Point(10, 0)] });
563
+ core.scene.addEntity('Line', { points: [new Point(), new Point(10, 0)] });
564
564
  const extend = new Extend();
565
- extend.selectedItem = core.scene.entities.get(0);
565
+ extend.selectedEntity = core.scene.entities.get(0);
566
566
  extend.selectedBoundaryItems = [];
567
567
 
568
568
  expect(() => extend.action()).not.toThrow();
569
- expect(extend.selectedItem).toBeNull();
569
+ expect(extend.selectedEntity).toBeNull();
570
570
  });
571
571
 
572
572
  test('Extend.action notifies NOEXTEND when selected entity lacks fromPolylinePoints', () => {
573
573
  // Use a stub entity that has toPolylinePoints but no fromPolylinePoints.
574
574
  // action() must notify and not throw.
575
575
  core.scene.clear();
576
- core.scene.addItem('Line', { points: [new Point(100, -10), new Point(100, 10)] }); // boundary
576
+ core.scene.addEntity('Line', { points: [new Point(100, -10), new Point(100, 10)] }); // boundary
577
577
 
578
578
  const extend = new Extend();
579
579
  extend.selectedBoundaryItems = [core.scene.entities.get(0)];
580
- extend.selectedItem = {
580
+ extend.selectedEntity = {
581
581
  type: 'FakeEntity',
582
582
  toPolylinePoints: () => [new Point(0, 0), new Point(50, 0)],
583
583
  // deliberately no fromPolylinePoints
@@ -588,30 +588,30 @@ test('Extend.action notifies NOEXTEND when selected entity lacks fromPolylinePoi
588
588
  extend.action();
589
589
 
590
590
  expect(notifySpy).toHaveBeenCalledWith(expect.stringContaining(Strings.Message.NOEXTEND));
591
- expect(extend.selectedItem).toBeNull();
591
+ expect(extend.selectedEntity).toBeNull();
592
592
  notifySpy.mockRestore();
593
593
  });
594
594
 
595
595
  test('Extend.action notifies NOEXTEND when selected entity is a closed polyline', () => {
596
596
  // Closed polylines have no open endpoints — extend must notify and leave the entity unchanged.
597
597
  core.scene.clear();
598
- core.scene.addItem('Line', { points: [new Point(200, -10), new Point(200, 10)] }); // boundary
598
+ core.scene.addEntity('Line', { points: [new Point(200, -10), new Point(200, 10)] }); // boundary
599
599
  // Closed square: flag bit 1 set
600
- core.scene.addItem('Lwpolyline', {
600
+ core.scene.addEntity('Lwpolyline', {
601
601
  points: [new Point(0, 0), new Point(100, 0), new Point(100, 100), new Point(0, 100)],
602
602
  flags: 1,
603
603
  });
604
604
 
605
605
  const extend = new Extend();
606
606
  extend.selectedBoundaryItems = [core.scene.entities.get(0)];
607
- extend.selectedItem = core.scene.entities.get(1);
607
+ extend.selectedEntity = core.scene.entities.get(1);
608
608
  core.mouse.setPosFromScenePoint(new Point(95, 0));
609
609
 
610
610
  const notifySpy = jest.spyOn(core, 'notify').mockImplementation(() => {});
611
611
  extend.action();
612
612
 
613
613
  expect(notifySpy).toHaveBeenCalledWith(expect.stringContaining(Strings.Message.NOEXTEND));
614
- expect(extend.selectedItem).toBeNull();
614
+ expect(extend.selectedEntity).toBeNull();
615
615
  notifySpy.mockRestore();
616
616
  });
617
617
 
@@ -619,7 +619,7 @@ test('Extend.preview silently skips entity that lacks fromPolylinePoints', () =>
619
619
  // Stub entity implements toPolylinePoints but not fromPolylinePoints.
620
620
  // preview() must return early without calling notify.
621
621
  core.scene.clear();
622
- core.scene.addItem('Line', { points: [new Point(100, -10), new Point(100, 10)] }); // boundary
622
+ core.scene.addEntity('Line', { points: [new Point(100, -10), new Point(100, 10)] }); // boundary
623
623
  DesignCore.Scene.previewEntities.clear();
624
624
 
625
625
  const stubEntity = {
@@ -648,30 +648,30 @@ test('Extend.preview silently skips entity that lacks fromPolylinePoints', () =>
648
648
  test('Extend.action notifies when no intersection found (parallel lines)', () => {
649
649
  core.scene.clear();
650
650
  // Two parallel horizontal lines — no intersection possible
651
- core.scene.addItem('Line', { points: [new Point(0, 0), new Point(100, 0)] });
652
- core.scene.addItem('Line', { points: [new Point(0, 50), new Point(50, 50)] });
651
+ core.scene.addEntity('Line', { points: [new Point(0, 0), new Point(100, 0)] });
652
+ core.scene.addEntity('Line', { points: [new Point(0, 50), new Point(50, 50)] });
653
653
 
654
654
  const extend = new Extend();
655
655
  extend.selectedBoundaryItems = [core.scene.entities.get(0)];
656
- extend.selectedItem = core.scene.entities.get(1);
656
+ extend.selectedEntity = core.scene.entities.get(1);
657
657
  core.mouse.setPosFromScenePoint(new Point(40, 50));
658
658
 
659
659
  const notifySpy = jest.spyOn(core, 'notify').mockImplementation(() => {});
660
660
  extend.action();
661
661
 
662
662
  expect(notifySpy).toHaveBeenCalledWith(expect.stringContaining(Strings.Message.NOEXTEND));
663
- expect(extend.selectedItem).toBeNull();
663
+ expect(extend.selectedEntity).toBeNull();
664
664
  notifySpy.mockRestore();
665
665
  });
666
666
 
667
667
  test('Extend.action notifies when boundary item equals selected item', () => {
668
668
  core.scene.clear();
669
- core.scene.addItem('Line', { points: [new Point(0, 0), new Point(50, 0)] });
669
+ core.scene.addEntity('Line', { points: [new Point(0, 0), new Point(50, 0)] });
670
670
  const entity = core.scene.entities.get(0);
671
671
 
672
672
  const extend = new Extend();
673
673
  extend.selectedBoundaryItems = [entity];
674
- extend.selectedItem = entity;
674
+ extend.selectedEntity = entity;
675
675
  core.mouse.setPosFromScenePoint(new Point(40, 0));
676
676
 
677
677
  const notifySpy = jest.spyOn(core, 'notify').mockImplementation(() => {});
@@ -686,12 +686,12 @@ test('Extend.action extends the start of a line', () => {
686
686
  // Boundary: vertical line at x=0
687
687
  // Mouse near the start (50,50) → extend start back to x=0
688
688
  core.scene.clear();
689
- core.scene.addItem('Line', { points: [new Point(0, 0), new Point(0, 100)] });
690
- core.scene.addItem('Line', { points: [new Point(50, 50), new Point(100, 50)] });
689
+ core.scene.addEntity('Line', { points: [new Point(0, 0), new Point(0, 100)] });
690
+ core.scene.addEntity('Line', { points: [new Point(50, 50), new Point(100, 50)] });
691
691
 
692
692
  const extend = new Extend();
693
693
  extend.selectedBoundaryItems = [core.scene.entities.get(0)];
694
- extend.selectedItem = core.scene.entities.get(1);
694
+ extend.selectedEntity = core.scene.entities.get(1);
695
695
  core.mouse.setPosFromScenePoint(new Point(55, 50));
696
696
  extend.action();
697
697
 
@@ -705,22 +705,22 @@ test('Extend.action notifies NOEXTEND when end segment of an Arc is curved', ()
705
705
  // A standalone Arc always has a non-zero bulge on its single segment.
706
706
  // #extendEntity must reject the extension and notify because endSegmentBulge !== 0.
707
707
  core.scene.clear();
708
- core.scene.addItem('Arc', {
708
+ core.scene.addEntity('Arc', {
709
709
  points: [new Point(0, 0), new Point(10, 0), new Point(0, 10)],
710
710
  direction: 1,
711
711
  });
712
712
  // Vertical boundary at x=5 — intersects the CCW quarter-arc
713
- core.scene.addItem('Line', { points: [new Point(5, -20), new Point(5, 20)] });
713
+ core.scene.addEntity('Line', { points: [new Point(5, -20), new Point(5, 20)] });
714
714
 
715
715
  const extend = new Extend();
716
716
  extend.selectedBoundaryItems = [core.scene.entities.get(1)];
717
- extend.selectedItem = core.scene.entities.get(0);
717
+ extend.selectedEntity = core.scene.entities.get(0);
718
718
  core.mouse.setPosFromScenePoint(new Point(9, 1)); // near arc start (10,0)
719
719
 
720
720
  const notifySpy = jest.spyOn(core, 'notify').mockImplementation(() => {});
721
721
  extend.action();
722
722
 
723
723
  expect(notifySpy).toHaveBeenCalledWith(expect.stringContaining(Strings.Message.NOEXTEND));
724
- expect(extend.selectedItem).toBeNull();
724
+ expect(extend.selectedEntity).toBeNull();
725
725
  notifySpy.mockRestore();
726
726
  });