@design-core/core 0.0.1 → 0.0.3

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 (254) hide show
  1. package/.eslintrc.json +14 -7
  2. package/.github/workflows/DesignCoreQA.yml +3 -1
  3. package/README.md +11 -4
  4. package/TODO.md +19 -0
  5. package/core/core/core.js +49 -42
  6. package/core/designCore.js +61 -2
  7. package/core/dimensions/alignedDimension.js +142 -0
  8. package/core/dimensions/angularDimension.js +550 -0
  9. package/core/dimensions/baseCircularDimension.js +244 -0
  10. package/core/dimensions/baseDimension.js +558 -0
  11. package/core/dimensions/baseLinearDimension.js +371 -0
  12. package/core/dimensions/diametricDimension.js +82 -0
  13. package/core/dimensions/dimension.js +298 -0
  14. package/core/dimensions/linearDimension.js +29 -0
  15. package/core/dimensions/radialDimension.js +78 -0
  16. package/core/dimensions/rotatedDimension.js +167 -0
  17. package/core/entities/arc.js +314 -60
  18. package/core/entities/arctext.js +642 -0
  19. package/core/entities/basePolyline.js +553 -94
  20. package/core/entities/circle.js +181 -54
  21. package/core/entities/entity.js +154 -74
  22. package/core/entities/hatch.js +807 -0
  23. package/core/entities/insert.js +200 -39
  24. package/core/entities/line.js +196 -134
  25. package/core/entities/lwpolyline.js +21 -44
  26. package/core/entities/point.js +194 -29
  27. package/core/entities/polyline.js +54 -7
  28. package/core/entities/rectangle.js +43 -13
  29. package/core/entities/solid.js +43 -6
  30. package/core/entities/text.js +324 -181
  31. package/core/lib/boundingBox.js +73 -13
  32. package/core/lib/canvas.js +256 -65
  33. package/core/lib/clipboard.js +198 -0
  34. package/core/lib/colour.js +144 -0
  35. package/core/lib/colours.js +367 -301
  36. package/core/lib/commandLine.js +16 -28
  37. package/core/lib/commandManager.js +115 -58
  38. package/core/lib/constants.js +23 -0
  39. package/core/lib/dxf/dxf.js +249 -34
  40. package/core/lib/dxf/dxfFile.js +23 -38
  41. package/core/lib/dxf/dxfIterator.js +17 -5
  42. package/core/lib/dxf/dxfRead.js +23 -7
  43. package/core/lib/dxf/dxfWrite.js +39 -129
  44. package/core/lib/dxf/handleManager.js +97 -0
  45. package/core/lib/dxf/sections/blocks.js +16 -2
  46. package/core/lib/dxf/sections/entities.js +17 -3
  47. package/core/lib/dxf/sections/header.js +10 -1
  48. package/core/lib/dxf/sections/objects.js +36 -0
  49. package/core/lib/dxf/sections/section.js +43 -5
  50. package/core/lib/dxf/sections/tables.js +17 -3
  51. package/core/lib/entityManager.js +178 -0
  52. package/core/lib/fileio.js +14 -4
  53. package/core/lib/headers.js +229 -0
  54. package/core/lib/input.js +46 -0
  55. package/core/lib/inputManager.js +199 -194
  56. package/core/lib/intersect.js +341 -468
  57. package/core/lib/logging.js +25 -1
  58. package/core/lib/matrix.js +6 -8
  59. package/core/lib/mouse.js +24 -79
  60. package/core/lib/patterns.js +690 -0
  61. package/core/lib/promptOptions.js +133 -0
  62. package/core/lib/scene.js +71 -174
  63. package/core/lib/selectionManager.js +74 -48
  64. package/core/lib/selectionWindow.js +24 -10
  65. package/core/lib/settings.js +18 -11
  66. package/core/lib/snapping.js +129 -21
  67. package/core/lib/stateManager.js +288 -0
  68. package/core/lib/strings.js +57 -5
  69. package/core/lib/utils.js +95 -11
  70. package/core/objects/dictionary.js +43 -0
  71. package/core/objects/dictionaryManager.js +80 -0
  72. package/core/properties/dimType.js +117 -0
  73. package/core/properties/flags.js +66 -0
  74. package/core/properties/property.js +26 -0
  75. package/core/properties/propertyManager.js +65 -19
  76. package/core/tables/appId.js +31 -0
  77. package/core/tables/appIdManager.js +44 -0
  78. package/core/tables/block.js +323 -0
  79. package/core/tables/blockManager.js +48 -0
  80. package/core/tables/blockRecord.js +29 -0
  81. package/core/tables/blockRecordManager.js +37 -0
  82. package/core/tables/dimStyle.js +627 -0
  83. package/core/tables/dimStyleManager.js +187 -0
  84. package/core/tables/endblk.js +28 -0
  85. package/core/tables/layer.js +219 -0
  86. package/core/tables/layerManager.js +47 -0
  87. package/core/tables/ltype.js +85 -0
  88. package/core/tables/ltypeManager.js +65 -0
  89. package/core/tables/style.js +145 -0
  90. package/core/tables/styleManager.js +55 -0
  91. package/core/tables/styleManagerBase.js +110 -0
  92. package/core/tables/tableManagerBase.js +354 -0
  93. package/core/tables/ucs.js +28 -0
  94. package/core/tables/ucsManager.js +44 -0
  95. package/core/tables/view.js +28 -0
  96. package/core/tables/viewManager.js +44 -0
  97. package/core/tables/vport.js +70 -0
  98. package/core/tables/vportManager.js +65 -0
  99. package/core/tools/chamfer.js +343 -0
  100. package/core/tools/chamferFilletBase.js +162 -0
  101. package/core/tools/copy.js +68 -40
  102. package/core/tools/copybase.js +65 -0
  103. package/core/tools/copyclip.js +59 -0
  104. package/core/tools/cornerEntity.js +138 -0
  105. package/core/tools/cutclip.js +72 -0
  106. package/core/tools/distance.js +37 -9
  107. package/core/tools/erase.js +43 -13
  108. package/core/tools/explode.js +117 -0
  109. package/core/tools/extend.js +71 -32
  110. package/core/tools/fillet.js +336 -0
  111. package/core/tools/identify.js +33 -6
  112. package/core/tools/matchProp.js +106 -0
  113. package/core/tools/mirror.js +141 -0
  114. package/core/tools/move.js +65 -32
  115. package/core/tools/offset.js +321 -0
  116. package/core/tools/pan.js +54 -0
  117. package/core/tools/pasteclip.js +93 -0
  118. package/core/tools/purge.js +90 -0
  119. package/core/tools/rotate.js +105 -70
  120. package/core/tools/scale.js +166 -0
  121. package/core/tools/tool.js +14 -4
  122. package/core/tools/trim.js +71 -32
  123. package/core/tools/zoom.js +152 -0
  124. package/package.json +3 -305
  125. package/test/dimensions/alignedDimension.test.js +211 -0
  126. package/test/dimensions/angularDimension.test.js +243 -0
  127. package/test/dimensions/baseDimension.test.js +239 -0
  128. package/test/dimensions/diametricDimension.test.js +203 -0
  129. package/test/dimensions/dimension.test.js +102 -0
  130. package/test/dimensions/radialDimension.test.js +203 -0
  131. package/test/dimensions/rotatedDimension.test.js +224 -0
  132. package/test/entities/arc.test.js +463 -41
  133. package/test/entities/arctext.test.js +329 -0
  134. package/test/entities/basePolyline.test.js +459 -10
  135. package/test/entities/circle.test.js +312 -7
  136. package/test/entities/entity.test.js +28 -9
  137. package/test/entities/hatch.test.js +606 -0
  138. package/test/entities/insert.test.js +90 -0
  139. package/test/entities/line.test.js +182 -6
  140. package/test/entities/point.test.js +375 -37
  141. package/test/entities/solid.test.js +156 -0
  142. package/test/entities/text.test.js +533 -7
  143. package/test/integration/exportIntegration.reference.dxf +1706 -0
  144. package/test/integration/exportIntegration.test.js +186 -0
  145. package/test/integration/importExportIntegration.test.js +126 -0
  146. package/test/integration/intersectionIntegration.test.js +880 -0
  147. package/test/integration/userInputIntegration.reference.dxf +1410 -0
  148. package/test/integration/userInputIntegration.test.js +269 -0
  149. package/test/lib/boundingBox.test.js +26 -2
  150. package/test/lib/canvas.test.js +613 -5
  151. package/test/lib/clipboard.test.js +70 -0
  152. package/test/lib/colour.test.js +114 -0
  153. package/test/lib/colours.test.js +63 -18
  154. package/test/lib/commandLine.test.js +159 -22
  155. package/test/lib/commandManager.test.js +4 -4
  156. package/test/lib/constants.test.js +9 -0
  157. package/test/lib/dxf/dxfFile.test.js +6 -2
  158. package/test/lib/dxf/dxfIterator.test.js +1 -1
  159. package/test/lib/dxf/dxfWrite.test.js +173 -0
  160. package/test/lib/dxf/handleManager.test.js +137 -0
  161. package/test/lib/dxf/sections/blocks.test.js +5 -5
  162. package/test/lib/dxf/sections/entities.test.js +4 -4
  163. package/test/lib/dxf/sections/header.test.js +18 -4
  164. package/test/lib/dxf/sections/objects.test.js +132 -0
  165. package/test/lib/dxf/sections/section.test.js +29 -29
  166. package/test/lib/dxf/sections/tables.test.js +3 -3
  167. package/test/lib/entityManager.test.js +163 -0
  168. package/test/lib/headers.test.js +233 -0
  169. package/test/lib/inputManager.test.js +1144 -5
  170. package/test/lib/intersect.test.js +454 -331
  171. package/test/lib/logging.test.js +1 -1
  172. package/test/lib/matrix.test.js +1 -1
  173. package/test/lib/mouse.test.js +327 -4
  174. package/test/lib/patterns.test.js +105 -0
  175. package/test/lib/promptOptions.test.js +179 -0
  176. package/test/lib/scene.test.js +16 -52
  177. package/test/lib/selectionManager.test.js +17 -5
  178. package/test/lib/settings.test.js +111 -5
  179. package/test/lib/snapping.test.js +142 -4
  180. package/test/lib/stateManager.test.js +155 -0
  181. package/test/lib/utils.test.js +81 -1
  182. package/test/objects/dictionary.test.js +81 -0
  183. package/test/objects/dictionaryManager.test.js +34 -0
  184. package/test/properties/dimType.test.js +62 -0
  185. package/test/properties/flags.test.js +164 -0
  186. package/test/properties/property.test.js +13 -0
  187. package/test/properties/propertyManager.test.js +10 -11
  188. package/test/tables/appId.test.js +46 -0
  189. package/test/tables/appIdManager.test.js +72 -0
  190. package/test/tables/block.test.js +157 -0
  191. package/test/tables/blockManager.test.js +52 -0
  192. package/test/tables/blockRecord.test.js +39 -0
  193. package/test/tables/blockRecordManager.test.js +60 -0
  194. package/test/tables/dimstyle.test.js +72 -0
  195. package/test/tables/endblk.test.js +30 -0
  196. package/test/tables/layer.test.js +95 -0
  197. package/test/tables/layerManager.test.js +172 -0
  198. package/test/{styles → tables}/ltype.test.js +7 -7
  199. package/test/{styles → tables}/ltypeManager.test.js +2 -2
  200. package/test/tables/style.test.js +44 -0
  201. package/test/tables/stylemanagerbase.test.js +220 -0
  202. package/test/tables/tableManagerBase.test.js +194 -0
  203. package/test/tables/ucs.test.js +37 -0
  204. package/test/tables/ucsManager.test.js +48 -0
  205. package/test/tables/view.test.js +37 -0
  206. package/test/tables/viewManager.test.js +48 -0
  207. package/test/tables/vport.test.js +117 -0
  208. package/test/tables/vportManager.test.js +54 -0
  209. package/test/test-helpers/test-helpers.js +66 -0
  210. package/test/tools/chamfer.test.js +970 -0
  211. package/test/tools/chamferFilletBase.test.js +446 -0
  212. package/test/tools/copy.test.js +22 -14
  213. package/test/tools/copybase.test.js +93 -0
  214. package/test/tools/copyclip.test.js +92 -0
  215. package/test/tools/cornerEntity.test.js +201 -0
  216. package/test/tools/cutclip.test.js +94 -0
  217. package/test/tools/distance.test.js +140 -18
  218. package/test/tools/erase.test.js +12 -12
  219. package/test/tools/explode.test.js +45 -0
  220. package/test/tools/extend.test.js +326 -44
  221. package/test/tools/fillet.test.js +831 -0
  222. package/test/tools/identify.test.js +115 -16
  223. package/test/tools/matchProp.test.js +84 -0
  224. package/test/tools/mirror.test.js +475 -0
  225. package/test/tools/move.test.js +75 -19
  226. package/test/tools/offset.test.js +748 -0
  227. package/test/tools/pan.test.js +72 -0
  228. package/test/tools/pasteclip.test.js +100 -0
  229. package/test/tools/purge.test.js +89 -0
  230. package/test/tools/rotate.test.js +89 -23
  231. package/test/tools/scale.test.js +529 -0
  232. package/test/tools/trim.test.js +419 -84
  233. package/test/tools/zoom.test.js +504 -0
  234. package/core/entities/alignedDimension.js +0 -279
  235. package/core/entities/angularDimension.js +0 -194
  236. package/core/entities/baseDimension.js +0 -227
  237. package/core/entities/block.js +0 -247
  238. package/core/entities/diametricDimension.js +0 -133
  239. package/core/entities/dimension.js +0 -202
  240. package/core/entities/radialDimension.js +0 -126
  241. package/core/styles/dimStyle.js +0 -719
  242. package/core/styles/dimStyleManager.js +0 -47
  243. package/core/styles/layer.js +0 -133
  244. package/core/styles/layerManager.js +0 -40
  245. package/core/styles/ltype.js +0 -86
  246. package/core/styles/ltypeManager.js +0 -50
  247. package/core/styles/style.js +0 -158
  248. package/core/styles/styleManager.js +0 -43
  249. package/core/styles/styleManagerBase.js +0 -299
  250. package/test/entities/block.test.js +0 -22
  251. package/test/styles/dimstyle.test.js +0 -19
  252. package/test/styles/layerManager.test.js +0 -150
  253. package/test/styles/style.test.js +0 -33
  254. package/test/styles/stylemanagerbase.test.js +0 -219
