docxmlater 10.1.3 → 10.1.5

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 (371) hide show
  1. package/README.md +759 -754
  2. package/dist/constants/legacyCompatFlags.js +1 -1
  3. package/dist/constants/legacyCompatFlags.js.map +1 -1
  4. package/dist/constants/limits.js.map +1 -1
  5. package/dist/core/Document.d.ts +50 -50
  6. package/dist/core/Document.d.ts.map +1 -1
  7. package/dist/core/Document.js +483 -471
  8. package/dist/core/Document.js.map +1 -1
  9. package/dist/core/DocumentContent.d.ts +9 -9
  10. package/dist/core/DocumentContent.d.ts.map +1 -1
  11. package/dist/core/DocumentContent.js +1 -1
  12. package/dist/core/DocumentContent.js.map +1 -1
  13. package/dist/core/DocumentGenerator.d.ts +11 -11
  14. package/dist/core/DocumentGenerator.d.ts.map +1 -1
  15. package/dist/core/DocumentGenerator.js +251 -251
  16. package/dist/core/DocumentGenerator.js.map +1 -1
  17. package/dist/core/DocumentIdManager.js.map +1 -1
  18. package/dist/core/DocumentParser.d.ts +15 -15
  19. package/dist/core/DocumentParser.d.ts.map +1 -1
  20. package/dist/core/DocumentParser.js +2123 -2155
  21. package/dist/core/DocumentParser.js.map +1 -1
  22. package/dist/core/DocumentValidator.d.ts.map +1 -1
  23. package/dist/core/DocumentValidator.js +2 -5
  24. package/dist/core/DocumentValidator.js.map +1 -1
  25. package/dist/core/Relationship.js.map +1 -1
  26. package/dist/core/RelationshipManager.d.ts.map +1 -1
  27. package/dist/core/RelationshipManager.js +3 -3
  28. package/dist/core/RelationshipManager.js.map +1 -1
  29. package/dist/elements/AlternateContent.js.map +1 -1
  30. package/dist/elements/Bookmark.d.ts.map +1 -1
  31. package/dist/elements/Bookmark.js +3 -1
  32. package/dist/elements/Bookmark.js.map +1 -1
  33. package/dist/elements/BookmarkManager.d.ts.map +1 -1
  34. package/dist/elements/BookmarkManager.js.map +1 -1
  35. package/dist/elements/Comment.d.ts.map +1 -1
  36. package/dist/elements/Comment.js +9 -6
  37. package/dist/elements/Comment.js.map +1 -1
  38. package/dist/elements/CommentManager.d.ts.map +1 -1
  39. package/dist/elements/CommentManager.js +18 -17
  40. package/dist/elements/CommentManager.js.map +1 -1
  41. package/dist/elements/CommonTypes.d.ts +21 -21
  42. package/dist/elements/CommonTypes.d.ts.map +1 -1
  43. package/dist/elements/CommonTypes.js +56 -56
  44. package/dist/elements/CommonTypes.js.map +1 -1
  45. package/dist/elements/CustomXml.js.map +1 -1
  46. package/dist/elements/Endnote.d.ts.map +1 -1
  47. package/dist/elements/Endnote.js +6 -6
  48. package/dist/elements/Endnote.js.map +1 -1
  49. package/dist/elements/EndnoteManager.d.ts.map +1 -1
  50. package/dist/elements/EndnoteManager.js +6 -7
  51. package/dist/elements/EndnoteManager.js.map +1 -1
  52. package/dist/elements/Field.d.ts.map +1 -1
  53. package/dist/elements/Field.js +82 -25
  54. package/dist/elements/Field.js.map +1 -1
  55. package/dist/elements/FieldHelpers.d.ts.map +1 -1
  56. package/dist/elements/FieldHelpers.js.map +1 -1
  57. package/dist/elements/FontManager.d.ts.map +1 -1
  58. package/dist/elements/FontManager.js +1 -1
  59. package/dist/elements/FontManager.js.map +1 -1
  60. package/dist/elements/Footer.js +2 -2
  61. package/dist/elements/Footer.js.map +1 -1
  62. package/dist/elements/Footnote.d.ts.map +1 -1
  63. package/dist/elements/Footnote.js +6 -6
  64. package/dist/elements/Footnote.js.map +1 -1
  65. package/dist/elements/FootnoteManager.d.ts.map +1 -1
  66. package/dist/elements/FootnoteManager.js +6 -7
  67. package/dist/elements/FootnoteManager.js.map +1 -1
  68. package/dist/elements/Header.js +2 -2
  69. package/dist/elements/Header.js.map +1 -1
  70. package/dist/elements/HeaderFooterManager.js.map +1 -1
  71. package/dist/elements/Hyperlink.d.ts +5 -3
  72. package/dist/elements/Hyperlink.d.ts.map +1 -1
  73. package/dist/elements/Hyperlink.js +134 -76
  74. package/dist/elements/Hyperlink.js.map +1 -1
  75. package/dist/elements/Image.d.ts.map +1 -1
  76. package/dist/elements/Image.js +238 -106
  77. package/dist/elements/Image.js.map +1 -1
  78. package/dist/elements/ImageManager.d.ts.map +1 -1
  79. package/dist/elements/ImageManager.js +1 -1
  80. package/dist/elements/ImageManager.js.map +1 -1
  81. package/dist/elements/ImageRun.js +1 -1
  82. package/dist/elements/ImageRun.js.map +1 -1
  83. package/dist/elements/MathElement.js.map +1 -1
  84. package/dist/elements/Paragraph.d.ts +24 -24
  85. package/dist/elements/Paragraph.d.ts.map +1 -1
  86. package/dist/elements/Paragraph.js +181 -188
  87. package/dist/elements/Paragraph.js.map +1 -1
  88. package/dist/elements/PreservedElement.js.map +1 -1
  89. package/dist/elements/PropertyChangeTypes.d.ts.map +1 -1
  90. package/dist/elements/PropertyChangeTypes.js +6 -6
  91. package/dist/elements/PropertyChangeTypes.js.map +1 -1
  92. package/dist/elements/RangeMarker.d.ts.map +1 -1
  93. package/dist/elements/RangeMarker.js.map +1 -1
  94. package/dist/elements/Revision.d.ts.map +1 -1
  95. package/dist/elements/Revision.js +4 -5
  96. package/dist/elements/Revision.js.map +1 -1
  97. package/dist/elements/RevisionContent.js.map +1 -1
  98. package/dist/elements/RevisionManager.d.ts.map +1 -1
  99. package/dist/elements/RevisionManager.js +40 -48
  100. package/dist/elements/RevisionManager.js.map +1 -1
  101. package/dist/elements/Run.d.ts +16 -16
  102. package/dist/elements/Run.d.ts.map +1 -1
  103. package/dist/elements/Run.js +256 -238
  104. package/dist/elements/Run.js.map +1 -1
  105. package/dist/elements/Section.d.ts.map +1 -1
  106. package/dist/elements/Section.js +36 -11
  107. package/dist/elements/Section.js.map +1 -1
  108. package/dist/elements/Shape.d.ts.map +1 -1
  109. package/dist/elements/Shape.js.map +1 -1
  110. package/dist/elements/StructuredDocumentTag.d.ts +6 -6
  111. package/dist/elements/StructuredDocumentTag.d.ts.map +1 -1
  112. package/dist/elements/StructuredDocumentTag.js +99 -104
  113. package/dist/elements/StructuredDocumentTag.js.map +1 -1
  114. package/dist/elements/Table.d.ts +11 -11
  115. package/dist/elements/Table.d.ts.map +1 -1
  116. package/dist/elements/Table.js +102 -107
  117. package/dist/elements/Table.js.map +1 -1
  118. package/dist/elements/TableCell.d.ts +10 -10
  119. package/dist/elements/TableCell.d.ts.map +1 -1
  120. package/dist/elements/TableCell.js +105 -106
  121. package/dist/elements/TableCell.js.map +1 -1
  122. package/dist/elements/TableGridChange.d.ts.map +1 -1
  123. package/dist/elements/TableGridChange.js.map +1 -1
  124. package/dist/elements/TableOfContents.d.ts.map +1 -1
  125. package/dist/elements/TableOfContents.js +4 -4
  126. package/dist/elements/TableOfContents.js.map +1 -1
  127. package/dist/elements/TableOfContentsElement.js.map +1 -1
  128. package/dist/elements/TableRow.d.ts.map +1 -1
  129. package/dist/elements/TableRow.js +13 -6
  130. package/dist/elements/TableRow.js.map +1 -1
  131. package/dist/elements/TextBox.d.ts.map +1 -1
  132. package/dist/elements/TextBox.js +3 -5
  133. package/dist/elements/TextBox.js.map +1 -1
  134. package/dist/formatting/AbstractNumbering.d.ts +4 -4
  135. package/dist/formatting/AbstractNumbering.d.ts.map +1 -1
  136. package/dist/formatting/AbstractNumbering.js +54 -49
  137. package/dist/formatting/AbstractNumbering.js.map +1 -1
  138. package/dist/formatting/NumberingInstance.d.ts.map +1 -1
  139. package/dist/formatting/NumberingInstance.js +1 -3
  140. package/dist/formatting/NumberingInstance.js.map +1 -1
  141. package/dist/formatting/NumberingLevel.d.ts +5 -5
  142. package/dist/formatting/NumberingLevel.d.ts.map +1 -1
  143. package/dist/formatting/NumberingLevel.js +119 -125
  144. package/dist/formatting/NumberingLevel.js.map +1 -1
  145. package/dist/formatting/NumberingManager.d.ts.map +1 -1
  146. package/dist/formatting/NumberingManager.js +9 -9
  147. package/dist/formatting/NumberingManager.js.map +1 -1
  148. package/dist/formatting/Style.d.ts +11 -11
  149. package/dist/formatting/Style.d.ts.map +1 -1
  150. package/dist/formatting/Style.js +219 -247
  151. package/dist/formatting/Style.js.map +1 -1
  152. package/dist/formatting/StylesManager.d.ts +2 -2
  153. package/dist/formatting/StylesManager.d.ts.map +1 -1
  154. package/dist/formatting/StylesManager.js +96 -102
  155. package/dist/formatting/StylesManager.js.map +1 -1
  156. package/dist/helpers/CleanupHelper.d.ts +1 -1
  157. package/dist/helpers/CleanupHelper.d.ts.map +1 -1
  158. package/dist/helpers/CleanupHelper.js +6 -6
  159. package/dist/helpers/CleanupHelper.js.map +1 -1
  160. package/dist/images/ImageOptimizer.js +7 -7
  161. package/dist/images/ImageOptimizer.js.map +1 -1
  162. package/dist/index.d.ts +9 -9
  163. package/dist/index.d.ts.map +1 -1
  164. package/dist/index.js.map +1 -1
  165. package/dist/managers/DrawingManager.js.map +1 -1
  166. package/dist/tracking/DocumentTrackingContext.d.ts.map +1 -1
  167. package/dist/tracking/DocumentTrackingContext.js +23 -7
  168. package/dist/tracking/DocumentTrackingContext.js.map +1 -1
  169. package/dist/tracking/TrackingContext.d.ts.map +1 -1
  170. package/dist/tracking/TrackingContext.js.map +1 -1
  171. package/dist/types/compatibility-types.js.map +1 -1
  172. package/dist/types/formatting.js.map +1 -1
  173. package/dist/types/list-types.d.ts +6 -6
  174. package/dist/types/list-types.js.map +1 -1
  175. package/dist/types/settings-types.js.map +1 -1
  176. package/dist/types/styleConfig.d.ts +2 -2
  177. package/dist/types/styleConfig.js.map +1 -1
  178. package/dist/utils/ChangelogGenerator.d.ts.map +1 -1
  179. package/dist/utils/ChangelogGenerator.js +97 -101
  180. package/dist/utils/ChangelogGenerator.js.map +1 -1
  181. package/dist/utils/CompatibilityUpgrader.d.ts.map +1 -1
  182. package/dist/utils/CompatibilityUpgrader.js +1 -1
  183. package/dist/utils/CompatibilityUpgrader.js.map +1 -1
  184. package/dist/utils/InMemoryRevisionAcceptor.d.ts.map +1 -1
  185. package/dist/utils/InMemoryRevisionAcceptor.js +1 -6
  186. package/dist/utils/InMemoryRevisionAcceptor.js.map +1 -1
  187. package/dist/utils/MoveOperationHelper.d.ts.map +1 -1
  188. package/dist/utils/MoveOperationHelper.js +1 -1
  189. package/dist/utils/MoveOperationHelper.js.map +1 -1
  190. package/dist/utils/RevisionAwareProcessor.d.ts.map +1 -1
  191. package/dist/utils/RevisionAwareProcessor.js +2 -4
  192. package/dist/utils/RevisionAwareProcessor.js.map +1 -1
  193. package/dist/utils/RevisionWalker.d.ts.map +1 -1
  194. package/dist/utils/RevisionWalker.js +4 -12
  195. package/dist/utils/RevisionWalker.js.map +1 -1
  196. package/dist/utils/SelectiveRevisionAcceptor.d.ts.map +1 -1
  197. package/dist/utils/SelectiveRevisionAcceptor.js +2 -6
  198. package/dist/utils/SelectiveRevisionAcceptor.js.map +1 -1
  199. package/dist/utils/ShadingResolver.d.ts.map +1 -1
  200. package/dist/utils/ShadingResolver.js +1 -1
  201. package/dist/utils/ShadingResolver.js.map +1 -1
  202. package/dist/utils/acceptRevisions.d.ts.map +1 -1
  203. package/dist/utils/acceptRevisions.js +23 -12
  204. package/dist/utils/acceptRevisions.js.map +1 -1
  205. package/dist/utils/cnfStyleDecoder.d.ts +1 -1
  206. package/dist/utils/cnfStyleDecoder.d.ts.map +1 -1
  207. package/dist/utils/cnfStyleDecoder.js +40 -40
  208. package/dist/utils/cnfStyleDecoder.js.map +1 -1
  209. package/dist/utils/corruptionDetection.d.ts.map +1 -1
  210. package/dist/utils/corruptionDetection.js.map +1 -1
  211. package/dist/utils/dateFormatting.js.map +1 -1
  212. package/dist/utils/deepClone.js +1 -1
  213. package/dist/utils/deepClone.js.map +1 -1
  214. package/dist/utils/diagnostics.d.ts.map +1 -1
  215. package/dist/utils/diagnostics.js +1 -1
  216. package/dist/utils/diagnostics.js.map +1 -1
  217. package/dist/utils/errorHandling.js.map +1 -1
  218. package/dist/utils/formatting.d.ts.map +1 -1
  219. package/dist/utils/formatting.js +10 -2
  220. package/dist/utils/formatting.js.map +1 -1
  221. package/dist/utils/list-detection.d.ts +2 -2
  222. package/dist/utils/list-detection.d.ts.map +1 -1
  223. package/dist/utils/list-detection.js +21 -23
  224. package/dist/utils/list-detection.js.map +1 -1
  225. package/dist/utils/logger.d.ts.map +1 -1
  226. package/dist/utils/logger.js +12 -7
  227. package/dist/utils/logger.js.map +1 -1
  228. package/dist/utils/parsingHelpers.js.map +1 -1
  229. package/dist/utils/stripTrackedChanges.d.ts.map +1 -1
  230. package/dist/utils/stripTrackedChanges.js +3 -3
  231. package/dist/utils/stripTrackedChanges.js.map +1 -1
  232. package/dist/utils/textDiff.d.ts +1 -1
  233. package/dist/utils/textDiff.js +8 -8
  234. package/dist/utils/textDiff.js.map +1 -1
  235. package/dist/utils/units.js.map +1 -1
  236. package/dist/utils/validation.d.ts.map +1 -1
  237. package/dist/utils/validation.js +24 -7
  238. package/dist/utils/validation.js.map +1 -1
  239. package/dist/utils/xmlSanitization.d.ts.map +1 -1
  240. package/dist/utils/xmlSanitization.js +3 -3
  241. package/dist/utils/xmlSanitization.js.map +1 -1
  242. package/dist/validation/RevisionAutoFixer.d.ts.map +1 -1
  243. package/dist/validation/RevisionAutoFixer.js +5 -5
  244. package/dist/validation/RevisionAutoFixer.js.map +1 -1
  245. package/dist/validation/RevisionValidator.d.ts.map +1 -1
  246. package/dist/validation/RevisionValidator.js +7 -9
  247. package/dist/validation/RevisionValidator.js.map +1 -1
  248. package/dist/validation/ValidationRules.js +3 -3
  249. package/dist/validation/ValidationRules.js.map +1 -1
  250. package/dist/validation/index.js.map +1 -1
  251. package/dist/xml/XMLBuilder.d.ts +1 -1
  252. package/dist/xml/XMLBuilder.d.ts.map +1 -1
  253. package/dist/xml/XMLBuilder.js +98 -100
  254. package/dist/xml/XMLBuilder.js.map +1 -1
  255. package/dist/xml/XMLParser.d.ts.map +1 -1
  256. package/dist/xml/XMLParser.js +61 -66
  257. package/dist/xml/XMLParser.js.map +1 -1
  258. package/dist/zip/ZipHandler.d.ts.map +1 -1
  259. package/dist/zip/ZipHandler.js.map +1 -1
  260. package/dist/zip/ZipReader.d.ts.map +1 -1
  261. package/dist/zip/ZipReader.js +1 -3
  262. package/dist/zip/ZipReader.js.map +1 -1
  263. package/dist/zip/ZipWriter.d.ts +1 -1
  264. package/dist/zip/ZipWriter.d.ts.map +1 -1
  265. package/dist/zip/ZipWriter.js +28 -36
  266. package/dist/zip/ZipWriter.js.map +1 -1
  267. package/dist/zip/types.js +1 -1
  268. package/dist/zip/types.js.map +1 -1
  269. package/package.json +92 -92
  270. package/src/__tests__/helper-methods.test.ts +512 -512
  271. package/src/constants/legacyCompatFlags.ts +138 -138
  272. package/src/constants/limits.ts +50 -50
  273. package/src/core/Document.ts +985 -1145
  274. package/src/core/DocumentContent.ts +461 -467
  275. package/src/core/DocumentGenerator.ts +1133 -1104
  276. package/src/core/DocumentIdManager.ts +158 -158
  277. package/src/core/DocumentParser.ts +2347 -2716
  278. package/src/core/DocumentValidator.ts +363 -372
  279. package/src/core/Relationship.ts +367 -367
  280. package/src/core/RelationshipManager.ts +429 -428
  281. package/src/elements/AlternateContent.ts +42 -42
  282. package/src/elements/Bookmark.ts +212 -210
  283. package/src/elements/BookmarkManager.ts +247 -250
  284. package/src/elements/Comment.ts +356 -359
  285. package/src/elements/CommentManager.ts +499 -502
  286. package/src/elements/CommonTypes.ts +524 -549
  287. package/src/elements/CustomXml.ts +36 -36
  288. package/src/elements/Endnote.ts +221 -217
  289. package/src/elements/EndnoteManager.ts +246 -249
  290. package/src/elements/Field.ts +1292 -1233
  291. package/src/elements/FieldHelpers.ts +329 -333
  292. package/src/elements/FontManager.ts +336 -339
  293. package/src/elements/Footer.ts +269 -269
  294. package/src/elements/Footnote.ts +221 -217
  295. package/src/elements/FootnoteManager.ts +246 -249
  296. package/src/elements/Header.ts +269 -269
  297. package/src/elements/HeaderFooterManager.ts +219 -219
  298. package/src/elements/Hyperlink.ts +1288 -1193
  299. package/src/elements/Image.ts +1982 -1756
  300. package/src/elements/ImageManager.ts +437 -432
  301. package/src/elements/ImageRun.ts +59 -59
  302. package/src/elements/MathElement.ts +65 -65
  303. package/src/elements/Paragraph.ts +4347 -4287
  304. package/src/elements/PreservedElement.ts +53 -53
  305. package/src/elements/PropertyChangeTypes.ts +458 -442
  306. package/src/elements/RangeMarker.ts +382 -400
  307. package/src/elements/Revision.ts +1198 -1217
  308. package/src/elements/RevisionContent.ts +73 -73
  309. package/src/elements/RevisionManager.ts +1070 -1070
  310. package/src/elements/Run.ts +3103 -3073
  311. package/src/elements/Section.ts +1521 -1421
  312. package/src/elements/Shape.ts +884 -873
  313. package/src/elements/StructuredDocumentTag.ts +1176 -1207
  314. package/src/elements/Table.ts +2468 -2524
  315. package/src/elements/TableCell.ts +1617 -1621
  316. package/src/elements/TableGridChange.ts +149 -151
  317. package/src/elements/TableOfContents.ts +701 -691
  318. package/src/elements/TableOfContentsElement.ts +89 -89
  319. package/src/elements/TableRow.ts +960 -929
  320. package/src/elements/TextBox.ts +766 -768
  321. package/src/formatting/AbstractNumbering.ts +580 -579
  322. package/src/formatting/NumberingInstance.ts +295 -299
  323. package/src/formatting/NumberingLevel.ts +981 -1040
  324. package/src/formatting/NumberingManager.ts +833 -827
  325. package/src/formatting/Style.ts +1785 -1879
  326. package/src/formatting/StylesManager.ts +1090 -1130
  327. package/src/helpers/CleanupHelper.ts +524 -524
  328. package/src/images/ImageOptimizer.ts +274 -274
  329. package/src/index.ts +559 -554
  330. package/src/managers/DrawingManager.ts +319 -319
  331. package/src/tracking/DocumentTrackingContext.ts +687 -674
  332. package/src/tracking/TrackingContext.ts +175 -173
  333. package/src/types/compatibility-types.ts +49 -49
  334. package/src/types/formatting.ts +210 -210
  335. package/src/types/list-types.ts +14 -14
  336. package/src/types/settings-types.ts +59 -59
  337. package/src/types/styleConfig.ts +189 -189
  338. package/src/utils/ChangelogGenerator.ts +1583 -1581
  339. package/src/utils/CompatibilityUpgrader.ts +235 -237
  340. package/src/utils/InMemoryRevisionAcceptor.ts +691 -696
  341. package/src/utils/MoveOperationHelper.ts +233 -238
  342. package/src/utils/RevisionAwareProcessor.ts +518 -526
  343. package/src/utils/RevisionWalker.ts +427 -457
  344. package/src/utils/SelectiveRevisionAcceptor.ts +662 -683
  345. package/src/utils/ShadingResolver.ts +105 -107
  346. package/src/utils/acceptRevisions.ts +723 -714
  347. package/src/utils/cnfStyleDecoder.ts +212 -217
  348. package/src/utils/corruptionDetection.ts +346 -345
  349. package/src/utils/dateFormatting.ts +20 -20
  350. package/src/utils/deepClone.ts +77 -78
  351. package/src/utils/diagnostics.ts +125 -129
  352. package/src/utils/errorHandling.ts +80 -80
  353. package/src/utils/formatting.ts +220 -213
  354. package/src/utils/list-detection.ts +32 -42
  355. package/src/utils/logger.ts +412 -404
  356. package/src/utils/parsingHelpers.ts +190 -190
  357. package/src/utils/stripTrackedChanges.ts +356 -353
  358. package/src/utils/textDiff.ts +100 -100
  359. package/src/utils/units.ts +421 -421
  360. package/src/utils/validation.ts +553 -542
  361. package/src/utils/xmlSanitization.ts +179 -182
  362. package/src/validation/RevisionAutoFixer.ts +541 -542
  363. package/src/validation/RevisionValidator.ts +470 -460
  364. package/src/validation/ValidationRules.ts +338 -338
  365. package/src/validation/index.ts +30 -30
  366. package/src/xml/XMLBuilder.ts +857 -871
  367. package/src/xml/XMLParser.ts +877 -919
  368. package/src/zip/ZipHandler.ts +629 -637
  369. package/src/zip/ZipReader.ts +295 -299
  370. package/src/zip/ZipWriter.ts +374 -390
  371. package/src/zip/types.ts +116 -116
