@shbernal/ts-xlsx 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (223) hide show
  1. package/LICENSE +23 -0
  2. package/README.md +230 -0
  3. package/dist/core/address.d.ts +49 -0
  4. package/dist/core/address.js +125 -0
  5. package/dist/core/autofilter.d.ts +55 -0
  6. package/dist/core/autofilter.js +48 -0
  7. package/dist/core/cell.d.ts +132 -0
  8. package/dist/core/cell.js +249 -0
  9. package/dist/core/color-resolution.d.ts +58 -0
  10. package/dist/core/color-resolution.js +170 -0
  11. package/dist/core/column.d.ts +87 -0
  12. package/dist/core/column.js +167 -0
  13. package/dist/core/comment-thread.d.ts +116 -0
  14. package/dist/core/comment-thread.js +62 -0
  15. package/dist/core/conditional-formatting-overlay.d.ts +15 -0
  16. package/dist/core/conditional-formatting-overlay.js +24 -0
  17. package/dist/core/conditional-formatting.d.ts +70 -0
  18. package/dist/core/conditional-formatting.js +35 -0
  19. package/dist/core/containers.d.ts +2 -0
  20. package/dist/core/containers.js +25 -0
  21. package/dist/core/data-validation-overlay.d.ts +28 -0
  22. package/dist/core/data-validation-overlay.js +56 -0
  23. package/dist/core/data-validation.d.ts +38 -0
  24. package/dist/core/data-validation.js +13 -0
  25. package/dist/core/date.d.ts +25 -0
  26. package/dist/core/date.js +58 -0
  27. package/dist/core/formula.d.ts +49 -0
  28. package/dist/core/formula.js +319 -0
  29. package/dist/core/grid-edits.d.ts +22 -0
  30. package/dist/core/grid-edits.js +206 -0
  31. package/dist/core/image.d.ts +76 -0
  32. package/dist/core/image.js +65 -0
  33. package/dist/core/internal.d.ts +11 -0
  34. package/dist/core/internal.js +29 -0
  35. package/dist/core/merge.d.ts +13 -0
  36. package/dist/core/merge.js +26 -0
  37. package/dist/core/modern-functions.d.ts +1 -0
  38. package/dist/core/modern-functions.js +165 -0
  39. package/dist/core/page-setup.d.ts +94 -0
  40. package/dist/core/page-setup.js +6 -0
  41. package/dist/core/pivot-table.d.ts +113 -0
  42. package/dist/core/pivot-table.js +249 -0
  43. package/dist/core/preserved.d.ts +58 -0
  44. package/dist/core/preserved.js +5 -0
  45. package/dist/core/protection.d.ts +67 -0
  46. package/dist/core/protection.js +68 -0
  47. package/dist/core/range.d.ts +112 -0
  48. package/dist/core/range.js +283 -0
  49. package/dist/core/row.d.ts +73 -0
  50. package/dist/core/row.js +135 -0
  51. package/dist/core/style.d.ts +246 -0
  52. package/dist/core/style.js +125 -0
  53. package/dist/core/table-style.d.ts +67 -0
  54. package/dist/core/table-style.js +90 -0
  55. package/dist/core/table.d.ts +194 -0
  56. package/dist/core/table.js +291 -0
  57. package/dist/core/theme.d.ts +90 -0
  58. package/dist/core/theme.js +272 -0
  59. package/dist/core/value.d.ts +115 -0
  60. package/dist/core/value.js +144 -0
  61. package/dist/core/workbook-protection.d.ts +27 -0
  62. package/dist/core/workbook-protection.js +25 -0
  63. package/dist/core/workbook.d.ts +528 -0
  64. package/dist/core/workbook.js +732 -0
  65. package/dist/core/worksheet-model.d.ts +34 -0
  66. package/dist/core/worksheet-model.js +100 -0
  67. package/dist/core/worksheet.d.ts +647 -0
  68. package/dist/core/worksheet.js +1025 -0
  69. package/dist/customui/errors.d.ts +15 -0
  70. package/dist/customui/errors.js +15 -0
  71. package/dist/customui/index.d.ts +2 -0
  72. package/dist/customui/index.js +7 -0
  73. package/dist/customui/ribbon.d.ts +86 -0
  74. package/dist/customui/ribbon.js +180 -0
  75. package/dist/entries/core.d.ts +23 -0
  76. package/dist/entries/core.js +20 -0
  77. package/dist/entries/csv.d.ts +2 -0
  78. package/dist/entries/csv.js +6 -0
  79. package/dist/entries/customui.d.ts +1 -0
  80. package/dist/entries/customui.js +3 -0
  81. package/dist/entries/errors.d.ts +7 -0
  82. package/dist/entries/errors.js +20 -0
  83. package/dist/entries/vba.d.ts +2 -0
  84. package/dist/entries/vba.js +7 -0
  85. package/dist/entries/xlsb.d.ts +1 -0
  86. package/dist/entries/xlsb.js +7 -0
  87. package/dist/entries/xlsx.d.ts +5 -0
  88. package/dist/entries/xlsx.js +18 -0
  89. package/dist/errors.d.ts +65 -0
  90. package/dist/errors.js +66 -0
  91. package/dist/index.d.ts +7 -0
  92. package/dist/index.js +19 -0
  93. package/dist/io/csv/read.d.ts +15 -0
  94. package/dist/io/csv/read.js +113 -0
  95. package/dist/io/csv/write.d.ts +28 -0
  96. package/dist/io/csv/write.js +124 -0
  97. package/dist/io/opc/errors.d.ts +46 -0
  98. package/dist/io/opc/errors.js +49 -0
  99. package/dist/io/opc/inflate.d.ts +15 -0
  100. package/dist/io/opc/inflate.js +91 -0
  101. package/dist/io/opc/namespaces.d.ts +18 -0
  102. package/dist/io/opc/namespaces.js +18 -0
  103. package/dist/io/opc/part-paths.d.ts +4 -0
  104. package/dist/io/opc/part-paths.js +35 -0
  105. package/dist/io/opc/read-opc.d.ts +24 -0
  106. package/dist/io/opc/read-opc.js +153 -0
  107. package/dist/io/opc/read-options.d.ts +10 -0
  108. package/dist/io/opc/read-options.js +7 -0
  109. package/dist/io/opc/rels.d.ts +15 -0
  110. package/dist/io/opc/rels.js +28 -0
  111. package/dist/io/opc/sniff-format.d.ts +27 -0
  112. package/dist/io/opc/sniff-format.js +92 -0
  113. package/dist/io/style/xf-style.d.ts +47 -0
  114. package/dist/io/style/xf-style.js +95 -0
  115. package/dist/io/xlsb/errors.d.ts +15 -0
  116. package/dist/io/xlsb/errors.js +15 -0
  117. package/dist/io/xlsb/formula.d.ts +48 -0
  118. package/dist/io/xlsb/formula.js +398 -0
  119. package/dist/io/xlsb/primitives.d.ts +86 -0
  120. package/dist/io/xlsb/primitives.js +230 -0
  121. package/dist/io/xlsb/ptg-functions.d.ts +16 -0
  122. package/dist/io/xlsb/ptg-functions.js +659 -0
  123. package/dist/io/xlsb/read-shared-strings.d.ts +2 -0
  124. package/dist/io/xlsb/read-shared-strings.js +22 -0
  125. package/dist/io/xlsb/read-styles.d.ts +4 -0
  126. package/dist/io/xlsb/read-styles.js +386 -0
  127. package/dist/io/xlsb/read-worksheet.d.ts +9 -0
  128. package/dist/io/xlsb/read-worksheet.js +301 -0
  129. package/dist/io/xlsb/read.d.ts +20 -0
  130. package/dist/io/xlsb/read.js +199 -0
  131. package/dist/io/xlsb/record-stream.d.ts +14 -0
  132. package/dist/io/xlsb/record-stream.js +56 -0
  133. package/dist/io/xlsb/record-types.d.ts +55 -0
  134. package/dist/io/xlsb/record-types.js +73 -0
  135. package/dist/io/xlsx/cell-accumulator.d.ts +25 -0
  136. package/dist/io/xlsx/cell-accumulator.js +172 -0
  137. package/dist/io/xlsx/cell-value.d.ts +32 -0
  138. package/dist/io/xlsx/cell-value.js +85 -0
  139. package/dist/io/xlsx/comments.d.ts +74 -0
  140. package/dist/io/xlsx/comments.js +243 -0
  141. package/dist/io/xlsx/conditional-formatting.d.ts +32 -0
  142. package/dist/io/xlsx/conditional-formatting.js +464 -0
  143. package/dist/io/xlsx/data-validation.d.ts +20 -0
  144. package/dist/io/xlsx/data-validation.js +258 -0
  145. package/dist/io/xlsx/edit-vba.d.ts +23 -0
  146. package/dist/io/xlsx/edit-vba.js +139 -0
  147. package/dist/io/xlsx/errors.d.ts +17 -0
  148. package/dist/io/xlsx/errors.js +17 -0
  149. package/dist/io/xlsx/hyperlinks.d.ts +42 -0
  150. package/dist/io/xlsx/hyperlinks.js +139 -0
  151. package/dist/io/xlsx/images.d.ts +34 -0
  152. package/dist/io/xlsx/images.js +218 -0
  153. package/dist/io/xlsx/namespaces.d.ts +55 -0
  154. package/dist/io/xlsx/namespaces.js +55 -0
  155. package/dist/io/xlsx/package-plan.d.ts +103 -0
  156. package/dist/io/xlsx/package-plan.js +168 -0
  157. package/dist/io/xlsx/pivot-read.d.ts +5 -0
  158. package/dist/io/xlsx/pivot-read.js +134 -0
  159. package/dist/io/xlsx/pivot.d.ts +12 -0
  160. package/dist/io/xlsx/pivot.js +141 -0
  161. package/dist/io/xlsx/read-rows.d.ts +85 -0
  162. package/dist/io/xlsx/read-rows.js +286 -0
  163. package/dist/io/xlsx/read-styles.d.ts +8 -0
  164. package/dist/io/xlsx/read-styles.js +551 -0
  165. package/dist/io/xlsx/read-worksheet.d.ts +4 -0
  166. package/dist/io/xlsx/read-worksheet.js +528 -0
  167. package/dist/io/xlsx/read.d.ts +32 -0
  168. package/dist/io/xlsx/read.js +680 -0
  169. package/dist/io/xlsx/relationships.d.ts +33 -0
  170. package/dist/io/xlsx/relationships.js +47 -0
  171. package/dist/io/xlsx/rich-runs.d.ts +13 -0
  172. package/dist/io/xlsx/rich-runs.js +59 -0
  173. package/dist/io/xlsx/rich-text.d.ts +7 -0
  174. package/dist/io/xlsx/rich-text.js +23 -0
  175. package/dist/io/xlsx/shared-formulas.d.ts +6 -0
  176. package/dist/io/xlsx/shared-formulas.js +52 -0
  177. package/dist/io/xlsx/shared-strings-read.d.ts +2 -0
  178. package/dist/io/xlsx/shared-strings-read.js +70 -0
  179. package/dist/io/xlsx/shared-strings.d.ts +17 -0
  180. package/dist/io/xlsx/shared-strings.js +50 -0
  181. package/dist/io/xlsx/sheet-properties.d.ts +13 -0
  182. package/dist/io/xlsx/sheet-properties.js +211 -0
  183. package/dist/io/xlsx/styles.d.ts +138 -0
  184. package/dist/io/xlsx/styles.js +821 -0
  185. package/dist/io/xlsx/tables.d.ts +9 -0
  186. package/dist/io/xlsx/tables.js +208 -0
  187. package/dist/io/xlsx/threaded-comments.d.ts +102 -0
  188. package/dist/io/xlsx/threaded-comments.js +308 -0
  189. package/dist/io/xlsx/workbook-xml.d.ts +12 -0
  190. package/dist/io/xlsx/workbook-xml.js +353 -0
  191. package/dist/io/xlsx/worksheet-xml.d.ts +86 -0
  192. package/dist/io/xlsx/worksheet-xml.js +643 -0
  193. package/dist/io/xlsx/write-stream.d.ts +171 -0
  194. package/dist/io/xlsx/write-stream.js +399 -0
  195. package/dist/io/xlsx/write.d.ts +81 -0
  196. package/dist/io/xlsx/write.js +396 -0
  197. package/dist/io/xlsx/x14-ext.d.ts +9 -0
  198. package/dist/io/xlsx/x14-ext.js +12 -0
  199. package/dist/vba/cfb-writer.d.ts +19 -0
  200. package/dist/vba/cfb-writer.js +277 -0
  201. package/dist/vba/cfb.d.ts +16 -0
  202. package/dist/vba/cfb.js +324 -0
  203. package/dist/vba/codepage.d.ts +18 -0
  204. package/dist/vba/codepage.js +87 -0
  205. package/dist/vba/errors.d.ts +24 -0
  206. package/dist/vba/errors.js +24 -0
  207. package/dist/vba/index.d.ts +5 -0
  208. package/dist/vba/index.js +15 -0
  209. package/dist/vba/ms-ovba.d.ts +12 -0
  210. package/dist/vba/ms-ovba.js +176 -0
  211. package/dist/vba/project-editor.d.ts +62 -0
  212. package/dist/vba/project-editor.js +377 -0
  213. package/dist/vba/project.d.ts +45 -0
  214. package/dist/vba/project.js +160 -0
  215. package/dist/vba/vba-encoding.d.ts +14 -0
  216. package/dist/vba/vba-encoding.js +39 -0
  217. package/dist/xml/errors.d.ts +15 -0
  218. package/dist/xml/errors.js +15 -0
  219. package/dist/xml/xml-read.d.ts +107 -0
  220. package/dist/xml/xml-read.js +283 -0
  221. package/dist/xml/xml.d.ts +41 -0
  222. package/dist/xml/xml.js +86 -0
  223. package/package.json +117 -0
