@mlightcad/cad-simple-viewer 1.7.0 → 1.7.2

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 (358) hide show
  1. package/README.md +6 -1
  2. package/dist/cad-simple-viewer.js +17658 -13023
  3. package/dist/cad-simple-viewer.umd.cjs +985 -114
  4. package/dist/mtext-renderer-worker.js +7390 -7160
  5. package/lib/app/AcApContext.d.ts.map +1 -1
  6. package/lib/app/AcApContext.js +4 -3
  7. package/lib/app/AcApContext.js.map +1 -1
  8. package/lib/app/AcApDocManager.d.ts +41 -18
  9. package/lib/app/AcApDocManager.d.ts.map +1 -1
  10. package/lib/app/AcApDocManager.js +89 -49
  11. package/lib/app/AcApDocManager.js.map +1 -1
  12. package/lib/app/AcApDocument.d.ts +3 -0
  13. package/lib/app/AcApDocument.d.ts.map +1 -1
  14. package/lib/app/AcApDocument.js +31 -24
  15. package/lib/app/AcApDocument.js.map +1 -1
  16. package/lib/app/AcApOpenDatabaseOptions.d.ts +33 -7
  17. package/lib/app/AcApOpenDatabaseOptions.d.ts.map +1 -1
  18. package/lib/app/AcApOpenDatabaseOptions.js +1 -1
  19. package/lib/app/AcApOpenDatabaseOptions.js.map +1 -1
  20. package/lib/app/AcApOpenFileProgressController.d.ts +13 -4
  21. package/lib/app/AcApOpenFileProgressController.d.ts.map +1 -1
  22. package/lib/app/AcApOpenFileProgressController.js +25 -6
  23. package/lib/app/AcApOpenFileProgressController.js.map +1 -1
  24. package/lib/app/AcApWorkerAssets.d.ts +3 -3
  25. package/lib/app/AcApWorkerAssets.d.ts.map +1 -1
  26. package/lib/app/AcApWorkerAssets.js +3 -3
  27. package/lib/app/AcApWorkerAssets.js.map +1 -1
  28. package/lib/app/index.d.ts +1 -0
  29. package/lib/app/index.d.ts.map +1 -1
  30. package/lib/app/index.js +1 -0
  31. package/lib/app/index.js.map +1 -1
  32. package/lib/app/notification/AcApNotificationEventBridge.d.ts +130 -0
  33. package/lib/app/notification/AcApNotificationEventBridge.d.ts.map +1 -0
  34. package/lib/app/notification/AcApNotificationEventBridge.js +309 -0
  35. package/lib/app/notification/AcApNotificationEventBridge.js.map +1 -0
  36. package/lib/app/notification/AcApNotificationService.d.ts +185 -0
  37. package/lib/app/notification/AcApNotificationService.d.ts.map +1 -0
  38. package/lib/app/notification/AcApNotificationService.js +271 -0
  39. package/lib/app/notification/AcApNotificationService.js.map +1 -0
  40. package/lib/app/notification/AcApNotificationStore.d.ts +147 -0
  41. package/lib/app/notification/AcApNotificationStore.d.ts.map +1 -0
  42. package/lib/app/notification/AcApNotificationStore.js +345 -0
  43. package/lib/app/notification/AcApNotificationStore.js.map +1 -0
  44. package/lib/app/notification/AcApNotificationTypes.d.ts +195 -0
  45. package/lib/app/notification/AcApNotificationTypes.d.ts.map +1 -0
  46. package/lib/app/notification/AcApNotificationTypes.js +78 -0
  47. package/lib/app/notification/AcApNotificationTypes.js.map +1 -0
  48. package/lib/app/notification/index.d.ts +13 -0
  49. package/lib/app/notification/index.d.ts.map +1 -0
  50. package/lib/app/notification/index.js +13 -0
  51. package/lib/app/notification/index.js.map +1 -0
  52. package/lib/command/AcApInstallDrawStyleSessionAccessory.js +11 -7
  53. package/lib/command/AcApInstallDrawStyleSessionAccessory.js.map +1 -1
  54. package/lib/command/AcApSwitchBgCmd.d.ts.map +1 -1
  55. package/lib/command/AcApSwitchBgCmd.js +7 -2
  56. package/lib/command/AcApSwitchBgCmd.js.map +1 -1
  57. package/lib/command/AcApToolbarDocBind.d.ts +19 -0
  58. package/lib/command/AcApToolbarDocBind.d.ts.map +1 -0
  59. package/lib/command/AcApToolbarDocBind.js +62 -0
  60. package/lib/command/AcApToolbarDocBind.js.map +1 -0
  61. package/lib/command/convert/AcApConvertToBmpCmd.d.ts +14 -0
  62. package/lib/command/convert/AcApConvertToBmpCmd.d.ts.map +1 -0
  63. package/lib/command/convert/AcApConvertToBmpCmd.js +34 -0
  64. package/lib/command/convert/AcApConvertToBmpCmd.js.map +1 -0
  65. package/lib/command/convert/AcApConvertToJpgCmd.d.ts +14 -0
  66. package/lib/command/convert/AcApConvertToJpgCmd.d.ts.map +1 -0
  67. package/lib/command/convert/AcApConvertToJpgCmd.js +34 -0
  68. package/lib/command/convert/AcApConvertToJpgCmd.js.map +1 -0
  69. package/lib/command/convert/AcApConvertToPngCmd.d.ts +4 -36
  70. package/lib/command/convert/AcApConvertToPngCmd.d.ts.map +1 -1
  71. package/lib/command/convert/AcApConvertToPngCmd.js +4 -138
  72. package/lib/command/convert/AcApConvertToPngCmd.js.map +1 -1
  73. package/lib/command/convert/AcApConvertToRasterImageCmd.d.ts +40 -0
  74. package/lib/command/convert/AcApConvertToRasterImageCmd.d.ts.map +1 -0
  75. package/lib/command/convert/AcApConvertToRasterImageCmd.js +161 -0
  76. package/lib/command/convert/AcApConvertToRasterImageCmd.js.map +1 -0
  77. package/lib/command/convert/{AcApPngConvertor.d.ts → AcApRasterImageConvertor.d.ts} +36 -12
  78. package/lib/command/convert/AcApRasterImageConvertor.d.ts.map +1 -0
  79. package/lib/command/convert/{AcApPngConvertor.js → AcApRasterImageConvertor.js} +163 -32
  80. package/lib/command/convert/AcApRasterImageConvertor.js.map +1 -0
  81. package/lib/command/convert/index.d.ts +4 -1
  82. package/lib/command/convert/index.d.ts.map +1 -1
  83. package/lib/command/convert/index.js +4 -1
  84. package/lib/command/convert/index.js.map +1 -1
  85. package/lib/command/index.d.ts +2 -0
  86. package/lib/command/index.d.ts.map +1 -1
  87. package/lib/command/index.js +2 -0
  88. package/lib/command/index.js.map +1 -1
  89. package/lib/command/markup/AcApMarkupCalloutCmd.d.ts.map +1 -1
  90. package/lib/command/markup/AcApMarkupCalloutCmd.js +51 -1
  91. package/lib/command/markup/AcApMarkupCalloutCmd.js.map +1 -1
  92. package/lib/command/markup/AcApMarkupCmdUtil.d.ts +5 -0
  93. package/lib/command/markup/AcApMarkupCmdUtil.d.ts.map +1 -1
  94. package/lib/command/markup/AcApMarkupCmdUtil.js +27 -9
  95. package/lib/command/markup/AcApMarkupCmdUtil.js.map +1 -1
  96. package/lib/command/markup/AcApMarkupShapeCallout.d.ts.map +1 -1
  97. package/lib/command/markup/AcApMarkupShapeCallout.js +49 -1
  98. package/lib/command/markup/AcApMarkupShapeCallout.js.map +1 -1
  99. package/lib/editor/global/AcEdUiLayout.d.ts +6 -0
  100. package/lib/editor/global/AcEdUiLayout.d.ts.map +1 -1
  101. package/lib/editor/global/AcEdUiLayout.js +6 -0
  102. package/lib/editor/global/AcEdUiLayout.js.map +1 -1
  103. package/lib/editor/input/ui/AcEdCanvasTouchCalloutGuard.d.ts +31 -0
  104. package/lib/editor/input/ui/AcEdCanvasTouchCalloutGuard.d.ts.map +1 -0
  105. package/lib/editor/input/ui/AcEdCanvasTouchCalloutGuard.js +67 -0
  106. package/lib/editor/input/ui/AcEdCanvasTouchCalloutGuard.js.map +1 -0
  107. package/lib/editor/input/ui/AcEdFloatingInput.d.ts +2 -0
  108. package/lib/editor/input/ui/AcEdFloatingInput.d.ts.map +1 -1
  109. package/lib/editor/input/ui/AcEdFloatingInput.js +13 -2
  110. package/lib/editor/input/ui/AcEdFloatingInput.js.map +1 -1
  111. package/lib/editor/input/ui/AcEdFloatingInputTypes.d.ts +6 -0
  112. package/lib/editor/input/ui/AcEdFloatingInputTypes.d.ts.map +1 -1
  113. package/lib/editor/input/ui/AcEdInputManager.d.ts.map +1 -1
  114. package/lib/editor/input/ui/AcEdInputManager.js +47 -7
  115. package/lib/editor/input/ui/AcEdInputManager.js.map +1 -1
  116. package/lib/editor/input/ui/AcEdMTextEditor.d.ts.map +1 -1
  117. package/lib/editor/input/ui/AcEdMTextEditor.js +2 -1
  118. package/lib/editor/input/ui/AcEdMTextEditor.js.map +1 -1
  119. package/lib/editor/input/ui/AcEdMobileBoxGesture.d.ts.map +1 -1
  120. package/lib/editor/input/ui/AcEdMobileBoxGesture.js +2 -0
  121. package/lib/editor/input/ui/AcEdMobileBoxGesture.js.map +1 -1
  122. package/lib/editor/input/ui/AcEdMobileCommandChrome.d.ts +18 -4
  123. package/lib/editor/input/ui/AcEdMobileCommandChrome.d.ts.map +1 -1
  124. package/lib/editor/input/ui/AcEdMobileCommandChrome.js +14 -0
  125. package/lib/editor/input/ui/AcEdMobileCommandChrome.js.map +1 -1
  126. package/lib/editor/input/ui/AcEdSessionAccessoryController.d.ts +10 -2
  127. package/lib/editor/input/ui/AcEdSessionAccessoryController.d.ts.map +1 -1
  128. package/lib/editor/input/ui/AcEdSessionAccessoryController.js +15 -4
  129. package/lib/editor/input/ui/AcEdSessionAccessoryController.js.map +1 -1
  130. package/lib/editor/input/ui/AcEdTouchPointTiming.d.ts +1 -1
  131. package/lib/editor/input/ui/AcEdTouchPointTiming.d.ts.map +1 -1
  132. package/lib/editor/input/ui/AcEdTouchPointTiming.js +1 -1
  133. package/lib/editor/input/ui/AcEdTouchPointTiming.js.map +1 -1
  134. package/lib/editor/input/ui/index.d.ts +1 -0
  135. package/lib/editor/input/ui/index.d.ts.map +1 -1
  136. package/lib/editor/input/ui/index.js +1 -0
  137. package/lib/editor/input/ui/index.js.map +1 -1
  138. package/lib/editor/view/AcEdBaseView.d.ts +12 -0
  139. package/lib/editor/view/AcEdBaseView.d.ts.map +1 -1
  140. package/lib/editor/view/AcEdBaseView.js +19 -9
  141. package/lib/editor/view/AcEdBaseView.js.map +1 -1
  142. package/lib/editor/view/AcEdSelectionBoxIntersect.d.ts +36 -0
  143. package/lib/editor/view/AcEdSelectionBoxIntersect.d.ts.map +1 -0
  144. package/lib/editor/view/AcEdSelectionBoxIntersect.js +113 -0
  145. package/lib/editor/view/AcEdSelectionBoxIntersect.js.map +1 -0
  146. package/lib/editor/view/index.d.ts +1 -0
  147. package/lib/editor/view/index.d.ts.map +1 -1
  148. package/lib/editor/view/index.js +1 -0
  149. package/lib/editor/view/index.js.map +1 -1
  150. package/lib/i18n/AcApI18n.d.ts +2 -1
  151. package/lib/i18n/AcApI18n.d.ts.map +1 -1
  152. package/lib/i18n/AcApI18n.js +4 -1
  153. package/lib/i18n/AcApI18n.js.map +1 -1
  154. package/lib/i18n/ar/command.d.ts +9 -0
  155. package/lib/i18n/ar/command.d.ts.map +1 -1
  156. package/lib/i18n/ar/command.js +1 -1
  157. package/lib/i18n/ar/command.js.map +1 -1
  158. package/lib/i18n/ar/jig.d.ts +47 -0
  159. package/lib/i18n/ar/jig.d.ts.map +1 -1
  160. package/lib/i18n/ar/jig.js +17 -1
  161. package/lib/i18n/ar/jig.js.map +1 -1
  162. package/lib/i18n/ar/main.d.ts +32 -0
  163. package/lib/i18n/ar/main.d.ts.map +1 -1
  164. package/lib/i18n/ar/main.js +38 -6
  165. package/lib/i18n/ar/main.js.map +1 -1
  166. package/lib/i18n/cs/command.d.ts +9 -0
  167. package/lib/i18n/cs/command.d.ts.map +1 -1
  168. package/lib/i18n/cs/command.js +9 -0
  169. package/lib/i18n/cs/command.js.map +1 -1
  170. package/lib/i18n/cs/jig.d.ts +47 -0
  171. package/lib/i18n/cs/jig.d.ts.map +1 -1
  172. package/lib/i18n/cs/jig.js +47 -0
  173. package/lib/i18n/cs/jig.js.map +1 -1
  174. package/lib/i18n/cs/main.d.ts +32 -0
  175. package/lib/i18n/cs/main.d.ts.map +1 -1
  176. package/lib/i18n/cs/main.js +38 -6
  177. package/lib/i18n/cs/main.js.map +1 -1
  178. package/lib/i18n/en/command.d.ts +9 -0
  179. package/lib/i18n/en/command.d.ts.map +1 -1
  180. package/lib/i18n/en/command.js +9 -0
  181. package/lib/i18n/en/command.js.map +1 -1
  182. package/lib/i18n/en/jig.d.ts +47 -0
  183. package/lib/i18n/en/jig.d.ts.map +1 -1
  184. package/lib/i18n/en/jig.js +47 -0
  185. package/lib/i18n/en/jig.js.map +1 -1
  186. package/lib/i18n/en/main.d.ts +32 -0
  187. package/lib/i18n/en/main.d.ts.map +1 -1
  188. package/lib/i18n/en/main.js +38 -6
  189. package/lib/i18n/en/main.js.map +1 -1
  190. package/lib/i18n/index.d.ts +2 -2
  191. package/lib/i18n/index.d.ts.map +1 -1
  192. package/lib/i18n/index.js.map +1 -1
  193. package/lib/i18n/tr/command.d.ts +9 -0
  194. package/lib/i18n/tr/command.d.ts.map +1 -1
  195. package/lib/i18n/tr/command.js +9 -0
  196. package/lib/i18n/tr/command.js.map +1 -1
  197. package/lib/i18n/tr/jig.d.ts +47 -0
  198. package/lib/i18n/tr/jig.d.ts.map +1 -1
  199. package/lib/i18n/tr/jig.js +47 -0
  200. package/lib/i18n/tr/jig.js.map +1 -1
  201. package/lib/i18n/tr/main.d.ts +32 -0
  202. package/lib/i18n/tr/main.d.ts.map +1 -1
  203. package/lib/i18n/tr/main.js +38 -6
  204. package/lib/i18n/tr/main.js.map +1 -1
  205. package/lib/i18n/zh/command.d.ts +9 -0
  206. package/lib/i18n/zh/command.d.ts.map +1 -1
  207. package/lib/i18n/zh/command.js +9 -0
  208. package/lib/i18n/zh/command.js.map +1 -1
  209. package/lib/i18n/zh/jig.d.ts +47 -0
  210. package/lib/i18n/zh/jig.d.ts.map +1 -1
  211. package/lib/i18n/zh/jig.js +47 -0
  212. package/lib/i18n/zh/jig.js.map +1 -1
  213. package/lib/i18n/zh/main.d.ts +32 -0
  214. package/lib/i18n/zh/main.d.ts.map +1 -1
  215. package/lib/i18n/zh/main.js +38 -6
  216. package/lib/i18n/zh/main.js.map +1 -1
  217. package/lib/index.d.ts +1 -1
  218. package/lib/index.d.ts.map +1 -1
  219. package/lib/index.js +1 -1
  220. package/lib/index.js.map +1 -1
  221. package/lib/spatialIndex/AcTrHierarchicalSpatialIndex.d.ts +6 -0
  222. package/lib/spatialIndex/AcTrHierarchicalSpatialIndex.d.ts.map +1 -1
  223. package/lib/spatialIndex/AcTrHierarchicalSpatialIndex.js +10 -0
  224. package/lib/spatialIndex/AcTrHierarchicalSpatialIndex.js.map +1 -1
  225. package/lib/spatialIndex/AcTrLinearSpatialIndex.d.ts +4 -0
  226. package/lib/spatialIndex/AcTrLinearSpatialIndex.d.ts.map +1 -1
  227. package/lib/spatialIndex/AcTrLinearSpatialIndex.js +9 -0
  228. package/lib/spatialIndex/AcTrLinearSpatialIndex.js.map +1 -1
  229. package/lib/spatialIndex/AcTrRBushSpatialIndex.d.ts +4 -0
  230. package/lib/spatialIndex/AcTrRBushSpatialIndex.d.ts.map +1 -1
  231. package/lib/spatialIndex/AcTrRBushSpatialIndex.js +9 -0
  232. package/lib/spatialIndex/AcTrRBushSpatialIndex.js.map +1 -1
  233. package/lib/ui/AcUiDefaultNotificationUi.d.ts +167 -0
  234. package/lib/ui/AcUiDefaultNotificationUi.d.ts.map +1 -0
  235. package/lib/ui/AcUiDefaultNotificationUi.js +604 -0
  236. package/lib/ui/AcUiDefaultNotificationUi.js.map +1 -0
  237. package/lib/ui/AcUiDrawStyle.d.ts +2 -1
  238. package/lib/ui/AcUiDrawStyle.d.ts.map +1 -1
  239. package/lib/ui/AcUiDrawStyle.js +2 -1
  240. package/lib/ui/AcUiDrawStyle.js.map +1 -1
  241. package/lib/ui/AcUiDrawStyleSessionAccessory.d.ts.map +1 -1
  242. package/lib/ui/AcUiDrawStyleSessionAccessory.js +5 -1
  243. package/lib/ui/AcUiDrawStyleSessionAccessory.js.map +1 -1
  244. package/lib/ui/AcUiMobileSessionPanel.d.ts +73 -8
  245. package/lib/ui/AcUiMobileSessionPanel.d.ts.map +1 -1
  246. package/lib/ui/AcUiMobileSessionPanel.js +314 -49
  247. package/lib/ui/AcUiMobileSessionPanel.js.map +1 -1
  248. package/lib/ui/AcUiShortCutToolbar.d.ts +24 -0
  249. package/lib/ui/AcUiShortCutToolbar.d.ts.map +1 -1
  250. package/lib/ui/AcUiShortCutToolbar.js +73 -5
  251. package/lib/ui/AcUiShortCutToolbar.js.map +1 -1
  252. package/lib/ui/icons.d.ts +7 -1
  253. package/lib/ui/icons.d.ts.map +1 -1
  254. package/lib/ui/icons.js +10 -2
  255. package/lib/ui/icons.js.map +1 -1
  256. package/lib/ui/index.d.ts +2 -0
  257. package/lib/ui/index.d.ts.map +1 -1
  258. package/lib/ui/index.js +2 -0
  259. package/lib/ui/index.js.map +1 -1
  260. package/lib/ui/toolbar/AcUiDropdownMenu.d.ts +48 -0
  261. package/lib/ui/toolbar/AcUiDropdownMenu.d.ts.map +1 -0
  262. package/lib/ui/toolbar/AcUiDropdownMenu.js +116 -0
  263. package/lib/ui/toolbar/AcUiDropdownMenu.js.map +1 -0
  264. package/lib/ui/toolbar/AcUiSubToolbar.d.ts +125 -0
  265. package/lib/ui/toolbar/AcUiSubToolbar.d.ts.map +1 -0
  266. package/lib/ui/toolbar/AcUiSubToolbar.js +625 -0
  267. package/lib/ui/toolbar/AcUiSubToolbar.js.map +1 -0
  268. package/lib/ui/toolbar/AcUiToolbar.d.ts +446 -0
  269. package/lib/ui/toolbar/AcUiToolbar.d.ts.map +1 -0
  270. package/lib/ui/toolbar/AcUiToolbar.js +1550 -0
  271. package/lib/ui/toolbar/AcUiToolbar.js.map +1 -0
  272. package/lib/ui/toolbar/AcUiToolbarStyles.d.ts +20 -0
  273. package/lib/ui/toolbar/AcUiToolbarStyles.d.ts.map +1 -0
  274. package/lib/ui/toolbar/AcUiToolbarStyles.js +34 -0
  275. package/lib/ui/toolbar/AcUiToolbarStyles.js.map +1 -0
  276. package/lib/ui/toolbar/acuiWrapPackLayout.d.ts +19 -0
  277. package/lib/ui/toolbar/acuiWrapPackLayout.d.ts.map +1 -0
  278. package/lib/ui/toolbar/acuiWrapPackLayout.js +36 -0
  279. package/lib/ui/toolbar/acuiWrapPackLayout.js.map +1 -0
  280. package/lib/ui/toolbar/index.d.ts +19 -0
  281. package/lib/ui/toolbar/index.d.ts.map +1 -0
  282. package/lib/ui/toolbar/index.js +15 -0
  283. package/lib/ui/toolbar/index.js.map +1 -0
  284. package/lib/ui/toolbar/resolveToolbarChrome.d.ts +14 -0
  285. package/lib/ui/toolbar/resolveToolbarChrome.d.ts.map +1 -0
  286. package/lib/ui/toolbar/resolveToolbarChrome.js +35 -0
  287. package/lib/ui/toolbar/resolveToolbarChrome.js.map +1 -0
  288. package/lib/ui/toolbar/resolveToolbarItemState.d.ts +63 -0
  289. package/lib/ui/toolbar/resolveToolbarItemState.d.ts.map +1 -0
  290. package/lib/ui/toolbar/resolveToolbarItemState.js +171 -0
  291. package/lib/ui/toolbar/resolveToolbarItemState.js.map +1 -0
  292. package/lib/ui/toolbar/toolbarItemUtils.d.ts +62 -0
  293. package/lib/ui/toolbar/toolbarItemUtils.d.ts.map +1 -0
  294. package/lib/ui/toolbar/toolbarItemUtils.js +184 -0
  295. package/lib/ui/toolbar/toolbarItemUtils.js.map +1 -0
  296. package/lib/ui/toolbar/types.d.ts +268 -0
  297. package/lib/ui/toolbar/types.d.ts.map +1 -0
  298. package/lib/ui/toolbar/types.js +8 -0
  299. package/lib/ui/toolbar/types.js.map +1 -0
  300. package/lib/ui-html-entry.d.ts +8 -1
  301. package/lib/ui-html-entry.d.ts.map +1 -1
  302. package/lib/ui-html-entry.js +6 -1
  303. package/lib/ui-html-entry.js.map +1 -1
  304. package/lib/util/AcApAnalyzeUnsupportedDrawing.d.ts +53 -0
  305. package/lib/util/AcApAnalyzeUnsupportedDrawing.d.ts.map +1 -0
  306. package/lib/util/AcApAnalyzeUnsupportedDrawing.js +164 -0
  307. package/lib/util/AcApAnalyzeUnsupportedDrawing.js.map +1 -0
  308. package/lib/util/AcApFormatFontMissedMessage.d.ts +32 -0
  309. package/lib/util/AcApFormatFontMissedMessage.d.ts.map +1 -0
  310. package/lib/util/AcApFormatFontMissedMessage.js +46 -0
  311. package/lib/util/AcApFormatFontMissedMessage.js.map +1 -0
  312. package/lib/util/AcApFormatUnsupportedEntitiesMessage.d.ts +44 -0
  313. package/lib/util/AcApFormatUnsupportedEntitiesMessage.d.ts.map +1 -0
  314. package/lib/util/AcApFormatUnsupportedEntitiesMessage.js +105 -0
  315. package/lib/util/AcApFormatUnsupportedEntitiesMessage.js.map +1 -0
  316. package/lib/util/AcApMessageLink.d.ts +41 -0
  317. package/lib/util/AcApMessageLink.d.ts.map +1 -0
  318. package/lib/util/AcApMessageLink.js +127 -0
  319. package/lib/util/AcApMessageLink.js.map +1 -0
  320. package/lib/util/AcApOpenFileErrorMessage.d.ts +18 -1
  321. package/lib/util/AcApOpenFileErrorMessage.d.ts.map +1 -1
  322. package/lib/util/AcApOpenFileErrorMessage.js +34 -2
  323. package/lib/util/AcApOpenFileErrorMessage.js.map +1 -1
  324. package/lib/util/index.d.ts +4 -0
  325. package/lib/util/index.d.ts.map +1 -1
  326. package/lib/util/index.js +4 -0
  327. package/lib/util/index.js.map +1 -1
  328. package/lib/view/AcTrDirectBatch.d.ts.map +1 -1
  329. package/lib/view/AcTrDirectBatch.js +12 -1
  330. package/lib/view/AcTrDirectBatch.js.map +1 -1
  331. package/lib/view/AcTrLayer.d.ts +13 -1
  332. package/lib/view/AcTrLayer.d.ts.map +1 -1
  333. package/lib/view/AcTrLayer.js +28 -11
  334. package/lib/view/AcTrLayer.js.map +1 -1
  335. package/lib/view/AcTrLayout.d.ts +17 -2
  336. package/lib/view/AcTrLayout.d.ts.map +1 -1
  337. package/lib/view/AcTrLayout.js +44 -3
  338. package/lib/view/AcTrLayout.js.map +1 -1
  339. package/lib/view/AcTrProgressiveOpenFitController.d.ts +8 -0
  340. package/lib/view/AcTrProgressiveOpenFitController.d.ts.map +1 -1
  341. package/lib/view/AcTrProgressiveOpenFitController.js +13 -0
  342. package/lib/view/AcTrProgressiveOpenFitController.js.map +1 -1
  343. package/lib/view/AcTrScene.d.ts +4 -0
  344. package/lib/view/AcTrScene.d.ts.map +1 -1
  345. package/lib/view/AcTrScene.js +6 -0
  346. package/lib/view/AcTrScene.js.map +1 -1
  347. package/lib/view/AcTrView2d.d.ts +173 -17
  348. package/lib/view/AcTrView2d.d.ts.map +1 -1
  349. package/lib/view/AcTrView2d.js +742 -144
  350. package/lib/view/AcTrView2d.js.map +1 -1
  351. package/lib/view/fontLoadRegen.d.ts +25 -0
  352. package/lib/view/fontLoadRegen.d.ts.map +1 -0
  353. package/lib/view/fontLoadRegen.js +33 -0
  354. package/lib/view/fontLoadRegen.js.map +1 -0
  355. package/package.json +10 -8
  356. package/src/ui/icons.ts +14 -2
  357. package/lib/command/convert/AcApPngConvertor.d.ts.map +0 -1
  358. package/lib/command/convert/AcApPngConvertor.js.map +0 -1
