@rowsncolumns/toolkit 24.4.1

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 (456) hide show
  1. package/LICENSE.md +100 -0
  2. package/Readme.md +27 -0
  3. package/dist/cjs/autofilter-condition.d.ts +43 -0
  4. package/dist/cjs/autofilter-condition.d.ts.map +1 -0
  5. package/dist/cjs/autofilter-condition.js +155 -0
  6. package/dist/cjs/csv-export.d.ts +49 -0
  7. package/dist/cjs/csv-export.d.ts.map +1 -0
  8. package/dist/cjs/csv-export.js +142 -0
  9. package/dist/cjs/csv-import-worker.d.ts +16 -0
  10. package/dist/cjs/csv-import-worker.d.ts.map +1 -0
  11. package/dist/cjs/csv-import-worker.js +60 -0
  12. package/dist/cjs/csv-import.d.ts +38 -0
  13. package/dist/cjs/csv-import.d.ts.map +1 -0
  14. package/dist/cjs/csv-import.js +166 -0
  15. package/dist/cjs/csv-parser/helpers.d.ts +14 -0
  16. package/dist/cjs/csv-parser/helpers.d.ts.map +1 -0
  17. package/dist/cjs/csv-parser/helpers.js +145 -0
  18. package/dist/cjs/csv-parser/types.d.ts +66 -0
  19. package/dist/cjs/csv-parser/types.d.ts.map +1 -0
  20. package/dist/cjs/csv-parser/types.js +14 -0
  21. package/dist/cjs/csv-parser/worker.d.ts +2 -0
  22. package/dist/cjs/csv-parser/worker.d.ts.map +1 -0
  23. package/dist/cjs/csv-parser/worker.js +200 -0
  24. package/dist/cjs/excel-export.d.ts +11 -0
  25. package/dist/cjs/excel-export.d.ts.map +1 -0
  26. package/dist/cjs/excel-export.js +22 -0
  27. package/dist/cjs/excel-import-session.d.ts +51 -0
  28. package/dist/cjs/excel-import-session.d.ts.map +1 -0
  29. package/dist/cjs/excel-import-session.js +307 -0
  30. package/dist/cjs/excel-import-worker.d.ts +7 -0
  31. package/dist/cjs/excel-import-worker.d.ts.map +1 -0
  32. package/dist/cjs/excel-import-worker.js +119 -0
  33. package/dist/cjs/excel-parser/builtin-numfmts.d.ts +24 -0
  34. package/dist/cjs/excel-parser/builtin-numfmts.d.ts.map +1 -0
  35. package/dist/cjs/excel-parser/builtin-numfmts.js +63 -0
  36. package/dist/cjs/excel-parser/cfb-decryptor.d.ts +53 -0
  37. package/dist/cjs/excel-parser/cfb-decryptor.d.ts.map +1 -0
  38. package/dist/cjs/excel-parser/cfb-decryptor.js +553 -0
  39. package/dist/cjs/excel-parser/cfb-encryptor.d.ts +23 -0
  40. package/dist/cjs/excel-parser/cfb-encryptor.d.ts.map +1 -0
  41. package/dist/cjs/excel-parser/cfb-encryptor.js +200 -0
  42. package/dist/cjs/excel-parser/dv-cell-stamp.d.ts +29 -0
  43. package/dist/cjs/excel-parser/dv-cell-stamp.d.ts.map +1 -0
  44. package/dist/cjs/excel-parser/dv-cell-stamp.js +239 -0
  45. package/dist/cjs/excel-parser/helpers.d.ts +28 -0
  46. package/dist/cjs/excel-parser/helpers.d.ts.map +1 -0
  47. package/dist/cjs/excel-parser/helpers.js +188 -0
  48. package/dist/cjs/excel-parser/interface.d.ts +179 -0
  49. package/dist/cjs/excel-parser/interface.d.ts.map +1 -0
  50. package/dist/cjs/excel-parser/interface.js +1 -0
  51. package/dist/cjs/excel-parser/plugins/base/index.d.ts +31 -0
  52. package/dist/cjs/excel-parser/plugins/base/index.d.ts.map +1 -0
  53. package/dist/cjs/excel-parser/plugins/base/index.js +101 -0
  54. package/dist/cjs/excel-parser/plugins/ods/conditional-formatting.d.ts +16 -0
  55. package/dist/cjs/excel-parser/plugins/ods/conditional-formatting.d.ts.map +1 -0
  56. package/dist/cjs/excel-parser/plugins/ods/conditional-formatting.js +488 -0
  57. package/dist/cjs/excel-parser/plugins/ods/data-validations.d.ts +15 -0
  58. package/dist/cjs/excel-parser/plugins/ods/data-validations.d.ts.map +1 -0
  59. package/dist/cjs/excel-parser/plugins/ods/data-validations.js +353 -0
  60. package/dist/cjs/excel-parser/plugins/ods/formula.d.ts +8 -0
  61. package/dist/cjs/excel-parser/plugins/ods/formula.d.ts.map +1 -0
  62. package/dist/cjs/excel-parser/plugins/ods/formula.js +82 -0
  63. package/dist/cjs/excel-parser/plugins/ods/index.d.ts +122 -0
  64. package/dist/cjs/excel-parser/plugins/ods/index.d.ts.map +1 -0
  65. package/dist/cjs/excel-parser/plugins/ods/index.js +3642 -0
  66. package/dist/cjs/excel-parser/plugins/ods/sparklines.d.ts +25 -0
  67. package/dist/cjs/excel-parser/plugins/ods/sparklines.d.ts.map +1 -0
  68. package/dist/cjs/excel-parser/plugins/ods/sparklines.js +221 -0
  69. package/dist/cjs/excel-parser/plugins/ods/styles.d.ts +60 -0
  70. package/dist/cjs/excel-parser/plugins/ods/styles.d.ts.map +1 -0
  71. package/dist/cjs/excel-parser/plugins/ods/styles.js +808 -0
  72. package/dist/cjs/excel-parser/plugins/ods/types.d.ts +7 -0
  73. package/dist/cjs/excel-parser/plugins/ods/types.d.ts.map +1 -0
  74. package/dist/cjs/excel-parser/plugins/ods/types.js +1 -0
  75. package/dist/cjs/excel-parser/plugins/xls/index.d.ts +5 -0
  76. package/dist/cjs/excel-parser/plugins/xls/index.d.ts.map +1 -0
  77. package/dist/cjs/excel-parser/plugins/xls/index.js +19 -0
  78. package/dist/cjs/excel-parser/plugins/xlsb/biff-record-reader.d.ts +13 -0
  79. package/dist/cjs/excel-parser/plugins/xlsb/biff-record-reader.d.ts.map +1 -0
  80. package/dist/cjs/excel-parser/plugins/xlsb/biff-record-reader.js +49 -0
  81. package/dist/cjs/excel-parser/plugins/xlsb/index.d.ts +117 -0
  82. package/dist/cjs/excel-parser/plugins/xlsb/index.d.ts.map +1 -0
  83. package/dist/cjs/excel-parser/plugins/xlsb/index.js +2972 -0
  84. package/dist/cjs/excel-parser/plugins/xlsb/rgce-parser.d.ts +18 -0
  85. package/dist/cjs/excel-parser/plugins/xlsb/rgce-parser.d.ts.map +1 -0
  86. package/dist/cjs/excel-parser/plugins/xlsb/rgce-parser.js +527 -0
  87. package/dist/cjs/excel-parser/plugins/xlsm/index.d.ts +5 -0
  88. package/dist/cjs/excel-parser/plugins/xlsm/index.d.ts.map +1 -0
  89. package/dist/cjs/excel-parser/plugins/xlsm/index.js +10 -0
  90. package/dist/cjs/excel-parser/plugins/xlsx/charts.d.ts +60 -0
  91. package/dist/cjs/excel-parser/plugins/xlsx/charts.d.ts.map +1 -0
  92. package/dist/cjs/excel-parser/plugins/xlsx/charts.js +2178 -0
  93. package/dist/cjs/excel-parser/plugins/xlsx/conditional-formatting.d.ts +18 -0
  94. package/dist/cjs/excel-parser/plugins/xlsx/conditional-formatting.d.ts.map +1 -0
  95. package/dist/cjs/excel-parser/plugins/xlsx/conditional-formatting.js +620 -0
  96. package/dist/cjs/excel-parser/plugins/xlsx/data-validations.d.ts +4 -0
  97. package/dist/cjs/excel-parser/plugins/xlsx/data-validations.d.ts.map +1 -0
  98. package/dist/cjs/excel-parser/plugins/xlsx/data-validations.js +515 -0
  99. package/dist/cjs/excel-parser/plugins/xlsx/drawing.d.ts +39 -0
  100. package/dist/cjs/excel-parser/plugins/xlsx/drawing.d.ts.map +1 -0
  101. package/dist/cjs/excel-parser/plugins/xlsx/drawing.js +941 -0
  102. package/dist/cjs/excel-parser/plugins/xlsx/index.d.ts +320 -0
  103. package/dist/cjs/excel-parser/plugins/xlsx/index.d.ts.map +1 -0
  104. package/dist/cjs/excel-parser/plugins/xlsx/index.js +6056 -0
  105. package/dist/cjs/excel-parser/plugins/xlsx/numfmt.d.ts +2 -0
  106. package/dist/cjs/excel-parser/plugins/xlsx/numfmt.d.ts.map +1 -0
  107. package/dist/cjs/excel-parser/plugins/xlsx/numfmt.js +3 -0
  108. package/dist/cjs/excel-parser/plugins/xlsx/pivots.d.ts +40 -0
  109. package/dist/cjs/excel-parser/plugins/xlsx/pivots.d.ts.map +1 -0
  110. package/dist/cjs/excel-parser/plugins/xlsx/pivots.js +342 -0
  111. package/dist/cjs/excel-parser/plugins/xlsx/relationships.d.ts +8 -0
  112. package/dist/cjs/excel-parser/plugins/xlsx/relationships.d.ts.map +1 -0
  113. package/dist/cjs/excel-parser/plugins/xlsx/relationships.js +26 -0
  114. package/dist/cjs/excel-parser/plugins/xlsx/sheet-views.d.ts +26 -0
  115. package/dist/cjs/excel-parser/plugins/xlsx/sheet-views.d.ts.map +1 -0
  116. package/dist/cjs/excel-parser/plugins/xlsx/sheet-views.js +59 -0
  117. package/dist/cjs/excel-parser/plugins/xlsx/styles.d.ts +44 -0
  118. package/dist/cjs/excel-parser/plugins/xlsx/styles.d.ts.map +1 -0
  119. package/dist/cjs/excel-parser/plugins/xlsx/styles.js +1377 -0
  120. package/dist/cjs/excel-parser/plugins/xlsx/theme.d.ts +50 -0
  121. package/dist/cjs/excel-parser/plugins/xlsx/theme.d.ts.map +1 -0
  122. package/dist/cjs/excel-parser/plugins/xlsx/theme.js +150 -0
  123. package/dist/cjs/excel-parser/plugins/xlsx/threaded-comments.d.ts +47 -0
  124. package/dist/cjs/excel-parser/plugins/xlsx/threaded-comments.d.ts.map +1 -0
  125. package/dist/cjs/excel-parser/plugins/xlsx/threaded-comments.js +141 -0
  126. package/dist/cjs/excel-parser/plugins/xlsx/value-type-detection.d.ts +44 -0
  127. package/dist/cjs/excel-parser/plugins/xlsx/value-type-detection.d.ts.map +1 -0
  128. package/dist/cjs/excel-parser/plugins/xlsx/value-type-detection.js +407 -0
  129. package/dist/cjs/excel-parser/registry.d.ts +5 -0
  130. package/dist/cjs/excel-parser/registry.d.ts.map +1 -0
  131. package/dist/cjs/excel-parser/registry.js +21 -0
  132. package/dist/cjs/excel-parser/style-registry.d.ts +51 -0
  133. package/dist/cjs/excel-parser/style-registry.d.ts.map +1 -0
  134. package/dist/cjs/excel-parser/style-registry.js +175 -0
  135. package/dist/cjs/excel-parser/theme-default.d.ts +3 -0
  136. package/dist/cjs/excel-parser/theme-default.d.ts.map +1 -0
  137. package/dist/cjs/excel-parser/theme-default.js +19 -0
  138. package/dist/cjs/excel-parser/types.d.ts +365 -0
  139. package/dist/cjs/excel-parser/types.d.ts.map +1 -0
  140. package/dist/cjs/excel-parser/types.js +59 -0
  141. package/dist/cjs/excel-parser/utils.d.ts +6 -0
  142. package/dist/cjs/excel-parser/utils.d.ts.map +1 -0
  143. package/dist/cjs/excel-parser/utils.js +30 -0
  144. package/dist/cjs/excel-parser/workbook.d.ts +51 -0
  145. package/dist/cjs/excel-parser/workbook.d.ts.map +1 -0
  146. package/dist/cjs/excel-parser/workbook.js +317 -0
  147. package/dist/cjs/excel-parser/worker.d.ts +2 -0
  148. package/dist/cjs/excel-parser/worker.d.ts.map +1 -0
  149. package/dist/cjs/excel-parser/worker.js +1149 -0
  150. package/dist/cjs/excel-parser/zip-parser-streaming.d.ts +13 -0
  151. package/dist/cjs/excel-parser/zip-parser-streaming.d.ts.map +1 -0
  152. package/dist/cjs/excel-parser/zip-parser-streaming.js +200 -0
  153. package/dist/cjs/excel-parser/zip-parser.d.ts +11 -0
  154. package/dist/cjs/excel-parser/zip-parser.d.ts.map +1 -0
  155. package/dist/cjs/excel-parser/zip-parser.js +49 -0
  156. package/dist/cjs/exporter/invalid-data-validation.d.ts +19 -0
  157. package/dist/cjs/exporter/invalid-data-validation.d.ts.map +1 -0
  158. package/dist/cjs/exporter/invalid-data-validation.js +39 -0
  159. package/dist/cjs/exporter/ods/ods-export.d.ts +26 -0
  160. package/dist/cjs/exporter/ods/ods-export.d.ts.map +1 -0
  161. package/dist/cjs/exporter/ods/ods-export.js +3714 -0
  162. package/dist/cjs/exporter/ods/sparkline-builder.d.ts +33 -0
  163. package/dist/cjs/exporter/ods/sparkline-builder.d.ts.map +1 -0
  164. package/dist/cjs/exporter/ods/sparkline-builder.js +221 -0
  165. package/dist/cjs/exporter/xlsx/chart-builder.d.ts +3 -0
  166. package/dist/cjs/exporter/xlsx/chart-builder.d.ts.map +1 -0
  167. package/dist/cjs/exporter/xlsx/chart-builder.js +1901 -0
  168. package/dist/cjs/exporter/xlsx/chart-templates.d.ts +1781 -0
  169. package/dist/cjs/exporter/xlsx/chart-templates.d.ts.map +1 -0
  170. package/dist/cjs/exporter/xlsx/chart-templates.js +1798 -0
  171. package/dist/cjs/exporter/xlsx/future-functions.d.ts +10 -0
  172. package/dist/cjs/exporter/xlsx/future-functions.d.ts.map +1 -0
  173. package/dist/cjs/exporter/xlsx/future-functions.js +264 -0
  174. package/dist/cjs/exporter/xlsx/pivot-builder.d.ts +58 -0
  175. package/dist/cjs/exporter/xlsx/pivot-builder.d.ts.map +1 -0
  176. package/dist/cjs/exporter/xlsx/pivot-builder.js +277 -0
  177. package/dist/cjs/exporter/xlsx/power-query-builder.d.ts +26 -0
  178. package/dist/cjs/exporter/xlsx/power-query-builder.d.ts.map +1 -0
  179. package/dist/cjs/exporter/xlsx/power-query-builder.js +306 -0
  180. package/dist/cjs/exporter/xlsx/slicer-builder.d.ts +11 -0
  181. package/dist/cjs/exporter/xlsx/slicer-builder.d.ts.map +1 -0
  182. package/dist/cjs/exporter/xlsx/slicer-builder.js +87 -0
  183. package/dist/cjs/exporter/xlsx/sparkline-builder.d.ts +61 -0
  184. package/dist/cjs/exporter/xlsx/sparkline-builder.d.ts.map +1 -0
  185. package/dist/cjs/exporter/xlsx/sparkline-builder.js +489 -0
  186. package/dist/cjs/exporter/xlsx/style-builder.d.ts +93 -0
  187. package/dist/cjs/exporter/xlsx/style-builder.d.ts.map +1 -0
  188. package/dist/cjs/exporter/xlsx/style-builder.js +813 -0
  189. package/dist/cjs/exporter/xlsx/threaded-comments-builder.d.ts +58 -0
  190. package/dist/cjs/exporter/xlsx/threaded-comments-builder.d.ts.map +1 -0
  191. package/dist/cjs/exporter/xlsx/threaded-comments-builder.js +189 -0
  192. package/dist/cjs/exporter/xlsx/xlsx-export.d.ts +121 -0
  193. package/dist/cjs/exporter/xlsx/xlsx-export.d.ts.map +1 -0
  194. package/dist/cjs/exporter/xlsx/xlsx-export.js +4596 -0
  195. package/dist/cjs/helpers/theme-xml-generator.d.ts +8 -0
  196. package/dist/cjs/helpers/theme-xml-generator.d.ts.map +1 -0
  197. package/dist/cjs/helpers/theme-xml-generator.js +33 -0
  198. package/dist/cjs/helpers.d.ts +34 -0
  199. package/dist/cjs/helpers.d.ts.map +1 -0
  200. package/dist/cjs/helpers.js +189 -0
  201. package/dist/cjs/index.d.ts +16 -0
  202. package/dist/cjs/index.d.ts.map +1 -0
  203. package/dist/cjs/index.js +15 -0
  204. package/dist/cjs/indexed-colors.d.ts +2 -0
  205. package/dist/cjs/indexed-colors.d.ts.map +1 -0
  206. package/dist/cjs/indexed-colors.js +75 -0
  207. package/dist/cjs/ods-export.d.ts +24 -0
  208. package/dist/cjs/ods-export.d.ts.map +1 -0
  209. package/dist/cjs/ods-export.js +23 -0
  210. package/dist/cjs/parse.d.ts +24 -0
  211. package/dist/cjs/parse.d.ts.map +1 -0
  212. package/dist/cjs/parse.js +68 -0
  213. package/dist/cjs/power-query.d.ts +41 -0
  214. package/dist/cjs/power-query.d.ts.map +1 -0
  215. package/dist/cjs/power-query.js +22 -0
  216. package/dist/cjs/server.d.ts +9 -0
  217. package/dist/cjs/server.d.ts.map +1 -0
  218. package/dist/cjs/server.js +8 -0
  219. package/dist/cjs/theme1.d.ts +3 -0
  220. package/dist/cjs/theme1.d.ts.map +1 -0
  221. package/dist/cjs/theme1.js +2 -0
  222. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -0
  223. package/dist/cjs/types.d.ts +14 -0
  224. package/dist/cjs/types.d.ts.map +1 -0
  225. package/dist/cjs/types.js +14 -0
  226. package/dist/cjs/vitest.config.d.ts +3 -0
  227. package/dist/cjs/vitest.config.d.ts.map +1 -0
  228. package/dist/cjs/vitest.config.js +16 -0
  229. package/dist/esm/autofilter-condition.d.ts +43 -0
  230. package/dist/esm/autofilter-condition.d.ts.map +1 -0
  231. package/dist/esm/autofilter-condition.js +145 -0
  232. package/dist/esm/csv-export.d.ts +49 -0
  233. package/dist/esm/csv-export.d.ts.map +1 -0
  234. package/dist/esm/csv-export.js +126 -0
  235. package/dist/esm/csv-import-worker.d.ts +16 -0
  236. package/dist/esm/csv-import-worker.d.ts.map +1 -0
  237. package/dist/esm/csv-import-worker.js +60 -0
  238. package/dist/esm/csv-import.d.ts +38 -0
  239. package/dist/esm/csv-import.d.ts.map +1 -0
  240. package/dist/esm/csv-import.js +132 -0
  241. package/dist/esm/csv-parser/helpers.d.ts +14 -0
  242. package/dist/esm/csv-parser/helpers.d.ts.map +1 -0
  243. package/dist/esm/csv-parser/helpers.js +0 -0
  244. package/dist/esm/csv-parser/types.d.ts +66 -0
  245. package/dist/esm/csv-parser/types.d.ts.map +1 -0
  246. package/dist/esm/csv-parser/types.js +14 -0
  247. package/dist/esm/csv-parser/worker.d.ts +2 -0
  248. package/dist/esm/csv-parser/worker.d.ts.map +1 -0
  249. package/dist/esm/csv-parser/worker.js +154 -0
  250. package/dist/esm/excel-export.d.ts +11 -0
  251. package/dist/esm/excel-export.d.ts.map +1 -0
  252. package/dist/esm/excel-export.js +13 -0
  253. package/dist/esm/excel-import-session.d.ts +51 -0
  254. package/dist/esm/excel-import-session.d.ts.map +1 -0
  255. package/dist/esm/excel-import-session.js +255 -0
  256. package/dist/esm/excel-import-worker.d.ts +7 -0
  257. package/dist/esm/excel-import-worker.d.ts.map +1 -0
  258. package/dist/esm/excel-import-worker.js +116 -0
  259. package/dist/esm/excel-parser/builtin-numfmts.d.ts +24 -0
  260. package/dist/esm/excel-parser/builtin-numfmts.d.ts.map +1 -0
  261. package/dist/esm/excel-parser/builtin-numfmts.js +59 -0
  262. package/dist/esm/excel-parser/cfb-decryptor.d.ts +53 -0
  263. package/dist/esm/excel-parser/cfb-decryptor.d.ts.map +1 -0
  264. package/dist/esm/excel-parser/cfb-decryptor.js +493 -0
  265. package/dist/esm/excel-parser/cfb-encryptor.d.ts +23 -0
  266. package/dist/esm/excel-parser/cfb-encryptor.d.ts.map +1 -0
  267. package/dist/esm/excel-parser/cfb-encryptor.js +181 -0
  268. package/dist/esm/excel-parser/dv-cell-stamp.d.ts +29 -0
  269. package/dist/esm/excel-parser/dv-cell-stamp.d.ts.map +1 -0
  270. package/dist/esm/excel-parser/dv-cell-stamp.js +155 -0
  271. package/dist/esm/excel-parser/helpers.d.ts +28 -0
  272. package/dist/esm/excel-parser/helpers.d.ts.map +1 -0
  273. package/dist/esm/excel-parser/helpers.js +160 -0
  274. package/dist/esm/excel-parser/interface.d.ts +179 -0
  275. package/dist/esm/excel-parser/interface.d.ts.map +1 -0
  276. package/dist/esm/excel-parser/interface.js +1 -0
  277. package/dist/esm/excel-parser/plugins/base/index.d.ts +31 -0
  278. package/dist/esm/excel-parser/plugins/base/index.d.ts.map +1 -0
  279. package/dist/esm/excel-parser/plugins/base/index.js +64 -0
  280. package/dist/esm/excel-parser/plugins/ods/conditional-formatting.d.ts +16 -0
  281. package/dist/esm/excel-parser/plugins/ods/conditional-formatting.d.ts.map +1 -0
  282. package/dist/esm/excel-parser/plugins/ods/conditional-formatting.js +405 -0
  283. package/dist/esm/excel-parser/plugins/ods/data-validations.d.ts +15 -0
  284. package/dist/esm/excel-parser/plugins/ods/data-validations.d.ts.map +1 -0
  285. package/dist/esm/excel-parser/plugins/ods/data-validations.js +331 -0
  286. package/dist/esm/excel-parser/plugins/ods/formula.d.ts +8 -0
  287. package/dist/esm/excel-parser/plugins/ods/formula.d.ts.map +1 -0
  288. package/dist/esm/excel-parser/plugins/ods/formula.js +82 -0
  289. package/dist/esm/excel-parser/plugins/ods/index.d.ts +122 -0
  290. package/dist/esm/excel-parser/plugins/ods/index.d.ts.map +1 -0
  291. package/dist/esm/excel-parser/plugins/ods/index.js +2896 -0
  292. package/dist/esm/excel-parser/plugins/ods/sparklines.d.ts +25 -0
  293. package/dist/esm/excel-parser/plugins/ods/sparklines.d.ts.map +1 -0
  294. package/dist/esm/excel-parser/plugins/ods/sparklines.js +188 -0
  295. package/dist/esm/excel-parser/plugins/ods/styles.d.ts +60 -0
  296. package/dist/esm/excel-parser/plugins/ods/styles.d.ts.map +1 -0
  297. package/dist/esm/excel-parser/plugins/ods/styles.js +732 -0
  298. package/dist/esm/excel-parser/plugins/ods/types.d.ts +7 -0
  299. package/dist/esm/excel-parser/plugins/ods/types.d.ts.map +1 -0
  300. package/dist/esm/excel-parser/plugins/ods/types.js +1 -0
  301. package/dist/esm/excel-parser/plugins/xls/index.d.ts +5 -0
  302. package/dist/esm/excel-parser/plugins/xls/index.d.ts.map +1 -0
  303. package/dist/esm/excel-parser/plugins/xls/index.js +7 -0
  304. package/dist/esm/excel-parser/plugins/xlsb/biff-record-reader.d.ts +13 -0
  305. package/dist/esm/excel-parser/plugins/xlsb/biff-record-reader.d.ts.map +1 -0
  306. package/dist/esm/excel-parser/plugins/xlsb/biff-record-reader.js +48 -0
  307. package/dist/esm/excel-parser/plugins/xlsb/index.d.ts +117 -0
  308. package/dist/esm/excel-parser/plugins/xlsb/index.d.ts.map +1 -0
  309. package/dist/esm/excel-parser/plugins/xlsb/index.js +2339 -0
  310. package/dist/esm/excel-parser/plugins/xlsb/rgce-parser.d.ts +18 -0
  311. package/dist/esm/excel-parser/plugins/xlsb/rgce-parser.d.ts.map +1 -0
  312. package/dist/esm/excel-parser/plugins/xlsb/rgce-parser.js +522 -0
  313. package/dist/esm/excel-parser/plugins/xlsm/index.d.ts +5 -0
  314. package/dist/esm/excel-parser/plugins/xlsm/index.d.ts.map +1 -0
  315. package/dist/esm/excel-parser/plugins/xlsm/index.js +6 -0
  316. package/dist/esm/excel-parser/plugins/xlsx/charts.d.ts +60 -0
  317. package/dist/esm/excel-parser/plugins/xlsx/charts.d.ts.map +1 -0
  318. package/dist/esm/excel-parser/plugins/xlsx/charts.js +2036 -0
  319. package/dist/esm/excel-parser/plugins/xlsx/conditional-formatting.d.ts +18 -0
  320. package/dist/esm/excel-parser/plugins/xlsx/conditional-formatting.d.ts.map +1 -0
  321. package/dist/esm/excel-parser/plugins/xlsx/conditional-formatting.js +621 -0
  322. package/dist/esm/excel-parser/plugins/xlsx/data-validations.d.ts +4 -0
  323. package/dist/esm/excel-parser/plugins/xlsx/data-validations.d.ts.map +1 -0
  324. package/dist/esm/excel-parser/plugins/xlsx/data-validations.js +493 -0
  325. package/dist/esm/excel-parser/plugins/xlsx/drawing.d.ts +39 -0
  326. package/dist/esm/excel-parser/plugins/xlsx/drawing.d.ts.map +1 -0
  327. package/dist/esm/excel-parser/plugins/xlsx/drawing.js +905 -0
  328. package/dist/esm/excel-parser/plugins/xlsx/index.d.ts +320 -0
  329. package/dist/esm/excel-parser/plugins/xlsx/index.d.ts.map +1 -0
  330. package/dist/esm/excel-parser/plugins/xlsx/index.js +4654 -0
  331. package/dist/esm/excel-parser/plugins/xlsx/numfmt.d.ts +2 -0
  332. package/dist/esm/excel-parser/plugins/xlsx/numfmt.d.ts.map +1 -0
  333. package/dist/esm/excel-parser/plugins/xlsx/numfmt.js +3 -0
  334. package/dist/esm/excel-parser/plugins/xlsx/pivots.d.ts +40 -0
  335. package/dist/esm/excel-parser/plugins/xlsx/pivots.d.ts.map +1 -0
  336. package/dist/esm/excel-parser/plugins/xlsx/pivots.js +254 -0
  337. package/dist/esm/excel-parser/plugins/xlsx/relationships.d.ts +8 -0
  338. package/dist/esm/excel-parser/plugins/xlsx/relationships.d.ts.map +1 -0
  339. package/dist/esm/excel-parser/plugins/xlsx/relationships.js +13 -0
  340. package/dist/esm/excel-parser/plugins/xlsx/sheet-views.d.ts +26 -0
  341. package/dist/esm/excel-parser/plugins/xlsx/sheet-views.d.ts.map +1 -0
  342. package/dist/esm/excel-parser/plugins/xlsx/sheet-views.js +64 -0
  343. package/dist/esm/excel-parser/plugins/xlsx/styles.d.ts +44 -0
  344. package/dist/esm/excel-parser/plugins/xlsx/styles.d.ts.map +1 -0
  345. package/dist/esm/excel-parser/plugins/xlsx/styles.js +1365 -0
  346. package/dist/esm/excel-parser/plugins/xlsx/theme.d.ts +50 -0
  347. package/dist/esm/excel-parser/plugins/xlsx/theme.d.ts.map +1 -0
  348. package/dist/esm/excel-parser/plugins/xlsx/theme.js +127 -0
  349. package/dist/esm/excel-parser/plugins/xlsx/threaded-comments.d.ts +47 -0
  350. package/dist/esm/excel-parser/plugins/xlsx/threaded-comments.d.ts.map +1 -0
  351. package/dist/esm/excel-parser/plugins/xlsx/threaded-comments.js +103 -0
  352. package/dist/esm/excel-parser/plugins/xlsx/value-type-detection.d.ts +44 -0
  353. package/dist/esm/excel-parser/plugins/xlsx/value-type-detection.d.ts.map +1 -0
  354. package/dist/esm/excel-parser/plugins/xlsx/value-type-detection.js +399 -0
  355. package/dist/esm/excel-parser/registry.d.ts +5 -0
  356. package/dist/esm/excel-parser/registry.d.ts.map +1 -0
  357. package/dist/esm/excel-parser/registry.js +20 -0
  358. package/dist/esm/excel-parser/style-registry.d.ts +51 -0
  359. package/dist/esm/excel-parser/style-registry.d.ts.map +1 -0
  360. package/dist/esm/excel-parser/style-registry.js +163 -0
  361. package/dist/esm/excel-parser/theme-default.d.ts +3 -0
  362. package/dist/esm/excel-parser/theme-default.d.ts.map +1 -0
  363. package/dist/esm/excel-parser/theme-default.js +19 -0
  364. package/dist/esm/excel-parser/types.d.ts +365 -0
  365. package/dist/esm/excel-parser/types.d.ts.map +1 -0
  366. package/dist/esm/excel-parser/types.js +59 -0
  367. package/dist/esm/excel-parser/utils.d.ts +6 -0
  368. package/dist/esm/excel-parser/utils.d.ts.map +1 -0
  369. package/dist/esm/excel-parser/utils.js +25 -0
  370. package/dist/esm/excel-parser/workbook.d.ts +51 -0
  371. package/dist/esm/excel-parser/workbook.d.ts.map +1 -0
  372. package/dist/esm/excel-parser/workbook.js +192 -0
  373. package/dist/esm/excel-parser/worker.d.ts +2 -0
  374. package/dist/esm/excel-parser/worker.d.ts.map +1 -0
  375. package/dist/esm/excel-parser/worker.js +862 -0
  376. package/dist/esm/excel-parser/zip-parser-streaming.d.ts +13 -0
  377. package/dist/esm/excel-parser/zip-parser-streaming.d.ts.map +1 -0
  378. package/dist/esm/excel-parser/zip-parser-streaming.js +119 -0
  379. package/dist/esm/excel-parser/zip-parser.d.ts +11 -0
  380. package/dist/esm/excel-parser/zip-parser.d.ts.map +1 -0
  381. package/dist/esm/excel-parser/zip-parser.js +43 -0
  382. package/dist/esm/exporter/invalid-data-validation.d.ts +19 -0
  383. package/dist/esm/exporter/invalid-data-validation.d.ts.map +1 -0
  384. package/dist/esm/exporter/invalid-data-validation.js +37 -0
  385. package/dist/esm/exporter/ods/ods-export.d.ts +26 -0
  386. package/dist/esm/exporter/ods/ods-export.d.ts.map +1 -0
  387. package/dist/esm/exporter/ods/ods-export.js +3238 -0
  388. package/dist/esm/exporter/ods/sparkline-builder.d.ts +33 -0
  389. package/dist/esm/exporter/ods/sparkline-builder.d.ts.map +1 -0
  390. package/dist/esm/exporter/ods/sparkline-builder.js +165 -0
  391. package/dist/esm/exporter/xlsx/chart-builder.d.ts +3 -0
  392. package/dist/esm/exporter/xlsx/chart-builder.d.ts.map +1 -0
  393. package/dist/esm/exporter/xlsx/chart-builder.js +1805 -0
  394. package/dist/esm/exporter/xlsx/chart-templates.d.ts +1781 -0
  395. package/dist/esm/exporter/xlsx/chart-templates.d.ts.map +1 -0
  396. package/dist/esm/exporter/xlsx/chart-templates.js +1798 -0
  397. package/dist/esm/exporter/xlsx/future-functions.d.ts +10 -0
  398. package/dist/esm/exporter/xlsx/future-functions.d.ts.map +1 -0
  399. package/dist/esm/exporter/xlsx/future-functions.js +264 -0
  400. package/dist/esm/exporter/xlsx/pivot-builder.d.ts +58 -0
  401. package/dist/esm/exporter/xlsx/pivot-builder.d.ts.map +1 -0
  402. package/dist/esm/exporter/xlsx/pivot-builder.js +230 -0
  403. package/dist/esm/exporter/xlsx/power-query-builder.d.ts +26 -0
  404. package/dist/esm/exporter/xlsx/power-query-builder.d.ts.map +1 -0
  405. package/dist/esm/exporter/xlsx/power-query-builder.js +257 -0
  406. package/dist/esm/exporter/xlsx/slicer-builder.d.ts +11 -0
  407. package/dist/esm/exporter/xlsx/slicer-builder.d.ts.map +1 -0
  408. package/dist/esm/exporter/xlsx/slicer-builder.js +84 -0
  409. package/dist/esm/exporter/xlsx/sparkline-builder.d.ts +61 -0
  410. package/dist/esm/exporter/xlsx/sparkline-builder.d.ts.map +1 -0
  411. package/dist/esm/exporter/xlsx/sparkline-builder.js +437 -0
  412. package/dist/esm/exporter/xlsx/style-builder.d.ts +93 -0
  413. package/dist/esm/exporter/xlsx/style-builder.d.ts.map +1 -0
  414. package/dist/esm/exporter/xlsx/style-builder.js +795 -0
  415. package/dist/esm/exporter/xlsx/threaded-comments-builder.d.ts +58 -0
  416. package/dist/esm/exporter/xlsx/threaded-comments-builder.d.ts.map +1 -0
  417. package/dist/esm/exporter/xlsx/threaded-comments-builder.js +175 -0
  418. package/dist/esm/exporter/xlsx/xlsx-export.d.ts +121 -0
  419. package/dist/esm/exporter/xlsx/xlsx-export.d.ts.map +1 -0
  420. package/dist/esm/exporter/xlsx/xlsx-export.js +4062 -0
  421. package/dist/esm/helpers/theme-xml-generator.d.ts +8 -0
  422. package/dist/esm/helpers/theme-xml-generator.d.ts.map +1 -0
  423. package/dist/esm/helpers/theme-xml-generator.js +33 -0
  424. package/dist/esm/helpers.d.ts +34 -0
  425. package/dist/esm/helpers.d.ts.map +1 -0
  426. package/dist/esm/helpers.js +182 -0
  427. package/dist/esm/index.d.ts +16 -0
  428. package/dist/esm/index.d.ts.map +1 -0
  429. package/dist/esm/index.js +15 -0
  430. package/dist/esm/indexed-colors.d.ts +2 -0
  431. package/dist/esm/indexed-colors.d.ts.map +1 -0
  432. package/dist/esm/indexed-colors.js +75 -0
  433. package/dist/esm/ods-export.d.ts +24 -0
  434. package/dist/esm/ods-export.d.ts.map +1 -0
  435. package/dist/esm/ods-export.js +12 -0
  436. package/dist/esm/parse.d.ts +24 -0
  437. package/dist/esm/parse.d.ts.map +1 -0
  438. package/dist/esm/parse.js +55 -0
  439. package/dist/esm/power-query.d.ts +41 -0
  440. package/dist/esm/power-query.d.ts.map +1 -0
  441. package/dist/esm/power-query.js +19 -0
  442. package/dist/esm/server.d.ts +9 -0
  443. package/dist/esm/server.d.ts.map +1 -0
  444. package/dist/esm/server.js +8 -0
  445. package/dist/esm/theme1.d.ts +3 -0
  446. package/dist/esm/theme1.d.ts.map +1 -0
  447. package/dist/esm/theme1.js +2 -0
  448. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -0
  449. package/dist/esm/types.d.ts +14 -0
  450. package/dist/esm/types.d.ts.map +1 -0
  451. package/dist/esm/types.js +14 -0
  452. package/dist/esm/vitest.config.d.ts +3 -0
  453. package/dist/esm/vitest.config.d.ts.map +1 -0
  454. package/dist/esm/vitest.config.js +16 -0
  455. package/package.json +62 -0
  456. package/xlsx.d.ts +52 -0