@@ -9,24 +9,24 @@ function getLogger() {
9
9
  exports.DEFAULT_MAX_NESTING_DEPTH = 256;
10
10
  class XMLParser {
11
11
  static extractBody(docXml) {
12
- const startTag = "<w:body";
13
- const endTag = "</w:body>";
12
+ const startTag = '<w:body';
13
+ const endTag = '</w:body>';
14
14
  const startIdx = docXml.indexOf(startTag);
15
15
  if (startIdx === -1)
16
- return "";
17
- const openEnd = docXml.indexOf(">", startIdx);
16
+ return '';
17
+ const openEnd = docXml.indexOf('>', startIdx);
18
18
  if (openEnd === -1)
19
- return "";
19
+ return '';
20
20
  const endIdx = docXml.indexOf(endTag, openEnd);
21
21
  if (endIdx === -1)
22
- return "";
22
+ return '';
23
23
  return docXml.substring(openEnd + 1, endIdx);
24
24
  }
25
25
  static extractElements(xml, tagName) {
26
26
  const elements = [];
27
27
  const openTag = `<${tagName}`;
28
28
  const closeTag = `</${tagName}>`;
29
- const selfClosingEnd = "/>";
29
+ const selfClosingEnd = '/>';
30
30
  let pos = 0;
31
31
  while (pos < xml.length) {
32
32
  const startIdx = xml.indexOf(openTag, pos);
@@ -34,17 +34,17 @@ class XMLParser {
34
34
  break;
35
35
  const charAfterTag = xml[startIdx + openTag.length];
36
36
  if (charAfterTag &&
37
- charAfterTag !== ">" &&
38
- charAfterTag !== "/" &&
39
- charAfterTag !== " " &&
40
- charAfterTag !== "\t" &&
41
- charAfterTag !== "\n" &&
42
- charAfterTag !== "\r" &&
43
- charAfterTag !== "=") {
37
+ charAfterTag !== '>' &&
38
+ charAfterTag !== '/' &&
39
+ charAfterTag !== ' ' &&
40
+ charAfterTag !== '\t' &&
41
+ charAfterTag !== '\n' &&
42
+ charAfterTag !== '\r' &&
43
+ charAfterTag !== '=') {
44
44
  pos = startIdx + openTag.length;
45
45
  continue;
46
46
  }
47
- const openEnd = xml.indexOf(">", startIdx);
47
+ const openEnd = xml.indexOf('>', startIdx);
48
48
  if (openEnd === -1)
49
49
  break;
50
50
  if (xml.substring(openEnd - 1, openEnd + 1) === selfClosingEnd) {
@@ -64,12 +64,12 @@ class XMLParser {
64
64
  }
65
65
  const charAfter = xml[candidateOpen + openTag.length];
66
66
  if (charAfter &&
67
- charAfter !== ">" &&
68
- charAfter !== "/" &&
69
- charAfter !== " " &&
70
- charAfter !== "\t" &&
71
- charAfter !== "\n" &&
72
- charAfter !== "\r") {
67
+ charAfter !== '>' &&
68
+ charAfter !== '/' &&
69
+ charAfter !== ' ' &&
70
+ charAfter !== '\t' &&
71
+ charAfter !== '\n' &&
72
+ charAfter !== '\r') {
73
73
  openSearchPos = candidateOpen + openTag.length;
74
74
  continue;
75
75
  }
@@ -116,8 +116,7 @@ class XMLParser {
116
116
  return xml.includes(`<${tagName}/>`) || xml.includes(`<${tagName} `);
117
117
  }
118
118
  static hasBooleanProperty(xml, tagName) {
119
- if (xml.includes(`<${tagName} w:val="1"`) ||
120
- xml.includes(`<${tagName} w:val="true"`)) {
119
+ if (xml.includes(`<${tagName} w:val="1"`) || xml.includes(`<${tagName} w:val="true"`)) {
121
120
  return true;
122
121
  }
123
122
  if (xml.includes(`<${tagName}/>`)) {
@@ -127,14 +126,14 @@ class XMLParser {
127
126
  }
128
127
  static extractText(xml) {
129
128
  const texts = [];
130
- const openTag = "<w:t";
131
- const closeTag = "</w:t>";
129
+ const openTag = '<w:t';
130
+ const closeTag = '</w:t>';
132
131
  let pos = 0;
133
132
  while (pos < xml.length) {
134
133
  const startIdx = xml.indexOf(openTag, pos);
135
134
  if (startIdx === -1)
136
135
  break;
137
- const openEnd = xml.indexOf(">", startIdx);
136
+ const openEnd = xml.indexOf('>', startIdx);
138
137
  if (openEnd === -1)
139
138
  break;
140
139
  const closeIdx = xml.indexOf(closeTag, openEnd);
@@ -144,13 +143,11 @@ class XMLParser {
144
143
  texts.push(text);
145
144
  pos = closeIdx + closeTag.length;
146
145
  }
147
- return texts.join("");
146
+ return texts.join('');
148
147
  }
149
148
  static validateSize(xml, maxSize = 10 * 1024 * 1024) {
150
149
  if (xml.length > maxSize) {
151
- throw new Error(`XML content too large for parsing (${(xml.length /
152
- 1024 /
153
- 1024).toFixed(1)}MB). ` +
150
+ throw new Error(`XML content too large for parsing (${(xml.length / 1024 / 1024).toFixed(1)}MB). ` +
154
151
  `Maximum allowed: ${(maxSize / 1024 / 1024).toFixed(0)}MB`);
155
152
  }
156
153
  }
@@ -158,7 +155,7 @@ class XMLParser {
158
155
  const startIdx = xml.indexOf(startTag);
159
156
  if (startIdx === -1)
160
157
  return undefined;
161
- const openEnd = xml.indexOf(">", startIdx);
158
+ const openEnd = xml.indexOf('>', startIdx);
162
159
  if (openEnd === -1)
163
160
  return undefined;
164
161
  const endIdx = xml.indexOf(endTag, openEnd);
@@ -192,8 +189,8 @@ class XMLParser {
192
189
  logger.debug('Parsing XML to object', { xmlSize: xml.length });
193
190
  const opts = {
194
191
  ignoreAttributes: options?.ignoreAttributes ?? false,
195
- attributeNamePrefix: options?.attributeNamePrefix ?? "@_",
196
- textNodeName: options?.textNodeName ?? "#text",
192
+ attributeNamePrefix: options?.attributeNamePrefix ?? '@_',
193
+ textNodeName: options?.textNodeName ?? '#text',
197
194
  ignoreNamespace: options?.ignoreNamespace ?? false,
198
195
  parseAttributeValue: options?.parseAttributeValue ?? true,
199
196
  trimValues: options?.trimValues ?? true,
@@ -201,7 +198,7 @@ class XMLParser {
201
198
  maxNestingDepth: options?.maxNestingDepth ?? exports.DEFAULT_MAX_NESTING_DEPTH,
202
199
  };
203
200
  XMLParser.validateSize(xml);
204
- xml = xml.replace(/<\?xml[^>]*\?>\s*/g, "").trim();
201
+ xml = xml.replace(/<\?xml[^>]*\?>\s*/g, '').trim();
205
202
  if (!xml) {
206
203
  return {};
207
204
  }
@@ -215,34 +212,33 @@ class XMLParser {
215
212
  `This may indicate malformed XML or an attack attempt. ` +
216
213
  `Use the maxNestingDepth option to increase the limit if needed.`);
217
214
  }
218
- const openTagStart = xml.indexOf("<", startPos);
215
+ const openTagStart = xml.indexOf('<', startPos);
219
216
  if (openTagStart === -1) {
220
217
  return { value: {}, endPos: xml.length };
221
218
  }
222
- if (xml.substring(openTagStart, openTagStart + 4) === "<!--") {
223
- const commentEnd = xml.indexOf("-->", openTagStart + 4);
219
+ if (xml.substring(openTagStart, openTagStart + 4) === '<!--') {
220
+ const commentEnd = xml.indexOf('-->', openTagStart + 4);
224
221
  if (commentEnd !== -1) {
225
222
  return XMLParser.parseElementToObject(xml, commentEnd + 3, options, depth);
226
223
  }
227
224
  return { value: {}, endPos: xml.length };
228
225
  }
229
- const nameMatch = /^([a-zA-Z0-9:_-]+)/.exec(xml
230
- .substring(openTagStart + 1));
226
+ const nameMatch = /^([a-zA-Z0-9:_-]+)/.exec(xml.substring(openTagStart + 1));
231
227
  if (!nameMatch) {
232
228
  return { value: {}, endPos: openTagStart + 1 };
233
229
  }
234
- const originalElementName = nameMatch[1] || "";
230
+ const originalElementName = nameMatch[1] || '';
235
231
  let elementName = originalElementName;
236
- const tagHeaderEnd = xml.indexOf(">", openTagStart);
232
+ const tagHeaderEnd = xml.indexOf('>', openTagStart);
237
233
  if (tagHeaderEnd === -1) {
238
234
  return { value: {}, endPos: xml.length };
239
235
  }
240
- if (options.ignoreNamespace && elementName.includes(":")) {
241
- elementName = elementName.split(":")[1] || elementName;
236
+ if (options.ignoreNamespace && elementName.includes(':')) {
237
+ elementName = elementName.split(':')[1] || elementName;
242
238
  }
243
239
  const tagHeader = xml.substring(openTagStart + 1 + originalElementName.length, tagHeaderEnd);
244
240
  const attributes = XMLParser.extractAttributesFromTag(tagHeader, options);
245
- const isSelfClosing = tagHeader.trim().endsWith("/") || xml[tagHeaderEnd - 1] === "/";
241
+ const isSelfClosing = tagHeader.trim().endsWith('/') || xml[tagHeaderEnd - 1] === '/';
246
242
  if (isSelfClosing) {
247
243
  const elementValue = { ...attributes };
248
244
  return {
@@ -261,10 +257,10 @@ class XMLParser {
261
257
  }
262
258
  const content = xml.substring(contentStart, closingTagPos);
263
259
  const children = [];
264
- let textContent = "";
260
+ let textContent = '';
265
261
  let pos = 0;
266
262
  while (pos < content.length) {
267
- const nextTag = content.indexOf("<", pos);
263
+ const nextTag = content.indexOf('<', pos);
268
264
  if (nextTag === -1) {
269
265
  const text = content.substring(pos);
270
266
  if (text.length > 0 && (!options.trimValues || text.trim())) {
@@ -296,25 +292,25 @@ class XMLParser {
296
292
  }
297
293
  if (textContent.length > 0 && (!options.trimValues || textContent.trim())) {
298
294
  const text = options.trimValues ? textContent.trim() : textContent;
299
- if (typeof elementValue === "object" && !Array.isArray(elementValue)) {
295
+ if (typeof elementValue === 'object' && !Array.isArray(elementValue)) {
300
296
  if (Object.keys(elementValue).length === 0) {
301
297
  elementValue = text;
302
298
  }
303
299
  else {
304
- (elementValue)[options.textNodeName] = text;
300
+ elementValue[options.textNodeName] = text;
305
301
  }
306
302
  }
307
303
  }
308
304
  if (children.length > 0) {
309
305
  const coalescedChildren = XMLParser.coalesceChildren(children, options);
310
- if (typeof elementValue === "object" && !Array.isArray(elementValue)) {
306
+ if (typeof elementValue === 'object' && !Array.isArray(elementValue)) {
311
307
  elementValue = { ...elementValue, ...coalescedChildren };
312
308
  }
313
309
  else {
314
310
  elementValue = coalescedChildren;
315
311
  }
316
312
  }
317
- if (typeof elementValue === "object" &&
313
+ if (typeof elementValue === 'object' &&
318
314
  !Array.isArray(elementValue) &&
319
315
  Object.keys(elementValue).length === 0) {
320
316
  elementValue = {};
@@ -340,7 +336,7 @@ class XMLParser {
340
336
  break;
341
337
  }
342
338
  }
343
- if (pos >= tagHeader.length || tagHeader[pos] === "/") {
339
+ if (pos >= tagHeader.length || tagHeader[pos] === '/') {
344
340
  break;
345
341
  }
346
342
  const nameStart = pos;
@@ -366,9 +362,8 @@ class XMLParser {
366
362
  break;
367
363
  }
368
364
  }
369
- let attrValue = "";
370
- if (pos < tagHeader.length &&
371
- (tagHeader[pos] === '"' || tagHeader[pos] === "'")) {
365
+ let attrValue = '';
366
+ if (pos < tagHeader.length && (tagHeader[pos] === '"' || tagHeader[pos] === "'")) {
372
367
  const quote = tagHeader[pos];
373
368
  pos++;
374
369
  const valueStart = pos;
@@ -378,8 +373,8 @@ class XMLParser {
378
373
  attrValue = tagHeader.substring(valueStart, pos);
379
374
  pos++;
380
375
  }
381
- if (options.ignoreNamespace && attrName.includes(":")) {
382
- attrName = attrName.split(":")[1] || attrName;
376
+ if (options.ignoreNamespace && attrName.includes(':')) {
377
+ attrName = attrName.split(':')[1] || attrName;
383
378
  }
384
379
  const prefixedName = options.attributeNamePrefix + attrName;
385
380
  attributes[prefixedName] = options.parseAttributeValue
@@ -406,14 +401,14 @@ class XMLParser {
406
401
  break;
407
402
  }
408
403
  const charAfter = xml[candidateOpen + openTag.length];
409
- if (charAfter === ">" ||
410
- charAfter === " " ||
411
- charAfter === "/" ||
412
- charAfter === "\t" ||
413
- charAfter === "\n" ||
414
- charAfter === "\r") {
415
- const tagEnd = xml.indexOf(">", candidateOpen);
416
- if (tagEnd !== -1 && xml[tagEnd - 1] === "/") {
404
+ if (charAfter === '>' ||
405
+ charAfter === ' ' ||
406
+ charAfter === '/' ||
407
+ charAfter === '\t' ||
408
+ charAfter === '\n' ||
409
+ charAfter === '\r') {
410
+ const tagEnd = xml.indexOf('>', candidateOpen);
411
+ if (tagEnd !== -1 && xml[tagEnd - 1] === '/') {
417
412
  searchPos = tagEnd + 1;
418
413
  continue;
419
414
  }
@@ -465,9 +460,9 @@ class XMLParser {
465
460
  return result;
466
461
  }
467
462
  static parseValue(value) {
468
- if (value === "true")
463
+ if (value === 'true')
469
464
  return true;
470
- if (value === "false")
465
+ if (value === 'false')
471
466
  return false;
472
467
  if (/^[0-9A-Fa-f]{6}$/.test(value)) {
473
468
  return value.toUpperCase();
@@ -1 +1 @@
1
- {"version":3,"file":"XMLParser.js","sourceRoot":"","sources":["../../src/xml/XMLParser.ts"],"names":[],"mappings":"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","sourcesContent":["/**\r\n * XMLParser - Simple position-based XML parser\r\n * Avoids regex backtracking issues that can cause ReDoS attacks\r\n * Completes the DocXML framework (XMLBuilder + XMLParser)\r\n */\r\n\r\nimport { getGlobalLogger, createScopedLogger, ILogger } from \"../utils/logger\";\r\nimport { XMLBuilder } from \"./XMLBuilder\";\r\n\r\n// Create scoped logger for XMLParser operations\r\nfunction getLogger(): ILogger {\r\n return createScopedLogger(getGlobalLogger(), 'XMLParser');\r\n}\r\n\r\n/**\r\n * Default maximum nesting depth for XML parsing.\r\n * Prevents stack overflow on deeply nested documents.\r\n */\r\nexport const DEFAULT_MAX_NESTING_DEPTH = 256;\r\n\r\n/**\r\n * Options for XML-to-object parsing\r\n */\r\nexport interface ParseToObjectOptions {\r\n /** Ignore attributes (default: false) */\r\n ignoreAttributes?: boolean;\r\n\r\n /** Attribute name prefix (default: '@_') */\r\n attributeNamePrefix?: string;\r\n\r\n /** Text node property name (default: '#text') */\r\n textNodeName?: string;\r\n\r\n /** Remove namespace prefixes from element names (default: false) */\r\n ignoreNamespace?: boolean;\r\n\r\n /** Parse numeric attribute values (default: true) */\r\n parseAttributeValue?: boolean;\r\n\r\n /** Trim whitespace from text values (default: true) */\r\n trimValues?: boolean;\r\n\r\n /** Always return arrays for elements (default: false) */\r\n alwaysArray?: boolean;\r\n\r\n /** Maximum nesting depth (default: 256). Prevents stack overflow on deeply nested documents. */\r\n maxNestingDepth?: number;\r\n}\r\n\r\n/**\r\n * Parsed XML object structure\r\n * Can be a string, object, array, or nested structure\r\n */\r\nexport type ParsedXMLValue =\r\n | string\r\n | number\r\n | boolean\r\n | ParsedXMLObject\r\n | ParsedXMLObject[]\r\n | null\r\n | undefined;\r\n\r\n/**\r\n * Parsed XML object with dynamic keys\r\n */\r\nexport interface ParsedXMLObject {\r\n [key: string]: ParsedXMLValue;\r\n}\r\n\r\n/**\r\n * Internal structure for tracking parsed elements during parsing\r\n */\r\ninterface ParsedElement {\r\n name: string;\r\n value: ParsedXMLValue;\r\n}\r\n\r\n/**\r\n * Simple XML parser using position-based parsing instead of regex\r\n * Prevents catastrophic backtracking (ReDoS attacks) by avoiding nested regex patterns\r\n */\r\nexport class XMLParser {\r\n /**\r\n * Extracts the body content from a Word document XML\r\n * @param docXml - The complete document.xml content\r\n * @returns The body content, or empty string if not found\r\n */\r\n static extractBody(docXml: string): string {\r\n const startTag = \"<w:body\";\r\n const endTag = \"</w:body>\";\r\n\r\n const startIdx = docXml.indexOf(startTag);\r\n if (startIdx === -1) return \"\";\r\n\r\n // Find the closing > of opening tag\r\n const openEnd = docXml.indexOf(\">\", startIdx);\r\n if (openEnd === -1) return \"\";\r\n\r\n // Find matching closing tag\r\n const endIdx = docXml.indexOf(endTag, openEnd);\r\n if (endIdx === -1) return \"\";\r\n\r\n return docXml.substring(openEnd + 1, endIdx);\r\n }\r\n\r\n /**\r\n * Extracts all elements of a given type using position-based parsing\r\n * Handles nested tags correctly by tracking depth\r\n * @param xml - XML content to parse\r\n * @param tagName - Tag name to extract (e.g., 'w:p', 'w:r')\r\n * @returns Array of XML strings for each element\r\n */\r\n static extractElements(xml: string, tagName: string): string[] {\r\n const elements: string[] = [];\r\n const openTag = `<${tagName}`;\r\n const closeTag = `</${tagName}>`;\r\n const selfClosingEnd = \"/>\";\r\n\r\n let pos = 0;\r\n while (pos < xml.length) {\r\n const startIdx = xml.indexOf(openTag, pos);\r\n if (startIdx === -1) break;\r\n\r\n // Verify this is the exact tag (not a prefix match like <w:p matching <w:pPr>)\r\n // The character after the tag name must be either '>', '/', whitespace, or '=' (for attributes)\r\n const charAfterTag = xml[startIdx + openTag.length];\r\n if (\r\n charAfterTag &&\r\n charAfterTag !== \">\" &&\r\n charAfterTag !== \"/\" &&\r\n charAfterTag !== \" \" &&\r\n charAfterTag !== \"\\t\" &&\r\n charAfterTag !== \"\\n\" &&\r\n charAfterTag !== \"\\r\" &&\r\n charAfterTag !== \"=\"\r\n ) {\r\n // This is a prefix match (e.g., <w:pPr> when looking for <w:p>), skip it (Issue #5)\r\n pos = startIdx + openTag.length;\r\n continue;\r\n }\r\n\r\n // Find the end of opening tag\r\n const openEnd = xml.indexOf(\">\", startIdx);\r\n if (openEnd === -1) break;\r\n\r\n // Check if self-closing\r\n if (xml.substring(openEnd - 1, openEnd + 1) === selfClosingEnd) {\r\n elements.push(xml.substring(startIdx, openEnd + 1));\r\n pos = openEnd + 1;\r\n continue;\r\n }\r\n\r\n // Find matching closing tag (handle nesting)\r\n let depth = 1;\r\n let searchPos = openEnd + 1;\r\n\r\n while (depth > 0 && searchPos < xml.length) {\r\n // Find next potential opening tag\r\n let nextOpen = -1;\r\n let openSearchPos = searchPos;\r\n while (true) {\r\n const candidateOpen = xml.indexOf(openTag, openSearchPos);\r\n if (candidateOpen === -1) {\r\n break;\r\n }\r\n // Verify it's an exact match (not a prefix)\r\n const charAfter = xml[candidateOpen + openTag.length];\r\n if (\r\n charAfter &&\r\n charAfter !== \">\" &&\r\n charAfter !== \"/\" &&\r\n charAfter !== \" \" &&\r\n charAfter !== \"\\t\" &&\r\n charAfter !== \"\\n\" &&\r\n charAfter !== \"\\r\"\r\n ) {\r\n // Prefix match, keep searching\r\n openSearchPos = candidateOpen + openTag.length;\r\n continue;\r\n }\r\n nextOpen = candidateOpen;\r\n break;\r\n }\r\n\r\n const nextClose = xml.indexOf(closeTag, searchPos);\r\n\r\n if (nextClose === -1) break;\r\n\r\n if (nextOpen !== -1 && nextOpen < nextClose) {\r\n depth++;\r\n searchPos = nextOpen + openTag.length;\r\n } else {\r\n depth--;\r\n if (depth === 0) {\r\n elements.push(xml.substring(startIdx, nextClose + closeTag.length));\r\n pos = nextClose + closeTag.length;\r\n } else {\r\n searchPos = nextClose + closeTag.length;\r\n }\r\n }\r\n }\r\n\r\n if (depth > 0) {\r\n // Unclosed tag - skip it\r\n pos = startIdx + openTag.length;\r\n }\r\n }\r\n\r\n return elements;\r\n }\r\n\r\n /**\r\n * Extracts attribute value from an XML string\r\n * @param xml - XML content\r\n * @param attributeName - Attribute name (e.g., 'w:val')\r\n * @returns Attribute value or undefined\r\n */\r\n static extractAttribute(\r\n xml: string,\r\n attributeName: string\r\n ): string | undefined {\r\n // Use simple indexOf for bounded string search (safe)\r\n const attrPattern = `${attributeName}=\"`;\r\n const startIdx = xml.indexOf(attrPattern);\r\n if (startIdx === -1) return undefined;\r\n\r\n const valueStart = startIdx + attrPattern.length;\r\n const valueEnd = xml.indexOf('\"', valueStart);\r\n if (valueEnd === -1) return undefined;\r\n\r\n const rawValue = xml.substring(valueStart, valueEnd);\r\n // Unescape XML entities to get the actual value\r\n // This prevents double-escaping when the value is later re-serialized\r\n return XMLBuilder.unescapeXml(rawValue);\r\n }\r\n\r\n /**\r\n * Checks if an XML string contains a self-closing tag\r\n * @param xml - XML content\r\n * @param tagName - Tag name to check\r\n * @returns True if the tag exists as self-closing\r\n */\r\n static hasSelfClosingTag(xml: string, tagName: string): boolean {\r\n return xml.includes(`<${tagName}/>`) || xml.includes(`<${tagName} `);\r\n }\r\n\r\n /**\r\n * Checks if a boolean property tag is enabled (w:val=\"1\" or w:val=\"true\")\r\n * Per ECMA-376, boolean properties can be:\r\n * - Present with w:val=\"1\" or w:val=\"true\" (enabled)\r\n * - Present with w:val=\"0\" or w:val=\"false\" (explicitly disabled)\r\n * - Absent (disabled by default)\r\n *\r\n * @param xml - XML content to search\r\n * @param tagName - Tag name (e.g., 'w:keepNext')\r\n * @returns True if tag exists with w:val=\"1\" or w:val=\"true\", false otherwise\r\n *\r\n * @example\r\n * hasBooleanProperty('<w:pPr><w:keepNext w:val=\"1\"/></w:pPr>', 'w:keepNext'); // true\r\n * hasBooleanProperty('<w:pPr><w:keepNext w:val=\"0\"/></w:pPr>', 'w:keepNext'); // false\r\n * hasBooleanProperty('<w:pPr><w:spacing/></w:pPr>', 'w:keepNext'); // false\r\n */\r\n static hasBooleanProperty(xml: string, tagName: string): boolean {\r\n // Check for tag with w:val=\"1\" or w:val=\"true\"\r\n if (\r\n xml.includes(`<${tagName} w:val=\"1\"`) ||\r\n xml.includes(`<${tagName} w:val=\"true\"`)\r\n ) {\r\n return true;\r\n }\r\n\r\n // Check for self-closing tag without w:val attribute (means true per ECMA-376)\r\n // Example: <w:b/> means bold=true\r\n if (xml.includes(`<${tagName}/>`)) {\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /**\r\n * Extracts text content from within tags\r\n * Finds all <w:t>...</w:t> tags and extracts their text\r\n * @param xml - XML content\r\n * @returns Combined text content\r\n */\r\n static extractText(xml: string): string {\r\n const texts: string[] = [];\r\n const openTag = \"<w:t\";\r\n const closeTag = \"</w:t>\";\r\n\r\n let pos = 0;\r\n while (pos < xml.length) {\r\n const startIdx = xml.indexOf(openTag, pos);\r\n if (startIdx === -1) break;\r\n\r\n // Find the end of opening tag\r\n const openEnd = xml.indexOf(\">\", startIdx);\r\n if (openEnd === -1) break;\r\n\r\n // Find closing tag\r\n const closeIdx = xml.indexOf(closeTag, openEnd);\r\n if (closeIdx === -1) break;\r\n\r\n // Extract text between tags\r\n const text = xml.substring(openEnd + 1, closeIdx);\r\n texts.push(text);\r\n\r\n pos = closeIdx + closeTag.length;\r\n }\r\n\r\n return texts.join(\"\");\r\n }\r\n\r\n /**\r\n * Validates input size to prevent excessive memory usage\r\n * @param xml - XML content\r\n * @param maxSize - Maximum size in bytes (default: 10MB)\r\n * @throws Error if XML exceeds max size\r\n */\r\n static validateSize(xml: string, maxSize: number = 10 * 1024 * 1024): void {\r\n if (xml.length > maxSize) {\r\n throw new Error(\r\n `XML content too large for parsing (${(\r\n xml.length /\r\n 1024 /\r\n 1024\r\n ).toFixed(1)}MB). ` +\r\n `Maximum allowed: ${(maxSize / 1024 / 1024).toFixed(0)}MB`\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Extracts content between two specific tags\r\n * More efficient than regex for large documents\r\n * @param xml - XML content\r\n * @param startTag - Opening tag (e.g., '<w:pPr')\r\n * @param endTag - Closing tag (e.g., '</w:pPr>')\r\n * @returns Content between tags, or undefined if not found\r\n */\r\n static extractBetweenTags(\r\n xml: string,\r\n startTag: string,\r\n endTag: string\r\n ): string | undefined {\r\n const startIdx = xml.indexOf(startTag);\r\n if (startIdx === -1) return undefined;\r\n\r\n // Find the end of the opening tag\r\n const openEnd = xml.indexOf(\">\", startIdx);\r\n if (openEnd === -1) return undefined;\r\n\r\n // Find the closing tag\r\n const endIdx = xml.indexOf(endTag, openEnd);\r\n if (endIdx === -1) return undefined;\r\n\r\n return xml.substring(openEnd + 1, endIdx);\r\n }\r\n\r\n /**\r\n * Extracts a complete self-closing tag with its attributes\r\n * Handles cases where multiple similar tags exist (e.g., <w:sz.../> and <w:szCs.../>)\r\n *\r\n * @param xml - XML string to search\r\n * @param tagName - Tag name to find (e.g., \"w:color\", \"w:sz\")\r\n * @returns The complete tag content (attributes portion) or undefined if not found\r\n *\r\n * @example\r\n * const xml = '<w:sz w:val=\"36\"/><w:color w:val=\"FF0000\"/>';\r\n * const colorTag = XMLParser.extractSelfClosingTag(xml, 'w:color');\r\n * // Returns: ' w:val=\"FF0000\"'\r\n */\r\n static extractSelfClosingTag(\r\n xml: string,\r\n tagName: string\r\n ): string | undefined {\r\n const startPattern = `<${tagName}`;\r\n let searchPos = 0;\r\n\r\n // Search for the exact tag (not tags that start with this pattern)\r\n while (true) {\r\n const startIdx = xml.indexOf(startPattern, searchPos);\r\n if (startIdx === -1) return undefined;\r\n\r\n // Check what character follows the tag name\r\n const charAfterTag = xml[startIdx + startPattern.length];\r\n\r\n // Valid separators after tag name: space, '/', or '>'\r\n if (charAfterTag === ' ' || charAfterTag === '/' || charAfterTag === '>') {\r\n // Found the exact tag, now find its end\r\n const endIdx = xml.indexOf('/>', startIdx);\r\n if (endIdx === -1) {\r\n // Try finding a closing tag instead (non-self-closing)\r\n const closeTagStart = xml.indexOf('>', startIdx);\r\n if (closeTagStart === -1) return undefined;\r\n\r\n // Return attributes portion\r\n return xml.substring(startIdx + startPattern.length, closeTagStart);\r\n }\r\n\r\n // Return attributes portion (between tag name and />)\r\n return xml.substring(startIdx + startPattern.length, endIdx);\r\n }\r\n\r\n // Not the exact tag (e.g., found \"w:sz\" when looking for \"w:s\")\r\n // Continue searching\r\n searchPos = startIdx + 1;\r\n }\r\n }\r\n\r\n /**\r\n * Parse XML string to JavaScript object\r\n * Compatible with fast-xml-parser output format\r\n *\r\n * @param xml - XML string to parse\r\n * @param options - Parsing options\r\n * @returns Parsed JavaScript object\r\n *\r\n * @example\r\n * const xml = '<Relationships><Relationship Id=\"rId1\" Target=\"https://example.com\"/></Relationships>';\r\n * const obj = XMLParser.parseToObject(xml);\r\n * // Returns: { Relationships: { Relationship: { '@_Id': 'rId1', '@_Target': 'https://example.com' } } }\r\n *\r\n * @example\r\n * // Multiple elements become arrays\r\n * const xml = '<Items><Item id=\"1\"/><Item id=\"2\"/></Items>';\r\n * const obj = XMLParser.parseToObject(xml);\r\n * // Returns: { Items: { Item: [{ '@_id': '1' }, { '@_id': '2' }] } }\r\n */\r\n static parseToObject(\r\n xml: string,\r\n options?: ParseToObjectOptions\r\n ): ParsedXMLObject {\r\n const logger = getLogger();\r\n logger.debug('Parsing XML to object', { xmlSize: xml.length });\r\n\r\n // Default options\r\n const opts: Required<ParseToObjectOptions> = {\r\n ignoreAttributes: options?.ignoreAttributes ?? false,\r\n attributeNamePrefix: options?.attributeNamePrefix ?? \"@_\",\r\n textNodeName: options?.textNodeName ?? \"#text\",\r\n ignoreNamespace: options?.ignoreNamespace ?? false,\r\n parseAttributeValue: options?.parseAttributeValue ?? true,\r\n trimValues: options?.trimValues ?? true,\r\n alwaysArray: options?.alwaysArray ?? false,\r\n maxNestingDepth: options?.maxNestingDepth ?? DEFAULT_MAX_NESTING_DEPTH,\r\n };\r\n\r\n // Validate input size\r\n XMLParser.validateSize(xml);\r\n\r\n // Remove XML declaration and trim\r\n xml = xml.replace(/<\\?xml[^>]*\\?>\\s*/g, \"\").trim();\r\n\r\n if (!xml) {\r\n return {};\r\n }\r\n\r\n // Parse root element (start at depth 0)\r\n const result = XMLParser.parseElementToObject(xml, 0, opts, 0);\r\n logger.debug('XML parsed to object');\r\n return result.value as ParsedXMLObject;\r\n }\r\n\r\n /**\r\n * Parses a single XML element into an object\r\n * @private\r\n */\r\n private static parseElementToObject(\r\n xml: string,\r\n startPos: number,\r\n options: Required<ParseToObjectOptions>,\r\n depth: number\r\n ): { value: ParsedXMLValue; endPos: number } {\r\n // Check nesting depth to prevent stack overflow\r\n if (depth > options.maxNestingDepth) {\r\n throw new Error(\r\n `XML nesting depth exceeds maximum of ${options.maxNestingDepth}. ` +\r\n `This may indicate malformed XML or an attack attempt. ` +\r\n `Use the maxNestingDepth option to increase the limit if needed.`\r\n );\r\n }\r\n\r\n // Find opening tag\r\n const openTagStart = xml.indexOf(\"<\", startPos);\r\n if (openTagStart === -1) {\r\n return { value: {}, endPos: xml.length };\r\n }\r\n\r\n // Skip comments\r\n if (xml.substring(openTagStart, openTagStart + 4) === \"<!--\") {\r\n const commentEnd = xml.indexOf(\"-->\", openTagStart + 4);\r\n if (commentEnd !== -1) {\r\n return XMLParser.parseElementToObject(xml, commentEnd + 3, options, depth);\r\n }\r\n return { value: {}, endPos: xml.length };\r\n }\r\n\r\n // Extract element name\r\n const nameMatch = /^([a-zA-Z0-9:_-]+)/.exec(xml\r\n .substring(openTagStart + 1));\r\n if (!nameMatch) {\r\n return { value: {}, endPos: openTagStart + 1 };\r\n }\r\n\r\n const originalElementName: string = nameMatch[1] || \"\";\r\n let elementName: string = originalElementName;\r\n const tagHeaderEnd = xml.indexOf(\">\", openTagStart);\r\n if (tagHeaderEnd === -1) {\r\n return { value: {}, endPos: xml.length };\r\n }\r\n\r\n // Remove namespace if requested (but keep original for offset calculations)\r\n if (options.ignoreNamespace && elementName.includes(\":\")) {\r\n elementName = elementName.split(\":\")[1] || elementName;\r\n }\r\n\r\n // Extract attributes using ORIGINAL element name length for correct offset\r\n const tagHeader = xml.substring(\r\n openTagStart + 1 + originalElementName.length,\r\n tagHeaderEnd\r\n );\r\n const attributes = XMLParser.extractAttributesFromTag(tagHeader, options);\r\n\r\n // Check if self-closing\r\n const isSelfClosing =\r\n tagHeader.trim().endsWith(\"/\") || xml[tagHeaderEnd - 1] === \"/\";\r\n\r\n if (isSelfClosing) {\r\n // Self-closing tag - return object with attributes only\r\n const elementValue: ParsedXMLObject = { ...attributes };\r\n return {\r\n value: { [elementName]: elementValue },\r\n endPos: tagHeaderEnd + 1,\r\n };\r\n }\r\n\r\n // Find closing tag (use original name with namespace for correct matching)\r\n const closingTag = `</${originalElementName}>`;\r\n const contentStart = tagHeaderEnd + 1;\r\n const closingTagPos = XMLParser.findClosingTag(\r\n xml,\r\n originalElementName,\r\n contentStart\r\n );\r\n\r\n if (closingTagPos === -1) {\r\n // No closing tag found - treat as self-closing\r\n return {\r\n value: { [elementName]: { ...attributes } },\r\n endPos: tagHeaderEnd + 1,\r\n };\r\n }\r\n\r\n // Extract content between tags\r\n const content = xml.substring(contentStart, closingTagPos);\r\n\r\n // Parse content (children or text)\r\n const children: ParsedElement[] = [];\r\n let textContent = \"\";\r\n let pos = 0;\r\n\r\n while (pos < content.length) {\r\n const nextTag = content.indexOf(\"<\", pos);\r\n\r\n if (nextTag === -1) {\r\n // No more tags - rest is text\r\n const text = content.substring(pos);\r\n // When trimValues is false, preserve whitespace-only text\r\n // When trimValues is true, only include text that has non-whitespace content\r\n if (text.length > 0 && (!options.trimValues || text.trim())) {\r\n // Unescape XML entities in text content (e.g., &lt; -> <)\r\n textContent += XMLBuilder.unescapeXml(text);\r\n }\r\n break;\r\n }\r\n\r\n // Collect text before next tag\r\n if (nextTag > pos) {\r\n const text = content.substring(pos, nextTag);\r\n // When trimValues is false, preserve whitespace-only text\r\n // When trimValues is true, only include text that has non-whitespace content\r\n if (text.length > 0 && (!options.trimValues || text.trim())) {\r\n // Unescape XML entities in text content (e.g., &lt; -> <)\r\n textContent += XMLBuilder.unescapeXml(text);\r\n }\r\n }\r\n\r\n // Parse child element (increment depth for children)\r\n const childResult = XMLParser.parseElementToObject(\r\n content,\r\n nextTag,\r\n options,\r\n depth + 1\r\n );\r\n const childObj = childResult.value as ParsedXMLObject;\r\n\r\n // Extract child name and value\r\n const childKeys = Object.keys(childObj);\r\n if (childKeys.length > 0) {\r\n const childName = childKeys[0];\r\n if (childName) {\r\n const childValue = childObj[childName];\r\n children.push({ name: childName, value: childValue });\r\n }\r\n }\r\n\r\n pos = childResult.endPos;\r\n }\r\n\r\n // Build element value\r\n let elementValue: ParsedXMLValue = {};\r\n\r\n // Add attributes\r\n if (!options.ignoreAttributes && Object.keys(attributes).length > 0) {\r\n elementValue = { ...attributes };\r\n }\r\n\r\n // Add text content\r\n // When trimValues is false, include whitespace-only text\r\n // When trimValues is true, only include text with non-whitespace content\r\n if (textContent.length > 0 && (!options.trimValues || textContent.trim())) {\r\n const text = options.trimValues ? textContent.trim() : textContent;\r\n if (typeof elementValue === \"object\" && !Array.isArray(elementValue)) {\r\n if (Object.keys(elementValue).length === 0) {\r\n // Only text, no attributes - return as direct value if simple\r\n elementValue = text;\r\n } else {\r\n // Text with attributes\r\n (elementValue)[options.textNodeName] = text;\r\n }\r\n }\r\n }\r\n\r\n // Add children\r\n if (children.length > 0) {\r\n const coalescedChildren = XMLParser.coalesceChildren(children, options);\r\n if (typeof elementValue === \"object\" && !Array.isArray(elementValue)) {\r\n elementValue = { ...elementValue, ...coalescedChildren };\r\n } else {\r\n elementValue = coalescedChildren;\r\n }\r\n }\r\n\r\n // If element has no content, attributes, or children - return empty object\r\n if (\r\n typeof elementValue === \"object\" &&\r\n !Array.isArray(elementValue) &&\r\n Object.keys(elementValue).length === 0\r\n ) {\r\n elementValue = {};\r\n }\r\n\r\n return {\r\n value: { [elementName]: elementValue },\r\n endPos: closingTagPos + closingTag.length,\r\n };\r\n }\r\n\r\n /**\r\n * Extracts attributes from a tag header\r\n * @private\r\n */\r\n private static extractAttributesFromTag(\r\n tagHeader: string,\r\n options: Required<ParseToObjectOptions>\r\n ): Record<string, string | number | boolean> {\r\n const attributes: Record<string, string | number | boolean> = {};\r\n\r\n if (options.ignoreAttributes) {\r\n return attributes;\r\n }\r\n\r\n // Simple attribute extraction using position-based parsing\r\n let pos = 0;\r\n while (pos < tagHeader.length) {\r\n // Skip whitespace\r\n while (pos < tagHeader.length) {\r\n const char = tagHeader[pos];\r\n if (char && /\\s/.test(char)) {\r\n pos++;\r\n } else {\r\n break;\r\n }\r\n }\r\n\r\n if (pos >= tagHeader.length || tagHeader[pos] === \"/\") {\r\n break;\r\n }\r\n\r\n // Extract attribute name\r\n const nameStart = pos;\r\n while (pos < tagHeader.length) {\r\n const char = tagHeader[pos];\r\n if (char && /[a-zA-Z0-9:_-]/.test(char)) {\r\n pos++;\r\n } else {\r\n break;\r\n }\r\n }\r\n\r\n if (pos === nameStart) {\r\n break;\r\n }\r\n\r\n let attrName = tagHeader.substring(nameStart, pos);\r\n\r\n // Skip whitespace and '='\r\n while (pos < tagHeader.length) {\r\n const char = tagHeader[pos];\r\n if (char && /[\\s=]/.test(char)) {\r\n pos++;\r\n } else {\r\n break;\r\n }\r\n }\r\n\r\n // Extract attribute value\r\n let attrValue = \"\";\r\n if (\r\n pos < tagHeader.length &&\r\n (tagHeader[pos] === '\"' || tagHeader[pos] === \"'\")\r\n ) {\r\n const quote = tagHeader[pos];\r\n pos++; // Skip opening quote\r\n const valueStart = pos;\r\n\r\n while (pos < tagHeader.length && tagHeader[pos] !== quote) {\r\n pos++;\r\n }\r\n\r\n attrValue = tagHeader.substring(valueStart, pos);\r\n pos++; // Skip closing quote\r\n }\r\n\r\n // Remove namespace from attribute name if requested\r\n if (options.ignoreNamespace && attrName.includes(\":\")) {\r\n attrName = attrName.split(\":\")[1] || attrName;\r\n }\r\n\r\n // Add prefix to attribute name\r\n const prefixedName = options.attributeNamePrefix + attrName;\r\n\r\n // Parse attribute value\r\n attributes[prefixedName] = options.parseAttributeValue\r\n ? XMLParser.parseValue(attrValue)\r\n : attrValue;\r\n }\r\n\r\n return attributes;\r\n }\r\n\r\n /**\r\n * Finds the closing tag for an element, handling nesting\r\n * @private\r\n */\r\n private static findClosingTag(\r\n xml: string,\r\n elementName: string,\r\n startPos: number\r\n ): number {\r\n const openTag = `<${elementName}`;\r\n const closeTag = `</${elementName}>`;\r\n let depth = 1;\r\n let pos = startPos;\r\n\r\n while (depth > 0 && pos < xml.length) {\r\n const nextClose = xml.indexOf(closeTag, pos);\r\n\r\n if (nextClose === -1) {\r\n return -1; // No closing tag found\r\n }\r\n\r\n // Find the next REAL opening tag (not a prefix match like <w:pPrChange for <w:pPr)\r\n // Must search for all potential matches and verify each one\r\n let realOpenPos = -1;\r\n let searchPos = pos;\r\n while (searchPos < nextClose) {\r\n const candidateOpen = xml.indexOf(openTag, searchPos);\r\n if (candidateOpen === -1 || candidateOpen >= nextClose) {\r\n break; // No more candidates before the closing tag\r\n }\r\n\r\n const charAfter = xml[candidateOpen + openTag.length];\r\n if (\r\n charAfter === \">\" ||\r\n charAfter === \" \" ||\r\n charAfter === \"/\" ||\r\n charAfter === \"\\t\" ||\r\n charAfter === \"\\n\" ||\r\n charAfter === \"\\r\"\r\n ) {\r\n // This looks like a real opening tag - but check if it's self-closing\r\n // Self-closing tags like <w:rPr/> should NOT increase depth\r\n const tagEnd = xml.indexOf(\">\", candidateOpen);\r\n if (tagEnd !== -1 && xml[tagEnd - 1] === \"/\") {\r\n // Self-closing tag - skip it (don't affect depth)\r\n searchPos = tagEnd + 1;\r\n continue;\r\n }\r\n // This is a real opening tag (not self-closing)\r\n realOpenPos = candidateOpen;\r\n break;\r\n }\r\n\r\n // False positive (e.g., <w:pPrChange when looking for <w:pPr)\r\n // Keep searching from after this position\r\n searchPos = candidateOpen + openTag.length;\r\n }\r\n\r\n if (realOpenPos !== -1) {\r\n // Found a real opening tag before the closing tag - increase depth\r\n depth++;\r\n pos = realOpenPos + openTag.length;\r\n } else {\r\n // No real opening tag before this closing tag - decrease depth\r\n depth--;\r\n if (depth === 0) {\r\n return nextClose;\r\n }\r\n pos = nextClose + closeTag.length;\r\n }\r\n }\r\n\r\n return -1;\r\n }\r\n\r\n /**\r\n * Coalesces children with duplicate names into arrays\r\n * @private\r\n */\r\n private static coalesceChildren(\r\n children: ParsedElement[],\r\n options: Required<ParseToObjectOptions>\r\n ): ParsedXMLObject {\r\n const result: ParsedXMLObject = {};\r\n const nameCounts: Record<string, number> = {};\r\n const nameIndices: Record<string, number> = {};\r\n\r\n // Track element order for correct run content parsing (tabs, breaks, text)\r\n // This is critical for preserving the order of mixed content like: text -> tab -> text\r\n const orderedChildren: { type: string; index: number }[] = [];\r\n\r\n // Count occurrences of each child name\r\n for (const child of children) {\r\n nameCounts[child.name] = (nameCounts[child.name] || 0) + 1;\r\n }\r\n\r\n // Build result object while tracking order\r\n for (const child of children) {\r\n const shouldBeArray =\r\n options.alwaysArray || (nameCounts[child.name] || 0) > 1;\r\n\r\n // Track element order with its index in the array\r\n const currentIndex = nameIndices[child.name] || 0;\r\n orderedChildren.push({ type: child.name, index: currentIndex });\r\n nameIndices[child.name] = currentIndex + 1;\r\n\r\n if (shouldBeArray) {\r\n if (!result[child.name]) {\r\n result[child.name] = [];\r\n }\r\n (result[child.name] as ParsedXMLValue[]).push(child.value);\r\n } else {\r\n result[child.name] = child.value;\r\n }\r\n }\r\n\r\n // Add _orderedChildren to track element order (used by DocumentParser for runs)\r\n if (orderedChildren.length > 0) {\r\n result._orderedChildren = orderedChildren;\r\n }\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Parses a string value to number or boolean if applicable\r\n * @private\r\n */\r\n private static parseValue(value: string): string | number | boolean {\r\n if (value === \"true\") return true;\r\n if (value === \"false\") return false;\r\n\r\n // Preserve 6-character hex color codes (OpenXML standard for colors)\r\n // This includes \"000000\" (black) which should stay as a string\r\n if (/^[0-9A-Fa-f]{6}$/.test(value)) {\r\n return value.toUpperCase(); // Normalize to uppercase per Microsoft convention\r\n }\r\n\r\n // Preserve long digit-only strings (e.g., cnfStyle binary strings like \"100000000000\")\r\n // These should not be converted to numbers to avoid losing leading zeros\r\n if (/^\\d{7,}$/.test(value)) {\r\n return value; // Keep as string for values with 7+ digits\r\n }\r\n\r\n // Try parsing as number\r\n // 3-character values like \"240\" will be parsed as numbers\r\n // 6-character hex values are already handled above\r\n if (/^-?\\d+$/.test(value)) {\r\n const num = parseInt(value, 10);\r\n if (!isNaN(num)) return num;\r\n }\r\n\r\n if (/^-?\\d+\\.\\d+$/.test(value)) {\r\n const num = parseFloat(value);\r\n if (!isNaN(num)) return num;\r\n }\r\n\r\n // Preserve 3-character hex codes (like \"F0A\") that have letters\r\n // Pure numeric 3-char values (like \"240\") are already parsed as numbers above\r\n if (/^[0-9A-Fa-f]{3}$/.test(value) && /[A-Fa-f]/.test(value)) {\r\n return value.toUpperCase();\r\n }\r\n\r\n return value;\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"XMLParser.js","sourceRoot":"","sources":["../../src/xml/XMLParser.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * XMLParser - Simple position-based XML parser\n * Avoids regex backtracking issues that can cause ReDoS attacks\n * Completes the DocXML framework (XMLBuilder + XMLParser)\n */\n\nimport { getGlobalLogger, createScopedLogger, ILogger } from '../utils/logger';\nimport { XMLBuilder } from './XMLBuilder';\n\n// Create scoped logger for XMLParser operations\nfunction getLogger(): ILogger {\n return createScopedLogger(getGlobalLogger(), 'XMLParser');\n}\n\n/**\n * Default maximum nesting depth for XML parsing.\n * Prevents stack overflow on deeply nested documents.\n */\nexport const DEFAULT_MAX_NESTING_DEPTH = 256;\n\n/**\n * Options for XML-to-object parsing\n */\nexport interface ParseToObjectOptions {\n /** Ignore attributes (default: false) */\n ignoreAttributes?: boolean;\n\n /** Attribute name prefix (default: '@_') */\n attributeNamePrefix?: string;\n\n /** Text node property name (default: '#text') */\n textNodeName?: string;\n\n /** Remove namespace prefixes from element names (default: false) */\n ignoreNamespace?: boolean;\n\n /** Parse numeric attribute values (default: true) */\n parseAttributeValue?: boolean;\n\n /** Trim whitespace from text values (default: true) */\n trimValues?: boolean;\n\n /** Always return arrays for elements (default: false) */\n alwaysArray?: boolean;\n\n /** Maximum nesting depth (default: 256). Prevents stack overflow on deeply nested documents. */\n maxNestingDepth?: number;\n}\n\n/**\n * Parsed XML object structure\n * Can be a string, object, array, or nested structure\n */\nexport type ParsedXMLValue =\n | string\n | number\n | boolean\n | ParsedXMLObject\n | ParsedXMLObject[]\n | null\n | undefined;\n\n/**\n * Parsed XML object with dynamic keys\n */\nexport interface ParsedXMLObject {\n [key: string]: ParsedXMLValue;\n}\n\n/**\n * Internal structure for tracking parsed elements during parsing\n */\ninterface ParsedElement {\n name: string;\n value: ParsedXMLValue;\n}\n\n/**\n * Simple XML parser using position-based parsing instead of regex\n * Prevents catastrophic backtracking (ReDoS attacks) by avoiding nested regex patterns\n */\nexport class XMLParser {\n /**\n * Extracts the body content from a Word document XML\n * @param docXml - The complete document.xml content\n * @returns The body content, or empty string if not found\n */\n static extractBody(docXml: string): string {\n const startTag = '<w:body';\n const endTag = '</w:body>';\n\n const startIdx = docXml.indexOf(startTag);\n if (startIdx === -1) return '';\n\n // Find the closing > of opening tag\n const openEnd = docXml.indexOf('>', startIdx);\n if (openEnd === -1) return '';\n\n // Find matching closing tag\n const endIdx = docXml.indexOf(endTag, openEnd);\n if (endIdx === -1) return '';\n\n return docXml.substring(openEnd + 1, endIdx);\n }\n\n /**\n * Extracts all elements of a given type using position-based parsing\n * Handles nested tags correctly by tracking depth\n * @param xml - XML content to parse\n * @param tagName - Tag name to extract (e.g., 'w:p', 'w:r')\n * @returns Array of XML strings for each element\n */\n static extractElements(xml: string, tagName: string): string[] {\n const elements: string[] = [];\n const openTag = `<${tagName}`;\n const closeTag = `</${tagName}>`;\n const selfClosingEnd = '/>';\n\n let pos = 0;\n while (pos < xml.length) {\n const startIdx = xml.indexOf(openTag, pos);\n if (startIdx === -1) break;\n\n // Verify this is the exact tag (not a prefix match like <w:p matching <w:pPr>)\n // The character after the tag name must be either '>', '/', whitespace, or '=' (for attributes)\n const charAfterTag = xml[startIdx + openTag.length];\n if (\n charAfterTag &&\n charAfterTag !== '>' &&\n charAfterTag !== '/' &&\n charAfterTag !== ' ' &&\n charAfterTag !== '\\t' &&\n charAfterTag !== '\\n' &&\n charAfterTag !== '\\r' &&\n charAfterTag !== '='\n ) {\n // This is a prefix match (e.g., <w:pPr> when looking for <w:p>), skip it (Issue #5)\n pos = startIdx + openTag.length;\n continue;\n }\n\n // Find the end of opening tag\n const openEnd = xml.indexOf('>', startIdx);\n if (openEnd === -1) break;\n\n // Check if self-closing\n if (xml.substring(openEnd - 1, openEnd + 1) === selfClosingEnd) {\n elements.push(xml.substring(startIdx, openEnd + 1));\n pos = openEnd + 1;\n continue;\n }\n\n // Find matching closing tag (handle nesting)\n let depth = 1;\n let searchPos = openEnd + 1;\n\n while (depth > 0 && searchPos < xml.length) {\n // Find next potential opening tag\n let nextOpen = -1;\n let openSearchPos = searchPos;\n while (true) {\n const candidateOpen = xml.indexOf(openTag, openSearchPos);\n if (candidateOpen === -1) {\n break;\n }\n // Verify it's an exact match (not a prefix)\n const charAfter = xml[candidateOpen + openTag.length];\n if (\n charAfter &&\n charAfter !== '>' &&\n charAfter !== '/' &&\n charAfter !== ' ' &&\n charAfter !== '\\t' &&\n charAfter !== '\\n' &&\n charAfter !== '\\r'\n ) {\n // Prefix match, keep searching\n openSearchPos = candidateOpen + openTag.length;\n continue;\n }\n nextOpen = candidateOpen;\n break;\n }\n\n const nextClose = xml.indexOf(closeTag, searchPos);\n\n if (nextClose === -1) break;\n\n if (nextOpen !== -1 && nextOpen < nextClose) {\n depth++;\n searchPos = nextOpen + openTag.length;\n } else {\n depth--;\n if (depth === 0) {\n elements.push(xml.substring(startIdx, nextClose + closeTag.length));\n pos = nextClose + closeTag.length;\n } else {\n searchPos = nextClose + closeTag.length;\n }\n }\n }\n\n if (depth > 0) {\n // Unclosed tag - skip it\n pos = startIdx + openTag.length;\n }\n }\n\n return elements;\n }\n\n /**\n * Extracts attribute value from an XML string\n * @param xml - XML content\n * @param attributeName - Attribute name (e.g., 'w:val')\n * @returns Attribute value or undefined\n */\n static extractAttribute(xml: string, attributeName: string): string | undefined {\n // Use simple indexOf for bounded string search (safe)\n const attrPattern = `${attributeName}=\"`;\n const startIdx = xml.indexOf(attrPattern);\n if (startIdx === -1) return undefined;\n\n const valueStart = startIdx + attrPattern.length;\n const valueEnd = xml.indexOf('\"', valueStart);\n if (valueEnd === -1) return undefined;\n\n const rawValue = xml.substring(valueStart, valueEnd);\n // Unescape XML entities to get the actual value\n // This prevents double-escaping when the value is later re-serialized\n return XMLBuilder.unescapeXml(rawValue);\n }\n\n /**\n * Checks if an XML string contains a self-closing tag\n * @param xml - XML content\n * @param tagName - Tag name to check\n * @returns True if the tag exists as self-closing\n */\n static hasSelfClosingTag(xml: string, tagName: string): boolean {\n return xml.includes(`<${tagName}/>`) || xml.includes(`<${tagName} `);\n }\n\n /**\n * Checks if a boolean property tag is enabled (w:val=\"1\" or w:val=\"true\")\n * Per ECMA-376, boolean properties can be:\n * - Present with w:val=\"1\" or w:val=\"true\" (enabled)\n * - Present with w:val=\"0\" or w:val=\"false\" (explicitly disabled)\n * - Absent (disabled by default)\n *\n * @param xml - XML content to search\n * @param tagName - Tag name (e.g., 'w:keepNext')\n * @returns True if tag exists with w:val=\"1\" or w:val=\"true\", false otherwise\n *\n * @example\n * hasBooleanProperty('<w:pPr><w:keepNext w:val=\"1\"/></w:pPr>', 'w:keepNext'); // true\n * hasBooleanProperty('<w:pPr><w:keepNext w:val=\"0\"/></w:pPr>', 'w:keepNext'); // false\n * hasBooleanProperty('<w:pPr><w:spacing/></w:pPr>', 'w:keepNext'); // false\n */\n static hasBooleanProperty(xml: string, tagName: string): boolean {\n // Check for tag with w:val=\"1\" or w:val=\"true\"\n if (xml.includes(`<${tagName} w:val=\"1\"`) || xml.includes(`<${tagName} w:val=\"true\"`)) {\n return true;\n }\n\n // Check for self-closing tag without w:val attribute (means true per ECMA-376)\n // Example: <w:b/> means bold=true\n if (xml.includes(`<${tagName}/>`)) {\n return true;\n }\n\n return false;\n }\n\n /**\n * Extracts text content from within tags\n * Finds all <w:t>...</w:t> tags and extracts their text\n * @param xml - XML content\n * @returns Combined text content\n */\n static extractText(xml: string): string {\n const texts: string[] = [];\n const openTag = '<w:t';\n const closeTag = '</w:t>';\n\n let pos = 0;\n while (pos < xml.length) {\n const startIdx = xml.indexOf(openTag, pos);\n if (startIdx === -1) break;\n\n // Find the end of opening tag\n const openEnd = xml.indexOf('>', startIdx);\n if (openEnd === -1) break;\n\n // Find closing tag\n const closeIdx = xml.indexOf(closeTag, openEnd);\n if (closeIdx === -1) break;\n\n // Extract text between tags\n const text = xml.substring(openEnd + 1, closeIdx);\n texts.push(text);\n\n pos = closeIdx + closeTag.length;\n }\n\n return texts.join('');\n }\n\n /**\n * Validates input size to prevent excessive memory usage\n * @param xml - XML content\n * @param maxSize - Maximum size in bytes (default: 10MB)\n * @throws Error if XML exceeds max size\n */\n static validateSize(xml: string, maxSize: number = 10 * 1024 * 1024): void {\n if (xml.length > maxSize) {\n throw new Error(\n `XML content too large for parsing (${(xml.length / 1024 / 1024).toFixed(1)}MB). ` +\n `Maximum allowed: ${(maxSize / 1024 / 1024).toFixed(0)}MB`\n );\n }\n }\n\n /**\n * Extracts content between two specific tags\n * More efficient than regex for large documents\n * @param xml - XML content\n * @param startTag - Opening tag (e.g., '<w:pPr')\n * @param endTag - Closing tag (e.g., '</w:pPr>')\n * @returns Content between tags, or undefined if not found\n */\n static extractBetweenTags(xml: string, startTag: string, endTag: string): string | undefined {\n const startIdx = xml.indexOf(startTag);\n if (startIdx === -1) return undefined;\n\n // Find the end of the opening tag\n const openEnd = xml.indexOf('>', startIdx);\n if (openEnd === -1) return undefined;\n\n // Find the closing tag\n const endIdx = xml.indexOf(endTag, openEnd);\n if (endIdx === -1) return undefined;\n\n return xml.substring(openEnd + 1, endIdx);\n }\n\n /**\n * Extracts a complete self-closing tag with its attributes\n * Handles cases where multiple similar tags exist (e.g., <w:sz.../> and <w:szCs.../>)\n *\n * @param xml - XML string to search\n * @param tagName - Tag name to find (e.g., \"w:color\", \"w:sz\")\n * @returns The complete tag content (attributes portion) or undefined if not found\n *\n * @example\n * const xml = '<w:sz w:val=\"36\"/><w:color w:val=\"FF0000\"/>';\n * const colorTag = XMLParser.extractSelfClosingTag(xml, 'w:color');\n * // Returns: ' w:val=\"FF0000\"'\n */\n static extractSelfClosingTag(xml: string, tagName: string): string | undefined {\n const startPattern = `<${tagName}`;\n let searchPos = 0;\n\n // Search for the exact tag (not tags that start with this pattern)\n while (true) {\n const startIdx = xml.indexOf(startPattern, searchPos);\n if (startIdx === -1) return undefined;\n\n // Check what character follows the tag name\n const charAfterTag = xml[startIdx + startPattern.length];\n\n // Valid separators after tag name: space, '/', or '>'\n if (charAfterTag === ' ' || charAfterTag === '/' || charAfterTag === '>') {\n // Found the exact tag, now find its end\n const endIdx = xml.indexOf('/>', startIdx);\n if (endIdx === -1) {\n // Try finding a closing tag instead (non-self-closing)\n const closeTagStart = xml.indexOf('>', startIdx);\n if (closeTagStart === -1) return undefined;\n\n // Return attributes portion\n return xml.substring(startIdx + startPattern.length, closeTagStart);\n }\n\n // Return attributes portion (between tag name and />)\n return xml.substring(startIdx + startPattern.length, endIdx);\n }\n\n // Not the exact tag (e.g., found \"w:sz\" when looking for \"w:s\")\n // Continue searching\n searchPos = startIdx + 1;\n }\n }\n\n /**\n * Parse XML string to JavaScript object\n * Compatible with fast-xml-parser output format\n *\n * @param xml - XML string to parse\n * @param options - Parsing options\n * @returns Parsed JavaScript object\n *\n * @example\n * const xml = '<Relationships><Relationship Id=\"rId1\" Target=\"https://example.com\"/></Relationships>';\n * const obj = XMLParser.parseToObject(xml);\n * // Returns: { Relationships: { Relationship: { '@_Id': 'rId1', '@_Target': 'https://example.com' } } }\n *\n * @example\n * // Multiple elements become arrays\n * const xml = '<Items><Item id=\"1\"/><Item id=\"2\"/></Items>';\n * const obj = XMLParser.parseToObject(xml);\n * // Returns: { Items: { Item: [{ '@_id': '1' }, { '@_id': '2' }] } }\n */\n static parseToObject(xml: string, options?: ParseToObjectOptions): ParsedXMLObject {\n const logger = getLogger();\n logger.debug('Parsing XML to object', { xmlSize: xml.length });\n\n // Default options\n const opts: Required<ParseToObjectOptions> = {\n ignoreAttributes: options?.ignoreAttributes ?? false,\n attributeNamePrefix: options?.attributeNamePrefix ?? '@_',\n textNodeName: options?.textNodeName ?? '#text',\n ignoreNamespace: options?.ignoreNamespace ?? false,\n parseAttributeValue: options?.parseAttributeValue ?? true,\n trimValues: options?.trimValues ?? true,\n alwaysArray: options?.alwaysArray ?? false,\n maxNestingDepth: options?.maxNestingDepth ?? DEFAULT_MAX_NESTING_DEPTH,\n };\n\n // Validate input size\n XMLParser.validateSize(xml);\n\n // Remove XML declaration and trim\n xml = xml.replace(/<\\?xml[^>]*\\?>\\s*/g, '').trim();\n\n if (!xml) {\n return {};\n }\n\n // Parse root element (start at depth 0)\n const result = XMLParser.parseElementToObject(xml, 0, opts, 0);\n logger.debug('XML parsed to object');\n return result.value as ParsedXMLObject;\n }\n\n /**\n * Parses a single XML element into an object\n * @private\n */\n private static parseElementToObject(\n xml: string,\n startPos: number,\n options: Required<ParseToObjectOptions>,\n depth: number\n ): { value: ParsedXMLValue; endPos: number } {\n // Check nesting depth to prevent stack overflow\n if (depth > options.maxNestingDepth) {\n throw new Error(\n `XML nesting depth exceeds maximum of ${options.maxNestingDepth}. ` +\n `This may indicate malformed XML or an attack attempt. ` +\n `Use the maxNestingDepth option to increase the limit if needed.`\n );\n }\n\n // Find opening tag\n const openTagStart = xml.indexOf('<', startPos);\n if (openTagStart === -1) {\n return { value: {}, endPos: xml.length };\n }\n\n // Skip comments\n if (xml.substring(openTagStart, openTagStart + 4) === '<!--') {\n const commentEnd = xml.indexOf('-->', openTagStart + 4);\n if (commentEnd !== -1) {\n return XMLParser.parseElementToObject(xml, commentEnd + 3, options, depth);\n }\n return { value: {}, endPos: xml.length };\n }\n\n // Extract element name\n const nameMatch = /^([a-zA-Z0-9:_-]+)/.exec(xml.substring(openTagStart + 1));\n if (!nameMatch) {\n return { value: {}, endPos: openTagStart + 1 };\n }\n\n const originalElementName: string = nameMatch[1] || '';\n let elementName: string = originalElementName;\n const tagHeaderEnd = xml.indexOf('>', openTagStart);\n if (tagHeaderEnd === -1) {\n return { value: {}, endPos: xml.length };\n }\n\n // Remove namespace if requested (but keep original for offset calculations)\n if (options.ignoreNamespace && elementName.includes(':')) {\n elementName = elementName.split(':')[1] || elementName;\n }\n\n // Extract attributes using ORIGINAL element name length for correct offset\n const tagHeader = xml.substring(openTagStart + 1 + originalElementName.length, tagHeaderEnd);\n const attributes = XMLParser.extractAttributesFromTag(tagHeader, options);\n\n // Check if self-closing\n const isSelfClosing = tagHeader.trim().endsWith('/') || xml[tagHeaderEnd - 1] === '/';\n\n if (isSelfClosing) {\n // Self-closing tag - return object with attributes only\n const elementValue: ParsedXMLObject = { ...attributes };\n return {\n value: { [elementName]: elementValue },\n endPos: tagHeaderEnd + 1,\n };\n }\n\n // Find closing tag (use original name with namespace for correct matching)\n const closingTag = `</${originalElementName}>`;\n const contentStart = tagHeaderEnd + 1;\n const closingTagPos = XMLParser.findClosingTag(xml, originalElementName, contentStart);\n\n if (closingTagPos === -1) {\n // No closing tag found - treat as self-closing\n return {\n value: { [elementName]: { ...attributes } },\n endPos: tagHeaderEnd + 1,\n };\n }\n\n // Extract content between tags\n const content = xml.substring(contentStart, closingTagPos);\n\n // Parse content (children or text)\n const children: ParsedElement[] = [];\n let textContent = '';\n let pos = 0;\n\n while (pos < content.length) {\n const nextTag = content.indexOf('<', pos);\n\n if (nextTag === -1) {\n // No more tags - rest is text\n const text = content.substring(pos);\n // When trimValues is false, preserve whitespace-only text\n // When trimValues is true, only include text that has non-whitespace content\n if (text.length > 0 && (!options.trimValues || text.trim())) {\n // Unescape XML entities in text content (e.g., &lt; -> <)\n textContent += XMLBuilder.unescapeXml(text);\n }\n break;\n }\n\n // Collect text before next tag\n if (nextTag > pos) {\n const text = content.substring(pos, nextTag);\n // When trimValues is false, preserve whitespace-only text\n // When trimValues is true, only include text that has non-whitespace content\n if (text.length > 0 && (!options.trimValues || text.trim())) {\n // Unescape XML entities in text content (e.g., &lt; -> <)\n textContent += XMLBuilder.unescapeXml(text);\n }\n }\n\n // Parse child element (increment depth for children)\n const childResult = XMLParser.parseElementToObject(content, nextTag, options, depth + 1);\n const childObj = childResult.value as ParsedXMLObject;\n\n // Extract child name and value\n const childKeys = Object.keys(childObj);\n if (childKeys.length > 0) {\n const childName = childKeys[0];\n if (childName) {\n const childValue = childObj[childName];\n children.push({ name: childName, value: childValue });\n }\n }\n\n pos = childResult.endPos;\n }\n\n // Build element value\n let elementValue: ParsedXMLValue = {};\n\n // Add attributes\n if (!options.ignoreAttributes && Object.keys(attributes).length > 0) {\n elementValue = { ...attributes };\n }\n\n // Add text content\n // When trimValues is false, include whitespace-only text\n // When trimValues is true, only include text with non-whitespace content\n if (textContent.length > 0 && (!options.trimValues || textContent.trim())) {\n const text = options.trimValues ? textContent.trim() : textContent;\n if (typeof elementValue === 'object' && !Array.isArray(elementValue)) {\n if (Object.keys(elementValue).length === 0) {\n // Only text, no attributes - return as direct value if simple\n elementValue = text;\n } else {\n // Text with attributes\n elementValue[options.textNodeName] = text;\n }\n }\n }\n\n // Add children\n if (children.length > 0) {\n const coalescedChildren = XMLParser.coalesceChildren(children, options);\n if (typeof elementValue === 'object' && !Array.isArray(elementValue)) {\n elementValue = { ...elementValue, ...coalescedChildren };\n } else {\n elementValue = coalescedChildren;\n }\n }\n\n // If element has no content, attributes, or children - return empty object\n if (\n typeof elementValue === 'object' &&\n !Array.isArray(elementValue) &&\n Object.keys(elementValue).length === 0\n ) {\n elementValue = {};\n }\n\n return {\n value: { [elementName]: elementValue },\n endPos: closingTagPos + closingTag.length,\n };\n }\n\n /**\n * Extracts attributes from a tag header\n * @private\n */\n private static extractAttributesFromTag(\n tagHeader: string,\n options: Required<ParseToObjectOptions>\n ): Record<string, string | number | boolean> {\n const attributes: Record<string, string | number | boolean> = {};\n\n if (options.ignoreAttributes) {\n return attributes;\n }\n\n // Simple attribute extraction using position-based parsing\n let pos = 0;\n while (pos < tagHeader.length) {\n // Skip whitespace\n while (pos < tagHeader.length) {\n const char = tagHeader[pos];\n if (char && /\\s/.test(char)) {\n pos++;\n } else {\n break;\n }\n }\n\n if (pos >= tagHeader.length || tagHeader[pos] === '/') {\n break;\n }\n\n // Extract attribute name\n const nameStart = pos;\n while (pos < tagHeader.length) {\n const char = tagHeader[pos];\n if (char && /[a-zA-Z0-9:_-]/.test(char)) {\n pos++;\n } else {\n break;\n }\n }\n\n if (pos === nameStart) {\n break;\n }\n\n let attrName = tagHeader.substring(nameStart, pos);\n\n // Skip whitespace and '='\n while (pos < tagHeader.length) {\n const char = tagHeader[pos];\n if (char && /[\\s=]/.test(char)) {\n pos++;\n } else {\n break;\n }\n }\n\n // Extract attribute value\n let attrValue = '';\n if (pos < tagHeader.length && (tagHeader[pos] === '\"' || tagHeader[pos] === \"'\")) {\n const quote = tagHeader[pos];\n pos++; // Skip opening quote\n const valueStart = pos;\n\n while (pos < tagHeader.length && tagHeader[pos] !== quote) {\n pos++;\n }\n\n attrValue = tagHeader.substring(valueStart, pos);\n pos++; // Skip closing quote\n }\n\n // Remove namespace from attribute name if requested\n if (options.ignoreNamespace && attrName.includes(':')) {\n attrName = attrName.split(':')[1] || attrName;\n }\n\n // Add prefix to attribute name\n const prefixedName = options.attributeNamePrefix + attrName;\n\n // Parse attribute value\n attributes[prefixedName] = options.parseAttributeValue\n ? XMLParser.parseValue(attrValue)\n : attrValue;\n }\n\n return attributes;\n }\n\n /**\n * Finds the closing tag for an element, handling nesting\n * @private\n */\n private static findClosingTag(xml: string, elementName: string, startPos: number): number {\n const openTag = `<${elementName}`;\n const closeTag = `</${elementName}>`;\n let depth = 1;\n let pos = startPos;\n\n while (depth > 0 && pos < xml.length) {\n const nextClose = xml.indexOf(closeTag, pos);\n\n if (nextClose === -1) {\n return -1; // No closing tag found\n }\n\n // Find the next REAL opening tag (not a prefix match like <w:pPrChange for <w:pPr)\n // Must search for all potential matches and verify each one\n let realOpenPos = -1;\n let searchPos = pos;\n while (searchPos < nextClose) {\n const candidateOpen = xml.indexOf(openTag, searchPos);\n if (candidateOpen === -1 || candidateOpen >= nextClose) {\n break; // No more candidates before the closing tag\n }\n\n const charAfter = xml[candidateOpen + openTag.length];\n if (\n charAfter === '>' ||\n charAfter === ' ' ||\n charAfter === '/' ||\n charAfter === '\\t' ||\n charAfter === '\\n' ||\n charAfter === '\\r'\n ) {\n // This looks like a real opening tag - but check if it's self-closing\n // Self-closing tags like <w:rPr/> should NOT increase depth\n const tagEnd = xml.indexOf('>', candidateOpen);\n if (tagEnd !== -1 && xml[tagEnd - 1] === '/') {\n // Self-closing tag - skip it (don't affect depth)\n searchPos = tagEnd + 1;\n continue;\n }\n // This is a real opening tag (not self-closing)\n realOpenPos = candidateOpen;\n break;\n }\n\n // False positive (e.g., <w:pPrChange when looking for <w:pPr)\n // Keep searching from after this position\n searchPos = candidateOpen + openTag.length;\n }\n\n if (realOpenPos !== -1) {\n // Found a real opening tag before the closing tag - increase depth\n depth++;\n pos = realOpenPos + openTag.length;\n } else {\n // No real opening tag before this closing tag - decrease depth\n depth--;\n if (depth === 0) {\n return nextClose;\n }\n pos = nextClose + closeTag.length;\n }\n }\n\n return -1;\n }\n\n /**\n * Coalesces children with duplicate names into arrays\n * @private\n */\n private static coalesceChildren(\n children: ParsedElement[],\n options: Required<ParseToObjectOptions>\n ): ParsedXMLObject {\n const result: ParsedXMLObject = {};\n const nameCounts: Record<string, number> = {};\n const nameIndices: Record<string, number> = {};\n\n // Track element order for correct run content parsing (tabs, breaks, text)\n // This is critical for preserving the order of mixed content like: text -> tab -> text\n const orderedChildren: { type: string; index: number }[] = [];\n\n // Count occurrences of each child name\n for (const child of children) {\n nameCounts[child.name] = (nameCounts[child.name] || 0) + 1;\n }\n\n // Build result object while tracking order\n for (const child of children) {\n const shouldBeArray = options.alwaysArray || (nameCounts[child.name] || 0) > 1;\n\n // Track element order with its index in the array\n const currentIndex = nameIndices[child.name] || 0;\n orderedChildren.push({ type: child.name, index: currentIndex });\n nameIndices[child.name] = currentIndex + 1;\n\n if (shouldBeArray) {\n if (!result[child.name]) {\n result[child.name] = [];\n }\n (result[child.name] as ParsedXMLValue[]).push(child.value);\n } else {\n result[child.name] = child.value;\n }\n }\n\n // Add _orderedChildren to track element order (used by DocumentParser for runs)\n if (orderedChildren.length > 0) {\n result._orderedChildren = orderedChildren;\n }\n\n return result;\n }\n\n /**\n * Parses a string value to number or boolean if applicable\n * @private\n */\n private static parseValue(value: string): string | number | boolean {\n if (value === 'true') return true;\n if (value === 'false') return false;\n\n // Preserve 6-character hex color codes (OpenXML standard for colors)\n // This includes \"000000\" (black) which should stay as a string\n if (/^[0-9A-Fa-f]{6}$/.test(value)) {\n return value.toUpperCase(); // Normalize to uppercase per Microsoft convention\n }\n\n // Preserve long digit-only strings (e.g., cnfStyle binary strings like \"100000000000\")\n // These should not be converted to numbers to avoid losing leading zeros\n if (/^\\d{7,}$/.test(value)) {\n return value; // Keep as string for values with 7+ digits\n }\n\n // Try parsing as number\n // 3-character values like \"240\" will be parsed as numbers\n // 6-character hex values are already handled above\n if (/^-?\\d+$/.test(value)) {\n const num = parseInt(value, 10);\n if (!isNaN(num)) return num;\n }\n\n if (/^-?\\d+\\.\\d+$/.test(value)) {\n const num = parseFloat(value);\n if (!isNaN(num)) return num;\n }\n\n // Preserve 3-character hex codes (like \"F0A\") that have letters\n // Pure numeric 3-char values (like \"240\") are already parsed as numbers above\n if (/^[0-9A-Fa-f]{3}$/.test(value) && /[A-Fa-f]/.test(value)) {\n return value.toUpperCase();\n }\n\n return value;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"ZipHandler.d.ts","sourceRoot":"","sources":["../../src/zip/ZipHandler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ZipHandler.d.ts","sourceRoot":"","sources":["../../src/zip/ZipHandler.ts"],"names":[],"mappings":"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"}