@@ -0,0 +1,230 @@
1
+ // The [MS-XLSB] primitive types a record payload is built from, behind one bounds-checked cursor.
2
+ //
3
+ // Binary parsing is where a reader most easily goes wrong in two directions at once: silently reading
4
+ // past the end of a buffer, and allocating on a length the file (not the reader) chose. `RecordReader`
5
+ // closes both. Every read goes through a single `#take`, so overrunning the record is impossible
6
+ // rather than merely unlikely; and a length-prefixed string checks its byte count against what the
7
+ // record actually holds *before* a single character is materialised, so a forged `cch` costs one
8
+ // comparison instead of gigabytes.
9
+ //
10
+ // Structures decoded here — RkNumber, XLWideString, BrtColor, Cell, UncheckedRfX, BErr — are shared
11
+ // across the workbook, worksheet, styles, and shared-string parsers; nothing part-specific lives here.
12
+ import { isErrorCode } from "../../core/value.js";
13
+ import { XlsbParseError } from "./errors.js";
14
+ // A length-prefixed string is decoded in code-unit batches rather than one `String.fromCharCode` call
15
+ // per character (quadratic concatenation) or one spread of every unit (which blows the argument limit
16
+ // on a long string). 4096 is comfortably under every engine's limit and makes the batching invisible.
17
+ const CHARS_PER_BATCH = 4096;
18
+ // `XLNullableWideString` marks "no string" with a character count of 0xFFFFFFFF rather than 0 — an
19
+ // empty string and an absent one are different values (a sheet's relationship id is nullable; its
20
+ // name is not).
21
+ const NULL_STRING_LENGTH = 0xffffffff;
22
+ // One reusable 8-byte window for reassembling an RkNumber's truncated double. The alternative — a
23
+ // fresh ArrayBuffer per RK cell — would allocate once per numeric cell in the workbook, on the single
24
+ // hottest path in the reader. Safe to share: the write and the read below are one synchronous pair.
25
+ const rkScratch = new DataView(new ArrayBuffer(8));
26
+ /**
27
+ * A bounds-checked cursor over one record's payload.
28
+ *
29
+ * Each accessor advances the cursor by exactly the bytes it consumed, so a record is decoded by
30
+ * naming its fields in order. Reading past the payload throws {@link XlsbParseError} — a record that
31
+ * is shorter than its own definition is a malformed file, not a case to guess through.
32
+ */
33
+ export class RecordReader {
34
+ #data;
35
+ #view;
36
+ #offset = 0;
37
+ constructor(data) {
38
+ this.#data = data;
39
+ this.#view = new DataView(data.buffer, data.byteOffset, data.byteLength);
40
+ }
41
+ /** Bytes left in the record. */
42
+ get remaining() {
43
+ return this.#data.length - this.#offset;
44
+ }
45
+ /** Whether the whole payload has been consumed. */
46
+ get done() {
47
+ return this.remaining <= 0;
48
+ }
49
+ /** Advance past `count` bytes without decoding them — a reserved or unmodelled field. */
50
+ skip(count) {
51
+ this.#take(count);
52
+ }
53
+ /**
54
+ * The next `count` bytes as a **view**, for a field whose own decoding happens elsewhere — a formula
55
+ * token stream, whose meaning depends on workbook tables this record knows nothing about. A view
56
+ * rather than a copy for the same reason a record's payload is one: the declared length comes from
57
+ * the file, so it must bound a read, never an allocation.
58
+ */
59
+ bytes(count) {
60
+ return this.#data.subarray(this.#take(count), this.#offset);
61
+ }
62
+ u8() {
63
+ return this.#view.getUint8(this.#take(1));
64
+ }
65
+ u16() {
66
+ return this.#view.getUint16(this.#take(2), true);
67
+ }
68
+ i16() {
69
+ return this.#view.getInt16(this.#take(2), true);
70
+ }
71
+ u32() {
72
+ return this.#view.getUint32(this.#take(4), true);
73
+ }
74
+ i32() {
75
+ return this.#view.getInt32(this.#take(4), true);
76
+ }
77
+ /** An `Xnum` ([MS-XLSB] 2.5.172): a little-endian IEEE-754 double. */
78
+ f64() {
79
+ return this.#view.getFloat64(this.#take(8), true);
80
+ }
81
+ /**
82
+ * An `RkNumber` ([MS-XLSB] 2.5.122): a number packed into 32 bits. Two flag bits steal the low end
83
+ * of the word — `fInt` says the remaining 30 bits are a signed integer rather than the *high* 30
84
+ * bits of a double whose low 34 bits are zero, and `fX100` says the result was scaled up by 100 to
85
+ * keep two decimal places in the integer form. It exists because most real spreadsheet numbers are
86
+ * small integers or two-decimal currency, and this stores them in half the bytes of a double.
87
+ */
88
+ rk() {
89
+ // Read signed: the `fInt` branch needs an arithmetic shift to sign-extend a negative 30-bit
90
+ // integer, which only works on a value JavaScript already considers negative.
91
+ const raw = this.i32();
92
+ const value = (raw & 0b10) !== 0 ? raw >> 2 : truncatedDouble(raw & ~0b11);
93
+ return (raw & 0b01) !== 0 ? value / 100 : value;
94
+ }
95
+ /** An `XLWideString` ([MS-XLSB] 2.5.169): a 4-byte character count then that many UTF-16LE units. */
96
+ wideString() {
97
+ return this.#characters(this.u32());
98
+ }
99
+ /**
100
+ * A UTF-16 string whose character count is 16-bit rather than 32-bit — the form used *inside* a
101
+ * formula token stream (`PtgStr`, and the string elements of an array constant), where a 4-byte
102
+ * count on every literal would be pure overhead.
103
+ */
104
+ shortString() {
105
+ return this.#characters(this.u16());
106
+ }
107
+ /** An `XLNullableWideString` ([MS-XLSB] 2.5.166): an {@link wideString} that can also be absent. */
108
+ nullableWideString() {
109
+ const length = this.u32();
110
+ return length === NULL_STRING_LENGTH ? undefined : this.#characters(length);
111
+ }
112
+ /**
113
+ * A `RichStr` ([MS-XLSB] 2.5.124): a string that may carry per-run formatting and phonetic guides.
114
+ * Only the text is returned — the run and phonetic tails are left unread, which is safe because the
115
+ * record's framing (not this cursor) bounds where the payload ends.
116
+ */
117
+ richString() {
118
+ this.skip(1); // fRichStr / fExtStr flags: which optional tails follow the text.
119
+ return this.wideString();
120
+ }
121
+ /** The `Cell` structure ([MS-XLSB] 2.5.10) that opens every cell record. */
122
+ cell() {
123
+ const column = this.u32();
124
+ // The style index shares its word with a phonetic-display flag in the high byte.
125
+ return { column, styleIndex: this.u32() & 0x00ffffff };
126
+ }
127
+ /** An `UncheckedRfX` ([MS-XLSB] 2.5.155): four zero-based, inclusive range bounds. */
128
+ range() {
129
+ return {
130
+ rowFirst: this.u32(),
131
+ rowLast: this.u32(),
132
+ colFirst: this.u32(),
133
+ colLast: this.u32(),
134
+ };
135
+ }
136
+ /**
137
+ * A `BrtColor` ([MS-XLSB] 2.4.337), mapped onto the model's {@link Color}.
138
+ *
139
+ * The four encodings are mutually exclusive and the type tag picks which of the payload's fields
140
+ * carry meaning; the rest are explicitly undefined. An *automatic* colour (type 0) names nothing at
141
+ * all, and reads back as no colour — the same absence the XML reader produces for `<color auto="1"/>`,
142
+ * so a cell whose font colour was never set does not gain one on read.
143
+ */
144
+ color() {
145
+ const flags = this.u8();
146
+ const index = this.u8();
147
+ const tintAndShade = this.i16();
148
+ const red = this.u8();
149
+ const green = this.u8();
150
+ const blue = this.u8();
151
+ const alpha = this.u8();
152
+ const base = colorByType(flags >> 1, index, alpha, red, green, blue);
153
+ if (base === undefined)
154
+ return undefined;
155
+ // Tint is stored as a fraction of the signed 16-bit range, where the extreme values mean 100%
156
+ // lightening/darkening; the model carries it as OOXML does, in [-1, 1].
157
+ if (tintAndShade === 0)
158
+ return base;
159
+ return { ...base, tint: Math.max(-1, Math.min(1, tintAndShade / 0x7fff)) };
160
+ }
161
+ #characters(count) {
162
+ // Check the byte count against the record *before* building anything: this is the guard that
163
+ // makes a forged character count a cheap failure rather than an allocation the file chose.
164
+ const start = this.#take(count * 2);
165
+ let text = '';
166
+ let batch = [];
167
+ for (let index = 0; index < count; index++) {
168
+ batch.push(this.#view.getUint16(start + index * 2, true));
169
+ if (batch.length === CHARS_PER_BATCH) {
170
+ text += String.fromCharCode(...batch);
171
+ batch = [];
172
+ }
173
+ }
174
+ return batch.length > 0 ? text + String.fromCharCode(...batch) : text;
175
+ }
176
+ // The single choke point every read passes through. Returns the offset the caller may read from,
177
+ // having proven that `count` bytes are there.
178
+ #take(count) {
179
+ if (count > this.remaining) {
180
+ throw new XlsbParseError(`BIFF12 record field needs ${count} bytes but only ${this.remaining} remain in the record`);
181
+ }
182
+ const start = this.#offset;
183
+ this.#offset += count;
184
+ return start;
185
+ }
186
+ }
187
+ /** A `BErr` ([MS-XLSB] 2.5.98.2) error code, as the model's error string. */
188
+ export function errorCodeFor(code) {
189
+ const text = BERR_CODES.get(code);
190
+ return text !== undefined && isErrorCode(text) ? text : undefined;
191
+ }
192
+ const BERR_CODES = new Map([
193
+ [0x00, '#NULL!'],
194
+ [0x07, '#DIV/0!'],
195
+ [0x0f, '#VALUE!'],
196
+ [0x17, '#REF!'],
197
+ [0x1d, '#NAME?'],
198
+ [0x24, '#NUM!'],
199
+ [0x2a, '#N/A'],
200
+ [0x2b, '#GETTING_DATA'],
201
+ ]);
202
+ // Rebuild the double whose *high* 32 bits are `high` and whose low 34 bits [MS-XLSB] guarantees to be
203
+ // zero. Written big-endian so the given word lands in the high half regardless of host endianness.
204
+ function truncatedDouble(high) {
205
+ rkScratch.setInt32(0, high, false);
206
+ rkScratch.setUint32(4, 0, false);
207
+ return rkScratch.getFloat64(0, false);
208
+ }
209
+ // The `xColorType` tag ([MS-XLSB] 2.4.337) selects which of a BrtColor's fields carry the colour.
210
+ const COLOR_TYPE_INDEXED = 1;
211
+ const COLOR_TYPE_RGB = 2;
212
+ const COLOR_TYPE_THEME = 3;
213
+ function colorByType(type, index, alpha, red, green, blue) {
214
+ switch (type) {
215
+ case COLOR_TYPE_INDEXED:
216
+ return { indexed: index };
217
+ case COLOR_TYPE_RGB:
218
+ return { argb: hexByte(alpha) + hexByte(red) + hexByte(green) + hexByte(blue) };
219
+ case COLOR_TYPE_THEME:
220
+ // The binary theme index and OOXML's `theme="…"` attribute both count the `clrScheme`
221
+ // subelements in declaration order (dk1, lt1, dk2, lt2, accent1–6, hlink, folHlink), so the
222
+ // index carries across unchanged.
223
+ return { theme: index };
224
+ default:
225
+ return undefined;
226
+ }
227
+ }
228
+ function hexByte(value) {
229
+ return value.toString(16).toUpperCase().padStart(2, '0');
230
+ }
@@ -0,0 +1,16 @@
1
+ /** The index [MS-XLS] reserves for a call whose name is given by the token stream's first operand. */
2
+ export declare const FTAB_USER_DEFINED = 255;
3
+ /** Look up a built-in function name by its `iftab` index, or `undefined` if the index names none. */
4
+ export declare function functionNameFor(index: number): string | undefined;
5
+ /**
6
+ * How many arguments a fixed-arity function takes, or `undefined` for one whose argument count varies.
7
+ *
8
+ * A `PtgFunc` token states only *which* function is called, never with how many arguments — it is the
9
+ * token Excel emits precisely because the count is implied by the function. So decoding `ROUND(A1,2)`
10
+ * back from its two operands and one call token is impossible without this: the arity is the only
11
+ * thing that says which operands on the stack belong to the call. (`PtgFuncVar` carries its own count
12
+ * and needs none of this; the two token forms partition the table between them.)
13
+ *
14
+ * Transcribed from the parameter grammar each function's [MS-XLS] 2.5.198.17 entry states.
15
+ */
16
+ export declare function fixedArityFor(name: string): number | undefined;