@@ -96,9 +96,10 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
96
96
  }
97
97
  return to.concat(ar || Array.prototype.slice.call(from));
98
98
  };
99
- import { AcCmUiYieldGate, AcDbAttribute, AcDbBlockReference, acdbHostApplicationServices, AcDbMText, AcDbRasterImage, AcDbRay, AcDbSysVarManager, AcDbViewport, AcDbXline, AcGeBox2d, AcGePoint2d, log } from '@mlightcad/data-model';
99
+ import { AcCmUiYieldGate, AcDbAttribute, AcDbBlockReference, acdbHostApplicationServices, AcDbMText, AcDbRasterImage, AcDbRay, AcDbSysVarManager, AcDbViewport, AcDbXline, AcGeBox2d, AcGePoint2d, acgiForegroundColorForBackground, log } from '@mlightcad/data-model';
100
100
  import { AcDbSystemVariables } from '@mlightcad/data-model';
101
- import { AcTrEntity, AcTrGlyphEntity, AcTrGroup, AcTrRenderer, AcTrViewportView } from '@mlightcad/three-renderer';
101
+ import { FontManager } from '@mlightcad/mtext-renderer';
102
+ import { AcTrEntity, AcTrGlyphEntity, AcTrGroup, AcTrRenderer, AcTrViewportView, hasPendingComplexLineTypeGlyphs } from '@mlightcad/three-renderer';
102
103
  import { AcTrMatrixUtil } from '@mlightcad/three-renderer';