@@ -0,0 +1,1901 @@
1
+ import { __assign, __read, __spreadArray, __values } from "tslib";
2
+ import { cellRangeToAddress, sanitizeSheetName } from "@rowsncolumns/utils";
3
+ import { XMLBuilder } from "fast-xml-parser";
4
+ import { area_series, bubble_series, chart_template, column_json, column_series, donut_json, line_series, scatter_json, scatter_series, static_title, } from "./chart-templates";
5
+ var XML_DECLARATION = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
6
+ var INVALID_XML_CHAR_REGEX = /[\u0000-\u0008\u000B\u000C\u000E-\u001F]/g;
7
+ var chartBuilder = new XMLBuilder({
8
+ ignoreAttributes: false,
9
+ attributesGroupName: "a$",
10
+ textNodeName: "t$",
11
+ suppressEmptyNode: true,
12
+ });
13
+ var sanitizeXmlText = function (value) {
14
+ return value ? value.replace(INVALID_XML_CHAR_REGEX, "") : value;
15
+ };
16
+ var cloneTemplate = function (template) {
17
+ return JSON.parse(JSON.stringify(template));
18
+ };
19
+ var removeProp = function (obj, key) {
20
+ delete obj[key];
21
+ };
22
+ var normalizeFormula = function (formula) {
23
+ var trimmed = formula.startsWith("=") ? formula.slice(1) : formula;
24
+ return sanitizeXmlText(trimmed).replace(/\r\n|\r|\n/g, " ");
25
+ };
26
+ var hasPropertyReference = function (formula) {
27
+ if (!formula)
28
+ return false;
29
+ // Detects cell references with property access: A1.property, $A$1.nested.value, etc.
30
+ var propertyReferencePattern = /[$]?[A-Za-z]{1,3}[$]?[1-9][0-9]*\./;
31
+ return propertyReferencePattern.test(formula);
32
+ };
33
+ var formatRangeRef = function (range, sheetNameById) {
34
+ if (!range)
35
+ return undefined;
36
+ var sheetName = sheetNameById.get(range.sheetId);
37
+ return cellRangeToAddress(sheetName, range);
38
+ };
39
+ /**
40
+ * A1 reference over EVERY range of a (possibly multi-area) source list,
41
+ * joined with the union operator — `'Sheet'!$E$19,'Sheet'!$E$26,…`. The old
42
+ * first-range-only behavior silently truncated discontiguous series.
43
+ */
44
+ var formatSourcesRef = function (sources, sheetNameById) {
45
+ if (!(sources === null || sources === void 0 ? void 0 : sources.length))
46
+ return undefined;
47
+ var parts = sources
48
+ .map(function (range) { return formatRangeRef(range, sheetNameById); })
49
+ .filter(function (ref) { return Boolean(ref); });
50
+ return parts.length ? parts.join(",") : undefined;
51
+ };
52
+ var seriesCategoryRef = function (entry, sheetNameById) {
53
+ return formatSourcesRef(entry === null || entry === void 0 ? void 0 : entry.categorySources, sheetNameById);
54
+ };
55
+ var buildSeriesLabel = function (label, sheetName, labelRef) {
56
+ // A captured source reference (`<c:tx><c:strRef>`) wins over the literal:
57
+ // emitting the ref without a cache lets Excel resolve the live series name
58
+ // on open, instead of freezing a possibly-generic literal.
59
+ if (labelRef) {
60
+ return {
61
+ "c:tx": {
62
+ "c:strRef": {
63
+ "c:f": labelRef,
64
+ },
65
+ },
66
+ };
67
+ }
68
+ if (label === undefined || label === null || label === "")
69
+ return undefined;
70
+ // Numeric series headers (e.g. a year like 2024) can reach us as numbers
71
+ var text = typeof label === "string" ? label : String(label);
72
+ if (text.startsWith("=")) {
73
+ // If label contains property references (e.g., =A1.propertyName),
74
+ // treat it as static text instead of formula reference
75
+ if (hasPropertyReference(text)) {
76
+ return {
77
+ "c:tx": {
78
+ "c:v": sanitizeXmlText(text),
79
+ },
80
+ };
81
+ }
82
+ var formula = normalizeFormula(text);
83
+ var resolved = sheetName && !formula.includes("!")
84
+ ? "".concat(sanitizeSheetName(sheetName), "!").concat(formula)
85
+ : formula;
86
+ return {
87
+ "c:tx": {
88
+ "c:strRef": {
89
+ "c:f": resolved,
90
+ },
91
+ },
92
+ };
93
+ }
94
+ return {
95
+ "c:tx": {
96
+ "c:v": sanitizeXmlText(text),
97
+ },
98
+ };
99
+ };
100
+ var buildColorNode = function (color) {
101
+ var normalized = color.startsWith("#") ? color.slice(1) : color;
102
+ var hex = normalized.length === 6
103
+ ? normalized
104
+ : normalized.slice(normalized.length - 6);
105
+ return {
106
+ "a:solidFill": {
107
+ "a:srgbClr": {
108
+ a$: {
109
+ val: hex,
110
+ },
111
+ },
112
+ },
113
+ };
114
+ };
115
+ var normalizeHex = function (color) {
116
+ var stripped = color.startsWith("#") ? color.slice(1) : color;
117
+ return stripped.length === 6
118
+ ? stripped
119
+ : stripped.slice(stripped.length - 6);
120
+ };
121
+ /**
122
+ * Build an OOXML `<a:gradFill>` node from a series-level gradient
123
+ * descriptor. Matches the DrawingML schema:
124
+ *
125
+ * <a:gradFill flip="none" rotWithShape="1">
126
+ * <a:gsLst>
127
+ * <a:gs pos="0"><a:srgbClr val="FF0000"/></a:gs>
128
+ * <a:gs pos="100000"><a:srgbClr val="0000FF"/></a:gs>
129
+ * </a:gsLst>
130
+ * <a:lin ang="5400000" scaled="0"/> <!-- or <a:path path="rect">…</a:path> -->
131
+ * </a:gradFill>
132
+ *
133
+ * Positions are EMU per-mille (0..100000). Linear angle is in 60000ths
134
+ * of a degree (90° == 5400000) — Excel's chart angle convention runs
135
+ * clockwise from 12 o'clock, so the conversion is `deg * 60000`.
136
+ *
137
+ * Path gradients use `<a:path path="rect">` with a `<a:fillToRect>`
138
+ * child carrying the inset of the inner stop in EMU per-mille.
139
+ */
140
+ var buildGradFillNode = function (gradient) {
141
+ var _a, _b;
142
+ if (!((_a = gradient === null || gradient === void 0 ? void 0 : gradient.stops) === null || _a === void 0 ? void 0 : _a.length))
143
+ return null;
144
+ var gsList = gradient.stops.map(function (stop) { return ({
145
+ a$: { pos: String(Math.round(Math.max(0, Math.min(1, stop.position)) * 100000)) },
146
+ "a:srgbClr": { a$: { val: normalizeHex(stop.color) } },
147
+ }); });
148
+ var direction = {};
149
+ if (gradient.type === "path") {
150
+ var toEmu = function (v) {
151
+ return v != null ? String(Math.round(v * 100000)) : "0";
152
+ };
153
+ direction["a:path"] = {
154
+ a$: { path: "rect" },
155
+ "a:fillToRect": {
156
+ a$: {
157
+ l: toEmu(gradient.left),
158
+ r: toEmu(gradient.right),
159
+ t: toEmu(gradient.top),
160
+ b: toEmu(gradient.bottom),
161
+ },
162
+ },
163
+ };
164
+ }
165
+ else {
166
+ var deg = (((_b = gradient.degree) !== null && _b !== void 0 ? _b : 0) % 360 + 360) % 360;
167
+ direction["a:lin"] = {
168
+ a$: {
169
+ ang: String(Math.round(deg * 60000)),
170
+ scaled: "0",
171
+ },
172
+ };
173
+ }
174
+ return __assign({ a$: { flip: "none", rotWithShape: "1" }, "a:gsLst": { "a:gs": gsList } }, direction);
175
+ };
176
+ /**
177
+ * Replace the series' shape-properties fill with a gradient when one
178
+ * is supplied. Strips any pre-existing solid/scheme fill so the
179
+ * gradient doesn't double up.
180
+ */
181
+ var applySeriesGradient = function (seriesNode, gradient) {
182
+ if (!gradient)
183
+ return false;
184
+ var gradFill = buildGradFillNode(gradient);
185
+ if (!gradFill)
186
+ return false;
187
+ var spPr = seriesNode["c:spPr"];
188
+ if (!spPr)
189
+ return false;
190
+ delete spPr["a:solidFill"];
191
+ spPr["a:gradFill"] = gradFill;
192
+ return true;
193
+ };
194
+ /**
195
+ * Build the extension list for a series with invertIfNegative support.
196
+ * This adds the c14:invertSolidFillFmt extension for negative fill color.
197
+ */
198
+ var buildSeriesExtLst = function (negativeColor, uniqueId) {
199
+ var extensions = [];
200
+ // Add unique ID extension (required by Excel)
201
+ extensions.push({
202
+ a$: {
203
+ uri: "{C3380CC4-5D6E-409C-BE32-E72D297353CC}",
204
+ "xmlns:c16": "http://schemas.microsoft.com/office/drawing/2014/chart",
205
+ },
206
+ "c16:uniqueId": {
207
+ a$: {
208
+ val: uniqueId,
209
+ },
210
+ },
211
+ });
212
+ // Add negative fill color extension if specified
213
+ if (negativeColor) {
214
+ var normalizedColor = negativeColor.startsWith("#")
215
+ ? negativeColor.slice(1)
216
+ : negativeColor;
217
+ var hex = normalizedColor.length === 6
218
+ ? normalizedColor
219
+ : normalizedColor.slice(normalizedColor.length - 6);
220
+ extensions.push({
221
+ a$: {
222
+ uri: "{6F2FDCE9-48DA-4B69-8628-5D25D57E5C99}",
223
+ "xmlns:c14": "http://schemas.microsoft.com/office/drawing/2007/8/2/chart",
224
+ },
225
+ "c14:invertSolidFillFmt": {
226
+ "c14:spPr": {
227
+ "a:solidFill": {
228
+ "a:srgbClr": {
229
+ a$: {
230
+ val: hex,
231
+ },
232
+ },
233
+ },
234
+ "a:ln": {
235
+ "a:noFill": {},
236
+ },
237
+ "a:effectLst": {},
238
+ },
239
+ },
240
+ });
241
+ }
242
+ return {
243
+ "c:ext": extensions.length === 1 ? extensions[0] : extensions,
244
+ };
245
+ };
246
+ // ─── Round-trip helpers (textFormat, marker, dPt, inline values) ─────
247
+ /**
248
+ * Build a `<c:txPr>` XML node from a ChartTextFormat. Returns
249
+ * `undefined` when the format has no settable properties so callers
250
+ * can skip emission. Used by axis, legend, title, and data-label
251
+ * blocks to preserve authored color/font on round-trip.
252
+ */
253
+ var buildTxPrNode = function (textFormat) {
254
+ if (!textFormat)
255
+ return undefined;
256
+ var defRPr = { a$: {} };
257
+ if (typeof textFormat.fontSize === "number") {
258
+ // ChartTextFormat stores points; OOXML stores 100ths of a point.
259
+ defRPr.a$.sz = String(Math.round(textFormat.fontSize * 100));
260
+ }
261
+ if (textFormat.bold)
262
+ defRPr.a$.b = "1";
263
+ if (textFormat.italic)
264
+ defRPr.a$.i = "1";
265
+ if (textFormat.underline)
266
+ defRPr.a$.u = "sng";
267
+ if (textFormat.strikethrough)
268
+ defRPr.a$.strike = "sngStrike";
269
+ if (textFormat.color) {
270
+ var hex = String(textFormat.color).replace(/^#/, "").toUpperCase();
271
+ defRPr["a:solidFill"] = {
272
+ "a:srgbClr": { a$: { val: hex } },
273
+ };
274
+ }
275
+ if (textFormat.fontFamily) {
276
+ defRPr["a:latin"] = { a$: { typeface: textFormat.fontFamily } };
277
+ }
278
+ // Only emit when we wrote something useful — otherwise Excel rejects
279
+ // an empty defRPr.
280
+ var hasAttrs = Object.keys(defRPr.a$).length > 0;
281
+ var hasChildren = Object.keys(defRPr).some(function (k) { return k !== "a$"; });
282
+ if (!hasAttrs && !hasChildren)
283
+ return undefined;
284
+ return {
285
+ "a:bodyPr": {
286
+ a$: {
287
+ rot: "0",
288
+ spcFirstLastPara: "1",
289
+ vertOverflow: "ellipsis",
290
+ wrap: "square",
291
+ anchor: "ctr",
292
+ anchorCtr: "1",
293
+ },
294
+ },
295
+ "a:lstStyle": {},
296
+ "a:p": {
297
+ "a:pPr": { "a:defRPr": defRPr },
298
+ "a:endParaRPr": { a$: { lang: "en-US" } },
299
+ },
300
+ };
301
+ };
302
+ /**
303
+ * Build a `<c:strLit>` inline category block from an array of values.
304
+ * Used when a chart's category axis is embedded literally in the chart
305
+ * XML (e.g. Event Budget's `["Estimated", "Actual"]`) instead of
306
+ * referencing the sheet.
307
+ */
308
+ var buildInlineStrLit = function (values) { return ({
309
+ "c:strLit": {
310
+ "c:ptCount": { a$: { val: String(values.length) } },
311
+ "c:pt": values.map(function (v, i) { return ({
312
+ a$: { idx: String(i) },
313
+ "c:v": sanitizeXmlText(String(v)),
314
+ }); }),
315
+ },
316
+ }); };
317
+ /**
318
+ * Build a `<c:numLit>` inline numeric block from values. Used for
319
+ * inline-value series (rare but legal in OOXML).
320
+ */
321
+ var buildInlineNumLit = function (values) { return ({
322
+ "c:numLit": {
323
+ "c:formatCode": "General",
324
+ "c:ptCount": { a$: { val: String(values.length) } },
325
+ "c:pt": values.map(function (v, i) { return ({
326
+ a$: { idx: String(i) },
327
+ "c:v": typeof v === "number" ? String(v) : Number(v).toString(),
328
+ }); }),
329
+ },
330
+ }); };
331
+ /**
332
+ * Build a `<c:marker>` node from a ChartData.marker spec. Returns
333
+ * `undefined` when the marker carries no information.
334
+ */
335
+ var buildMarkerNode = function (marker) {
336
+ if (!marker)
337
+ return undefined;
338
+ var node = {};
339
+ if (marker.symbol) {
340
+ node["c:symbol"] = { a$: { val: marker.symbol } };
341
+ }
342
+ if (typeof marker.size === "number") {
343
+ node["c:size"] = { a$: { val: String(Math.round(marker.size)) } };
344
+ }
345
+ if (marker.color) {
346
+ node["c:spPr"] = {
347
+ "a:solidFill": buildColorNode(marker.color)["a:solidFill"],
348
+ };
349
+ }
350
+ return Object.keys(node).length ? node : undefined;
351
+ };
352
+ /**
353
+ * Build a `<c:dPt>` array from per-point color overrides. Each entry
354
+ * pins a category index to a different fill — Gantt-style charts use
355
+ * this to colour each task individually.
356
+ */
357
+ var buildDataPointNodes = function (dataPointColors) {
358
+ if (!dataPointColors || !dataPointColors.length)
359
+ return undefined;
360
+ return dataPointColors.map(function (dp) { return ({
361
+ "c:idx": { a$: { val: String(dp.idx) } },
362
+ "c:invertIfNegative": { a$: { val: "0" } },
363
+ "c:bubble3D": { a$: { val: "0" } },
364
+ "c:spPr": {
365
+ "a:solidFill": buildColorNode(dp.color)["a:solidFill"],
366
+ "a:ln": { "a:noFill": {} },
367
+ },
368
+ }); });
369
+ };
370
+ /**
371
+ * Apply transparent fill to a series spPr node. Mirrors the
372
+ * `<a:noFill/>` form Excel uses for invisible "offset" bars (Gantt
373
+ * lag series). Replaces any existing solidFill/gradFill.
374
+ */
375
+ var applyNoFillToSeriesSpPr = function (seriesNode) {
376
+ var _a;
377
+ var spPr = (seriesNode["c:spPr"] = (_a = seriesNode["c:spPr"]) !== null && _a !== void 0 ? _a : {});
378
+ removeProp(spPr, "a:solidFill");
379
+ removeProp(spPr, "a:gradFill");
380
+ spPr["a:noFill"] = {};
381
+ };
382
+ /**
383
+ * Build the subtitle `<a:p>` paragraph node (fast-xml-parser object form)
384
+ * appended below the chart title inside the same `<c:rich>` block.
385
+ *
386
+ * Mirrors the legacy JS post-patcher (`chart-subtitle-patcher.ts`): the
387
+ * subtitle renders at ~70% of the title font size (9pt floor) in a muted
388
+ * `tx1` scheme colour. `titleSize` is in OOXML hundredths-of-a-point.
389
+ */
390
+ var buildSubtitleParagraphNode = function (subtitle, titleSize) {
391
+ var subtitleSize = Math.max(900, Math.round(titleSize * 0.7));
392
+ return {
393
+ "a:pPr": {
394
+ "a:defRPr": {
395
+ a$: {
396
+ sz: String(subtitleSize),
397
+ b: "0",
398
+ i: "0",
399
+ u: "none",
400
+ strike: "noStrike",
401
+ kern: "1200",
402
+ spc: "0",
403
+ baseline: "0",
404
+ },
405
+ "a:solidFill": {
406
+ "a:schemeClr": {
407
+ a$: { val: "tx1" },
408
+ "a:lumMod": { a$: { val: "65000" } },
409
+ "a:lumOff": { a$: { val: "35000" } },
410
+ },
411
+ },
412
+ "a:latin": { a$: { typeface: "+mn-lt" } },
413
+ "a:ea": { a$: { typeface: "+mn-ea" } },
414
+ "a:cs": { a$: { typeface: "+mn-cs" } },
415
+ },
416
+ },
417
+ "a:r": {
418
+ "a:rPr": { a$: { lang: "en-US", sz: String(subtitleSize), b: "0", i: "0" } },
419
+ "a:t": sanitizeXmlText(subtitle),
420
+ },
421
+ };
422
+ };
423
+ var applyChartTitle = function (chartNode, title, titleTextFormat, subtitle) {
424
+ var _a, _b, _c, _d, _e, _f, _g;
425
+ if (!title)
426
+ return;
427
+ var titleBlock = cloneTemplate(static_title);
428
+ titleBlock["c:tx"]["c:rich"]["a:p"]["a:r"]["a:rPr"].a$.lang = "en-US";
429
+ titleBlock["c:tx"]["c:rich"]["a:p"]["a:r"]["a:t"] = sanitizeXmlText(title);
430
+ // Apply authored text format on the rich run's `a:rPr` so Excel
431
+ // preserves color/font on round-trip. We mutate the rPr directly
432
+ // (it's already inside the template's a:p > a:r).
433
+ if (titleTextFormat) {
434
+ var rPr = titleBlock["c:tx"]["c:rich"]["a:p"]["a:r"]["a:rPr"];
435
+ if (typeof titleTextFormat.fontSize === "number") {
436
+ rPr.a$.sz = String(Math.round(titleTextFormat.fontSize * 100));
437
+ }
438
+ if (titleTextFormat.bold)
439
+ rPr.a$.b = "1";
440
+ if (titleTextFormat.italic)
441
+ rPr.a$.i = "1";
442
+ if (titleTextFormat.color) {
443
+ var hex = String(titleTextFormat.color).replace(/^#/, "").toUpperCase();
444
+ rPr["a:solidFill"] = { "a:srgbClr": { a$: { val: hex } } };
445
+ }
446
+ if (titleTextFormat.fontFamily) {
447
+ rPr["a:latin"] = { a$: { typeface: titleTextFormat.fontFamily } };
448
+ }
449
+ }
450
+ // Append the subtitle as a SECOND `<a:p>` inside the title's `<c:rich>`,
451
+ // matching what the legacy JS post-patcher spliced in. Emitted natively
452
+ // here so no post-processing pass is needed. Scale relative to the
453
+ // authored title size (defaults to the template's 14pt → sz="1400").
454
+ if (subtitle && subtitle.trim().length > 0) {
455
+ var rich = titleBlock["c:tx"]["c:rich"];
456
+ var titlePara = rich["a:p"];
457
+ var titleSizeStr = ((_d = (_c = (_b = (_a = titlePara === null || titlePara === void 0 ? void 0 : titlePara["a:pPr"]) === null || _a === void 0 ? void 0 : _a["a:defRPr"]) === null || _b === void 0 ? void 0 : _b.a$) === null || _c === void 0 ? void 0 : _c.sz) !== null && _d !== void 0 ? _d : (_g = (_f = (_e = titlePara === null || titlePara === void 0 ? void 0 : titlePara["a:r"]) === null || _e === void 0 ? void 0 : _e["a:rPr"]) === null || _f === void 0 ? void 0 : _f.a$) === null || _g === void 0 ? void 0 : _g.sz);
458
+ var titleSize = titleSizeStr && Number.isFinite(parseInt(titleSizeStr, 10))
459
+ ? parseInt(titleSizeStr, 10)
460
+ : 1400;
461
+ rich["a:p"] = [titlePara, buildSubtitleParagraphNode(subtitle, titleSize)];
462
+ }
463
+ chartNode["c:title"] = titleBlock;
464
+ };
465
+ var getPrimarySource = function (entry) { var _a; return (_a = entry === null || entry === void 0 ? void 0 : entry.sources) === null || _a === void 0 ? void 0 : _a[0]; };
466
+ /**
467
+ * c15 extension namespace (Excel 2012+) — histogram / boxplot /
468
+ * waterfall / funnel charts are emitted with a `c:barChart` body
469
+ * inside `mc:Fallback` (so older Excel still renders something) plus a
470
+ * full c15 chart element inside `mc:Choice` (so Excel 2016+ renders
471
+ * the chart natively). See `buildC15AlternateContent` and the per-type
472
+ * builders below.
473
+ */
474
+ var C15_NS = "http://schemas.microsoft.com/office/drawing/2012/chart";
475
+ var C15_ELEMENT_NAMES = {
476
+ histogram: "c15:histogramChart",
477
+ boxplot: "c15:boxWhiskerChart",
478
+ waterfall: "c15:waterfallChart",
479
+ funnel: "c15:funnelChart",
480
+ };
481
+ var isC15ChartType = function (t) {
482
+ return t === "histogram" || t === "boxplot" || t === "waterfall" || t === "funnel";
483
+ };
484
+ var MC_NS = "http://schemas.openxmlformats.org/markup-compatibility/2006";
485
+ /**
486
+ * Phase 5.5b — build the full c15:histogramChart body that Excel 2016+
487
+ * uses to render histograms natively. Lives inside `mc:Choice` next to
488
+ * the older `c:barChart` fallback (in `mc:Fallback`). Both share the
489
+ * `c:catAx`/`c:valAx` declared at `c:plotArea` level — c15 axId values
490
+ * are picked to match the bar chart's axId so Excel can resolve them.
491
+ */
492
+ var buildC15HistogramChartNode = function (spec, seriesRefs, series, domainRef, axIds) {
493
+ var c15SeriesEntries = [];
494
+ seriesRefs.forEach(function (ref, index) {
495
+ var _a;
496
+ if (!ref)
497
+ return;
498
+ var seriesNode = {
499
+ "c15:idx": { a$: { val: String(index) } },
500
+ "c15:order": { a$: { val: String(index) } },
501
+ };
502
+ // Series title — only if the consumer set a non-formula dataLabel.
503
+ var dataLabel = (_a = series[index]) === null || _a === void 0 ? void 0 : _a.dataLabel;
504
+ if (dataLabel && !dataLabel.startsWith("=")) {
505
+ seriesNode["c15:tx"] = {
506
+ "c15:v": dataLabel,
507
+ };
508
+ }
509
+ seriesNode["c15:val"] = {
510
+ "c15:numRef": {
511
+ "c15:f": ref,
512
+ },
513
+ };
514
+ c15SeriesEntries.push(seriesNode);
515
+ });
516
+ var histogramChart = {
517
+ "c15:varyColors": { a$: { val: "0" } },
518
+ "c15:ser": c15SeriesEntries.length === 1 ? c15SeriesEntries[0] : c15SeriesEntries,
519
+ "c15:axId": [
520
+ { a$: { val: axIds.catAxId } },
521
+ { a$: { val: axIds.valAxId } },
522
+ ],
523
+ };
524
+ // Bin configuration: explicit binCount when set, otherwise let Excel
525
+ // auto-bin (Sturges-like).
526
+ if (typeof (spec === null || spec === void 0 ? void 0 : spec.binCount) === "number" && spec.binCount > 0) {
527
+ histogramChart["c15:binCount"] = { a$: { val: String(spec.binCount) } };
528
+ }
529
+ else {
530
+ histogramChart["c15:binsAuto"] = { a$: { val: "1" } };
531
+ }
532
+ return histogramChart;
533
+ };
534
+ /**
535
+ * Phase 5.5b — c15:boxWhiskerChart body. Excel 2016+ renders box & whisker
536
+ * natively from this. Each series carries its raw values; Excel computes
537
+ * the quartiles + median + outliers from `c15:quartileMethod`.
538
+ */
539
+ var buildC15BoxplotChartNode = function (_spec, seriesRefs, series, domainRef, axIds) {
540
+ var c15SeriesEntries = [];
541
+ seriesRefs.forEach(function (ref, index) {
542
+ var _a;
543
+ if (!ref)
544
+ return;
545
+ var seriesNode = {
546
+ "c15:idx": { a$: { val: String(index) } },
547
+ "c15:order": { a$: { val: String(index) } },
548
+ "c15:invertIfNegative": { a$: { val: "0" } },
549
+ "c15:bubble3D": { a$: { val: "0" } },
550
+ };
551
+ var dataLabel = (_a = series[index]) === null || _a === void 0 ? void 0 : _a.dataLabel;
552
+ if (dataLabel && !dataLabel.startsWith("=")) {
553
+ seriesNode["c15:tx"] = { "c15:v": dataLabel };
554
+ }
555
+ if (domainRef) {
556
+ seriesNode["c15:cat"] = {
557
+ "c15:strRef": { "c15:f": domainRef },
558
+ };
559
+ }
560
+ seriesNode["c15:val"] = {
561
+ "c15:numRef": { "c15:f": ref },
562
+ };
563
+ c15SeriesEntries.push(seriesNode);
564
+ });
565
+ return {
566
+ "c15:varyColors": { a$: { val: "0" } },
567
+ "c15:ser": c15SeriesEntries.length === 1 ? c15SeriesEntries[0] : c15SeriesEntries,
568
+ "c15:showInnerPoints": { a$: { val: "0" } },
569
+ "c15:showOutlierPoints": { a$: { val: "1" } },
570
+ "c15:showMeanMarker": { a$: { val: "1" } },
571
+ "c15:showMeanLine": { a$: { val: "0" } },
572
+ "c15:quartileMethod": { a$: { val: "exclusive" } },
573
+ "c15:axId": [
574
+ { a$: { val: axIds.catAxId } },
575
+ { a$: { val: axIds.valAxId } },
576
+ ],
577
+ };
578
+ };
579
+ /**
580
+ * Phase 5.5b — c15:waterfallChart body. Each c15:ser carries one data
581
+ * point per category. Subtotals are marked at the series level via
582
+ * c15:dPt with c15:subTotal set; without these, Excel treats every
583
+ * point as a delta and the running cumulative is implicit.
584
+ */
585
+ var buildC15WaterfallChartNode = function (_spec, seriesRefs, series, domainRef, axIds) {
586
+ var c15SeriesEntries = [];
587
+ seriesRefs.forEach(function (ref, index) {
588
+ var _a;
589
+ if (!ref)
590
+ return;
591
+ var seriesNode = {
592
+ "c15:idx": { a$: { val: String(index) } },
593
+ "c15:order": { a$: { val: String(index) } },
594
+ };
595
+ var dataLabel = (_a = series[index]) === null || _a === void 0 ? void 0 : _a.dataLabel;
596
+ if (dataLabel && !dataLabel.startsWith("=")) {
597
+ seriesNode["c15:tx"] = { "c15:v": dataLabel };
598
+ }
599
+ if (domainRef) {
600
+ seriesNode["c15:cat"] = {
601
+ "c15:strRef": { "c15:f": domainRef },
602
+ };
603
+ }
604
+ seriesNode["c15:val"] = {
605
+ "c15:numRef": { "c15:f": ref },
606
+ };
607
+ c15SeriesEntries.push(seriesNode);
608
+ });
609
+ return {
610
+ "c15:varyColors": { a$: { val: "0" } },
611
+ "c15:ser": c15SeriesEntries.length === 1 ? c15SeriesEntries[0] : c15SeriesEntries,
612
+ "c15:axId": [
613
+ { a$: { val: axIds.catAxId } },
614
+ { a$: { val: axIds.valAxId } },
615
+ ],
616
+ };
617
+ };
618
+ /**
619
+ * Phase 5.5b — c15:funnelChart body. Categories label each funnel
620
+ * stage; values size the stages. No subtotals, no quartile config.
621
+ */
622
+ var buildC15FunnelChartNode = function (_spec, seriesRefs, series, domainRef, axIds) {
623
+ var c15SeriesEntries = [];
624
+ seriesRefs.forEach(function (ref, index) {
625
+ var _a;
626
+ if (!ref)
627
+ return;
628
+ var seriesNode = {
629
+ "c15:idx": { a$: { val: String(index) } },
630
+ "c15:order": { a$: { val: String(index) } },
631
+ };
632
+ var dataLabel = (_a = series[index]) === null || _a === void 0 ? void 0 : _a.dataLabel;
633
+ if (dataLabel && !dataLabel.startsWith("=")) {
634
+ seriesNode["c15:tx"] = { "c15:v": dataLabel };
635
+ }
636
+ if (domainRef) {
637
+ seriesNode["c15:cat"] = {
638
+ "c15:strRef": { "c15:f": domainRef },
639
+ };
640
+ }
641
+ seriesNode["c15:val"] = {
642
+ "c15:numRef": { "c15:f": ref },
643
+ };
644
+ c15SeriesEntries.push(seriesNode);
645
+ });
646
+ return {
647
+ "c15:varyColors": { a$: { val: "0" } },
648
+ "c15:ser": c15SeriesEntries.length === 1 ? c15SeriesEntries[0] : c15SeriesEntries,
649
+ "c15:axId": [
650
+ { a$: { val: axIds.catAxId } },
651
+ { a$: { val: axIds.valAxId } },
652
+ ],
653
+ };
654
+ };
655
+ /**
656
+ * Phase 5.5b — wrap a c15 chart body in `mc:AlternateContent` so Excel
657
+ * 2016+ uses the c15 chart and older Excel falls back to the bar chart.
658
+ * Returns the AlternateContent node ready to splice into c:plotArea.
659
+ */
660
+ var buildC15AlternateContent = function (chartType, c15ChartBody, fallbackBarChart) {
661
+ var _a;
662
+ var choiceElementName = C15_ELEMENT_NAMES[chartType];
663
+ return {
664
+ a$: { "xmlns:mc": MC_NS },
665
+ "mc:Choice": (_a = {
666
+ a$: {
667
+ Requires: "c15",
668
+ "xmlns:c15": C15_NS,
669
+ }
670
+ },
671
+ _a[choiceElementName] = c15ChartBody,
672
+ _a),
673
+ "mc:Fallback": {
674
+ "c:barChart": fallbackBarChart,
675
+ },
676
+ };
677
+ };
678
+ /**
679
+ * Group series by their effective chart type for combo chart support.
680
+ * Returns a map of chart type to array of {index, ref, seriesData}.
681
+ */
682
+ var groupSeriesByChartType = function (series, seriesRefs, defaultChartType) {
683
+ var groups = new Map();
684
+ seriesRefs.forEach(function (ref, index) {
685
+ var _a;
686
+ if (!ref)
687
+ return;
688
+ var seriesData = series[index];
689
+ var effectiveType = ((_a = seriesData === null || seriesData === void 0 ? void 0 : seriesData.seriesChartType) !== null && _a !== void 0 ? _a : defaultChartType);
690
+ if (!groups.has(effectiveType)) {
691
+ groups.set(effectiveType, []);
692
+ }
693
+ groups.get(effectiveType).push({ index: index, ref: ref, data: seriesData });
694
+ });
695
+ return groups;
696
+ };
697
+ /**
698
+ * Check if a chart has multiple series types (combo chart).
699
+ */
700
+ var isComboChart = function (series, defaultChartType) {
701
+ var e_1, _a;
702
+ var _b;
703
+ var types = new Set();
704
+ try {
705
+ for (var series_1 = __values(series), series_1_1 = series_1.next(); !series_1_1.done; series_1_1 = series_1.next()) {
706
+ var s = series_1_1.value;
707
+ types.add((_b = s.seriesChartType) !== null && _b !== void 0 ? _b : defaultChartType);
708
+ }
709
+ }
710
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
711
+ finally {
712
+ try {
713
+ if (series_1_1 && !series_1_1.done && (_a = series_1.return)) _a.call(series_1);
714
+ }
715
+ finally { if (e_1) throw e_1.error; }
716
+ }
717
+ return types.size > 1;
718
+ };
719
+ /**
720
+ * Build a bar/column series node.
721
+ */
722
+ var buildBarSeriesNode = function (index, ref, seriesData, domainRef, sheetName, isFirstInGroup) {
723
+ var _a;
724
+ var seriesNode = cloneTemplate(column_series);
725
+ seriesNode["c:idx"] = { a$: { val: index.toString() } };
726
+ seriesNode["c:order"] = { a$: { val: index.toString() } };
727
+ var seriesColor = seriesData === null || seriesData === void 0 ? void 0 : seriesData.color;
728
+ var anyData = seriesData;
729
+ // noFill takes precedence over any other fill — Gantt-style
730
+ // invisible offset series. Must run BEFORE solidFill/gradient so it
731
+ // can wipe the template's default fill.
732
+ if (anyData === null || anyData === void 0 ? void 0 : anyData.noFill) {
733
+ applyNoFillToSeriesSpPr(seriesNode);
734
+ }
735
+ else if (applySeriesGradient(seriesNode, seriesData === null || seriesData === void 0 ? void 0 : seriesData.gradient)) {
736
+ // Gradient wins — solid/scheme already cleared.
737
+ }
738
+ else if (seriesColor) {
739
+ seriesNode["c:spPr"]["a:solidFill"] =
740
+ buildColorNode(seriesColor)["a:solidFill"];
741
+ }
742
+ else if (index < 6) {
743
+ seriesNode["c:spPr"]["a:solidFill"]["a:schemeClr"].a$.val = "accent".concat(index + 1);
744
+ }
745
+ // Per-data-point colors — emit `<c:dPt>` array after the series-
746
+ // level fill. Each entry overrides the fill for one category index.
747
+ var dPtNodes = buildDataPointNodes(anyData === null || anyData === void 0 ? void 0 : anyData.dataPointColors);
748
+ if (dPtNodes) {
749
+ seriesNode["c:dPt"] = dPtNodes;
750
+ }
751
+ // Handle invertIfNegative for negative bar coloring
752
+ var invertIfNegative = seriesData === null || seriesData === void 0 ? void 0 : seriesData.invertIfNegative;
753
+ var negativeColor = seriesData === null || seriesData === void 0 ? void 0 : seriesData.negativeColor;
754
+ if (invertIfNegative) {
755
+ seriesNode["c:invertIfNegative"] = { a$: { val: "1" } };
756
+ var uniqueId = "{".concat(crypto.randomUUID().toUpperCase(), "}");
757
+ seriesNode["c:extLst"] = buildSeriesExtLst(negativeColor !== null && negativeColor !== void 0 ? negativeColor : undefined, uniqueId);
758
+ }
759
+ // Excel writes the category reference on every series, not just the first
760
+ // in a group — readers treat a cat-less series as having no categories.
761
+ if (domainRef) {
762
+ seriesNode["c:cat"] = {
763
+ "c:strRef": {
764
+ "c:f": domainRef,
765
+ },
766
+ };
767
+ }
768
+ else if (seriesData === null || seriesData === void 0 ? void 0 : seriesData.inlineDomainValues) {
769
+ // Inline category labels (`<c:strLit>`) — used when categories are
770
+ // embedded in the chart XML rather than from a sheet range.
771
+ seriesNode["c:cat"] = buildInlineStrLit(seriesData.inlineDomainValues);
772
+ }
773
+ seriesNode["c:val"]["c:numRef"]["c:f"] = ref;
774
+ // Inline series values (`<c:numLit>`) — when the series carries its
775
+ // own values rather than a cell-range. Rare for bars but valid.
776
+ var inlineValues = anyData === null || anyData === void 0 ? void 0 : anyData.inlineValues;
777
+ if (!ref && Array.isArray(inlineValues) && inlineValues.length) {
778
+ removeProp(seriesNode, "c:val");
779
+ seriesNode["c:val"] = buildInlineNumLit(inlineValues);
780
+ }
781
+ var labelNode = buildSeriesLabel((_a = seriesData === null || seriesData === void 0 ? void 0 : seriesData.dataLabel) !== null && _a !== void 0 ? _a : undefined, sheetName, seriesData === null || seriesData === void 0 ? void 0 : seriesData.dataLabelRef);
782
+ if (labelNode) {
783
+ seriesNode["c:tx"] = labelNode["c:tx"];
784
+ }
785
+ // Per-series marker — typically scatter/bubble but bar/line/area
786
+ // charts can carry one too via `<c:marker>`.
787
+ var markerNode = buildMarkerNode(anyData === null || anyData === void 0 ? void 0 : anyData.marker);
788
+ if (markerNode) {
789
+ seriesNode["c:marker"] = markerNode;
790
+ }
791
+ return seriesNode;
792
+ };
793
+ /**
794
+ * Build a line series node.
795
+ */
796
+ var buildLineSeriesNode = function (index, ref, seriesData, domainRef, sheetName, smooth) {
797
+ var _a, _b;
798
+ var seriesNode = cloneTemplate(line_series);
799
+ seriesNode["c:idx"] = { a$: { val: index.toString() } };
800
+ seriesNode["c:order"] = { a$: { val: index.toString() } };
801
+ var seriesColor = seriesData === null || seriesData === void 0 ? void 0 : seriesData.color;
802
+ // Line series carry the stroke fill on `c:spPr/a:ln`. A gradient on
803
+ // a line stroke is unusual (Excel renders a flat-color stroke even
804
+ // when the underlying spec carries a gradient on `a:ln`), so we
805
+ // prefer a solid stroke and only apply the gradient to the bg-style
806
+ // `c:spPr/a:solidFill` slot when present. If the caller explicitly
807
+ // requested a gradient, we replace the stroke's solid color with
808
+ // the first stop's hex — best-effort fallback.
809
+ if ((seriesData === null || seriesData === void 0 ? void 0 : seriesData.gradient) && ((_a = seriesData.gradient.stops) === null || _a === void 0 ? void 0 : _a.length)) {
810
+ var first = seriesData.gradient.stops[0].color;
811
+ seriesNode["c:spPr"]["a:ln"]["a:solidFill"] =
812
+ buildColorNode(first)["a:solidFill"];
813
+ }
814
+ else if (seriesColor) {
815
+ seriesNode["c:spPr"]["a:ln"]["a:solidFill"] =
816
+ buildColorNode(seriesColor)["a:solidFill"];
817
+ }
818
+ else if (index < 6) {
819
+ seriesNode["c:spPr"]["a:ln"]["a:solidFill"]["a:schemeClr"].a$.val = "accent".concat(index + 1);
820
+ }
821
+ if (domainRef) {
822
+ seriesNode["c:cat"]["c:strRef"]["c:f"] = domainRef;
823
+ }
824
+ else {
825
+ removeProp(seriesNode, "c:cat");
826
+ }
827
+ seriesNode["c:val"]["c:numRef"]["c:f"] = ref;
828
+ if (smooth) {
829
+ seriesNode["c:smooth"].a$.val = "1";
830
+ }
831
+ var labelNode = buildSeriesLabel((_b = seriesData === null || seriesData === void 0 ? void 0 : seriesData.dataLabel) !== null && _b !== void 0 ? _b : undefined, sheetName, seriesData === null || seriesData === void 0 ? void 0 : seriesData.dataLabelRef);
832
+ if (labelNode) {
833
+ seriesNode["c:tx"] = labelNode["c:tx"];
834
+ }
835
+ return seriesNode;
836
+ };
837
+ /**
838
+ * Build an area series node.
839
+ */
840
+ var buildAreaSeriesNode = function (index, ref, seriesData, domainRef, sheetName) {
841
+ var _a, _b, _c;
842
+ var seriesNode = cloneTemplate(area_series);
843
+ seriesNode["c:idx"] = { a$: { val: index.toString() } };
844
+ seriesNode["c:order"] = { a$: { val: index.toString() } };
845
+ var seriesColor = seriesData === null || seriesData === void 0 ? void 0 : seriesData.color;
846
+ if (applySeriesGradient(seriesNode, seriesData === null || seriesData === void 0 ? void 0 : seriesData.gradient)) {
847
+ // Gradient applied to the fill area. Stroke stays solid using
848
+ // the first stop's color so the outline is visible.
849
+ if ((_b = (_a = seriesData === null || seriesData === void 0 ? void 0 : seriesData.gradient) === null || _a === void 0 ? void 0 : _a.stops) === null || _b === void 0 ? void 0 : _b.length) {
850
+ seriesNode["c:spPr"]["a:ln"]["a:solidFill"] =
851
+ buildColorNode(seriesData.gradient.stops[0].color)["a:solidFill"];
852
+ }
853
+ }
854
+ else if (seriesColor) {
855
+ seriesNode["c:spPr"]["a:solidFill"] =
856
+ buildColorNode(seriesColor)["a:solidFill"];
857
+ seriesNode["c:spPr"]["a:ln"]["a:solidFill"] =
858
+ buildColorNode(seriesColor)["a:solidFill"];
859
+ }
860
+ else if (index < 6) {
861
+ seriesNode["c:spPr"]["a:solidFill"]["a:schemeClr"].a$.val = "accent".concat(index + 1);
862
+ seriesNode["c:spPr"]["a:ln"]["a:solidFill"]["a:schemeClr"].a$.val = "accent".concat(index + 1);
863
+ }
864
+ if (domainRef) {
865
+ seriesNode["c:cat"]["c:strRef"]["c:f"] = domainRef;
866
+ }
867
+ else {
868
+ removeProp(seriesNode, "c:cat");
869
+ }
870
+ seriesNode["c:val"]["c:numRef"]["c:f"] = ref;
871
+ var labelNode = buildSeriesLabel((_c = seriesData === null || seriesData === void 0 ? void 0 : seriesData.dataLabel) !== null && _c !== void 0 ? _c : undefined, sheetName, seriesData === null || seriesData === void 0 ? void 0 : seriesData.dataLabelRef);
872
+ if (labelNode) {
873
+ seriesNode["c:tx"] = labelNode["c:tx"];
874
+ }
875
+ return seriesNode;
876
+ };
877
+ /**
878
+ * Pie/doughnut templates carry exactly one `c:ser`; a source chart with
879
+ * several series (e.g. seven single-cell slices) silently lost all but the
880
+ * first. Convert the template's ser into an array and append one node per
881
+ * remaining series, each with its own idx/order, name, category and value
882
+ * reference.
883
+ */
884
+ var appendExtraCircularSeries = function (chartNode, groupKey, seriesRefs, seriesCatRefs, domainRef, series, sheetName) {
885
+ var e_2, _a;
886
+ var _b, _c, _d, _e, _f, _g, _h;
887
+ var group = (_b = chartNode["c:plotArea"]) === null || _b === void 0 ? void 0 : _b[groupKey];
888
+ if (!group)
889
+ return;
890
+ var extra = seriesRefs
891
+ .map(function (ref, index) { return ({ ref: ref, index: index }); })
892
+ .filter(function (_a) {
893
+ var ref = _a.ref, index = _a.index;
894
+ return index > 0 && Boolean(ref);
895
+ });
896
+ if (!extra.length)
897
+ return;
898
+ var firstSer = group["c:ser"];
899
+ var sers = Array.isArray(firstSer) ? firstSer : [firstSer];
900
+ // The template's single ser is series 0; give it its per-series cat when
901
+ // one was captured.
902
+ var firstCat = seriesCatRefs[0];
903
+ if (firstCat && ((_d = (_c = sers[0]) === null || _c === void 0 ? void 0 : _c["c:cat"]) === null || _d === void 0 ? void 0 : _d["c:strRef"])) {
904
+ sers[0]["c:cat"]["c:strRef"]["c:f"] = firstCat;
905
+ }
906
+ try {
907
+ for (var extra_1 = __values(extra), extra_1_1 = extra_1.next(); !extra_1_1.done; extra_1_1 = extra_1.next()) {
908
+ var _j = extra_1_1.value, ref = _j.ref, index = _j.index;
909
+ var node = {
910
+ "c:idx": { a$: { val: String(index) } },
911
+ "c:order": { a$: { val: String(index) } },
912
+ };
913
+ var labelNode = buildSeriesLabel((_f = (_e = series[index]) === null || _e === void 0 ? void 0 : _e.dataLabel) !== null && _f !== void 0 ? _f : undefined, sheetName, (_g = series[index]) === null || _g === void 0 ? void 0 : _g.dataLabelRef);
914
+ if (labelNode) {
915
+ node["c:tx"] = labelNode["c:tx"];
916
+ }
917
+ var catRef = (_h = seriesCatRefs[index]) !== null && _h !== void 0 ? _h : domainRef;
918
+ if (catRef) {
919
+ node["c:cat"] = { "c:strRef": { "c:f": catRef } };
920
+ }
921
+ node["c:val"] = { "c:numRef": { "c:f": ref } };
922
+ sers.push(node);
923
+ }
924
+ }
925
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
926
+ finally {
927
+ try {
928
+ if (extra_1_1 && !extra_1_1.done && (_a = extra_1.return)) _a.call(extra_1);
929
+ }
930
+ finally { if (e_2) throw e_2.error; }
931
+ }
932
+ group["c:ser"] = sers;
933
+ };
934
+ var buildPieChart = function (domainRef, valueRef, title, subtitle) {
935
+ var pieChart = cloneTemplate(donut_json);
936
+ applyChartTitle(pieChart, title, undefined, subtitle);
937
+ var plotArea = pieChart["c:plotArea"];
938
+ var donut = plotArea["c:doughnutChart"];
939
+ removeProp(donut, "c:holeSize");
940
+ plotArea["c:pieChart"] = donut;
941
+ removeProp(plotArea, "c:doughnutChart");
942
+ var seriesNode = plotArea["c:pieChart"]["c:ser"];
943
+ if (domainRef) {
944
+ seriesNode["c:cat"]["c:strRef"]["c:f"] = domainRef;
945
+ }
946
+ if (valueRef) {
947
+ seriesNode["c:val"]["c:numRef"]["c:f"] = valueRef;
948
+ }
949
+ return pieChart;
950
+ };
951
+ /**
952
+ * Pie-of-pie / bar-of-pie (`<c:ofPieChart>`). Reuses the donut template
953
+ * like buildPieChart but rebuilds the chart-group node so the of-pie
954
+ * elements land in the CT_OfPieChart sequence order: ofPieType,
955
+ * varyColors, ser, dLbls, gapWidth, splitType, splitPos, secondPieSize,
956
+ * serLines. splitType maps the spec vocabulary back to the OOXML
957
+ * tokens (`pos`/`val`/`percent`); `<c:serLines/>` turns on Excel's
958
+ * connector lines between the two plots.
959
+ */
960
+ var buildOfPieChart = function (domainRef, valueRef, title, spec, subtitle) {
961
+ var chartObj = cloneTemplate(donut_json);
962
+ applyChartTitle(chartObj, title, undefined, subtitle);
963
+ var plotArea = chartObj["c:plotArea"];
964
+ var donut = plotArea["c:doughnutChart"];
965
+ // holeSize and firstSliceAng are pie/doughnut-only — invalid inside
966
+ // <c:ofPieChart>.
967
+ removeProp(donut, "c:holeSize");
968
+ removeProp(donut, "c:firstSliceAng");
969
+ var splitTypeVal = (spec === null || spec === void 0 ? void 0 : spec.splitType) === "position"
970
+ ? "pos"
971
+ : (spec === null || spec === void 0 ? void 0 : spec.splitType) === "value"
972
+ ? "val"
973
+ : (spec === null || spec === void 0 ? void 0 : spec.splitType) === "percent"
974
+ ? "percent"
975
+ : undefined;
976
+ var ofPieNode = __assign(__assign(__assign(__assign({ "c:ofPieType": { a$: { val: (spec === null || spec === void 0 ? void 0 : spec.ofPieType) === "bar" ? "bar" : "pie" } }, "c:varyColors": donut["c:varyColors"], "c:ser": donut["c:ser"], "c:dLbls": donut["c:dLbls"],
977
+ // Excel's default gap between the two plots.
978
+ "c:gapWidth": { a$: { val: "100" } } }, (splitTypeVal ? { "c:splitType": { a$: { val: splitTypeVal } } } : {})), (typeof (spec === null || spec === void 0 ? void 0 : spec.splitPos) === "number" && Number.isFinite(spec.splitPos)
979
+ ? { "c:splitPos": { a$: { val: String(spec.splitPos) } } }
980
+ : {})), (typeof (spec === null || spec === void 0 ? void 0 : spec.secondPieSize) === "number" &&
981
+ Number.isFinite(spec.secondPieSize)
982
+ ? { "c:secondPieSize": { a$: { val: String(Math.round(spec.secondPieSize)) } } }
983
+ : {})), { "c:serLines": {} });
984
+ plotArea["c:ofPieChart"] = ofPieNode;
985
+ removeProp(plotArea, "c:doughnutChart");
986
+ var seriesNode = ofPieNode["c:ser"];
987
+ if (domainRef) {
988
+ seriesNode["c:cat"]["c:strRef"]["c:f"] = domainRef;
989
+ }
990
+ if (valueRef) {
991
+ seriesNode["c:val"]["c:numRef"]["c:f"] = valueRef;
992
+ }
993
+ return chartObj;
994
+ };
995
+ /**
996
+ * Minimal builder for chart types that follow the line-style template
997
+ * (radar, stock, etc.) — single chart-type container with a flat series
998
+ * list. Reuses the column template and rewrites its barChart block to
999
+ * the target chart-type element. The renderer/Excel handles the rest.
1000
+ */
1001
+ var buildRadarLikeChart = function (chartElementKey, domainRef, seriesRefs, title, radarStyle, subtitle) {
1002
+ var _a;
1003
+ var chartObj = cloneTemplate(column_json);
1004
+ applyChartTitle(chartObj, title, undefined, subtitle);
1005
+ var plotArea = chartObj["c:plotArea"];
1006
+ var barChart = plotArea["c:barChart"];
1007
+ var axisIds = (_a = barChart === null || barChart === void 0 ? void 0 : barChart["c:axId"]) !== null && _a !== void 0 ? _a : [];
1008
+ var containerNode = {
1009
+ "c:varyColors": { a$: { val: "0" } },
1010
+ "c:ser": [],
1011
+ "c:axId": axisIds,
1012
+ };
1013
+ if (chartElementKey === "c:radarChart") {
1014
+ containerNode["c:radarStyle"] = {
1015
+ a$: { val: radarStyle !== null && radarStyle !== void 0 ? radarStyle : "standard" },
1016
+ };
1017
+ }
1018
+ removeProp(plotArea, "c:barChart");
1019
+ plotArea[chartElementKey] = containerNode;
1020
+ var seriesContainer = containerNode["c:ser"];
1021
+ seriesRefs.forEach(function (ref, index) {
1022
+ if (!ref)
1023
+ return;
1024
+ var seriesNode = {
1025
+ "c:idx": { a$: { val: String(index) } },
1026
+ "c:order": { a$: { val: String(index) } },
1027
+ "c:cat": domainRef
1028
+ ? { "c:strRef": { "c:f": domainRef } }
1029
+ : undefined,
1030
+ "c:val": { "c:numRef": { "c:f": ref } },
1031
+ };
1032
+ if (!domainRef)
1033
+ delete seriesNode["c:cat"];
1034
+ seriesContainer.push(seriesNode);
1035
+ });
1036
+ return chartObj;
1037
+ };
1038
+ var buildDoughnutChart = function (domainRef, valueRef, title, subtitle) {
1039
+ // Doughnut uses the same donut_json template as pie but keeps the
1040
+ // <c:doughnutChart> wrapper (and the holeSize, which we set later
1041
+ // via applyDoughnutHole when the spec carries one).
1042
+ var chartObj = cloneTemplate(donut_json);
1043
+ applyChartTitle(chartObj, title, undefined, subtitle);
1044
+ var plotArea = chartObj["c:plotArea"];
1045
+ var seriesNode = plotArea["c:doughnutChart"]["c:ser"];
1046
+ if (domainRef) {
1047
+ seriesNode["c:cat"]["c:strRef"]["c:f"] = domainRef;
1048
+ }
1049
+ if (valueRef) {
1050
+ seriesNode["c:val"]["c:numRef"]["c:f"] = valueRef;
1051
+ }
1052
+ return chartObj;
1053
+ };
1054
+ export var buildChartXml = function (chart, sheetNameById) {
1055
+ var e_3, _a, e_4, _b, e_5, _c;
1056
+ var _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10;
1057
+ var series = (_e = (_d = chart.spec) === null || _d === void 0 ? void 0 : _d.series) !== null && _e !== void 0 ? _e : [];
1058
+ if (!series.length)
1059
+ return undefined;
1060
+ var domainRef = formatSourcesRef((_g = (_f = chart.spec.domains) === null || _f === void 0 ? void 0 : _f[0]) === null || _g === void 0 ? void 0 : _g.sources, sheetNameById);
1061
+ var seriesRefs = series.map(function (entry) {
1062
+ return formatSourcesRef(entry === null || entry === void 0 ? void 0 : entry.sources, sheetNameById);
1063
+ });
1064
+ var seriesCatRefs = series.map(function (entry) {
1065
+ return seriesCategoryRef(entry, sheetNameById);
1066
+ });
1067
+ if (!seriesRefs.some(Boolean))
1068
+ return undefined;
1069
+ var chartType = chart.spec.chartType;
1070
+ var chartTitle = (_h = chart.spec.title) !== null && _h !== void 0 ? _h : undefined;
1071
+ // Subtitle line rendered under the title (e.g. a "Total Value to
1072
+ // Paid-In" caption under "Net MOIC by Fund Vintage"). Emitted as a
1073
+ // second `<a:p>` in the title's rich block — see `applyChartTitle`.
1074
+ var chartSubtitle = (_j = chart.spec.subtitle) !== null && _j !== void 0 ? _j : undefined;
1075
+ // Authored title text formatting (color/font/bold) — round-tripped
1076
+ // back so Excel keeps the styled title we read on import.
1077
+ var chartTitleFmt = (_k = chart.spec.titleTextFormat) !== null && _k !== void 0 ? _k : undefined;
1078
+ var smooth = "smooth" in chart.spec ? chart.spec.smooth : undefined;
1079
+ var chartSpace = cloneTemplate(chart_template);
1080
+ var sheetName = sheetNameById.get(chart.position.sheetId);
1081
+ // Check for combo chart (multiple series chart types)
1082
+ if (isComboChart(series, chartType)) {
1083
+ var groups = groupSeriesByChartType(series, seriesRefs, chartType);
1084
+ // Build combo chart with multiple chart type containers
1085
+ var comboChart = cloneTemplate(column_json);
1086
+ applyChartTitle(comboChart, chartTitle, chartTitleFmt, chartSubtitle);
1087
+ var plotArea = comboChart["c:plotArea"];
1088
+ var baseBarChart = plotArea["c:barChart"];
1089
+ var axisIds = (_l = baseBarChart === null || baseBarChart === void 0 ? void 0 : baseBarChart["c:axId"]) !== null && _l !== void 0 ? _l : [];
1090
+ var dLbls = (_m = baseBarChart === null || baseBarChart === void 0 ? void 0 : baseBarChart["c:dLbls"]) !== null && _m !== void 0 ? _m : {};
1091
+ // Remove the default bar chart - we'll add specific chart types
1092
+ removeProp(plotArea, "c:barChart");
1093
+ try {
1094
+ // Add chart type containers for each group
1095
+ for (var groups_1 = __values(groups), groups_1_1 = groups_1.next(); !groups_1_1.done; groups_1_1 = groups_1.next()) {
1096
+ var _11 = __read(groups_1_1.value, 2), groupType = _11[0], groupSeries = _11[1];
1097
+ if (groupType === "bar" || groupType === "column") {
1098
+ var barChartNode = {
1099
+ "c:barDir": { a$: { val: groupType === "bar" ? "bar" : "col" } },
1100
+ "c:grouping": { a$: { val: "clustered" } },
1101
+ "c:varyColors": { a$: { val: "0" } },
1102
+ "c:ser": [],
1103
+ "c:dLbls": dLbls,
1104
+ "c:axId": axisIds,
1105
+ };
1106
+ for (var i = 0; i < groupSeries.length; i++) {
1107
+ var _12 = groupSeries[i], index = _12.index, ref = _12.ref, data = _12.data;
1108
+ var seriesNode = buildBarSeriesNode(index, ref, data, (_o = seriesCatRefs[index]) !== null && _o !== void 0 ? _o : domainRef, sheetName, i === 0);
1109
+ barChartNode["c:ser"].push(seriesNode);
1110
+ }
1111
+ plotArea["c:barChart"] = barChartNode;
1112
+ }
1113
+ else if (groupType === "line") {
1114
+ var lineChartNode = {
1115
+ "c:grouping": { a$: { val: "standard" } },
1116
+ "c:varyColors": { a$: { val: "0" } },
1117
+ "c:ser": [],
1118
+ "c:dLbls": dLbls,
1119
+ "c:axId": axisIds,
1120
+ };
1121
+ try {
1122
+ for (var groupSeries_1 = (e_4 = void 0, __values(groupSeries)), groupSeries_1_1 = groupSeries_1.next(); !groupSeries_1_1.done; groupSeries_1_1 = groupSeries_1.next()) {
1123
+ var _13 = groupSeries_1_1.value, index = _13.index, ref = _13.ref, data = _13.data;
1124
+ var seriesNode = buildLineSeriesNode(index, ref, data, (_p = seriesCatRefs[index]) !== null && _p !== void 0 ? _p : domainRef, sheetName, smooth);
1125
+ lineChartNode["c:ser"].push(seriesNode);
1126
+ }
1127
+ }
1128
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
1129
+ finally {
1130
+ try {
1131
+ if (groupSeries_1_1 && !groupSeries_1_1.done && (_b = groupSeries_1.return)) _b.call(groupSeries_1);
1132
+ }
1133
+ finally { if (e_4) throw e_4.error; }
1134
+ }
1135
+ plotArea["c:lineChart"] = lineChartNode;
1136
+ }
1137
+ else if (groupType === "area") {
1138
+ var areaChartNode = {
1139
+ "c:grouping": { a$: { val: "standard" } },
1140
+ "c:varyColors": { a$: { val: "0" } },
1141
+ "c:ser": [],
1142
+ "c:dLbls": dLbls,
1143
+ "c:axId": axisIds,
1144
+ };
1145
+ try {
1146
+ for (var groupSeries_2 = (e_5 = void 0, __values(groupSeries)), groupSeries_2_1 = groupSeries_2.next(); !groupSeries_2_1.done; groupSeries_2_1 = groupSeries_2.next()) {
1147
+ var _14 = groupSeries_2_1.value, index = _14.index, ref = _14.ref, data = _14.data;
1148
+ var seriesNode = buildAreaSeriesNode(index, ref, data, (_q = seriesCatRefs[index]) !== null && _q !== void 0 ? _q : domainRef, sheetName);
1149
+ areaChartNode["c:ser"].push(seriesNode);
1150
+ }
1151
+ }
1152
+ catch (e_5_1) { e_5 = { error: e_5_1 }; }
1153
+ finally {
1154
+ try {
1155
+ if (groupSeries_2_1 && !groupSeries_2_1.done && (_c = groupSeries_2.return)) _c.call(groupSeries_2);
1156
+ }
1157
+ finally { if (e_5) throw e_5.error; }
1158
+ }
1159
+ plotArea["c:areaChart"] = areaChartNode;
1160
+ }
1161
+ }
1162
+ }
1163
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
1164
+ finally {
1165
+ try {
1166
+ if (groups_1_1 && !groups_1_1.done && (_a = groups_1.return)) _a.call(groups_1);
1167
+ }
1168
+ finally { if (e_3) throw e_3.error; }
1169
+ }
1170
+ chartSpace["c:chartSpace"]["c:chart"] = comboChart;
1171
+ var xml_1 = chartBuilder.build(chartSpace);
1172
+ return "".concat(XML_DECLARATION).concat(xml_1);
1173
+ }
1174
+ // Handle non-combo charts (original logic)
1175
+ if (isC15ChartType(chartType)) {
1176
+ // Histogram / boxplot / waterfall / funnel emit as a barChart for
1177
+ // older Excel compatibility. For histogram (Phase 5.5b), the
1178
+ // barChart is wrapped in mc:AlternateContent with a c15:histogramChart
1179
+ // sibling in mc:Choice — Excel 2016+ uses the c15 chart, older
1180
+ // versions fall back to bar. For boxplot/waterfall/funnel we still
1181
+ // use the c15 extension marker (round-trips in our pipeline; opens
1182
+ // as bar chart in Excel) until those types get the same upgrade.
1183
+ var barChartDoc = cloneTemplate(column_json);
1184
+ applyChartTitle(barChartDoc, chartTitle, chartTitleFmt, chartSubtitle);
1185
+ var bar = barChartDoc["c:plotArea"]["c:barChart"];
1186
+ bar["c:barDir"].a$.val = "col";
1187
+ var seriesContainer_1 = bar["c:ser"];
1188
+ seriesRefs.forEach(function (ref, index) {
1189
+ var _a, _b, _c, _d, _e;
1190
+ if (!ref)
1191
+ return;
1192
+ var seriesNode = cloneTemplate(column_series);
1193
+ seriesNode["c:idx"] = { a$: { val: index.toString() } };
1194
+ seriesNode["c:order"] = { a$: { val: index.toString() } };
1195
+ var seriesColor = (_a = series[index]) === null || _a === void 0 ? void 0 : _a.color;
1196
+ if (applySeriesGradient(seriesNode, (_b = series[index]) === null || _b === void 0 ? void 0 : _b.gradient)) {
1197
+ // Gradient applied; nothing else.
1198
+ }
1199
+ else if (seriesColor) {
1200
+ seriesNode["c:spPr"]["a:solidFill"] =
1201
+ buildColorNode(seriesColor)["a:solidFill"];
1202
+ }
1203
+ else if (index < 6) {
1204
+ seriesNode["c:spPr"]["a:solidFill"]["a:schemeClr"].a$.val = "accent".concat(index + 1);
1205
+ }
1206
+ if (!index && domainRef) {
1207
+ seriesNode["c:cat"] = {
1208
+ "c:strRef": {
1209
+ "c:f": domainRef,
1210
+ },
1211
+ };
1212
+ }
1213
+ seriesNode["c:val"]["c:numRef"]["c:f"] = ref;
1214
+ var labelNode = buildSeriesLabel((_d = (_c = series[index]) === null || _c === void 0 ? void 0 : _c.dataLabel) !== null && _d !== void 0 ? _d : undefined, sheetNameById.get(chart.position.sheetId), (_e = series[index]) === null || _e === void 0 ? void 0 : _e.dataLabelRef);
1215
+ if (labelNode) {
1216
+ seriesNode["c:tx"] = labelNode["c:tx"];
1217
+ }
1218
+ seriesContainer_1.push(seriesNode);
1219
+ });
1220
+ // Phase 5.5b: wrap the bar chart in mc:AlternateContent and emit
1221
+ // a full c15:* chart in mc:Choice so Excel 2016+ renders natively.
1222
+ // c:catAx / c:valAx stay at c:plotArea level — both Choice and
1223
+ // Fallback reference them through matching axId values.
1224
+ var axIdNodes = bar["c:axId"];
1225
+ var catAxId = (_t = (_s = (_r = axIdNodes === null || axIdNodes === void 0 ? void 0 : axIdNodes[0]) === null || _r === void 0 ? void 0 : _r.a$) === null || _s === void 0 ? void 0 : _s.val) !== null && _t !== void 0 ? _t : "1";
1226
+ var valAxId = (_w = (_v = (_u = axIdNodes === null || axIdNodes === void 0 ? void 0 : axIdNodes[1]) === null || _u === void 0 ? void 0 : _u.a$) === null || _v === void 0 ? void 0 : _v.val) !== null && _w !== void 0 ? _w : "2";
1227
+ var c15Args = {
1228
+ seriesRefs: seriesRefs,
1229
+ series: series,
1230
+ domainRef: domainRef,
1231
+ axIds: { catAxId: catAxId, valAxId: valAxId },
1232
+ };
1233
+ var c15Chart = void 0;
1234
+ if (chartType === "histogram") {
1235
+ c15Chart = buildC15HistogramChartNode(chart.spec, c15Args.seriesRefs, c15Args.series, c15Args.domainRef, c15Args.axIds);
1236
+ }
1237
+ else if (chartType === "boxplot") {
1238
+ c15Chart = buildC15BoxplotChartNode(chart.spec, c15Args.seriesRefs, c15Args.series, c15Args.domainRef, c15Args.axIds);
1239
+ }
1240
+ else if (chartType === "waterfall") {
1241
+ c15Chart = buildC15WaterfallChartNode(chart.spec, c15Args.seriesRefs, c15Args.series, c15Args.domainRef, c15Args.axIds);
1242
+ }
1243
+ else {
1244
+ c15Chart = buildC15FunnelChartNode(chart.spec, c15Args.seriesRefs, c15Args.series, c15Args.domainRef, c15Args.axIds);
1245
+ }
1246
+ var altContent = buildC15AlternateContent(chartType, c15Chart, bar);
1247
+ removeProp(barChartDoc["c:plotArea"], "c:barChart");
1248
+ barChartDoc["c:plotArea"]["mc:AlternateContent"] = altContent;
1249
+ chartSpace["c:chartSpace"]["c:chart"] = barChartDoc;
1250
+ }
1251
+ else if (chartType === "bar" || chartType === "column") {
1252
+ var barChart = cloneTemplate(column_json);
1253
+ applyChartTitle(barChart, chartTitle, chartTitleFmt, chartSubtitle);
1254
+ var bar = barChart["c:plotArea"]["c:barChart"];
1255
+ bar["c:barDir"].a$.val = chartType === "bar" ? "bar" : "col";
1256
+ // Grouping / overlap / gapWidth — Excel's stacked / percent-stacked
1257
+ // bars need these set. Excel's defaults are `clustered` + overlap=0
1258
+ // + gapWidth=150; we only emit when the spec actually carries a
1259
+ // value to avoid bloating the file.
1260
+ var stackedType = chart.spec.stackedType;
1261
+ if (stackedType === "STACKED") {
1262
+ bar["c:grouping"] = { a$: { val: "stacked" } };
1263
+ }
1264
+ else if (stackedType === "PERCENT_STACKED") {
1265
+ bar["c:grouping"] = { a$: { val: "percentStacked" } };
1266
+ }
1267
+ else if (stackedType === "UNSTACKED") {
1268
+ bar["c:grouping"] = { a$: { val: "clustered" } };
1269
+ }
1270
+ var overlap = chart.spec.overlap;
1271
+ if (typeof overlap === "number") {
1272
+ bar["c:overlap"] = { a$: { val: String(Math.round(overlap)) } };
1273
+ }
1274
+ var gapWidth = chart.spec.gapWidth;
1275
+ if (typeof gapWidth === "number") {
1276
+ bar["c:gapWidth"] = { a$: { val: String(Math.round(gapWidth)) } };
1277
+ }
1278
+ var seriesContainer_2 = bar["c:ser"];
1279
+ // Inline categories — when no cell-range, use the first domain's
1280
+ // inlineValues directly on the first series' c:cat.
1281
+ var inlineDomainValues_1 = (_y = (_x = chart.spec.domains) === null || _x === void 0 ? void 0 : _x[0]) === null || _y === void 0 ? void 0 : _y.inlineValues;
1282
+ seriesRefs.forEach(function (ref, index) {
1283
+ var _a, _b;
1284
+ if (!ref && !((_a = series[index]) === null || _a === void 0 ? void 0 : _a.inlineValues))
1285
+ return;
1286
+ // Decorate the spec entry with the chart-level inline domain so
1287
+ // `buildBarSeriesNode` can emit `<c:strLit>` on the first series.
1288
+ var enrichedSeries = index === 0 && !domainRef && (inlineDomainValues_1 === null || inlineDomainValues_1 === void 0 ? void 0 : inlineDomainValues_1.length)
1289
+ ? __assign(__assign({}, series[index]), { inlineDomainValues: inlineDomainValues_1 })
1290
+ : series[index];
1291
+ var seriesNode = buildBarSeriesNode(index, ref !== null && ref !== void 0 ? ref : "", enrichedSeries, (_b = seriesCatRefs[index]) !== null && _b !== void 0 ? _b : domainRef, sheetNameById.get(chart.position.sheetId), index === 0);
1292
+ seriesContainer_2.push(seriesNode);
1293
+ });
1294
+ chartSpace["c:chartSpace"]["c:chart"] = barChart;
1295
+ }
1296
+ else if (chartType === "pie") {
1297
+ var valueRef = seriesRefs.find(Boolean);
1298
+ var specAny = chart.spec;
1299
+ // Pie-of-pie / bar-of-pie round-trips as <c:ofPieChart> when the
1300
+ // spec carries the OF_PIE marker (or an explicit ofPieType).
1301
+ var isOfPie = String((_z = specAny === null || specAny === void 0 ? void 0 : specAny.sourceChartType) !== null && _z !== void 0 ? _z : "").toUpperCase() === "OF_PIE" ||
1302
+ (specAny === null || specAny === void 0 ? void 0 : specAny.ofPieType) === "pie" ||
1303
+ (specAny === null || specAny === void 0 ? void 0 : specAny.ofPieType) === "bar";
1304
+ var pieChart = isOfPie
1305
+ ? buildOfPieChart(domainRef, valueRef, chartTitle, specAny, chartSubtitle)
1306
+ : buildPieChart(domainRef, valueRef, chartTitle, chartSubtitle);
1307
+ if (!isOfPie) {
1308
+ appendExtraCircularSeries(pieChart, "c:pieChart", seriesRefs, seriesCatRefs, domainRef, series, sheetNameById.get(chart.position.sheetId));
1309
+ }
1310
+ chartSpace["c:chartSpace"]["c:chart"] = pieChart;
1311
+ }
1312
+ else if (chartType === "doughnut") {
1313
+ var valueRef = seriesRefs.find(Boolean);
1314
+ var doughnutChart = buildDoughnutChart(domainRef, valueRef, chartTitle, chartSubtitle);
1315
+ appendExtraCircularSeries(doughnutChart, "c:doughnutChart", seriesRefs, seriesCatRefs, domainRef, series, sheetNameById.get(chart.position.sheetId));
1316
+ chartSpace["c:chartSpace"]["c:chart"] = doughnutChart;
1317
+ }
1318
+ else if (chartType === "radar") {
1319
+ var radarChart = buildRadarLikeChart("c:radarChart", domainRef, seriesRefs, chartTitle, (_0 = chart.spec.radarStyle) !== null && _0 !== void 0 ? _0 : "standard", chartSubtitle);
1320
+ chartSpace["c:chartSpace"]["c:chart"] = radarChart;
1321
+ }
1322
+ else if (chartType === "stock") {
1323
+ var stockChart = buildRadarLikeChart("c:stockChart", domainRef, seriesRefs, chartTitle, undefined, chartSubtitle);
1324
+ chartSpace["c:chartSpace"]["c:chart"] = stockChart;
1325
+ }
1326
+ else if (chartType === "line") {
1327
+ var lineChart = cloneTemplate(column_json);
1328
+ applyChartTitle(lineChart, chartTitle, chartTitleFmt, chartSubtitle);
1329
+ var plotArea = lineChart["c:plotArea"];
1330
+ var barChart = plotArea["c:barChart"];
1331
+ var lineChartNode = {
1332
+ "c:grouping": {
1333
+ a$: {
1334
+ val: "standard",
1335
+ },
1336
+ },
1337
+ "c:varyColors": {
1338
+ a$: {
1339
+ val: "0",
1340
+ },
1341
+ },
1342
+ "c:ser": [],
1343
+ "c:dLbls": (_1 = barChart === null || barChart === void 0 ? void 0 : barChart["c:dLbls"]) !== null && _1 !== void 0 ? _1 : {},
1344
+ "c:axId": (_2 = barChart === null || barChart === void 0 ? void 0 : barChart["c:axId"]) !== null && _2 !== void 0 ? _2 : [],
1345
+ };
1346
+ removeProp(plotArea, "c:barChart");
1347
+ plotArea["c:lineChart"] = lineChartNode;
1348
+ var seriesContainer_3 = lineChartNode["c:ser"];
1349
+ seriesRefs.forEach(function (ref, index) {
1350
+ var _a, _b, _c, _d, _e;
1351
+ if (!ref)
1352
+ return;
1353
+ var seriesNode = cloneTemplate(line_series);
1354
+ seriesNode["c:idx"] = { a$: { val: index.toString() } };
1355
+ seriesNode["c:order"] = { a$: { val: index.toString() } };
1356
+ var seriesColor = (_a = series[index]) === null || _a === void 0 ? void 0 : _a.color;
1357
+ if (seriesColor) {
1358
+ seriesNode["c:spPr"]["a:ln"]["a:solidFill"] =
1359
+ buildColorNode(seriesColor)["a:solidFill"];
1360
+ }
1361
+ else if (index < 6) {
1362
+ seriesNode["c:spPr"]["a:ln"]["a:solidFill"]["a:schemeClr"].a$.val = "accent".concat(index + 1);
1363
+ }
1364
+ // Category axis is optional - Excel will use numeric indices if not provided
1365
+ var catRef = (_b = seriesCatRefs[index]) !== null && _b !== void 0 ? _b : domainRef;
1366
+ if (catRef) {
1367
+ seriesNode["c:cat"]["c:strRef"]["c:f"] = catRef;
1368
+ }
1369
+ else {
1370
+ // Remove the category reference if no domain
1371
+ removeProp(seriesNode, "c:cat");
1372
+ }
1373
+ seriesNode["c:val"]["c:numRef"]["c:f"] = ref;
1374
+ if (smooth) {
1375
+ seriesNode["c:smooth"].a$.val = "1";
1376
+ }
1377
+ var labelNode = buildSeriesLabel((_d = (_c = series[index]) === null || _c === void 0 ? void 0 : _c.dataLabel) !== null && _d !== void 0 ? _d : undefined, sheetNameById.get(chart.position.sheetId), (_e = series[index]) === null || _e === void 0 ? void 0 : _e.dataLabelRef);
1378
+ if (labelNode) {
1379
+ seriesNode["c:tx"] = labelNode["c:tx"];
1380
+ }
1381
+ seriesContainer_3.push(seriesNode);
1382
+ });
1383
+ chartSpace["c:chartSpace"]["c:chart"] = lineChart;
1384
+ }
1385
+ else if (chartType === "area") {
1386
+ var areaChart = cloneTemplate(column_json);
1387
+ applyChartTitle(areaChart, chartTitle, chartTitleFmt, chartSubtitle);
1388
+ var plotArea = areaChart["c:plotArea"];
1389
+ var barChart = plotArea["c:barChart"];
1390
+ var areaChartNode = {
1391
+ "c:grouping": {
1392
+ a$: {
1393
+ val: "standard",
1394
+ },
1395
+ },
1396
+ "c:varyColors": {
1397
+ a$: {
1398
+ val: "0",
1399
+ },
1400
+ },
1401
+ "c:ser": [],
1402
+ "c:dLbls": (_3 = barChart === null || barChart === void 0 ? void 0 : barChart["c:dLbls"]) !== null && _3 !== void 0 ? _3 : {},
1403
+ "c:axId": (_4 = barChart === null || barChart === void 0 ? void 0 : barChart["c:axId"]) !== null && _4 !== void 0 ? _4 : [],
1404
+ };
1405
+ removeProp(plotArea, "c:barChart");
1406
+ plotArea["c:areaChart"] = areaChartNode;
1407
+ var seriesContainer_4 = areaChartNode["c:ser"];
1408
+ seriesRefs.forEach(function (ref, index) {
1409
+ var _a, _b, _c, _d, _e;
1410
+ if (!ref)
1411
+ return;
1412
+ var seriesNode = cloneTemplate(area_series);
1413
+ seriesNode["c:idx"] = { a$: { val: index.toString() } };
1414
+ seriesNode["c:order"] = { a$: { val: index.toString() } };
1415
+ var seriesColor = (_a = series[index]) === null || _a === void 0 ? void 0 : _a.color;
1416
+ if (seriesColor) {
1417
+ seriesNode["c:spPr"]["a:solidFill"] =
1418
+ buildColorNode(seriesColor)["a:solidFill"];
1419
+ seriesNode["c:spPr"]["a:ln"]["a:solidFill"] =
1420
+ buildColorNode(seriesColor)["a:solidFill"];
1421
+ }
1422
+ else if (index < 6) {
1423
+ seriesNode["c:spPr"]["a:solidFill"]["a:schemeClr"].a$.val = "accent".concat(index + 1);
1424
+ seriesNode["c:spPr"]["a:ln"]["a:solidFill"]["a:schemeClr"].a$.val = "accent".concat(index + 1);
1425
+ }
1426
+ // Category axis is optional - Excel will use numeric indices if not provided
1427
+ var catRef = (_b = seriesCatRefs[index]) !== null && _b !== void 0 ? _b : domainRef;
1428
+ if (catRef) {
1429
+ seriesNode["c:cat"]["c:strRef"]["c:f"] = catRef;
1430
+ }
1431
+ else {
1432
+ removeProp(seriesNode, "c:cat");
1433
+ }
1434
+ seriesNode["c:val"]["c:numRef"]["c:f"] = ref;
1435
+ var labelNode = buildSeriesLabel((_d = (_c = series[index]) === null || _c === void 0 ? void 0 : _c.dataLabel) !== null && _d !== void 0 ? _d : undefined, sheetNameById.get(chart.position.sheetId), (_e = series[index]) === null || _e === void 0 ? void 0 : _e.dataLabelRef);
1436
+ if (labelNode) {
1437
+ seriesNode["c:tx"] = labelNode["c:tx"];
1438
+ }
1439
+ seriesContainer_4.push(seriesNode);
1440
+ });
1441
+ chartSpace["c:chartSpace"]["c:chart"] = areaChart;
1442
+ }
1443
+ else if (chartType === "scatter" || chartType === "bubble") {
1444
+ var bubbleSpec = chart.spec;
1445
+ var domainEntries_1 = (_5 = bubbleSpec.domains) !== null && _5 !== void 0 ? _5 : [];
1446
+ var seriesEntries = (_6 = bubbleSpec.series) !== null && _6 !== void 0 ? _6 : [];
1447
+ var bubbleSizeEntries_1 = (_7 = bubbleSpec.bubbleSizes) !== null && _7 !== void 0 ? _7 : [];
1448
+ var bubbleLabelEntries_1 = (_8 = bubbleSpec.bubbleLabels) !== null && _8 !== void 0 ? _8 : [];
1449
+ var seriesContainer_5 = [];
1450
+ var seriesTemplate_1 = chartType === "bubble" ? bubble_series : scatter_series;
1451
+ seriesEntries.forEach(function (entry, index) {
1452
+ var _a, _b, _c, _d, _e, _f;
1453
+ var domainRef = formatRangeRef((_a = getPrimarySource(domainEntries_1[index])) !== null && _a !== void 0 ? _a : getPrimarySource(domainEntries_1[0]), sheetNameById);
1454
+ var valueRef = formatRangeRef(getPrimarySource(entry), sheetNameById);
1455
+ if (!domainRef || !valueRef)
1456
+ return;
1457
+ var seriesNode = cloneTemplate(seriesTemplate_1);
1458
+ seriesNode["c:idx"] = { a$: { val: index.toString() } };
1459
+ seriesNode["c:order"] = { a$: { val: index.toString() } };
1460
+ var seriesColor = entry === null || entry === void 0 ? void 0 : entry.color;
1461
+ if (seriesColor) {
1462
+ if (chartType === "bubble") {
1463
+ seriesNode["c:spPr"]["a:solidFill"] =
1464
+ buildColorNode(seriesColor)["a:solidFill"];
1465
+ }
1466
+ else {
1467
+ seriesNode["c:spPr"]["a:ln"]["a:solidFill"] =
1468
+ buildColorNode(seriesColor)["a:solidFill"];
1469
+ }
1470
+ }
1471
+ else if (index < 6) {
1472
+ var colorNode = chartType === "bubble"
1473
+ ? seriesNode["c:spPr"]["a:solidFill"]["a:schemeClr"]
1474
+ : seriesNode["c:spPr"]["a:ln"]["a:solidFill"]["a:schemeClr"];
1475
+ colorNode.a$.val = "accent".concat(index + 1);
1476
+ }
1477
+ seriesNode["c:xVal"]["c:numRef"]["c:f"] = domainRef;
1478
+ seriesNode["c:yVal"]["c:numRef"]["c:f"] = valueRef;
1479
+ if (chartType === "bubble") {
1480
+ var sizeRef = formatRangeRef((_c = (_b = getPrimarySource(bubbleSizeEntries_1[index])) !== null && _b !== void 0 ? _b : getPrimarySource(bubbleSizeEntries_1[0])) !== null && _c !== void 0 ? _c : getPrimarySource(entry), sheetNameById);
1481
+ if (sizeRef) {
1482
+ seriesNode["c:bubbleSize"]["c:numRef"]["c:f"] = sizeRef;
1483
+ }
1484
+ }
1485
+ else if (smooth) {
1486
+ seriesNode["c:smooth"].a$.val = "1";
1487
+ }
1488
+ var labelNode = buildSeriesLabel((_f = (_d = entry === null || entry === void 0 ? void 0 : entry.dataLabel) !== null && _d !== void 0 ? _d : (_e = bubbleLabelEntries_1[index]) === null || _e === void 0 ? void 0 : _e.dataLabel) !== null && _f !== void 0 ? _f : undefined, sheetNameById.get(chart.position.sheetId), entry === null || entry === void 0 ? void 0 : entry.dataLabelRef);
1489
+ if (labelNode) {
1490
+ seriesNode["c:tx"] = labelNode["c:tx"];
1491
+ }
1492
+ seriesContainer_5.push(seriesNode);
1493
+ });
1494
+ if (!seriesContainer_5.length)
1495
+ return undefined;
1496
+ var chartDoc = cloneTemplate(scatter_json);
1497
+ applyChartTitle(chartDoc, chartTitle, chartTitleFmt, chartSubtitle);
1498
+ var plotArea = chartDoc["c:plotArea"];
1499
+ var scatterChart = plotArea["c:scatterChart"];
1500
+ if (chartType === "bubble") {
1501
+ removeProp(plotArea, "c:scatterChart");
1502
+ removeProp(scatterChart, "c:scatterStyle");
1503
+ scatterChart["c:bubbleScale"] = { a$: { val: "100" } };
1504
+ scatterChart["c:showNegBubbles"] = { a$: { val: "0" } };
1505
+ scatterChart["c:sizeRepresents"] = { a$: { val: "area" } };
1506
+ plotArea["c:bubbleChart"] = scatterChart;
1507
+ }
1508
+ else {
1509
+ // <c:scatterStyle> — Excel default is "lineMarker". Round-trip
1510
+ // whatever the spec carries so the connecting line / marker mix
1511
+ // survives re-saving.
1512
+ var scatterStyle = chart.spec.scatterStyle;
1513
+ if (scatterStyle && typeof scatterStyle === "string") {
1514
+ scatterChart["c:scatterStyle"] = { a$: { val: scatterStyle } };
1515
+ }
1516
+ }
1517
+ // Per-series marker — append to each series node that doesn't yet
1518
+ // carry one (scatter/bubble series templates already include a
1519
+ // marker block in many cases; only add when authored).
1520
+ seriesContainer_5.forEach(function (node, i) {
1521
+ var _a, _b;
1522
+ var markerSpec = (_b = (_a = chart.spec.series) === null || _a === void 0 ? void 0 : _a[i]) === null || _b === void 0 ? void 0 : _b.marker;
1523
+ var m = buildMarkerNode(markerSpec);
1524
+ if (m) {
1525
+ node["c:marker"] = m;
1526
+ }
1527
+ });
1528
+ var targetChart = chartType === "bubble" ? plotArea["c:bubbleChart"] : scatterChart;
1529
+ targetChart["c:ser"] = seriesContainer_5;
1530
+ chartSpace["c:chartSpace"]["c:chart"] = chartDoc;
1531
+ }
1532
+ else if (chartType === "treemap" || chartType === "sunburst") {
1533
+ var treeSpec = chart.spec;
1534
+ var labelRef = formatRangeRef(getPrimarySource((_9 = treeSpec.labels) === null || _9 === void 0 ? void 0 : _9[0]), sheetNameById);
1535
+ var sizeRef = formatRangeRef(getPrimarySource((_10 = treeSpec.sizeData) === null || _10 === void 0 ? void 0 : _10[0]), sheetNameById);
1536
+ if (!labelRef || !sizeRef)
1537
+ return undefined;
1538
+ if (chartType === "sunburst") {
1539
+ var pieChart = buildPieChart(labelRef, sizeRef, chartTitle, chartSubtitle);
1540
+ chartSpace["c:chartSpace"]["c:chart"] = pieChart;
1541
+ }
1542
+ else {
1543
+ var columnChart = cloneTemplate(column_json);
1544
+ applyChartTitle(columnChart, chartTitle, chartTitleFmt, chartSubtitle);
1545
+ var bar = columnChart["c:plotArea"]["c:barChart"];
1546
+ var seriesContainer = bar["c:ser"];
1547
+ var seriesNode = cloneTemplate(column_series);
1548
+ seriesNode["c:idx"] = { a$: { val: "0" } };
1549
+ seriesNode["c:order"] = { a$: { val: "0" } };
1550
+ seriesNode["c:cat"] = {
1551
+ "c:strRef": {
1552
+ "c:f": labelRef,
1553
+ },
1554
+ };
1555
+ seriesNode["c:val"]["c:numRef"]["c:f"] = sizeRef;
1556
+ seriesContainer.push(seriesNode);
1557
+ chartSpace["c:chartSpace"]["c:chart"] = columnChart;
1558
+ }
1559
+ }
1560
+ else {
1561
+ return undefined;
1562
+ }
1563
+ // Apply Phase 5.1 formatting (legend, data labels, axis options) to the
1564
+ // assembled chart. These mutate the chart node in place — they're
1565
+ // chartType-agnostic and intentionally run last so per-type branches
1566
+ // don't have to know about them.
1567
+ applyChartFormatting(chartSpace, chart.spec, sheetNameById);
1568
+ // `<c:roundedCorners val="1"/>` lives at the chartSpace root (sibling
1569
+ // of `<c:chart>`). Default per OOXML §21.2.2.183 is `false`; only
1570
+ // emit when the spec opted in so files imported without the element
1571
+ // round-trip cleanly without gaining a spurious one.
1572
+ if (chart.spec.roundedCorners) {
1573
+ chartSpace["c:chartSpace"]["c:roundedCorners"] = { a$: { val: "1" } };
1574
+ }
1575
+ var xml = chartBuilder.build(chartSpace);
1576
+ return "".concat(XML_DECLARATION).concat(xml);
1577
+ };
1578
+ // -------------------------- Phase 5 helpers --------------------------
1579
+ var LEGEND_POS = {
1580
+ top: "t",
1581
+ bottom: "b",
1582
+ left: "l",
1583
+ right: "r",
1584
+ topRight: "tr",
1585
+ };
1586
+ var DLBL_POS = {
1587
+ center: "ctr",
1588
+ inside: "inBase",
1589
+ outside: "outEnd",
1590
+ insideEnd: "inEnd",
1591
+ outsideEnd: "outEnd",
1592
+ bestFit: "bestFit",
1593
+ };
1594
+ var applyChartFormatting = function (chartSpace, spec, sheetNameById) {
1595
+ var _a;
1596
+ var chartNode = (_a = chartSpace === null || chartSpace === void 0 ? void 0 : chartSpace["c:chartSpace"]) === null || _a === void 0 ? void 0 : _a["c:chart"];
1597
+ if (!chartNode)
1598
+ return;
1599
+ applyLegend(chartNode, spec === null || spec === void 0 ? void 0 : spec.legend);
1600
+ var plotArea = chartNode["c:plotArea"];
1601
+ if (!plotArea)
1602
+ return;
1603
+ applyDataLabels(plotArea, spec === null || spec === void 0 ? void 0 : spec.dataLabels);
1604
+ applyAxisOptions(plotArea, spec === null || spec === void 0 ? void 0 : spec.valueAxisOptions, "value");
1605
+ applyAxisOptions(plotArea, spec === null || spec === void 0 ? void 0 : spec.categoryAxisOptions, "category");
1606
+ applyDoughnutHole(plotArea, spec === null || spec === void 0 ? void 0 : spec.doughnutHoleSize);
1607
+ applySeriesOverlays(plotArea, spec === null || spec === void 0 ? void 0 : spec.series, sheetNameById);
1608
+ applySecondaryAxis(plotArea, spec === null || spec === void 0 ? void 0 : spec.secondaryValueAxisOptions);
1609
+ };
1610
+ var SERIES_CONTAINER_KEYS = [
1611
+ "c:barChart",
1612
+ "c:lineChart",
1613
+ "c:pieChart",
1614
+ "c:doughnutChart",
1615
+ "c:areaChart",
1616
+ "c:scatterChart",
1617
+ "c:bubbleChart",
1618
+ ];
1619
+ /**
1620
+ * Walk the per-chart-type containers in plotArea and apply trendlines
1621
+ * / errBars to each emitted `<c:ser>`. The series order in spec.series
1622
+ * matches the order emitted by the builder, so we index by position.
1623
+ */
1624
+ var applySeriesOverlays = function (plotArea, series, sheetNameById) {
1625
+ var e_6, _a, e_7, _b;
1626
+ if (!Array.isArray(series) || !series.length)
1627
+ return;
1628
+ var seriesIndex = 0;
1629
+ try {
1630
+ for (var SERIES_CONTAINER_KEYS_1 = __values(SERIES_CONTAINER_KEYS), SERIES_CONTAINER_KEYS_1_1 = SERIES_CONTAINER_KEYS_1.next(); !SERIES_CONTAINER_KEYS_1_1.done; SERIES_CONTAINER_KEYS_1_1 = SERIES_CONTAINER_KEYS_1.next()) {
1631
+ var key = SERIES_CONTAINER_KEYS_1_1.value;
1632
+ var container = plotArea[key];
1633
+ if (!container)
1634
+ continue;
1635
+ var ser = container["c:ser"];
1636
+ if (!ser)
1637
+ continue;
1638
+ var list = Array.isArray(ser) ? ser : [ser];
1639
+ try {
1640
+ for (var list_1 = (e_7 = void 0, __values(list)), list_1_1 = list_1.next(); !list_1_1.done; list_1_1 = list_1.next()) {
1641
+ var node = list_1_1.value;
1642
+ var data = series[seriesIndex++];
1643
+ if (!data)
1644
+ continue;
1645
+ if (Array.isArray(data.trendlines) && data.trendlines.length) {
1646
+ var built = data.trendlines
1647
+ .map(buildTrendlineNode)
1648
+ .filter(Boolean);
1649
+ // OOXML allows multiple <c:trendline> on a series; preserve the
1650
+ // order from the spec.
1651
+ node["c:trendline"] = built.length === 1 ? built[0] : built;
1652
+ }
1653
+ if (data.errorBars) {
1654
+ var built = buildErrorBarsNode(data.errorBars, sheetNameById);
1655
+ if (built)
1656
+ node["c:errBars"] = built;
1657
+ }
1658
+ }
1659
+ }
1660
+ catch (e_7_1) { e_7 = { error: e_7_1 }; }
1661
+ finally {
1662
+ try {
1663
+ if (list_1_1 && !list_1_1.done && (_b = list_1.return)) _b.call(list_1);
1664
+ }
1665
+ finally { if (e_7) throw e_7.error; }
1666
+ }
1667
+ }
1668
+ }
1669
+ catch (e_6_1) { e_6 = { error: e_6_1 }; }
1670
+ finally {
1671
+ try {
1672
+ if (SERIES_CONTAINER_KEYS_1_1 && !SERIES_CONTAINER_KEYS_1_1.done && (_a = SERIES_CONTAINER_KEYS_1.return)) _a.call(SERIES_CONTAINER_KEYS_1);
1673
+ }
1674
+ finally { if (e_6) throw e_6.error; }
1675
+ }
1676
+ };
1677
+ var buildTrendlineNode = function (t) {
1678
+ var _a;
1679
+ if (!t)
1680
+ return undefined;
1681
+ var node = {};
1682
+ if (t.name) {
1683
+ node["c:name"] = { t$: String(t.name) };
1684
+ }
1685
+ // <c:trendlineType val="linear|exp|log|poly|power|movingAvg"/>
1686
+ node["c:trendlineType"] = {
1687
+ a$: { val: (_a = t.type) !== null && _a !== void 0 ? _a : "linear" },
1688
+ };
1689
+ if (t.type === "poly" && typeof t.order === "number") {
1690
+ node["c:order"] = { a$: { val: String(t.order) } };
1691
+ }
1692
+ if (t.type === "movingAvg" && typeof t.period === "number") {
1693
+ node["c:period"] = { a$: { val: String(t.period) } };
1694
+ }
1695
+ if (typeof t.forecastForward === "number") {
1696
+ node["c:forward"] = { a$: { val: String(t.forecastForward) } };
1697
+ }
1698
+ if (typeof t.forecastBackward === "number") {
1699
+ node["c:backward"] = { a$: { val: String(t.forecastBackward) } };
1700
+ }
1701
+ if (t.showEquation) {
1702
+ node["c:dispEq"] = { a$: { val: "1" } };
1703
+ }
1704
+ if (t.showRSquared) {
1705
+ node["c:dispRSqr"] = { a$: { val: "1" } };
1706
+ }
1707
+ return node;
1708
+ };
1709
+ var buildErrorBarsNode = function (eb, sheetNameById) {
1710
+ var _a, _b, _c;
1711
+ if (!eb)
1712
+ return undefined;
1713
+ var node = {};
1714
+ if (eb.direction === "x" || eb.direction === "y") {
1715
+ node["c:errDir"] = { a$: { val: eb.direction } };
1716
+ }
1717
+ node["c:errBarType"] = { a$: { val: (_a = eb.barType) !== null && _a !== void 0 ? _a : "both" } };
1718
+ var valueType = eb.valueType === "custom" ? "cust" : eb.valueType;
1719
+ node["c:errValType"] = { a$: { val: valueType !== null && valueType !== void 0 ? valueType : "fixedVal" } };
1720
+ if (eb.noEndCap) {
1721
+ node["c:noEndCap"] = { a$: { val: "1" } };
1722
+ }
1723
+ // Custom error bars — per-point magnitudes come from worksheet
1724
+ // ranges emitted as `<c:plus>/<c:minus>` numRefs. Schema order puts
1725
+ // them after noEndCap and before `<c:val>`.
1726
+ if (valueType === "cust") {
1727
+ var plusRef = formatRangeRef((_b = eb.plusRange) !== null && _b !== void 0 ? _b : undefined, sheetNameById);
1728
+ var minusRef = formatRangeRef((_c = eb.minusRange) !== null && _c !== void 0 ? _c : undefined, sheetNameById);
1729
+ if (plusRef) {
1730
+ node["c:plus"] = { "c:numRef": { "c:f": plusRef } };
1731
+ }
1732
+ if (minusRef) {
1733
+ node["c:minus"] = { "c:numRef": { "c:f": minusRef } };
1734
+ }
1735
+ }
1736
+ if (typeof eb.value === "number") {
1737
+ node["c:val"] = { a$: { val: String(eb.value) } };
1738
+ }
1739
+ return node;
1740
+ };
1741
+ /**
1742
+ * Add a secondary `<c:valAx>` next to the primary one when the spec
1743
+ * carries `secondaryValueAxisOptions`. We give it a distinct axId
1744
+ * (existing primary axId + 100) — series-level routing to the new axis
1745
+ * is intentionally not wired up here (most consumers of "secondary
1746
+ * axis" only care about the data round-trip; full charting fidelity
1747
+ * lands in a follow-up).
1748
+ */
1749
+ var applySecondaryAxis = function (plotArea, opts) {
1750
+ var _a, _b, _c;
1751
+ if (!opts)
1752
+ return;
1753
+ var existing = plotArea["c:valAx"];
1754
+ if (!existing)
1755
+ return;
1756
+ var existingArr = Array.isArray(existing) ? existing : [existing];
1757
+ if (existingArr.length >= 2)
1758
+ return; // already has secondary
1759
+ var primary = existingArr[0];
1760
+ var primaryAxId = parseInt(((_c = (_b = (_a = primary === null || primary === void 0 ? void 0 : primary["c:axId"]) === null || _a === void 0 ? void 0 : _a.a$) === null || _b === void 0 ? void 0 : _b.val) !== null && _c !== void 0 ? _c : "1000"), 10);
1761
+ var secondary = {
1762
+ "c:axId": { a$: { val: String(primaryAxId + 100) } },
1763
+ "c:scaling": { "c:orientation": { a$: { val: "minMax" } } },
1764
+ "c:delete": { a$: { val: "0" } },
1765
+ "c:axPos": { a$: { val: "r" } },
1766
+ "c:crossAx": { a$: { val: String(primaryAxId) } },
1767
+ };
1768
+ // Apply the same logarithmic / reverse / min / max / gridlines etc.
1769
+ applyAxisOptions({ "c:valAx": secondary }, opts, "value");
1770
+ plotArea["c:valAx"] = __spreadArray(__spreadArray([], __read(existingArr), false), [secondary], false);
1771
+ };
1772
+ var applyLegend = function (chartNode, legend) {
1773
+ var _a;
1774
+ if (!legend)
1775
+ return;
1776
+ if (legend.position === "none") {
1777
+ // Excel omits <c:legend> entirely when hidden; some readers expect
1778
+ // an explicit <c:legend><c:delete val="1"/> instead. Use the
1779
+ // explicit form so the suppression survives ANY reader.
1780
+ chartNode["c:legend"] = {
1781
+ "c:delete": { a$: { val: "1" } },
1782
+ };
1783
+ return;
1784
+ }
1785
+ var posCode = LEGEND_POS[legend.position];
1786
+ var txPr = buildTxPrNode(legend.textFormat);
1787
+ if (!posCode) {
1788
+ // No explicit position — just ensure the legend element exists,
1789
+ // attach text formatting if authored.
1790
+ var existing = (_a = chartNode["c:legend"]) !== null && _a !== void 0 ? _a : {};
1791
+ if (txPr)
1792
+ existing["c:txPr"] = txPr;
1793
+ chartNode["c:legend"] = existing;
1794
+ return;
1795
+ }
1796
+ chartNode["c:legend"] = __assign({ "c:legendPos": { a$: { val: posCode } }, "c:overlay": { a$: { val: "0" } } }, (txPr ? { "c:txPr": txPr } : {}));
1797
+ };
1798
+ var applyDataLabels = function (plotArea, dataLabels) {
1799
+ if (!(dataLabels === null || dataLabels === void 0 ? void 0 : dataLabels.show))
1800
+ return;
1801
+ // Find the chart-type container inside <c:plotArea>. We attach <c:dLbls>
1802
+ // to whichever exists.
1803
+ var containerKey = [
1804
+ "c:barChart",
1805
+ "c:lineChart",
1806
+ "c:pieChart",
1807
+ "c:doughnutChart",
1808
+ "c:areaChart",
1809
+ ].find(function (k) { return plotArea[k]; });
1810
+ if (!containerKey)
1811
+ return;
1812
+ var container = plotArea[containerKey];
1813
+ var posCode = dataLabels.position && DLBL_POS[dataLabels.position];
1814
+ var dLbls = {};
1815
+ if (posCode)
1816
+ dLbls["c:dLblPos"] = { a$: { val: posCode } };
1817
+ // <c:numFmt> — emit before the show* flags. Excel reads this to
1818
+ // format the label value (e.g. `"$"#,##0` → "$1,831").
1819
+ if (dataLabels.numberFormatPattern) {
1820
+ dLbls["c:numFmt"] = {
1821
+ a$: {
1822
+ formatCode: dataLabels.numberFormatPattern,
1823
+ sourceLinked: "0",
1824
+ },
1825
+ };
1826
+ }
1827
+ // <c:txPr> — authored color / font / bold for the label text.
1828
+ var txPr = buildTxPrNode(dataLabels.textFormat);
1829
+ if (txPr)
1830
+ dLbls["c:txPr"] = txPr;
1831
+ // OOXML requires explicit boolean flags. When none of show* are set,
1832
+ // default to showVal=1 since that's Excel's default for "Show Labels".
1833
+ var showValue = dataLabels.showValue === undefined
1834
+ ? !dataLabels.showCategoryName &&
1835
+ !dataLabels.showPercent &&
1836
+ !dataLabels.showSeriesName
1837
+ : !!dataLabels.showValue;
1838
+ dLbls["c:showLegendKey"] = { a$: { val: "0" } };
1839
+ dLbls["c:showVal"] = { a$: { val: showValue ? "1" : "0" } };
1840
+ dLbls["c:showCatName"] = {
1841
+ a$: { val: dataLabels.showCategoryName ? "1" : "0" },
1842
+ };
1843
+ dLbls["c:showSerName"] = {
1844
+ a$: { val: dataLabels.showSeriesName ? "1" : "0" },
1845
+ };
1846
+ dLbls["c:showPercent"] = {
1847
+ a$: { val: dataLabels.showPercent ? "1" : "0" },
1848
+ };
1849
+ dLbls["c:showBubbleSize"] = { a$: { val: "0" } };
1850
+ container["c:dLbls"] = dLbls;
1851
+ };
1852
+ var applyAxisOptions = function (plotArea, options, kind) {
1853
+ var _a;
1854
+ if (!options)
1855
+ return;
1856
+ var axisKey = kind === "value" ? "c:valAx" : "c:catAx";
1857
+ var ax = plotArea[axisKey];
1858
+ if (!ax)
1859
+ return;
1860
+ // OOXML can carry multiple axes (e.g. primary + secondary). Target the
1861
+ // first one for now — secondary axes ship in Phase 5.2.
1862
+ var node = Array.isArray(ax) ? ax[0] : ax;
1863
+ var scaling = (node["c:scaling"] = (_a = node["c:scaling"]) !== null && _a !== void 0 ? _a : {});
1864
+ if (options.logarithmic) {
1865
+ scaling["c:logBase"] = { a$: { val: "10" } };
1866
+ }
1867
+ if (options.reverse) {
1868
+ scaling["c:orientation"] = { a$: { val: "maxMin" } };
1869
+ }
1870
+ if (typeof options.min === "number") {
1871
+ scaling["c:min"] = { a$: { val: String(options.min) } };
1872
+ }
1873
+ if (typeof options.max === "number") {
1874
+ scaling["c:max"] = { a$: { val: String(options.max) } };
1875
+ }
1876
+ if (options.visible === false) {
1877
+ node["c:delete"] = { a$: { val: "1" } };
1878
+ }
1879
+ if (options.showMajorGridlines === true && !node["c:majorGridlines"]) {
1880
+ node["c:majorGridlines"] = {};
1881
+ }
1882
+ if (options.showMajorGridlines === false && node["c:majorGridlines"]) {
1883
+ delete node["c:majorGridlines"];
1884
+ }
1885
+ // <c:txPr> — axis tick-label color/font. Without this, exported
1886
+ // axes would render with the default theme color instead of the
1887
+ // authored one (BEP.xlsx axis colors #14325A / #F0621C).
1888
+ var txPr = buildTxPrNode(options.textFormat);
1889
+ if (txPr)
1890
+ node["c:txPr"] = txPr;
1891
+ };
1892
+ var applyDoughnutHole = function (plotArea, holeSize) {
1893
+ if (typeof holeSize !== "number")
1894
+ return;
1895
+ var doughnut = plotArea["c:doughnutChart"];
1896
+ if (!doughnut)
1897
+ return;
1898
+ // Convert 0-1 fraction back to OOXML's 0-90 percentage.
1899
+ var pct = Math.round(Math.max(0, Math.min(0.9, holeSize)) * 100);
1900
+ doughnut["c:holeSize"] = { a$: { val: String(pct) } };
1901
+ };