@@ -0,0 +1,178 @@
1
+
2
+ import { DesignCore } from '../designCore.js';
3
+
4
+ /**
5
+ * Entity Manager Class
6
+ * Holds all entity instances and manages all changes to them
7
+ */
8
+ export class EntityManager {
9
+ #entities = [];
10
+ #trackHandles;
11
+
12
+ /**
13
+ * Create EntityManager
14
+ * @param {boolean} [trackHandles=true] - whether to track handles for entities
15
+ */
16
+ constructor(trackHandles = true) {
17
+ this.#trackHandles = trackHandles;
18
+ }
19
+
20
+ /**
21
+ * Create and add new entity
22
+ * @param {string} type
23
+ * @param {object} data
24
+ */
25
+ create(type, data) {
26
+ data.layer = DesignCore.LayerManager.getCstyle();
27
+ const entity = DesignCore.CommandManager.createNew(type, data);
28
+ this.add(entity);
29
+ }
30
+
31
+ /**
32
+ * Add entity to manager
33
+ * @param {object} entity
34
+ */
35
+ add(entity) {
36
+ if (!entity) return;
37
+
38
+ if (this.#trackHandles) {
39
+ if (entity.handle === undefined) {
40
+ entity.handle = DesignCore.HandleManager.next();
41
+ } else {
42
+ DesignCore.HandleManager.checkHandle(entity.handle);
43
+ }
44
+ }
45
+
46
+ this.#entities.push(entity);
47
+ }
48
+
49
+ /**
50
+ * Remove entity at index
51
+ * @param {number} index
52
+ */
53
+ remove(index) {
54
+ if (this.#trackHandles) {
55
+ const entity = this.#entities[index];
56
+ if (entity?.handle !== undefined) {
57
+ DesignCore.HandleManager.releaseHandle(entity.handle);
58
+ }
59
+ }
60
+ this.#entities.splice(index, 1);
61
+ }
62
+
63
+ /**
64
+ * Get entity at index
65
+ * @param {number} index
66
+ * @return {object} entity
67
+ */
68
+ get(index) {
69
+ return this.#entities.at(index);
70
+ }
71
+
72
+ /**
73
+ * Return all entities
74
+ * @return {Array} all entities
75
+ */
76
+ getAll() {
77
+ return this.#entities;
78
+ }
79
+
80
+ /**
81
+ * Replace entity at index
82
+ * @param {number} index
83
+ * @param {object} entity
84
+ */
85
+ replace(index, entity) {
86
+ this.#entities.splice(index, 1, entity);
87
+ }
88
+
89
+ /**
90
+ * Find items in scene
91
+ * @param {string} type - entity type or "ANY"
92
+ * @param {string} prop - object of entity parameters
93
+ * @param {any} value - value of the property
94
+ * @return {number} - index of items
95
+ */
96
+ find(type, prop, value) {
97
+ const filteredItems = [];
98
+
99
+ this.#entities.forEach((item, index) => {
100
+ if ((type.toUpperCase() === 'ANY' || item.type.toUpperCase() === type.toUpperCase()) && item.hasOwnProperty(prop) && item[prop] === value) {
101
+ filteredItems.push(index);
102
+ }
103
+ });
104
+
105
+ return filteredItems;
106
+ }
107
+
108
+ /** Get index of entity
109
+ * @param {object} entity
110
+ * @return {number} index
111
+ */
112
+ indexOf(entity) {
113
+ return this.#entities.indexOf(entity);
114
+ }
115
+
116
+
117
+ /**
118
+ * Find closest item to point
119
+ * @param {Point} point
120
+ * @return {number} - return index of closest item or undefined
121
+ */
122
+ findClosest(point) {
123
+ let delta = 1.65 / DesignCore.Core.canvas.getScale(); // find a more suitable starting value
124
+ let closestItemIndex;
125
+
126
+ for (let i = 0; i < this.#entities.length; i++) {
127
+ // check the items layer is selectable - i.e. on, thawed, etc...
128
+ const layer = DesignCore.LayerManager.getItemByName(this.#entities[i].layer);
129
+
130
+ if (!layer?.isSelectable) {
131
+ continue;
132
+ }
133
+
134
+ const distance = this.#entities[i].closestPoint(point)[1]; // ClosestPoint()[1] returns a distance to the closest point
135
+
136
+ if (distance < delta) {
137
+ delta = distance;
138
+ closestItemIndex = i;
139
+ }
140
+ }
141
+
142
+ return closestItemIndex;
143
+ }
144
+
145
+ /**
146
+ * Update entity at index with data
147
+ * @param {number} index
148
+ * @param {object} data
149
+ */
150
+ update(index, data) {
151
+ const item = this.get(index);
152
+
153
+ if (!item) {
154
+ throw Error('Item not found in scene');
155
+ }
156
+
157
+ for (const property of Object.keys(data)) {
158
+ if (item.hasOwnProperty(property)) {
159
+ item.setProperty(property, data[property]);
160
+ }
161
+ }
162
+ }
163
+
164
+ /**
165
+ * Get count of entities
166
+ * @return {number}
167
+ */
168
+ count() {
169
+ return this.#entities.length;
170
+ }
171
+
172
+ /**
173
+ * Clear all entities
174
+ */
175
+ clear() {
176
+ this.#entities = [];
177
+ }
178
+ }
@@ -1,16 +1,26 @@
1
- import {DXF} from './dxf/dxf.js';
2
- import {Logging} from './logging.js';
3
- import {Strings} from './strings.js';
1
+ import { DXF } from './dxf/dxf.js';
2
+ import { Logging } from './logging.js';
3
+ import { Strings } from './strings.js';
4
4
 