103
104
  import * as THREE from 'three';
104
105
  import Stats from 'three/examples/jsm/libs/stats.module';
@@ -107,9 +108,10 @@ import { AcApDocManager, AcApSettingManager } from '../app';
107
108
  import { AcApZoomCmd } from '../command/AcApZoomCmd';
108
109
  import { isMarkupHtmlTextEditing } from '../command/markup/AcApMarkupTextEdit';
109
110
  import { notifyMeasurementLayoutChanged } from '../command/measure/AcApMeasurementStore';
110
- import { acedAttachMobileBoxGesture, AcEdBaseView, AcEdConditionWaiter, AcEdCorsorType, AcEdGripManager, acedInteractionStrategy, acedIsTouchDerivedMouseEvent, AcEdMTextEditor, AcEdOpenMode, acedShouldIgnoreCompatMouse, AcEdViewMode, eventBus, resolvePointerSelectionAction } from '../editor';
111
+ import { acedAttachMobileBoxGesture, AcEdBaseView, AcEdConditionWaiter, AcEdCorsorType, AcEdGripManager, acedGuardCanvasTouchCallout, acedInteractionStrategy, acedIsTouchDerivedMouseEvent, AcEdMTextEditor, AcEdOpenMode, acedShouldIgnoreCompatMouse, AcEdViewMode, eventBus, resolvePointerSelectionAction } from '../editor';
111
112
  import { ACGI_MODEL_SPACE_BACKGROUND, isModelSpaceDatabase, readLayoutBackgroundColor } from '../editor/global/AcEdUiColor';
112
113
  import { ML_UI_Z_CANVAS_HTML_OVERLAY } from '../editor/global/AcEdUiLayout';
114
+ import { acedEntityIntersectsSelectionBox, acedNeedsCrossingGeometryRefine } from '../editor/view/AcEdSelectionBoxIntersect';
113
115
  import { isEffectiveSpatialQueryHit } from '../editor/view/AcEdSpatialQueryResult';
114
116
  import { AcTrGeometryUtil } from '../util';
115
117
  import { acapRunDatabaseEdit } from '../util/AcApDatabaseEdit';
@@ -128,6 +130,7 @@ import { AcTrLayoutViewManager } from './AcTrLayoutViewManager';
128
130
  import { sortPickResults } from './AcTrPickResultUtil';
129
131
  import { AcTrProgressiveOpenFitController } from './AcTrProgressiveOpenFitController';
130
132
  import { AcTrScene } from './AcTrScene';
133
+ import { shouldRegenDatabaseAfterFontLoad } from './fontLoadRegen';
131
134
  /**
132
135
  * Default view option values
133
136
  */