5
- import {DesignCore} from '../designCore.js';
5
+ import { DesignCore } from '../designCore.js';
6
6
 
7
+ /** FileIO Class */
7
8
  export class FileIO {
9
+ /**
10
+ * Save to DXF
11
+ * @param {string} version
12
+ * @return {string} dxf file as a string
13
+ */
8
14
  static saveDxf(version) {
9
15
  const dxfWriter = new DXF();
10
16
  const data = dxfWriter.write(version);
11
17
  return data;
12
18
  }
13
19
 
20
+ /**
21
+ * Open data as a dxf file
22
+ * @param {string} data
23
+ */
14
24
  static openFile(data) {
15
25
  const dxf = new DXF();
16
26
  try {
@@ -0,0 +1,229 @@
1
+ import { DesignCore } from '../designCore.js';
2
+ import { DXFFile } from './dxf/dxfFile.js';
3
+ import { Property } from '../properties/property.js';
4
+
5
+ /** Headers Class
6
+ *
7
+ * Stores drawing-level variables that correspond to DXF HEADER section entries.
8
+ * These values are per-drawing, not application preferences
9
+ */
10
+ export class Headers {
11
+ // $FILLETRAD (group code 40)
12
+ #filletRadius = 0;
13
+
14
+ // $TRIMMODE (group code 70) - false = no trim, true = trim
15
+ #trimMode = true;
16
+
17
+ // $TEXTSIZE (group code 40)
18
+ #textSize = 2.5;
19
+
20
+ // $CHAMFERA (group code 40)
21
+ #chamferDistanceA = 0;
22
+
23
+ // $CHAMFERB (group code 40)
24
+ #chamferDistanceB = 0;
25
+
26
+ // $CHAMFERC (group code 40)
27
+ #chamferLength = 0;
28
+
29
+ // $CHAMFERD (group code 40)
30
+ #chamferAngle = 0;
31
+
32
+ // $CHAMMODE (group code 70) - false = distances, true = angle
33
+ #chamferMode = false;
34
+
35
+ // $OFFSETDIST (group code 40)
36
+ #offsetDistance = 0;
37
+
38
+ // $ACADVER (group code 1)
39
+ #dxfVersion = 'R2018';
40
+
41
+ /** Create Headers */
42
+ constructor() { }
43
+
44
+ /** @type {number} Fillet radius ($FILLETRAD) */
45
+ get filletRadius() {
46
+ return this.#filletRadius;
47
+ }
48
+
49
+ /** @param {number} value */
50
+ set filletRadius(value) {
51
+ const num = parseFloat(value);
52
+ if (!isFinite(num) || num < 0) throw new Error(`Invalid filletRadius: ${value}`);
53
+ this.#filletRadius = num;
54
+ }
55
+
56
+ /** @type {boolean} Trim mode ($TRIMMODE) */
57
+ get trimMode() {
58
+ return this.#trimMode;
59
+ }
60
+
61
+ /** @param {boolean} value */
62
+ set trimMode(value) {
63
+ if (typeof value !== 'boolean') throw new Error(`Invalid trimMode: ${value}`);
64
+ this.#trimMode = value;
65
+ }
66
+
67
+ /** @type {number} Default text size ($TEXTSIZE) */
68
+ get textSize() {
69
+ return this.#textSize;
70
+ }
71
+
72
+ /** @param {number} value */
73
+ set textSize(value) {
74
+ const num = parseFloat(value);
75
+ if (!isFinite(num) || num <= 0) throw new Error(`Invalid textSize: ${value}`);
76
+ this.#textSize = num;
77
+ }
78
+
79
+ /** @type {number} Chamfer distance A ($CHAMFERA) */
80
+ get chamferDistanceA() {
81
+ return this.#chamferDistanceA;
82
+ }
83
+
84
+ /** @param {number} value */
85
+ set chamferDistanceA(value) {
86
+ const num = parseFloat(value);
87
+ if (!isFinite(num) || num < 0) throw new Error(`Invalid chamferDistanceA: ${value}`);
88
+ this.#chamferDistanceA = num;
89
+ }
90
+
91
+ /** @type {number} Chamfer distance B ($CHAMFERB) */
92
+ get chamferDistanceB() {
93
+ return this.#chamferDistanceB;
94
+ }
95
+
96
+ /** @param {number} value */
97
+ set chamferDistanceB(value) {
98
+ const num = parseFloat(value);
99
+ if (!isFinite(num) || num < 0) throw new Error(`Invalid chamferDistanceB: ${value}`);
100
+ this.#chamferDistanceB = num;
101
+ }
102
+
103
+ /** @type {number} Chamfer length ($CHAMFERC) */
104
+ get chamferLength() {
105
+ return this.#chamferLength;
106
+ }
107
+
108
+ /** @param {number} value */
109
+ set chamferLength(value) {
110
+ const num = parseFloat(value);
111
+ if (!isFinite(num) || num < 0) throw new Error(`Invalid chamferLength: ${value}`);
112
+ this.#chamferLength = num;
113
+ }
114
+
115
+ /** @type {number} Chamfer angle ($CHAMFERD) */
116
+ get chamferAngle() {
117
+ return this.#chamferAngle;
118
+ }
119
+
120
+ /** @param {number} value */
121
+ set chamferAngle(value) {
122
+ const num = parseFloat(value);
123
+ if (!isFinite(num) || num < 0) throw new Error(`Invalid chamferAngle: ${value}`);
124
+ this.#chamferAngle = num;
125
+ }
126
+
127
+ /** @type {boolean} Chamfer method ($CHAMMODE): false = distances, true = angle */
128
+ get chamferMode() {
129
+ return this.#chamferMode;
130
+ }
131
+
132
+ /** @param {boolean} value */
133
+ set chamferMode(value) {
134
+ if (typeof value !== 'boolean') throw new Error(`Invalid chamferMode: ${value}`);
135
+ this.#chamferMode = value;
136
+ }
137
+
138
+ /** @type {number} Offset distance ($OFFSETDIST) */
139
+ get offsetDistance() {
140
+ return this.#offsetDistance;
141
+ }
142
+
143
+ /** @param {number} value */
144
+ set offsetDistance(value) {
145
+ const num = parseFloat(value);
146
+ if (!isFinite(num)) throw new Error(`Invalid offsetDistance: ${value}`);
147
+ this.#offsetDistance = num;
148
+ }
149
+
150
+ /** @type {string} DXF version key ($ACADVER) */
151
+ get dxfVersion() {
152
+ return this.#dxfVersion;
153
+ }
154
+
155
+ /** @param {string} value - DXF version string or key */
156
+ set dxfVersion(value) {
157
+ if (DXFFile.validDxfVersion(value)) value = DXFFile.getVersionKey(value);
158
+ if (!DXFFile.validDxfKey(value)) throw new Error(`Invalid DXF version: ${value}`);
159
+ this.#dxfVersion = value;
160
+ }
161
+
162
+ /**
163
+ * Load header values from a parsed DXF header object.
164
+ * Only updates values that are present in the file; defaults are preserved otherwise.
165
+ * @param {Object} header - parsed header section object from DXFReader
166
+ */
167
+ load(header) {
168
+ this.filletRadius = parseFloat(Property.loadValue([header?.['$FILLETRAD']?.['40']], this.filletRadius));
169
+ this.textSize = parseFloat(Property.loadValue([header?.['$TEXTSIZE']?.['40']], this.textSize));
170
+ this.chamferDistanceA = parseFloat(Property.loadValue([header?.['$CHAMFERA']?.['40']], this.chamferDistanceA));
171
+ this.chamferDistanceB = parseFloat(Property.loadValue([header?.['$CHAMFERB']?.['40']], this.chamferDistanceB));
172
+ this.chamferLength = parseFloat(Property.loadValue([header?.['$CHAMFERC']?.['40']], this.chamferLength));
173
+ this.chamferAngle = parseFloat(Property.loadValue([header?.['$CHAMFERD']?.['40']], this.chamferAngle));
174
+
175
+ // $TRIMMODE, $CHAMMODE, and $OFFSETDIST are system variables not written to file by AutoCAD.
176
+ // These are commented out but retained in case files from other applications include them.
177
+ // const trimModeRaw = Property.loadValue([header?.['$TRIMMODE']?.['70']]);
178
+ // if (trimModeRaw !== undefined) this.trimMode = parseInt(trimModeRaw) !== 0;
179
+
180
+ // const chamferModeRaw = Property.loadValue([header?.['$CHAMMODE']?.['70']]);
181
+ // if (chamferModeRaw !== undefined) this.chamferMode = parseInt(chamferModeRaw) !== 0;
182
+
183
+ // this.offsetDistance = parseFloat(Property.loadValue([header?.['$OFFSETDIST']?.['40']], this.offsetDistance));
184
+
185
+ const acadVer = Property.loadValue([header?.['$ACADVER']?.['1']]);
186
+ if (acadVer !== undefined) this.dxfVersion = acadVer;
187
+ }
188
+
189
+ /**
190
+ * Write the DXF HEADER section content to a DXF file
191
+ * @param {DXFFile} file
192
+ */
193
+ dxf(file) {
194
+ file.writeGroupCode('9', '$ACADVER');
195
+ file.writeGroupCode('1', file.version);
196
+ file.writeGroupCode('9', '$TEXTSTYLE');
197
+ // TODO: StyleManager write to headers?
198
+ file.writeGroupCode('7', DesignCore.StyleManager.getCstyle());
199
+ file.writeGroupCode('9', '$CLAYER');
200
+ // TODO: LayerManager write to headers?
201
+ file.writeGroupCode('8', DesignCore.LayerManager.getCstyle());
202
+ file.writeGroupCode('9', '$DIMSTYLE');
203
+ // TODO: DimStyleManager write to headers?
204
+ file.writeGroupCode('2', DesignCore.DimStyleManager.getCstyle());
205
+ file.writeGroupCode('9', '$HANDSEED', DXFFile.Version.R2000);
206
+ file.writeGroupCode('5', DesignCore.HandleManager.handseed, DXFFile.Version.R2000);
207
+ file.writeGroupCode('9', '$TEXTSIZE');
208
+ file.writeGroupCode('40', this.textSize);
209
+ file.writeGroupCode('9', '$FILLETRAD');
210
+ file.writeGroupCode('40', this.filletRadius);
211
+ // $TRIMMODE is a system variable and is not written to file by AutoCAD
212
+ // file.writeGroupCode('9', '$TRIMMODE');
213
+ // file.writeGroupCode('70', this.trimMode ? 1 : 0);
214
+ file.writeGroupCode('9', '$CHAMFERA');
215
+ file.writeGroupCode('40', this.chamferDistanceA);
216
+ file.writeGroupCode('9', '$CHAMFERB');
217
+ file.writeGroupCode('40', this.chamferDistanceB);
218
+ file.writeGroupCode('9', '$CHAMFERC');
219
+ file.writeGroupCode('40', this.chamferLength);
220
+ file.writeGroupCode('9', '$CHAMFERD');
221
+ file.writeGroupCode('40', this.chamferAngle);
222
+ // $CHAMMODE is a system variable and is not written to file by AutoCAD
223
+ // file.writeGroupCode('9', '$CHAMMODE');
224
+ // file.writeGroupCode('70', this.chamferMode ? 1 : 0);
225
+ // $OFFSETDIST is a system variable and is not written to file by AutoCAD
226
+ // file.writeGroupCode('9', '$OFFSETDIST');
227
+ // file.writeGroupCode('40', this.offsetDistance);
228
+ }
229
+ }
@@ -0,0 +1,46 @@
1
+ /** Sentinel resolved when a MOUSEDOWN prompt completes */
2
+ export class MouseDown {}
3
+
4
+ /** Sentinel resolved when a MOUSEUP prompt completes */
5
+ export class MouseUp {}
6
+
7
+ /** Input Class */
8
+ export class Input {
9
+ static Cursor = {
10
+ DEFAULT: 'DEFAULT',
11
+ GRAB: 'GRAB',
12
+ GRABBING: 'GRABBING',
13
+ SELECTION: 'SELECTION',
14
+ };
15
+
16
+ /**
17
+ * Input type definitions.
18
+ * Each entry describes an accepted input type:
19
+ * value — matches value.constructor.name for runtime type detection via getType()
20
+ * cursor — the cursor state to apply when this type is requested (null = DEFAULT)
21
+ */
22
+ static Type = {
23
+ POINT: { value: 'Point', cursor: null },
24
+ SELECTIONSET: { value: 'SelectionSet', cursor: Input.Cursor.SELECTION },
25
+ SINGLESELECTION: { value: 'SingleSelection', cursor: Input.Cursor.SELECTION },
26
+ NUMBER: { value: 'Number', cursor: null },
27
+ STRING: { value: 'String', cursor: null },
28
+ DYNAMIC: { value: 'Dynamic', cursor: null },
29
+ MOUSEDOWN: { value: 'MouseDown', cursor: null },
30
+ MOUSEUP: { value: 'MouseUp', cursor: null },
31
+ };
32
+
33
+ /**
34
+ * Return the Input.Type for value
35
+ * @param {any} value
36
+ * @return {Object|undefined}
37
+ */
38
+ static getType(value) {
39
+ if (value === undefined) {
40
+ return undefined;
41
+ }
42
+
43
+ const name = value.constructor.name;
44
+ return Object.values(Input.Type).find((t) => t.value === name);
45
+ }
46
+ }