@@ -182,11 +185,8 @@ var AcTrView2d = /** @class */ (function (_super) {
182
185
  renderer.domElement.style.maxWidth = '100%';
183
186
  renderer.domElement.style.maxHeight = '100%';
184
187
  // Keep one-finger picks (measure snap loupe) from being stolen by the
185
- // browser scroll / long-press context-menu gesture.
186
- renderer.domElement.style.touchAction = 'none';
187
- renderer.domElement.style.userSelect = 'none';
188
- renderer.domElement.style.setProperty('-webkit-user-select', 'none');
189
- renderer.domElement.style.setProperty('-webkit-touch-callout', 'none');
188
+ // browser scroll / long-press copy-selection callout (especially iOS).
189
+ var disposeCanvasTouchCallout = acedGuardCanvasTouchCallout(renderer.domElement, container);
190
190
  _this = _super.call(this, renderer.domElement, container) || this;
191
191
  /**
192
192
  * ID of the currently scheduled requestAnimationFrame callback.
@@ -248,6 +248,21 @@ var AcTrView2d = /** @class */ (function (_super) {
248
248
  * wasted conversion work — this set skips re-entry until the current pass ends.
249
249
  */
250
250
  _this._convertingLayers = new Set();
251
+ /**
252
+ * Object ids claimed by an in-flight interactive {@link batchConvert},
253
+ * including deferred glyph commits that have not yet called
254
+ * {@link AcTrScene.addEntity}. Without this, a second convert pass can
255
+ * append another batched slot for the same id (visible as doubled TEXT
256
+ * linetype labels) because {@link hasEntity} is still false.
257
+ */
258
+ _this._claimedConvertObjectIds = new Set();
259
+ /**
260
+ * Per-objectId convert generation. Bumped by {@link updateEntity} so an
261
+ * in-flight progressive {@link batchConvert} / deferred commit for the same
262
+ * id cannot `addEntity` after the scene was cleared for reconversion
263
+ * (ghost RasterImage / pre-replacement pixels).
264
+ */
265
+ _this._entityConvertGeneration = new Map();
251
266
  /**
252
267
  * When true, entity conversion during document open yields cooperatively so
253
268
  * geometry paints incrementally while the open overlay is still visible.
@@ -275,10 +290,47 @@ var AcTrView2d = /** @class */ (function (_super) {
275
290
  /** Cooperative yields taken inside progressive {@link batchConvert}. */
276
291
  _this._progressiveYieldCount = 0;
277
292
  /**
278
- * In-flight glyph/group geometry jobs that await fonts via asyncDraw.
293
+ * Saved view was not applied at open. Frame batch bounds once linework
294
+ * convert drains, so the canvas is not blank until deferred glyphs finish.
295
+ * Applied on a timer so it does not run on the entity-parse stack.
296
+ */
297
+ _this._openLineworkFramePending = false;
298
+ _this._openLineworkFrameTimer = null;
299
+ /**
300
+ * In-flight + queued glyph/group geometry jobs that await fonts via asyncDraw.
279
301
  * Counted separately so linework convert can continue while text waits.
280
302
  */
281
303
  _this._pendingGeometryJobs = 0;
304
+ /**
305
+ * Waiting deferred geometry runners. Capped concurrency avoids scheduling
306
+ * thousands of INSERT/text `asyncDraw` jobs at once (large multi-sheet DWGs
307
+ * otherwise flood the main thread and freeze on "Rendering drawing ...").
308
+ */
309
+ _this._deferredGeometryQueue = [];
310
+ /** Currently executing deferred geometry runners. */
311
+ _this._deferredGeometryActive = 0;
312
+ /**
313
+ * Debounced glyph rebuild after {@link FontManager.events.fontLoaded} so a
314
+ * burst of lazy face loads (simsun + malgun, etc.) triggers one redraw pass.
315
+ */
316
+ _this._fontLoadedRedrawTimer = null;
317
+ _this._fontLoadedRedrawEpoch = 0;
318
+ /**
319
+ * `performance.now()` when convert and deferred glyph jobs last reached
320
+ * idle together. Zero until that first transition. Used to ignore the
321
+ * open-time `fontLoaded` regen that replays the loading spinner.
322
+ */
323
+ _this._entityProcessingIdleAt = 0;
324
+ /**
325
+ * Convert epoch for which text-style font preload was started.
326
+ */
327
+ _this._textStyleFontPreloadEpoch = -1;
328
+ /**
329
+ * In-flight (or resolved) preload of {@link AcDbTextStyleTable.fonts}.
330
+ * Started at conversion stage `STYLE` END so download overlaps LAYER/BLOCK/
331
+ * ENTITY parse and linework convert; glyph jobs await this before draw.
332
+ */
333
+ _this._textStyleFontPreloadPromise = null;
282
334
  /** Transient reading mode forces black linework on a white canvas. */
283
335
  _this._readingMode = new AcApReadingModeState({
284
336
  getCurrentBackgroundColor: function () { return _this._renderer.currentBackgroundColor; },
@@ -323,6 +375,7 @@ var AcTrView2d = /** @class */ (function (_super) {
323
375
  _this._isDirty = needsRedraw;
324
376
  _this._htmlDirty = false;
325
377
  };
378
+ _this._disposeCanvasTouchCallout = disposeCanvasTouchCallout;
326
379
  _this._gripManager = new AcEdGripManager(_this);
327
380
  _this._keyHandler = new AcEdViewKeyHandler(_this);
328
381
  if (options.calculateSizeCallback) {
@@ -340,9 +393,12 @@ var AcTrView2d = /** @class */ (function (_super) {
340
393
  count: (_a = args.count) !== null && _a !== void 0 ? _a : 0
341
394
  });
342
395
  });
343
- _this._renderer.events.fontLoaded.addEventListener(function () {
396
+ _this._renderer.events.fontLoaded.addEventListener(function (args) {
344
397
  // Lazy load success clears FontManager.missedFonts; refresh status-bar state.
345
398
  eventBus.emit('missed-data-changed', {});
399
+ // On-demand faces (e.g. style `malgun`) may finish after the first glyph
400
+ // bake. Rebuild text so Hangul is not left as permanent '?'.
401
+ _this.scheduleGlyphRedrawAfterFontLoad(args === null || args === void 0 ? void 0 : args.fontName);
346
402
  });
347
403
  _this._scene = _this.createScene();
348
404
  _this._layerAppearance = new AcTrLayerAppearanceController(_this._scene, _this._renderer);
@@ -631,7 +687,7 @@ var AcTrView2d = /** @class */ (function (_super) {
631
687
  _this._htmlDirty = false;
632
688
  _this.startAnimationLoop();
633
689
  _this._numOfEntitiesToProcess = 0;
634
- _this._pendingGeometryJobs = 0;
690
+ _this.resetDeferredGeometryQueue();
635
691
  return _this;
636
692
  }
637
693
  AcTrView2d.prototype.getPointerSelectionAction = function (e) {
@@ -763,9 +819,17 @@ var AcTrView2d = /** @class */ (function (_super) {
763
819
  * True while batch conversion or deferred glyph/group geometry is still
764
820
  * running.
765
821
  *
766
- * Parsing can report 100% before this reaches zero; callers opening files
767
- * should wait on this (as {@link zoomToFitDrawing} does) before hiding
768
- * progress UI or assuming the canvas is ready.
822
+ * Parsing can report 100% before this reaches zero; callers that need a
823
+ * fully drawable scene (export, scripted zoom) should wait on this (as
824
+ * {@link waitUntilIdle} / {@link zoomToFitDrawing} do).
825
+ *
826
+ * The open-file progress overlay uses this when
827
+ * {@link AcApOpenDatabaseOptions.progressiveRendering} is off, so
828
+ * "Rendering drawing ..." stays up until deferred glyph jobs finish.
829
+ * When progressive rendering is on, the overlay uses
830
+ * {@link isConvertingEntities} and may hide while text geometry continues
831
+ * in the deferred pool (pan/zoom enabled). Deprecated `waitForTextGeometry`
832
+ * no longer selects this gate.
769
833
  */
770
834
  get: function () {
771
835
  return this._numOfEntitiesToProcess > 0 || this._pendingGeometryJobs > 0;
@@ -773,6 +837,17 @@ var AcTrView2d = /** @class */ (function (_super) {
773
837
  enumerable: false,
774
838
  configurable: true
775
839
  });
840
+ Object.defineProperty(AcTrView2d.prototype, "isConvertingEntities", {
841
+ /**
842
+ * True while the entity convert queue / {@link batchConvert} is still
843
+ * draining. Does **not** include deferred glyph/INSERT geometry jobs.
844
+ */
845
+ get: function () {
846
+ return this._numOfEntitiesToProcess > 0;
847
+ },
848
+ enumerable: false,
849
+ configurable: true
850
+ });
776
851
  /**
777
852
  * Waits until batch conversion and deferred glyph/font geometry finish.
778
853
  *
@@ -832,8 +907,9 @@ var AcTrView2d = /** @class */ (function (_super) {
832
907
  });
833
908
  Object.defineProperty(AcTrView2d.prototype, "progressiveOpenStats", {
834
909
  /**
835
- * Progressive-open counters for OPENPROF / palette (paints while converting,
836
- * cooperative yields). Reset when progressive mode is enabled for an open.
910
+ * Open-convert counters for OPENPROF / palette (cooperative yields during
911
+ * convert, and mid-open paints when progressive rendering is enabled).
912
+ * Reset when progressive mode is enabled for an open.
837
913
  */
838
914
  get: function () {
839
915
  return {
@@ -962,6 +1038,9 @@ var AcTrView2d = /** @class */ (function (_super) {
962
1038
  AcTrView2d.prototype.applyCanvasBackground = function (value) {
963
1039
  this._renderer.currentBackgroundColor = value;
964
1040
  this._layerAppearance.refreshTextMaterialsInObjectTree(this._scene.internalScene);
1041
+ // Style-manager changeForeground only updates cache entries; batch
1042
+ // containers own private material clones and must be repainted too.
1043
+ this._scene.repaintForegroundMaterials(acgiForegroundColorForBackground(value));
965
1044
  this.resyncForegroundLayersForBackground();
966
1045
  if (this._readingMode.isEnabled) {
967
1046
  this._readingMode.noteLayoutBackground(value);
@@ -1145,13 +1224,16 @@ var AcTrView2d = /** @class */ (function (_super) {
1145
1224
  threeEntity.visible = entity.visibility !== false;
1146
1225
  if (threeEntity instanceof AcTrGroup &&
1147
1226
  threeEntity.isOnTheSameLayer) {
1148
- // Children authored on layer "0" inherit the INSERT layer for
1149
- // ByLayer traits (color, etc.), same as the primary-document path.
1150
- this._inheritedLayerMaterialMapper.remap(threeEntity.children, '0', threeEntity.layerName);
1227
+ threeEntity.userData.insertLayerName = threeEntity.layerName;
1151
1228
  }
1152
1229
  return [4 /*yield*/, this.finishEntityGeometry(threeEntity, false)];
1153
1230
  case 5:
1154
1231
  _g.sent();
1232
+ if (threeEntity instanceof AcTrGroup &&
1233
+ threeEntity.isOnTheSameLayer) {
1234
+ // Remap after glyph geometry exists — see same-layer commit path.
1235
+ this._inheritedLayerMaterialMapper.remap(threeEntity.children, '0', threeEntity.layerName);
1236
+ }
1155
1237
  layout.addEntity(threeEntity);
1156
1238
  threeEntity.dispose();
1157
1239
  return [3 /*break*/, 7];
@@ -1421,14 +1503,50 @@ var AcTrView2d = /** @class */ (function (_super) {
1421
1503
  /**
1422
1504
  * Re-render points with latest point style settings
1423
1505
  * @param displayMode Input display mode of points
1506
+ * @param displaySize Input display size of points (`PDSIZE`)
1424
1507
  */
1425
- AcTrView2d.prototype.rerenderPoints = function (displayMode) {
1508
+ AcTrView2d.prototype.rerenderPoints = function (displayMode, displaySize) {
1509
+ if (displaySize === void 0) { displaySize = 0; }
1426
1510
  var activeLayout = this._scene.activeLayout;
1427
1511
  if (activeLayout) {
1428
- activeLayout.rerenderPoints(displayMode);
1512
+ activeLayout.rerenderPoints(displayMode, displaySize);
1429
1513
  this._isDirty = true;
1430
1514
  }
1431
1515
  };
1516
+ /**
1517
+ * When open framing waits on {@link zoomToFitDrawing}, show the linework
1518
+ * bounds as soon as entity convert drains. The final fit still runs after
1519
+ * deferred glyphs so text extents can refine the camera.
1520
+ */
1521
+ AcTrView2d.prototype.requestOpenLineworkFrame = function () {
1522
+ this._openLineworkFramePending = true;
1523
+ this.scheduleOpenLineworkFrame();
1524
+ };
1525
+ AcTrView2d.prototype.cancelOpenLineworkFrame = function () {
1526
+ this._openLineworkFramePending = false;
1527
+ if (this._openLineworkFrameTimer != null) {
1528
+ clearTimeout(this._openLineworkFrameTimer);
1529
+ this._openLineworkFrameTimer = null;
1530
+ }
1531
+ };
1532
+ AcTrView2d.prototype.scheduleOpenLineworkFrame = function () {
1533
+ var _this = this;
1534
+ if (this._openLineworkFrameTimer != null ||
1535
+ !this._openLineworkFramePending) {
1536
+ return;
1537
+ }
1538
+ var delay = this.isConvertingEntities ? 50 : 0;
1539
+ this._openLineworkFrameTimer = setTimeout(function () {
1540
+ _this._openLineworkFrameTimer = null;
1541
+ if (!_this._openLineworkFramePending)
1542
+ return;
1543
+ if (_this.isConvertingEntities) {
1544
+ _this.scheduleOpenLineworkFrame();
1545
+ return;
1546
+ }
1547
+ _this.frameOpenLineworkIfReady();
1548
+ }, delay);
1549
+ };
1432
1550
  /**
1433
1551
  * @inheritdoc
1434
1552
  */
@@ -1796,6 +1914,48 @@ var AcTrView2d = /** @class */ (function (_super) {
1796
1914
  AcTrView2d.prototype.selectByBox = function (box) {
1797
1915
  this.selectByBoxWithMode(box, 'crossing', 'add');
1798
1916
  };
1917
+ /**
1918
+ * Drops crossing spatial hits whose curve geometry misses the pick box.
1919
+ *
1920
+ * Large closed polylines (site boundaries, frames) have AABBs that cover
1921
+ * huge empty interiors. Without this refine, crossing a small INSERT inside
1922
+ * that interior also selects those polylines and can stall highlight work.
1923
+ */
1924
+ AcTrView2d.prototype.refineCrossingSelectionHits = function (box, results) {
1925
+ var e_8, _a;
1926
+ var _b;
1927
+ var database = (_b = AcApDocManager.instance.curDocument) === null || _b === void 0 ? void 0 : _b.database;
1928
+ if (!database) {
1929
+ return results.map(function (item) { return item.id; });
1930
+ }
1931
+ var ids = [];
1932
+ try {
1933
+ for (var results_1 = __values(results), results_1_1 = results_1.next(); !results_1_1.done; results_1_1 = results_1.next()) {
1934
+ var item = results_1_1.value;
1935
+ if (!acedNeedsCrossingGeometryRefine(item)) {
1936
+ ids.push(item.id);
1937
+ continue;
1938
+ }
1939
+ var entityBox = new AcGeBox2d({ x: item.minX, y: item.minY }, { x: item.maxX, y: item.maxY });
1940
+ if (box.containsBox(entityBox)) {
1941
+ ids.push(item.id);
1942
+ continue;
1943
+ }
1944
+ var entity = database.tables.blockTable.getEntityById(item.id);
1945
+ if (!entity || acedEntityIntersectsSelectionBox(entity, box)) {
1946
+ ids.push(item.id);
1947
+ }
1948
+ }
1949
+ }
1950
+ catch (e_8_1) { e_8 = { error: e_8_1 }; }
1951
+ finally {
1952
+ try {
1953
+ if (results_1_1 && !results_1_1.done && (_a = results_1.return)) _a.call(results_1);
1954
+ }
1955
+ finally { if (e_8) throw e_8.error; }
1956
+ }
1957
+ return ids;
1958
+ };
1799
1959
  /**
1800
1960
  * @inheritdoc
1801
1961
  */
@@ -1808,7 +1968,7 @@ var AcTrView2d = /** @class */ (function (_super) {
1808
1968
  * @inheritdoc
1809
1969
  */
1810
1970
  AcTrView2d.prototype.updateLayer = function (layer, changes) {
1811
- var e_8, _a;
1971
+ var e_9, _a;
1812
1972
  var touchedObjectIds = this._scene.updateLayer(this.toLayerInfo(layer)).touchedObjectIds;
1813
1973
  if (this._layerAppearance.layerStyleMayHaveChanged(changes)) {
1814
1974
  this._layerAppearance.syncFromLiveRecord(layer);
@@ -1830,12 +1990,12 @@ var AcTrView2d = /** @class */ (function (_super) {
1830
1990
  this.applySessionHiddenObjectState(objectId);
1831
1991
  }
1832
1992
  }
1833
- catch (e_8_1) { e_8 = { error: e_8_1 }; }
1993
+ catch (e_9_1) { e_9 = { error: e_9_1 }; }
1834
1994
  finally {
1835
1995
  try {
1836
1996
  if (touchedObjectIds_1_1 && !touchedObjectIds_1_1.done && (_a = touchedObjectIds_1.return)) _a.call(touchedObjectIds_1);
1837
1997
  }
1838
- finally { if (e_8) throw e_8.error; }
1998
+ finally { if (e_9) throw e_9.error; }
1839
1999
  }
1840
2000
  this._isDirty = true;
1841
2001
  };
@@ -1950,15 +2110,36 @@ var AcTrView2d = /** @class */ (function (_super) {
1950
2110
  */
1951
2111
  AcTrView2d.prototype.addEntity = function (entity) {
1952
2112
  var _a;
2113
+ var _b;
1953
2114
  var entities = Array.isArray(entity) ? entity : [entity];
1954
- this._numOfEntitiesToProcess += entities.length;
1955
- if (this._progressiveRendering) {
1956
- (_a = this._convertQueue).push.apply(_a, __spreadArray([], __read(entities), false));
1957
- void this.drainConvertQueue();
1958
- }
1959
- else {
1960
- void this.batchConvert(entities);
2115
+ // Mark each owner layout as loaded as soon as the open-time ENTITY stream
2116
+ // enqueues work. Progressive convert may not have committed scene entities
2117
+ // yet (`entityCount` still 0); without this, `loadLayoutEntitiesIfNeeded`
2118
+ // (from `onAfterOpenDocument` → `setActiveLayout`) re-iterates the BTR,
2119
+ // double-increments `_numOfEntitiesToProcess`, and keeps
2120
+ // "Rendering drawing ..." up long after linework should have finished —
2121
+ // so progressive rendering cannot release pan/zoom on time.
2122
+ for (var i = 0; i < entities.length; i++) {
2123
+ var ownerId = (_b = entities[i]) === null || _b === void 0 ? void 0 : _b.ownerId;
2124
+ if (!ownerId)
2125
+ continue;
2126
+ var layout = this._scene.layouts.get(ownerId);
2127
+ if (!layout) {
2128
+ this._scene.addEmptyLayout(ownerId);
2129
+ layout = this._scene.layouts.get(ownerId);
2130
+ }
2131
+ if (layout && !layout.isLoaded) {
2132
+ layout.isLoaded = true;
2133
+ }
1961
2134
  }
2135
+ this._numOfEntitiesToProcess += entities.length;
2136
+ // Always serialize convert through one drain loop. Non-progressive opens
2137
+ // used to `void batchConvert(chunk)` per ENTITY flush chunk, which ran
2138
+ // many converts in parallel and OOM'd dense drawings (e.g. cathedral.dwg)
2139
+ // during "Rendering drawing ...". Progressive mid-open paints stay gated
2140
+ // by `_progressiveRendering` inside batchConvert / markProgressiveDirty.
2141
+ (_a = this._convertQueue).push.apply(_a, __spreadArray([], __read(entities), false));
2142
+ void this.drainConvertQueue();
1962
2143
  };
1963
2144
  /**
1964
2145
  * @inheritdoc
@@ -2021,6 +2202,7 @@ var AcTrView2d = /** @class */ (function (_super) {
2021
2202
  */
2022
2203
  AcTrView2d.prototype.updateEntity = function (entity) {
2023
2204
  var _this = this;
2205
+ var _a, _b;
2024
2206
  var entities = this.resolveSceneUpdateEntities(Array.isArray(entity) ? entity : [entity]);
2025
2207
  if (entities.length === 0)
2026
2208
  return;
@@ -2029,6 +2211,17 @@ var AcTrView2d = /** @class */ (function (_super) {
2029
2211
  .filter(function (objectId) { return _this.selectionSet.has(objectId); });
2030
2212
  for (var i = 0; i < entities.length; ++i) {
2031
2213
  var item = entities[i];
2214
+ var objectId = String((_a = item.objectId) !== null && _a !== void 0 ? _a : '');
2215
+ if (objectId) {
2216
+ // Invalidate in-flight commits for this id before releasing the claim /
2217
+ // clearing the scene, so a stale progressive convert cannot re-add the
2218
+ // pre-update drawable after (or instead of) the reconversion pass.
2219
+ this._entityConvertGeneration.set(objectId, ((_b = this._entityConvertGeneration.get(objectId)) !== null && _b !== void 0 ? _b : 0) + 1);
2220
+ // Allow reconversion: open-time batchConvert claims objectIds to prevent
2221
+ // duplicate progressive slots. updateEntity must release that claim or
2222
+ // batchConvert skips the entity (scene already cleared → blank RasterImage).
2223
+ this._claimedConvertObjectIds.delete(objectId);
2224
+ }
2032
2225
  if (this._scene.hasEntity(item.objectId)) {
2033
2226
  this._scene.removeEntity(item.objectId);
2034
2227
  }
@@ -2048,6 +2241,7 @@ var AcTrView2d = /** @class */ (function (_super) {
2048
2241
  this.highlight(selectedIds);
2049
2242
  }
2050
2243
  this._gripManager.refresh();
2244
+ this._isDirty = true;
2051
2245
  return [2 /*return*/];
2052
2246
  }
2053
2247
  });
@@ -2064,7 +2258,7 @@ var AcTrView2d = /** @class */ (function (_super) {
2064
2258
  * drawable entity that must be rebuilt (for example ATTRIB → INSERT).
2065
2259
  */
2066
2260
  AcTrView2d.prototype.resolveSceneUpdateEntities = function (entities) {
2067
- var e_9, _a;
2261
+ var e_10, _a;
2068
2262
  var _b;
2069
2263
  var db = (_b = AcApDocManager.instance.curDocument) === null || _b === void 0 ? void 0 : _b.database;
2070
2264
  var resolved = [];
@@ -2086,12 +2280,12 @@ var AcTrView2d = /** @class */ (function (_super) {
2086
2280
  resolved.push(target);
2087
2281
  }
2088
2282
  }
2089
- catch (e_9_1) { e_9 = { error: e_9_1 }; }
2283
+ catch (e_10_1) { e_10 = { error: e_10_1 }; }
2090
2284
  finally {
2091
2285
  try {
2092
2286
  if (entities_1_1 && !entities_1_1.done && (_a = entities_1.return)) _a.call(entities_1);
2093
2287
  }
2094
- finally { if (e_9) throw e_9.error; }
2288
+ finally { if (e_10) throw e_10.error; }
2095
2289
  }
2096
2290
  return resolved;
2097
2291
  };
@@ -2215,9 +2409,14 @@ var AcTrView2d = /** @class */ (function (_super) {
2215
2409
  // Invalidate any in-flight progressive convert so it neither paints into
2216
2410
  // the cleared scene nor double-decrements the processing counter.
2217
2411
  this._convertEpoch++;
2412
+ this.clearFontLoadedRedrawTimer();
2218
2413
  this._convertQueue.length = 0;
2219
2414
  this._numOfEntitiesToProcess = 0;
2220
- this._pendingGeometryJobs = 0;
2415
+ this._claimedConvertObjectIds.clear();
2416
+ this._entityConvertGeneration.clear();
2417
+ this.cancelOpenLineworkFrame();
2418
+ this.resetDeferredGeometryQueue();
2419
+ this._entityProcessingIdleAt = 0;
2221
2420
  this._scene.clear();
2222
2421
  this._isDirty = true;
2223
2422
  this._missedImages.clear();
@@ -2252,9 +2451,14 @@ var AcTrView2d = /** @class */ (function (_super) {
2252
2451
  AcTrView2d.prototype.restoreSessionState = function (state) {
2253
2452
  var _a;
2254
2453
  this._convertEpoch++;
2454
+ this.clearFontLoadedRedrawTimer();
2455
+ this.cancelOpenLineworkFrame();
2255
2456
  this._convertQueue.length = 0;
2256
2457
  this._numOfEntitiesToProcess = 0;
2257
- this._pendingGeometryJobs = 0;
2458
+ this._claimedConvertObjectIds.clear();
2459
+ this._entityConvertGeneration.clear();
2460
+ this.resetDeferredGeometryQueue();
2461
+ this._entityProcessingIdleAt = 0;
2258
2462
  this._scene = state.scene;
2259
2463
  this._layoutViewManager = state.layoutViewManager;
2260
2464
  this._initializedLayouts = state.initializedLayouts;
@@ -2279,9 +2483,14 @@ var AcTrView2d = /** @class */ (function (_super) {
2279
2483
  AcTrView2d.prototype.beginNewSession = function () {
2280
2484
  var parked = this.captureSessionState();
2281
2485
  this._convertEpoch++;
2486
+ this.clearFontLoadedRedrawTimer();
2487
+ this.cancelOpenLineworkFrame();
2282
2488
  this._convertQueue.length = 0;
2283
2489
  this._numOfEntitiesToProcess = 0;
2284
- this._pendingGeometryJobs = 0;
2490
+ this._claimedConvertObjectIds.clear();
2491
+ this._entityConvertGeneration.clear();
2492
+ this.resetDeferredGeometryQueue();
2493
+ this._entityProcessingIdleAt = 0;
2285
2494
  this._scene = this.createScene();
2286
2495
  this._layoutViewManager = new AcTrLayoutViewManager();
2287
2496
  this._initializedLayouts = new Set();
@@ -2327,8 +2536,9 @@ var AcTrView2d = /** @class */ (function (_super) {
2327
2536
  return current == null || current === this;
2328
2537
  };
2329
2538
  /**
2330
- * Drains the progressive convert queue on a single serial worker so ENTITY
2331
- * flush chunks can enqueue while conversion overlaps the loading overlay.
2539
+ * Drains the convert queue on a single serial worker so ENTITY flush chunks
2540
+ * can enqueue without overlapping multiple {@link batchConvert} runs (which
2541
+ * spikes heap on large drawings).
2332
2542
  *
2333
2543
  * Concurrent callers share the same promise; if more entities are queued
2334
2544
  * after a drain finishes, a follow-up drain is started.
@@ -2437,6 +2647,20 @@ var AcTrView2d = /** @class */ (function (_super) {
2437
2647
  this._rafId = null;
2438
2648
  }
2439
2649
  };
2650
+ /**
2651
+ * Releases canvas DOM listeners and stops the animation loop.
2652
+ *
2653
+ * Call when this view will no longer be used (manager destroy / split
2654
+ * view teardown). Safe to call more than once.
2655
+ */
2656
+ AcTrView2d.prototype.dispose = function () {
2657
+ var _a;
2658
+ (_a = this._disposeCanvasTouchCallout) === null || _a === void 0 ? void 0 : _a.call(this);
2659
+ this._disposeCanvasTouchCallout = undefined;
2660
+ this.clearFontLoadedRedrawTimer();
2661
+ this.cancelOpenLineworkFrame();
2662
+ this.stopAnimationLoop();
2663
+ };
2440
2664
  /**
2441
2665
  * @inheritdoc
2442
2666
  */
@@ -2529,7 +2753,7 @@ var AcTrView2d = /** @class */ (function (_super) {
2529
2753
  * @param layoutBtrId Input the block table record id of the layout
2530
2754
  */
2531
2755
  AcTrView2d.prototype.loadLayoutEntitiesIfNeeded = function (layoutBtrId) {
2532
- var e_10, _a;
2756
+ var e_11, _a;
2533
2757
  var _this = this;
2534
2758
  try {
2535
2759
  var db = AcApDocManager.instance.curDocument.database;
@@ -2539,6 +2763,15 @@ var AcTrView2d = /** @class */ (function (_super) {
2539
2763
  }
2540
2764
  var existingLayout = this._scene.layouts.get(layoutBtrId);
2541
2765
  if (existingLayout && existingLayout.isLoaded) {
2766
+ // Streamed layouts flip `isLoaded` from `addEntity` before scene
2767
+ // commits finish. Still repair the viewport-view race when entities
2768
+ // are already in the scene but AcTrViewportView creation was skipped.
2769
+ var layoutView_1 = this._layoutViewManager.getAt(layoutBtrId);
2770
+ if (existingLayout.entityCount > 0 &&
2771
+ layoutView_1 &&
2772
+ layoutView_1.viewportCount === 0) {
2773
+ this.ensureViewportViews(blockTableRecord, layoutView_1);
2774
+ }
2542
2775
  return;
2543
2776
  }
2544
2777
  if (this._loadingLayouts.has(layoutBtrId)) {
@@ -2582,6 +2815,11 @@ var AcTrView2d = /** @class */ (function (_super) {
2582
2815
  // is only for layouts whose entities were never streamed in
2583
2816
  // (typically non-active paper-space layouts loaded on first user
2584
2817
  // visit).
2818
+ //
2819
+ // Note: `addEntity` now sets `isLoaded` when the open stream
2820
+ // enqueues work, so the common progressive-open race (entityCount
2821
+ // still 0 at `onAfterOpenDocument` while the convert queue is full)
2822
+ // is handled by the `isLoaded` early return above.
2585
2823
  if (existingLayout && existingLayout.entityCount > 0) {
2586
2824
  existingLayout.isLoaded = true;
2587
2825
  return;
@@ -2600,12 +2838,12 @@ var AcTrView2d = /** @class */ (function (_super) {
2600
2838
  entities_2.push(entity);
2601
2839
  }
2602
2840
  }
2603
- catch (e_10_1) { e_10 = { error: e_10_1 }; }
2841
+ catch (e_11_1) { e_11 = { error: e_11_1 }; }
2604
2842
  finally {
2605
2843
  try {
2606
2844
  if (iterator_1_1 && !iterator_1_1.done && (_a = iterator_1.return)) _a.call(iterator_1);
2607
2845
  }
2608
- finally { if (e_10) throw e_10.error; }
2846
+ finally { if (e_11) throw e_11.error; }
2609
2847
  }
2610
2848
  if (entities_2.length === 0) {
2611
2849
  // Empty layout (e.g. a freshly-created paper space tab). Mark as
@@ -2723,36 +2961,115 @@ var AcTrView2d = /** @class */ (function (_super) {
2723
2961
  AcTrView2d.prototype.drawEntity = function (entity, delay) {
2724
2962
  return entity.worldDraw(this._renderer, delay);
2725
2963
  };
2964
+ /**
2965
+ * Starts loading fonts referenced by the drawing text style table.
2966
+ *
2967
+ * Call when conversion stage `STYLE` ends so the download overlaps later
2968
+ * parse stages and linework convert. Does not block the caller — glyph
2969
+ * finalize awaits {@link awaitTextStyleFontsReady} instead.
2970
+ *
2971
+ * @param database - Database whose text style table has just been filled.
2972
+ */
2973
+ AcTrView2d.prototype.startTextStyleFontPreload = function (database) {
2974
+ var _a;
2975
+ var epoch = this._convertEpoch;
2976
+ if (this._textStyleFontPreloadEpoch === epoch &&
2977
+ this._textStyleFontPreloadPromise) {
2978
+ return;
2979
+ }
2980
+ this._textStyleFontPreloadEpoch = epoch;
2981
+ var names = [];
2982
+ try {
2983
+ names = (_a = database.tables.textStyleTable.fonts) !== null && _a !== void 0 ? _a : [];
2984
+ }
2985
+ catch (_b) {
2986
+ this._textStyleFontPreloadPromise = Promise.resolve();
2987
+ return;
2988
+ }
2989
+ if (names.length === 0) {
2990
+ this._textStyleFontPreloadPromise = Promise.resolve();
2991
+ return;
2992
+ }
2993
+ this._textStyleFontPreloadPromise = FontManager.instance
2994
+ .requestFonts(names)
2995
+ .then(function () { }, function () {
2996
+ // Glyph draw still falls back via FontManager defaults / '?'.
2997
+ });
2998
+ };
2999
+ /**
3000
+ * Waits until {@link startTextStyleFontPreload} has finished (or starts a
3001
+ * fallback preload from this view's bound draw database if STYLE was missed).
3002
+ */
3003
+ AcTrView2d.prototype.awaitTextStyleFontsReady = function () {
3004
+ return __awaiter(this, void 0, void 0, function () {
3005
+ var db;
3006
+ return __generator(this, function (_a) {
3007
+ switch (_a.label) {
3008
+ case 0:
3009
+ if (!this._textStyleFontPreloadPromise) {
3010
+ db = this._renderer.context.database;
3011
+ if (db) {
3012
+ this.startTextStyleFontPreload(db);
3013
+ }
3014
+ else {
3015
+ return [2 /*return*/];
3016
+ }
3017
+ }
3018
+ return [4 /*yield*/, this._textStyleFontPreloadPromise];
3019
+ case 1:
3020
+ _a.sent();
3021
+ return [2 /*return*/];
3022
+ }
3023
+ });
3024
+ });
3025
+ };
2726
3026
  /**
2727
3027
  * Finishes geometry for a converted entity.
2728
3028
  *
2729
- * Glyph entities and block groups use {@link AcTrEntity.asyncDraw} so
2730
- * {@link FontManager.awaitFontsBeforeDraw} can wait for fonts without
2731
- * relying on a full-scene regen. Other entities keep the sync finalize path.
3029
+ * Glyph entities, complex-linetype lines, and block groups use
3030
+ * {@link AcTrEntity.asyncDraw} so {@link FontManager.awaitFontsBeforeDraw}
3031
+ * can wait for fonts without relying on a full-scene regen. Other entities
3032
+ * keep the sync finalize path.
2732
3033
  */
2733
3034
  AcTrView2d.prototype.finishEntityGeometry = function (threeEntity, _progressive) {
2734
3035
  return __awaiter(this, void 0, void 0, function () {
3036
+ var needsGlyphDraw;
2735
3037
  return __generator(this, function (_a) {
2736
3038
  switch (_a.label) {
2737
3039
  case 0:
2738
- if (!(threeEntity instanceof AcTrGroup)) return [3 /*break*/, 2];
2739
- // Compacted INSERT templates may skip syncDraw when fonts are awaited
2740
- // later; still walk for empty glyph shells. Skip only when there is
2741
- // nothing left to finalize (incl. post-cache ATTRIBs).
2742
- if (threeEntity.getSourceEntities().length === 0 &&
2743
- !this.groupHasPendingGlyphGeometry(threeEntity)) {
3040
+ needsGlyphDraw = (threeEntity instanceof AcTrGroup &&
3041
+ this.groupHasPendingGlyphGeometry(threeEntity)) ||
3042
+ hasPendingComplexLineTypeGlyphs(threeEntity) ||
3043
+ (threeEntity instanceof AcTrGlyphEntity &&
3044
+ !threeEntity.hasDrawableGeometry());
3045
+ if (!needsGlyphDraw) return [3 /*break*/, 2];
3046
+ return [4 /*yield*/, this.awaitTextStyleFontsReady()];
3047
+ case 1:
3048
+ _a.sent();
3049
+ _a.label = 2;
3050
+ case 2:
3051
+ if (!(threeEntity instanceof AcTrGroup)) return [3 /*break*/, 4];
3052
+ // Linework-only INSERTs (no empty glyph shells) skip asyncDraw; spatial
3053
+ // boxes are refreshed by syncGroupSpatialBoundsForIndexing after commit.
3054
+ if (!this.groupHasPendingGlyphGeometry(threeEntity)) {
2744
3055
  return [2 /*return*/];
2745
3056
  }
2746
3057
  return [4 /*yield*/, threeEntity.asyncDraw()];
2747
- case 1:
3058
+ case 3:
2748
3059
  _a.sent();
2749
3060
  return [2 /*return*/];
2750
- case 2:
3061
+ case 4:
3062
+ if (!hasPendingComplexLineTypeGlyphs(threeEntity)) return [3 /*break*/, 6];
3063
+ return [4 /*yield*/, threeEntity.asyncDraw()];
3064
+ case 5:
3065
+ _a.sent();
3066
+ return [2 /*return*/];
3067
+ case 6:
2751
3068
  if (threeEntity.hasDrawableGeometry()) {
2752
3069
  return [2 /*return*/];
2753
3070
  }
2754
3071
  return [4 /*yield*/, threeEntity.asyncDraw()];
2755
- case 3:
3072
+ case 7:
2756
3073
  _a.sent();
2757
3074
  return [2 /*return*/];
2758
3075
  }
@@ -2760,7 +3077,152 @@ var AcTrView2d = /** @class */ (function (_super) {
2760
3077
  });
2761
3078
  };
2762
3079
  AcTrView2d.prototype.needsDeferredFontGeometry = function (threeEntity) {
2763
- return (threeEntity instanceof AcTrGlyphEntity || threeEntity instanceof AcTrGroup);
3080
+ if (threeEntity instanceof AcTrGlyphEntity) {
3081
+ return !threeEntity.hasDrawableGeometry();
3082
+ }
3083
+ // Only defer INSERTs that still have empty glyph shells. Linework-only
3084
+ // blocks should commit on the convert path and not occupy the geometry pool.
3085
+ if (threeEntity instanceof AcTrGroup) {
3086
+ return this.groupHasPendingGlyphGeometry(threeEntity);
3087
+ }
3088
+ return hasPendingComplexLineTypeGlyphs(threeEntity);
3089
+ };
3090
+ AcTrView2d.prototype.clearFontLoadedRedrawTimer = function () {
3091
+ if (this._fontLoadedRedrawTimer != null) {
3092
+ clearTimeout(this._fontLoadedRedrawTimer);
3093
+ this._fontLoadedRedrawTimer = null;
3094
+ }
3095
+ };
3096
+ /**
3097
+ * Coalesces late font-load notifications into one glyph rebuild pass.
3098
+ */
3099
+ AcTrView2d.prototype.scheduleGlyphRedrawAfterFontLoad = function (fontName) {
3100
+ var _this = this;
3101
+ this.clearFontLoadedRedrawTimer();
3102
+ var epoch = this._convertEpoch;
3103
+ this._fontLoadedRedrawTimer = setTimeout(function () {
3104
+ _this._fontLoadedRedrawTimer = null;
3105
+ if (epoch !== _this._convertEpoch) {
3106
+ return;
3107
+ }
3108
+ void _this.redrawGlyphEntitiesAfterFontLoad(epoch, fontName);
3109
+ }, 50);
3110
+ };
3111
+ /**
3112
+ * Rebuilds text after a late {@link FontManager.events.fontLoaded}.
3113
+ *
3114
+ * Live {@link AcTrGlyphEntity} shells (rare: mid-convert / not yet batched)
3115
+ * are re-drawn in place. Committed text is already flattened into batches and
3116
+ * disposed. A database regen does not rebuild those batches — `entityAppended`
3117
+ * skips ids the view already has — but it does replay open-file CONVERSION
3118
+ * progress. That replay is skipped while the open has just gone idle
3119
+ * ({@link shouldRegenDatabaseAfterFontLoad}); a face that arrives later can
3120
+ * still regen.
3121
+ */
3122
+ AcTrView2d.prototype.redrawGlyphEntitiesAfterFontLoad = function (epoch, fontName) {
3123
+ return __awaiter(this, void 0, void 0, function () {
3124
+ var redrawEpoch, glyphs, _a, _b, layout, glyphs_1, glyphs_1_1, glyph, e_12_1, defaults, normalized_1, msSinceIdle, db;
3125
+ var e_13, _c, e_12, _d;
3126
+ var _e, _f;
3127
+ return __generator(this, function (_g) {
3128
+ switch (_g.label) {
3129
+ case 0:
3130
+ if (epoch !== this._convertEpoch) {
3131
+ return [2 /*return*/];
3132
+ }
3133
+ redrawEpoch = ++this._fontLoadedRedrawEpoch;
3134
+ glyphs = [];
3135
+ try {
3136
+ for (_a = __values(this._scene.layouts.values()), _b = _a.next(); !_b.done; _b = _a.next()) {
3137
+ layout = _b.value;
3138
+ layout.layers.forEach(function (layer) {
3139
+ layer.internalObject.traverse(function (obj) {
3140
+ if (obj instanceof AcTrGlyphEntity) {
3141
+ glyphs.push(obj);
3142
+ }
3143
+ });
3144
+ });
3145
+ }
3146
+ }
3147
+ catch (e_13_1) { e_13 = { error: e_13_1 }; }
3148
+ finally {
3149
+ try {
3150
+ if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
3151
+ }
3152
+ finally { if (e_13) throw e_13.error; }
3153
+ }
3154
+ _g.label = 1;
3155
+ case 1:
3156
+ _g.trys.push([1, 6, 7, 8]);
3157
+ glyphs_1 = __values(glyphs), glyphs_1_1 = glyphs_1.next();
3158
+ _g.label = 2;
3159
+ case 2:
3160
+ if (!!glyphs_1_1.done) return [3 /*break*/, 5];
3161
+ glyph = glyphs_1_1.value;
3162
+ if (epoch !== this._convertEpoch ||
3163
+ redrawEpoch !== this._fontLoadedRedrawEpoch) {
3164
+ return [2 /*return*/];
3165
+ }
3166
+ return [4 /*yield*/, glyph.asyncDraw()];
3167
+ case 3:
3168
+ _g.sent();
3169
+ _g.label = 4;
3170
+ case 4:
3171
+ glyphs_1_1 = glyphs_1.next();
3172
+ return [3 /*break*/, 2];
3173
+ case 5: return [3 /*break*/, 8];
3174
+ case 6:
3175
+ e_12_1 = _g.sent();
3176
+ e_12 = { error: e_12_1 };
3177
+ return [3 /*break*/, 8];
3178
+ case 7:
3179
+ try {
3180
+ if (glyphs_1_1 && !glyphs_1_1.done && (_d = glyphs_1.return)) _d.call(glyphs_1);
3181
+ }
3182
+ finally { if (e_12) throw e_12.error; }
3183
+ return [7 /*endfinally*/];
3184
+ case 8:
3185
+ if (glyphs.length > 0) {
3186
+ if (epoch === this._convertEpoch) {
3187
+ this._isDirty = true;
3188
+ }
3189
+ return [2 /*return*/];
3190
+ }
3191
+ // Default/symbol preset faces are requested in the background under lazy
3192
+ // loading (mtext-renderer awaitFontsBeforeDraw only waits on content/style
3193
+ // fonts). Regenerating for every default face load would thrash after open;
3194
+ // style fonts that finish late still take the regen path below.
3195
+ if (fontName) {
3196
+ defaults = FontManager.instance.defaultFonts;
3197
+ normalized_1 = fontName.toLowerCase();
3198
+ if (defaults.has(fontName) ||
3199
+ defaults.has(normalized_1) ||
3200
+ __spreadArray([], __read(defaults), false).some(function (name) { return name.toLowerCase() === normalized_1; })) {
3201
+ return [2 /*return*/];
3202
+ }
3203
+ }
3204
+ if (epoch !== this._convertEpoch ||
3205
+ redrawEpoch !== this._fontLoadedRedrawEpoch) {
3206
+ return [2 /*return*/];
3207
+ }
3208
+ msSinceIdle = this._entityProcessingIdleAt > 0
3209
+ ? performance.now() - this._entityProcessingIdleAt
3210
+ : null;
3211
+ // Open-time text awaits its fonts, then this debounced callback runs.
3212
+ // Regen here only flashes the loading spinner again after
3213
+ // "Rendering drawing ..." has already hidden (progressive rendering on).
3214
+ if (!shouldRegenDatabaseAfterFontLoad(this.isProcessingEntities, 0, msSinceIdle)) {
3215
+ return [2 /*return*/];
3216
+ }
3217
+ db = (_f = (_e = AcApDocManager.instance) === null || _e === void 0 ? void 0 : _e.curDocument) === null || _f === void 0 ? void 0 : _f.database;
3218
+ if (!db) {
3219
+ return [2 /*return*/];
3220
+ }
3221
+ db.regen();
3222
+ return [2 /*return*/];
3223
+ }
3224
+ });
3225
+ });
2764
3226
  };
2765
3227
  AcTrView2d.prototype.groupHasPendingGlyphGeometry = function (group) {
2766
3228
  var pending = false;
@@ -2774,32 +3236,71 @@ var AcTrView2d = /** @class */ (function (_super) {
2774
3236
  /**
2775
3237
  * Runs glyph/group geometry finalize off the main convert loop so other
2776
3238
  * entities keep converting while fonts download.
3239
+ *
3240
+ * Jobs are queued with bounded concurrency — unbounded parallel
3241
+ * `asyncDraw` on large INSERT/text drawings can freeze the main thread
3242
+ * during the "Rendering drawing ..." stage.
2777
3243
  */
2778
3244
  AcTrView2d.prototype.enqueueDeferredGeometry = function (run, epoch) {
2779
- var _this = this;
2780
3245
  if (epoch !== this._convertEpoch) {
2781
3246
  return;
2782
3247
  }
2783
3248
  this._pendingGeometryJobs++;
2784
- void run()
2785
- .then(function () {
2786
- // Convert counter often hits 0 before fonts finish; without this,
2787
- // text added later never paints until the user pans/zooms.
2788
- if (epoch === _this._convertEpoch) {
2789
- _this._isDirty = true;
3249
+ this._deferredGeometryQueue.push({ run: run, epoch: epoch });
3250
+ this.pumpDeferredGeometryQueue();
3251
+ };
3252
+ /**
3253
+ * Starts queued deferred geometry jobs up to
3254
+ * {@link DEFERRED_GEOMETRY_CONCURRENCY}.
3255
+ */
3256
+ AcTrView2d.prototype.pumpDeferredGeometryQueue = function () {
3257
+ var _this = this;
3258
+ var _loop_3 = function () {
3259
+ var job = this_2._deferredGeometryQueue.shift();
3260
+ if (job.epoch !== this_2._convertEpoch) {
3261
+ this_2._pendingGeometryJobs = Math.max(0, this_2._pendingGeometryJobs - 1);
3262
+ return "continue";
2790
3263
  }
2791
- })
2792
- .catch(function (error) {
2793
- log.error('[AcTrView2d] Deferred entity geometry failed:', error);
2794
- })
2795
- .finally(function () {
2796
- if (epoch === _this._convertEpoch) {
2797
- _this._pendingGeometryJobs = Math.max(0, _this._pendingGeometryJobs - 1);
2798
- if (_this._pendingGeometryJobs === 0) {
3264
+ this_2._deferredGeometryActive++;
3265
+ void job
3266
+ .run()
3267
+ .then(function () {
3268
+ // Convert counter often hits 0 before fonts finish; without this,
3269
+ // text added later never paints until the user pans/zooms.
3270
+ if (job.epoch === _this._convertEpoch) {
2799
3271
  _this._isDirty = true;
2800
3272
  }
2801
- }
2802
- });
3273
+ })
3274
+ .catch(function (error) {
3275
+ log.error('[AcTrView2d] Deferred entity geometry failed:', error);
3276
+ })
3277
+ .finally(function () {
3278
+ _this._deferredGeometryActive = Math.max(0, _this._deferredGeometryActive - 1);
3279
+ if (job.epoch === _this._convertEpoch) {
3280
+ _this._pendingGeometryJobs = Math.max(0, _this._pendingGeometryJobs - 1);
3281
+ if (_this._pendingGeometryJobs === 0) {
3282
+ _this._isDirty = true;
3283
+ }
3284
+ _this.stampEntityProcessingIdle();
3285
+ }
3286
+ _this.pumpDeferredGeometryQueue();
3287
+ });
3288
+ };
3289
+ var this_2 = this;
3290
+ while (this._deferredGeometryActive < AcTrView2d.DEFERRED_GEOMETRY_CONCURRENCY &&
3291
+ this._deferredGeometryQueue.length > 0) {
3292
+ _loop_3();
3293
+ }
3294
+ };
3295
+ /** Drops queued deferred geometry and resets counters for a new epoch. */
3296
+ AcTrView2d.prototype.resetDeferredGeometryQueue = function () {
3297
+ this._deferredGeometryQueue.length = 0;
3298
+ // Keep `_deferredGeometryActive`: in-flight runners still own concurrency
3299
+ // slots until their `finally` runs. Zeroing here lets pump over-schedule
3300
+ // when those completions decrement the counter afterward.
3301
+ this._pendingGeometryJobs = 0;
3302
+ this._textStyleFontPreloadPromise = null;
3303
+ this._textStyleFontPreloadEpoch = -1;
2803
3304
  };
2804
3305
  /**
2805
3306
  * Waits until side-pool glyph/group jobs for the current convert epoch finish.
@@ -2843,7 +3344,7 @@ var AcTrView2d = /** @class */ (function (_super) {
2843
3344
  * paper layouts.
2844
3345
  */
2845
3346
  AcTrView2d.prototype.ensureViewportViews = function (blockTableRecord, layoutView) {
2846
- var e_11, _a;
3347
+ var e_14, _a;
2847
3348
  var iterator = blockTableRecord.newIterator();
2848
3349
  try {
2849
3350
  for (var iterator_2 = __values(iterator), iterator_2_1 = iterator_2.next(); !iterator_2_1.done; iterator_2_1 = iterator_2.next()) {
@@ -2856,12 +3357,12 @@ var AcTrView2d = /** @class */ (function (_super) {
2856
3357
  layoutView.addViewport(viewportView);
2857
3358
  }
2858
3359
  }
2859
- catch (e_11_1) { e_11 = { error: e_11_1 }; }
3360
+ catch (e_14_1) { e_14 = { error: e_14_1 }; }
2860
3361
  finally {
2861
3362
  try {
2862
3363
  if (iterator_2_1 && !iterator_2_1.done && (_a = iterator_2.return)) _a.call(iterator_2);
2863
3364
  }
2864
- finally { if (e_11) throw e_11.error; }
3365
+ finally { if (e_14) throw e_14.error; }
2865
3366
  }
2866
3367
  };
2867
3368
  /**
@@ -2871,31 +3372,41 @@ var AcTrView2d = /** @class */ (function (_super) {
2871
3372
  */
2872
3373
  AcTrView2d.prototype.batchConvert = function (entities_3) {
2873
3374
  return __awaiter(this, arguments, void 0, function (entities, options) {
2874
- var epoch, progressive, yieldGate, yieldToEventLoop, _loop_3, this_2, i;
3375
+ var epoch, db, progressive, yieldGate, yieldToEventLoop, _loop_4, this_3, i;
2875
3376
  var _this = this;
3377
+ var _a, _b, _c;
2876
3378
  if (options === void 0) { options = {}; }
2877
- return __generator(this, function (_a) {
2878
- switch (_a.label) {
3379
+ return __generator(this, function (_d) {
3380
+ switch (_d.label) {
2879
3381
  case 0:
2880
3382
  epoch = this._convertEpoch;
3383
+ // Fallback: if STYLE-stage preload never started (e.g. non-conversion open
3384
+ // paths), kick it off without blocking linework convert. Glyph finalize
3385
+ // awaits the promise via {@link awaitTextStyleFontsReady}.
3386
+ if (!options.forExport && !this._textStyleFontPreloadPromise) {
3387
+ db = this._renderer.context.database;
3388
+ if (db) {
3389
+ this.startTextStyleFontPreload(db);
3390
+ }
3391
+ }
2881
3392
  progressive = this._progressiveRendering && !options.forExport;
2882
- yieldGate = progressive
2883
- ? new AcCmUiYieldGate(AcTrView2d.PROGRESSIVE_OPEN_YIELD_BUDGET_MS)
2884
- : undefined;
3393
+ yieldGate = options.forExport
3394
+ ? undefined
3395
+ : new AcCmUiYieldGate(AcTrView2d.OPEN_CONVERT_YIELD_BUDGET_MS);
2885
3396
  yieldToEventLoop = function () {
2886
3397
  return new Promise(function (resolve) { return setTimeout(resolve, 0); });
2887
3398
  };
2888
- _loop_3 = function (i) {
2889
- var entity, shouldConvert, directMeta, added, threeEntity_1, isMultiLayerGroup, deferGeometry, isExtendBbox_1, commitEntity, layoutView, viewportView, fileName, error_2, didYield;
2890
- return __generator(this, function (_b) {
2891
- switch (_b.label) {
3399
+ _loop_4 = function (i) {
3400
+ var entity, shouldConvert, objectId_1, convertGen_1, directMeta, added, superseded, threeEntity_1, isMultiLayerGroup, deferGeometry, isExtendBbox_1, commitEntity, layoutView, viewportView, fileName, error_2, didYield;
3401
+ return __generator(this, function (_e) {
3402
+ switch (_e.label) {
2892
3403
  case 0:
2893
3404
  entity = entities[i];
2894
- _b.label = 1;
3405
+ _e.label = 1;
2895
3406
  case 1:
2896
- _b.trys.push([1, 9, 10, 11]);
3407
+ _e.trys.push([1, 9, 10, 11]);
2897
3408
  // Document was cleared / replaced while this batch was draining.
2898
- if (epoch !== this_2._convertEpoch) {
3409
+ if (epoch !== this_3._convertEpoch) {
2899
3410
  return [2 /*return*/, "continue"];
2900
3411
  }
2901
3412
  // Skip the default paper-space viewport (`*Paper_Space`) entirely:
@@ -2914,33 +3425,53 @@ var AcTrView2d = /** @class */ (function (_super) {
2914
3425
  return [2 /*return*/, "continue"];
2915
3426
  }
2916
3427
  shouldConvert = options.forExport
2917
- ? this_2._entityDisplay.shouldConvertForExport(entity)
2918
- : this_2._entityDisplay.shouldConvert(entity);
3428
+ ? this_3._entityDisplay.shouldConvertForExport(entity)
3429
+ : this_3._entityDisplay.shouldConvert(entity);
2919
3430
  if (!shouldConvert) {
2920
3431
  return [2 /*return*/, "continue"];
2921
3432
  }
2922
- directMeta = tryBuildDirectEntityMeta(entity, this_2._renderer);
3433
+ objectId_1 = String((_a = entity.objectId) !== null && _a !== void 0 ? _a : '');
3434
+ convertGen_1 = 0;
3435
+ if (!options.forExport) {
3436
+ if (objectId_1 &&
3437
+ (this_3.hasEntity(objectId_1) ||
3438
+ this_3._claimedConvertObjectIds.has(objectId_1))) {
3439
+ return [2 /*return*/, "continue"];
3440
+ }
3441
+ if (objectId_1) {
3442
+ this_3._claimedConvertObjectIds.add(objectId_1);
3443
+ convertGen_1 = (_b = this_3._entityConvertGeneration.get(objectId_1)) !== null && _b !== void 0 ? _b : 0;
3444
+ }
3445
+ }
3446
+ directMeta = tryBuildDirectEntityMeta(entity, this_3._renderer);
2923
3447
  if (directMeta) {
2924
3448
  added = false;
3449
+ superseded = false;
2925
3450
  try {
2926
- added = this_2._scene.addDirectEntity(directMeta, shouldExtendBboxForDirectEntity(entity));
2927
- if (added) {
2928
- this_2.applySessionHiddenObjectState(entity.objectId);
2929
- if (progressive) {
2930
- this_2.markProgressiveDirty();
2931
- this_2._progressiveOpenFit.afterGeometryBatch(function () { return _this.resolveLayoutFitBox(); }, i);
3451
+ if (objectId_1 &&
3452
+ ((_c = this_3._entityConvertGeneration.get(objectId_1)) !== null && _c !== void 0 ? _c : 0) !== convertGen_1) {
3453
+ superseded = true;
3454
+ }
3455
+ else {
3456
+ added = this_3._scene.addDirectEntity(directMeta, shouldExtendBboxForDirectEntity(entity));
3457
+ if (added) {
3458
+ this_3.applySessionHiddenObjectState(entity.objectId);
3459
+ if (progressive) {
3460
+ this_3.markProgressiveDirty();
3461
+ this_3._progressiveOpenFit.afterGeometryBatch(function () { return _this.resolveLayoutFitBox(); }, i);
3462
+ }
2932
3463
  }
2933
3464
  }
2934
3465
  }
2935
3466
  finally {
2936
3467
  directMeta.geometry.dispose();
2937
3468
  }
2938
- if (added) {
3469
+ if (superseded || added) {
2939
3470
  return [2 /*return*/, "continue"];
2940
3471
  }
2941
3472
  // Append refused (e.g. invisible) — fall through to the legacy path.
2942
3473
  }
2943
- threeEntity_1 = this_2.drawEntity(entity, false);
3474
+ threeEntity_1 = this_3.drawEntity(entity, false);
2944
3475
  // Viewports may produce no border geometry (e.g. on a no-plot layer) while
2945
3476
  // still needing an AcTrViewportView for model content below.
2946
3477
  if (!threeEntity_1 && !(entity instanceof AcDbViewport))
@@ -2952,40 +3483,51 @@ var AcTrView2d = /** @class */ (function (_super) {
2952
3483
  threeEntity_1.visible = entity.visibility !== false;
2953
3484
  if (threeEntity_1 instanceof AcTrGroup &&
2954
3485
  threeEntity_1.isOnTheSameLayer) {
2955
- // Even when a block expands to a single layer bucket, children authored on
2956
- // layer "0" still inherit the INSERT layer for ByLayer traits (color, etc.).
2957
- this_2._inheritedLayerMaterialMapper.remap(threeEntity_1.children, '0', threeEntity_1.layerName);
3486
+ // Layer-0 inheritance must run AFTER finishEntityGeometry so TEXT/
3487
+ // MTEXT glyph materials exist. Remapping earlier (before asyncDraw)
3488
+ // leaves GM/GB-style labels as ACI-7 white while the block frame
3489
+ // remaps correctly (GAS-Meter / GAS-Box, A517B / A517E).
2958
3490
  threeEntity_1.userData.insertLayerName = threeEntity_1.layerName;
2959
3491
  }
2960
3492
  isMultiLayerGroup = threeEntity_1 instanceof AcTrGroup &&
2961
3493
  !threeEntity_1.isOnTheSameLayer;
2962
- deferGeometry = !options.forExport && this_2.needsDeferredFontGeometry(threeEntity_1);
3494
+ deferGeometry = !options.forExport && this_3.needsDeferredFontGeometry(threeEntity_1);
2963
3495
  if (!isMultiLayerGroup) return [3 /*break*/, 5];
2964
3496
  if (!deferGeometry) return [3 /*break*/, 2];
2965
- this_2.enqueueDeferredGeometry(function () {
2966
- return _this.handleGroup(threeEntity_1, progressive, epoch);
3497
+ this_3.enqueueDeferredGeometry(function () {
3498
+ return _this.handleGroup(threeEntity_1, progressive, epoch, convertGen_1);
2967
3499
  }, epoch);
2968
3500
  return [3 /*break*/, 4];
2969
- case 2: return [4 /*yield*/, this_2.handleGroup(threeEntity_1, progressive, epoch)];
3501
+ case 2: return [4 /*yield*/, this_3.handleGroup(threeEntity_1, progressive, epoch, convertGen_1)];
2970
3502
  case 3:
2971
- _b.sent();
2972
- _b.label = 4;
3503
+ _e.sent();
3504
+ _e.label = 4;
2973
3505
  case 4: return [3 /*break*/, 8];
2974
3506
  case 5:
2975
3507
  isExtendBbox_1 = !(entity instanceof AcDbRay || entity instanceof AcDbXline);
2976
3508
  commitEntity = function () { return __awaiter(_this, void 0, void 0, function () {
2977
3509
  var _this = this;
2978
- return __generator(this, function (_a) {
2979
- switch (_a.label) {
3510
+ var _a;
3511
+ return __generator(this, function (_b) {
3512
+ switch (_b.label) {
2980
3513
  case 0: return [4 /*yield*/, this.finishEntityGeometry(threeEntity_1, progressive)];
2981
3514
  case 1:
2982
- _a.sent();
3515
+ _b.sent();
2983
3516
  if (epoch !== this._convertEpoch) {
2984
3517
  threeEntity_1.dispose();
2985
3518
  return [2 /*return*/];
2986
3519
  }
3520
+ if (objectId_1 &&
3521
+ ((_a = this._entityConvertGeneration.get(objectId_1)) !== null && _a !== void 0 ? _a : 0) !==
3522
+ convertGen_1) {
3523
+ threeEntity_1.dispose();
3524
+ return [2 /*return*/];
3525
+ }
2987
3526
  if (threeEntity_1 instanceof AcTrGroup) {
2988
3527
  this.syncGroupSpatialBoundsForIndexing(threeEntity_1);
3528
+ if (threeEntity_1.isOnTheSameLayer) {
3529
+ this._inheritedLayerMaterialMapper.remap(threeEntity_1.children, '0', threeEntity_1.layerName);
3530
+ }
2989
3531
  }
2990
3532
  this._scene.addEntity(threeEntity_1, isExtendBbox_1);
2991
3533
  this.applySessionHiddenObjectState(entity.objectId);
@@ -3000,14 +3542,14 @@ var AcTrView2d = /** @class */ (function (_super) {
3000
3542
  });
3001
3543
  }); };
3002
3544
  if (!deferGeometry) return [3 /*break*/, 6];
3003
- this_2.enqueueDeferredGeometry(commitEntity, epoch);
3545
+ this_3.enqueueDeferredGeometry(commitEntity, epoch);
3004
3546
  return [3 /*break*/, 8];
3005
3547
  case 6: return [4 /*yield*/, commitEntity()];
3006
3548
  case 7:
3007
- _b.sent();
3008
- _b.label = 8;
3549
+ _e.sent();
3550
+ _e.label = 8;
3009
3551
  case 8:
3010
- if (epoch !== this_2._convertEpoch) {
3552
+ if (epoch !== this_3._convertEpoch) {
3011
3553
  return [2 /*return*/, "continue"];
3012
3554
  }
3013
3555
  if (entity instanceof AcDbViewport) {
@@ -3017,9 +3559,9 @@ var AcTrView2d = /** @class */ (function (_super) {
3017
3559
  // a defensive guard in case a future refactor reorders the
3018
3560
  // early-skip — it costs ~nothing and prevents a regression.
3019
3561
  if (!AcTrViewportView.isDefaultPaperSpaceViewport(entity)) {
3020
- layoutView = this_2._layoutViewManager.getAt(entity.ownerId);
3562
+ layoutView = this_3._layoutViewManager.getAt(entity.ownerId);
3021
3563
  if (layoutView) {
3022
- viewportView = new AcTrViewportView(layoutView, entity.toGiViewport(), this_2._renderer);
3564
+ viewportView = new AcTrViewportView(layoutView, entity.toGiViewport(), this_3._renderer);
3023
3565
  layoutView.addViewport(viewportView);
3024
3566
  }
3025
3567
  }
@@ -3027,46 +3569,49 @@ var AcTrView2d = /** @class */ (function (_super) {
3027
3569
  else if (entity instanceof AcDbRasterImage) {
3028
3570
  fileName = entity.imageFileName;
3029
3571
  if (fileName && !entity.image) {
3030
- this_2._missedImages.set(entity.objectId, fileName);
3572
+ this_3._missedImages.set(entity.objectId, fileName);
3573
+ }
3574
+ else if (entity.image) {
3575
+ this_3._missedImages.delete(entity.objectId);
3031
3576
  }
3032
3577
  }
3033
3578
  return [3 /*break*/, 11];
3034
3579
  case 9:
3035
- error_2 = _b.sent();
3580
+ error_2 = _e.sent();
3036
3581
  log.error("[AcTrView2d] Failed to convert entity ".concat(entity.objectId, " (").concat(entity.type, "):"), error_2);
3037
3582
  return [3 /*break*/, 11];
3038
3583
  case 10:
3039
3584
  // Counter was reset in clear() when the epoch advanced; do not
3040
3585
  // decrease again or isProcessingEntities can go negative/warn.
3041
- if (epoch === this_2._convertEpoch) {
3042
- this_2.decreaseNumOfEntitiesToProcess();
3586
+ if (epoch === this_3._convertEpoch) {
3587
+ this_3.decreaseNumOfEntitiesToProcess();
3043
3588
  }
3044
3589
  return [7 /*endfinally*/];
3045
3590
  case 11:
3046
- if (epoch !== this_2._convertEpoch) {
3591
+ if (epoch !== this_3._convertEpoch) {
3047
3592
  return [2 /*return*/, "continue"];
3048
3593
  }
3049
3594
  if (!yieldGate) return [3 /*break*/, 13];
3050
3595
  return [4 /*yield*/, yieldGate.maybeYield(yieldToEventLoop)];
3051
3596
  case 12:
3052
- didYield = _b.sent();
3597
+ didYield = _e.sent();
3053
3598
  if (didYield) {
3054
- this_2._progressiveYieldCount++;
3599
+ this_3._progressiveYieldCount++;
3055
3600
  }
3056
- _b.label = 13;
3601
+ _e.label = 13;
3057
3602
  case 13: return [2 /*return*/];
3058
3603
  }
3059
3604
  });
3060
3605
  };
3061
- this_2 = this;
3606
+ this_3 = this;
3062
3607
  i = 0;
3063
- _a.label = 1;
3608
+ _d.label = 1;
3064
3609
  case 1:
3065
3610
  if (!(i < entities.length)) return [3 /*break*/, 4];
3066
- return [5 /*yield**/, _loop_3(i)];
3611
+ return [5 /*yield**/, _loop_4(i)];
3067
3612
  case 2:
3068
- _a.sent();
3069
- _a.label = 3;
3613
+ _d.sent();
3614
+ _d.label = 3;
3070
3615
  case 3:
3071
3616
  ++i;
3072
3617
  return [3 /*break*/, 1];
@@ -3096,20 +3641,28 @@ var AcTrView2d = /** @class */ (function (_super) {
3096
3641
  userData.spatialIndexChildBoxes = childBoxes;
3097
3642
  };
3098
3643
  AcTrView2d.prototype.handleGroup = function (group_1, progressive_1) {
3099
- return __awaiter(this, arguments, void 0, function (group, progressive, epoch) {
3100
- var children, objectsGroupByLayer, children_1, children_1_1, child, renderContext, groupObjectId, groupLayerName, groupChildBoxes, aggregateSpatialBbox;
3101
- var e_12, _a;
3644
+ return __awaiter(this, arguments, void 0, function (group, progressive, epoch, convertGen) {
3645
+ var objectId, children, objectsGroupByLayer, children_1, children_1_1, child, renderContext, groupObjectId, groupLayerName, groupChildBoxes, aggregateSpatialBbox;
3646
+ var e_15, _a;
3102
3647
  var _this = this;
3648
+ var _b, _c;
3103
3649
  if (epoch === void 0) { epoch = this._convertEpoch; }
3104
- return __generator(this, function (_b) {
3105
- switch (_b.label) {
3650
+ if (convertGen === void 0) { convertGen = 0; }
3651
+ return __generator(this, function (_d) {
3652
+ switch (_d.label) {
3106
3653
  case 0: return [4 /*yield*/, this.finishEntityGeometry(group, progressive)];
3107
3654
  case 1:
3108
- _b.sent();
3655
+ _d.sent();
3109
3656
  if (epoch !== this._convertEpoch) {
3110
3657
  group.dispose();
3111
3658
  return [2 /*return*/];
3112
3659
  }
3660
+ objectId = String((_b = group.objectId) !== null && _b !== void 0 ? _b : '');
3661
+ if (objectId &&
3662
+ ((_c = this._entityConvertGeneration.get(objectId)) !== null && _c !== void 0 ? _c : 0) !== convertGen) {
3663
+ group.dispose();
3664
+ return [2 /*return*/];
3665
+ }
3113
3666
  this.syncGroupSpatialBoundsForIndexing(group);
3114
3667
  children = group.children;
3115
3668
  objectsGroupByLayer = new Map();
@@ -3140,12 +3693,12 @@ var AcTrView2d = /** @class */ (function (_super) {
3140
3693
  child.parent = null;
3141
3694
  }
3142
3695
  }
3143
- catch (e_12_1) { e_12 = { error: e_12_1 }; }
3696
+ catch (e_15_1) { e_15 = { error: e_15_1 }; }
3144
3697
  finally {
3145
3698
  try {
3146
3699
  if (children_1_1 && !children_1_1.done && (_a = children_1.return)) _a.call(children_1);
3147
3700
  }
3148
- finally { if (e_12) throw e_12.error; }
3701
+ finally { if (e_15) throw e_15.error; }
3149
3702
  }
3150
3703
  renderContext = group.renderContext;
3151
3704
  groupObjectId = group.objectId;
@@ -3191,7 +3744,11 @@ var AcTrView2d = /** @class */ (function (_super) {
3191
3744
  // buckets, so selection/highlight still maps back to the same database object.
3192
3745
  // Within each layer bucket, the object id remains unique in scene indexing.
3193
3746
  var entity = new AcTrEntity(renderContext);
3194
- entity.applyMatrix4(group.matrix);
3747
+ // Copy the INSERT matrix exactly — applyMatrix4 decomposes and drops
3748
+ // reflections from mirrored block scales.
3749
+ entity.matrix.copy(group.matrix);
3750
+ entity.matrixAutoUpdate = false;
3751
+ entity.matrixWorldNeedsUpdate = true;
3195
3752
  entity.objectId = groupObjectId;
3196
3753
  entity.ownerId = group.ownerId;
3197
3754
  // If block-definition entities are on layer "0", this bucket now uses the layer
@@ -3207,6 +3764,7 @@ var AcTrView2d = /** @class */ (function (_super) {
3207
3764
  for (var i = 0; i < objects.length; i++) {
3208
3765
  entity.add(objects[i]);
3209
3766
  }
3767
+ entity.updateMatrixWorld(true);
3210
3768
  _this._layerAppearance.refreshTextMaterialsInObjectTree(entity);
3211
3769
  _this._scene.addEntity(entity, true);
3212
3770
  _this.applySessionHiddenObjectState(groupObjectId);
@@ -3236,20 +3794,60 @@ var AcTrView2d = /** @class */ (function (_super) {
3236
3794
  // the user pans/zooms (animate bails when !_isDirty && !_htmlDirty &&
3237
3795
  // !stillLoading).
3238
3796
  this._isDirty = true;
3797
+ // Missed images (and fonts already tracked) are collected during convert;
3798
+ // notify the Resources / External References palette once the queue is idle.
3799
+ eventBus.emit('missed-data-changed', {});
3800
+ }
3801
+ this.stampEntityProcessingIdle();
3802
+ };
3803
+ /**
3804
+ * Zooms to batch geometry once, after entity convert has drained.
3805
+ */
3806
+ AcTrView2d.prototype.frameOpenLineworkIfReady = function () {
3807
+ if (!this._openLineworkFramePending || this.isConvertingEntities) {
3808
+ return;
3809
+ }
3810
+ var box = this.resolveLayoutFitBox();
3811
+ if (!box || box.isEmpty()) {
3812
+ this._openLineworkFramePending = false;
3813
+ return;
3814
+ }
3815
+ this._openLineworkFramePending = false;
3816
+ // Programmatic so a progressive open does not treat this as a user zoom
3817
+ // and skip the glyph-aware final fit.
3818
+ this._progressiveOpenFit.frameProgrammatically(box);
3819
+ };
3820
+ /**
3821
+ * Records the moment convert and deferred glyph jobs are both idle.
3822
+ * Intermediate completions (linework done, text still queued) do not stamp.
3823
+ */
3824
+ AcTrView2d.prototype.stampEntityProcessingIdle = function () {
3825
+ if (this._numOfEntitiesToProcess === 0 && this._pendingGeometryJobs === 0) {
3826
+ this._entityProcessingIdleAt = performance.now();
3239
3827
  }
3240
3828
  };
3241
3829
  /**
3242
- * Wall-time between cooperative yields during progressive open (ms).
3243
- * Kept relatively large so convert throughput stays close to the
3244
- * non-progressive path; smaller budgets made open 2–3× slower.
3830
+ * Wall-time between cooperative yields during scene convert (ms).
3831
+ * Used for both progressive and non-progressive opens so large drawings
3832
+ * (e.g. multi-sheet architectural DWGs) cannot freeze the main thread long
3833
+ * enough for Chromium to show "Page Unresponsive" while the overlay still
3834
+ * reads "Rendering drawing ...". Kept relatively large so convert
3835
+ * throughput stays high; smaller budgets made open 2–3× slower.
3245
3836
  */
3246
- AcTrView2d.PROGRESSIVE_OPEN_YIELD_BUDGET_MS = 300;
3837
+ AcTrView2d.OPEN_CONVERT_YIELD_BUDGET_MS = 300;
3247
3838
  /**
3248
3839
  * Minimum interval between progressive mid-open paints (ms).
3249
3840
  * Full-scene WebGL paints dominate open wall time on large drawings;
3250
- * paint much less often than we yield.
3841
+ * paint much less often than we yield. Independent of convert yields —
3842
+ * non-progressive opens still yield without mid-open WebGL paints.
3251
3843
  */
3252
3844
  AcTrView2d.PROGRESSIVE_OPEN_PAINT_INTERVAL_MS = 1000;
3845
+ /**
3846
+ * Max concurrent deferred glyph/INSERT geometry finalizers. Large drawings
3847
+ * enqueue thousands of jobs; keep this modest to limit peak JS heap during
3848
+ * open while retaining reasonable text throughput after convert finishes.
3849
+ */
3850
+ AcTrView2d.DEFERRED_GEOMETRY_CONCURRENCY = 8;
3253
3851
  return AcTrView2d;
3254
3852
  }(AcEdBaseView));
3255
3853
  export { AcTrView2d };