@qvac/harness 0.7.2 → 0.8.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.
- package/CHANGELOG.md +70 -1
- package/NOTICE.md +16 -0
- package/dist-lib/lib/capabilities/completion.d.ts +1 -0
- package/dist-lib/lib/capabilities/completion.js +46 -8
- package/dist-lib/lib/capabilities/tool-turns.d.ts +3 -0
- package/dist-lib/lib/capabilities/tool-turns.js +7 -0
- package/dist-lib/lib/context-window.js +2 -2
- package/dist-lib/lib/helpers/run-outcome.d.ts +4 -1
- package/dist-lib/lib/helpers/run-outcome.js +14 -8
- package/dist-lib/lib/helpers/tool-call-markup.js +4 -4
- package/dist-lib/lib/hooks/built-in/arg-repair.js +7 -0
- package/dist-lib/lib/office/engine/codes.d.ts +62 -0
- package/dist-lib/lib/office/engine/codes.js +61 -0
- package/dist-lib/lib/office/engine/docx/document.d.ts +216 -0
- package/dist-lib/lib/office/engine/docx/document.js +1152 -0
- package/dist-lib/lib/office/engine/docx/index.d.ts +7 -0
- package/dist-lib/lib/office/engine/docx/index.js +8 -0
- package/dist-lib/lib/office/engine/docx/styles.d.ts +31 -0
- package/dist-lib/lib/office/engine/docx/styles.js +173 -0
- package/dist-lib/lib/office/engine/docx/template.d.ts +18 -0
- package/dist-lib/lib/office/engine/docx/template.js +133 -0
- package/dist-lib/lib/office/engine/docx/text.d.ts +55 -0
- package/dist-lib/lib/office/engine/docx/text.js +538 -0
- package/dist-lib/lib/office/engine/drawingml/chart.d.ts +63 -0
- package/dist-lib/lib/office/engine/drawingml/chart.js +539 -0
- package/dist-lib/lib/office/engine/drawingml/text.d.ts +35 -0
- package/dist-lib/lib/office/engine/drawingml/text.js +352 -0
- package/dist-lib/lib/office/engine/errors.d.ts +6 -0
- package/dist-lib/lib/office/engine/errors.js +12 -0
- package/dist-lib/lib/office/engine/image.d.ts +8 -0
- package/dist-lib/lib/office/engine/image.js +48 -0
- package/dist-lib/lib/office/engine/index.d.ts +12 -0
- package/dist-lib/lib/office/engine/index.js +7 -0
- package/dist-lib/lib/office/engine/opc/content-types.d.ts +17 -0
- package/dist-lib/lib/office/engine/opc/content-types.js +74 -0
- package/dist-lib/lib/office/engine/opc/media.d.ts +13 -0
- package/dist-lib/lib/office/engine/opc/media.js +11 -0
- package/dist-lib/lib/office/engine/opc/package.d.ts +51 -0
- package/dist-lib/lib/office/engine/opc/package.js +324 -0
- package/dist-lib/lib/office/engine/opc/paths.d.ts +7 -0
- package/dist-lib/lib/office/engine/opc/paths.js +46 -0
- package/dist-lib/lib/office/engine/opc/properties.d.ts +7 -0
- package/dist-lib/lib/office/engine/opc/properties.js +75 -0
- package/dist-lib/lib/office/engine/opc/relationships.d.ts +23 -0
- package/dist-lib/lib/office/engine/opc/relationships.js +65 -0
- package/dist-lib/lib/office/engine/opc/zip.d.ts +15 -0
- package/dist-lib/lib/office/engine/opc/zip.js +264 -0
- package/dist-lib/lib/office/engine/pptx/fit.d.ts +12 -0
- package/dist-lib/lib/office/engine/pptx/fit.js +37 -0
- package/dist-lib/lib/office/engine/pptx/index.d.ts +8 -0
- package/dist-lib/lib/office/engine/pptx/index.js +8 -0
- package/dist-lib/lib/office/engine/pptx/inherit.d.ts +29 -0
- package/dist-lib/lib/office/engine/pptx/inherit.js +155 -0
- package/dist-lib/lib/office/engine/pptx/notes.d.ts +5 -0
- package/dist-lib/lib/office/engine/pptx/notes.js +85 -0
- package/dist-lib/lib/office/engine/pptx/presentation.d.ts +54 -0
- package/dist-lib/lib/office/engine/pptx/presentation.js +749 -0
- package/dist-lib/lib/office/engine/pptx/read.d.ts +9 -0
- package/dist-lib/lib/office/engine/pptx/read.js +66 -0
- package/dist-lib/lib/office/engine/pptx/shapes.d.ts +52 -0
- package/dist-lib/lib/office/engine/pptx/shapes.js +276 -0
- package/dist-lib/lib/office/engine/pptx/slides.d.ts +27 -0
- package/dist-lib/lib/office/engine/pptx/slides.js +123 -0
- package/dist-lib/lib/office/engine/pptx/template.d.ts +20 -0
- package/dist-lib/lib/office/engine/pptx/template.js +391 -0
- package/dist-lib/lib/office/engine/pptx/types.d.ts +120 -0
- package/dist-lib/lib/office/engine/pptx/types.js +1 -0
- package/dist-lib/lib/office/engine/units.d.ts +3 -0
- package/dist-lib/lib/office/engine/units.js +12 -0
- package/dist-lib/lib/office/engine/utf8.d.ts +2 -0
- package/dist-lib/lib/office/engine/utf8.js +103 -0
- package/dist-lib/lib/office/engine/xlsx/formula.d.ts +49 -0
- package/dist-lib/lib/office/engine/xlsx/formula.js +381 -0
- package/dist-lib/lib/office/engine/xlsx/index.d.ts +8 -0
- package/dist-lib/lib/office/engine/xlsx/index.js +8 -0
- package/dist-lib/lib/office/engine/xlsx/refs.d.ts +22 -0
- package/dist-lib/lib/office/engine/xlsx/refs.js +82 -0
- package/dist-lib/lib/office/engine/xlsx/reshape.d.ts +21 -0
- package/dist-lib/lib/office/engine/xlsx/reshape.js +424 -0
- package/dist-lib/lib/office/engine/xlsx/sheet.d.ts +108 -0
- package/dist-lib/lib/office/engine/xlsx/sheet.js +662 -0
- package/dist-lib/lib/office/engine/xlsx/strings.d.ts +15 -0
- package/dist-lib/lib/office/engine/xlsx/strings.js +93 -0
- package/dist-lib/lib/office/engine/xlsx/styles.d.ts +38 -0
- package/dist-lib/lib/office/engine/xlsx/styles.js +369 -0
- package/dist-lib/lib/office/engine/xlsx/template.d.ts +7 -0
- package/dist-lib/lib/office/engine/xlsx/template.js +54 -0
- package/dist-lib/lib/office/engine/xlsx/workbook.d.ts +161 -0
- package/dist-lib/lib/office/engine/xlsx/workbook.js +850 -0
- package/dist-lib/lib/office/engine/xlsx/write.d.ts +2 -0
- package/dist-lib/lib/office/engine/xlsx/write.js +42 -0
- package/dist-lib/lib/office/engine/xml.d.ts +45 -0
- package/dist-lib/lib/office/engine/xml.js +258 -0
- package/dist-lib/lib/tools/exec/scope.d.ts +2 -0
- package/dist-lib/lib/tools/exec/scope.js +33 -2
- package/dist-lib/lib/tools/pdf/build.d.ts +43 -0
- package/dist-lib/lib/tools/pdf/build.js +150 -0
- package/dist-lib/lib/tools/pdf/images.d.ts +7 -0
- package/dist-lib/lib/tools/pdf/images.js +82 -0
- package/dist-lib/lib/tools/pdf/request.d.ts +63 -0
- package/dist-lib/lib/tools/pdf/request.js +335 -0
- package/dist-lib/lib/tools/pdf.d.ts +6 -0
- package/dist-lib/lib/tools/pdf.js +302 -0
- package/dist-lib/lib/tools/skill.js +14 -0
- package/dist-lib/lib/tools/weather-lookup/geocode.d.ts +26 -0
- package/dist-lib/lib/tools/weather-lookup/geocode.js +110 -0
- package/dist-lib/lib/tools/weather-lookup/place.js +5 -1
- package/dist-lib/lib/tools/weather-lookup.d.ts +2 -1
- package/dist-lib/lib/tools/weather-lookup.js +115 -84
- package/package.json +29 -1
- package/worker/harness-sidecar.mjs +3 -1
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import { deflateRawSync, inflateRawSync } from '#zlib';
|
|
2
|
+
import { DocsError } from '../errors.js';
|
|
3
|
+
import { errorCode, errorMessage } from '../../../guards.js';
|
|
4
|
+
import * as utf8 from '../utf8.js';
|
|
5
|
+
const EOCD = 0x06054b50;
|
|
6
|
+
const EOCD64_LOCATOR = 0x07064b50;
|
|
7
|
+
const EOCD64 = 0x06064b50;
|
|
8
|
+
const CENTRAL = 0x02014b50;
|
|
9
|
+
const LOCAL = 0x04034b50;
|
|
10
|
+
const DOS_DATE = 33;
|
|
11
|
+
const UTF8_FLAG = 0x0800;
|
|
12
|
+
const CRC_TABLE = new Uint32Array(256).map((_, n) => {
|
|
13
|
+
let c = n;
|
|
14
|
+
for (let k = 0; k < 8; k++) {
|
|
15
|
+
c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
|
|
16
|
+
}
|
|
17
|
+
return c >>> 0;
|
|
18
|
+
});
|
|
19
|
+
export function crc32(data) {
|
|
20
|
+
let crc = 0xffffffff;
|
|
21
|
+
for (let i = 0; i < data.length; i++) {
|
|
22
|
+
crc = CRC_TABLE[(crc ^ data[i]) & 0xff] ^ (crc >>> 8);
|
|
23
|
+
}
|
|
24
|
+
return (crc ^ 0xffffffff) >>> 0;
|
|
25
|
+
}
|
|
26
|
+
function broken(why) {
|
|
27
|
+
return new DocsError('NOT_OOXML', `the file is not a readable zip archive: ${why}`);
|
|
28
|
+
}
|
|
29
|
+
function findDirectory(view) {
|
|
30
|
+
const min = Math.max(0, view.byteLength - 65557);
|
|
31
|
+
for (let at = view.byteLength - 22; at >= min; at--) {
|
|
32
|
+
if (view.getUint32(at, true) !== EOCD)
|
|
33
|
+
continue;
|
|
34
|
+
const count = view.getUint16(at + 10, true);
|
|
35
|
+
const offset = view.getUint32(at + 16, true);
|
|
36
|
+
const locator = at - 20;
|
|
37
|
+
if ((count === 0xffff || offset === 0xffffffff) &&
|
|
38
|
+
locator >= 0 &&
|
|
39
|
+
view.getUint32(locator, true) === EOCD64_LOCATOR) {
|
|
40
|
+
return zip64Directory(view, Number(view.getBigUint64(locator + 8, true)));
|
|
41
|
+
}
|
|
42
|
+
return { offset, count };
|
|
43
|
+
}
|
|
44
|
+
throw broken('no end of central directory');
|
|
45
|
+
}
|
|
46
|
+
function zip64Directory(view, at) {
|
|
47
|
+
if (at + 56 > view.byteLength || view.getUint32(at, true) !== EOCD64) {
|
|
48
|
+
throw broken('bad zip64 directory');
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
count: Number(view.getBigUint64(at + 32, true)),
|
|
52
|
+
offset: Number(view.getBigUint64(at + 48, true))
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function zip64Extra(view, entry, extra) {
|
|
56
|
+
for (let at = extra.start; at + 4 <= extra.end;) {
|
|
57
|
+
const id = view.getUint16(at, true);
|
|
58
|
+
const length = view.getUint16(at + 2, true);
|
|
59
|
+
if (id === 0x0001) {
|
|
60
|
+
let field = at + 4;
|
|
61
|
+
const take = () => {
|
|
62
|
+
if (field + 8 > extra.end) {
|
|
63
|
+
throw broken(`${entry.name} has a short zip64 field`);
|
|
64
|
+
}
|
|
65
|
+
const value = Number(view.getBigUint64(field, true));
|
|
66
|
+
field += 8;
|
|
67
|
+
return value;
|
|
68
|
+
};
|
|
69
|
+
if (entry.size === 0xffffffff) {
|
|
70
|
+
entry.size = take();
|
|
71
|
+
}
|
|
72
|
+
if (entry.compressed === 0xffffffff) {
|
|
73
|
+
entry.compressed = take();
|
|
74
|
+
}
|
|
75
|
+
if (entry.offset === 0xffffffff) {
|
|
76
|
+
entry.offset = take();
|
|
77
|
+
}
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
at += 4 + length;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function readCentral(bytes, view, at) {
|
|
84
|
+
if (at + 46 > view.byteLength || view.getUint32(at, true) !== CENTRAL) {
|
|
85
|
+
throw broken('bad central directory entry');
|
|
86
|
+
}
|
|
87
|
+
const nameLength = view.getUint16(at + 28, true);
|
|
88
|
+
const extraLength = view.getUint16(at + 30, true);
|
|
89
|
+
const commentLength = view.getUint16(at + 32, true);
|
|
90
|
+
const entry = {
|
|
91
|
+
name: utf8.decode(bytes.subarray(at + 46, at + 46 + nameLength)),
|
|
92
|
+
flags: view.getUint16(at + 8, true),
|
|
93
|
+
method: view.getUint16(at + 10, true),
|
|
94
|
+
crc: view.getUint32(at + 16, true),
|
|
95
|
+
compressed: view.getUint32(at + 20, true),
|
|
96
|
+
size: view.getUint32(at + 24, true),
|
|
97
|
+
offset: view.getUint32(at + 42, true),
|
|
98
|
+
next: at + 46 + nameLength + extraLength + commentLength
|
|
99
|
+
};
|
|
100
|
+
const start = at + 46 + nameLength;
|
|
101
|
+
zip64Extra(view, entry, { start, end: start + extraLength });
|
|
102
|
+
return entry;
|
|
103
|
+
}
|
|
104
|
+
function checkLimits(entries, limits) {
|
|
105
|
+
if (entries.length > limits.maxEntries) {
|
|
106
|
+
throw new DocsError('TOO_LARGE', `the file has more than ${limits.maxEntries} entries`);
|
|
107
|
+
}
|
|
108
|
+
let declared = 0;
|
|
109
|
+
for (const entry of entries) {
|
|
110
|
+
declared += entry.size;
|
|
111
|
+
if (declared > limits.maxSize) {
|
|
112
|
+
throw new DocsError('TOO_LARGE', `the file expands past ${limits.maxSize} bytes`);
|
|
113
|
+
}
|
|
114
|
+
if (entry.size > 1024 * 1024 && entry.size / Math.max(1, entry.compressed) > limits.maxRatio) {
|
|
115
|
+
throw new DocsError('TOO_LARGE', `${entry.name} expands more than ${limits.maxRatio} times, which looks like a zip bomb`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function extract(bytes, view, entry) {
|
|
120
|
+
const at = entry.offset;
|
|
121
|
+
if (at + 30 > view.byteLength || view.getUint32(at, true) !== LOCAL) {
|
|
122
|
+
throw broken(`bad local header for ${entry.name}`);
|
|
123
|
+
}
|
|
124
|
+
if (entry.flags & 1) {
|
|
125
|
+
throw broken(`${entry.name} is encrypted`);
|
|
126
|
+
}
|
|
127
|
+
const start = at + 30 + view.getUint16(at + 26, true) + view.getUint16(at + 28, true);
|
|
128
|
+
const raw = bytes.subarray(start, start + entry.compressed);
|
|
129
|
+
if (raw.length !== entry.compressed) {
|
|
130
|
+
throw broken(`${entry.name} is truncated`);
|
|
131
|
+
}
|
|
132
|
+
let data;
|
|
133
|
+
if (entry.method === 0) {
|
|
134
|
+
data = raw;
|
|
135
|
+
}
|
|
136
|
+
else if (entry.method === 8) {
|
|
137
|
+
data = inflate(raw, entry);
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
throw broken(`${entry.name} uses compression method ${entry.method}`);
|
|
141
|
+
}
|
|
142
|
+
if (data.length !== entry.size) {
|
|
143
|
+
throw broken(`${entry.name} has the wrong size`);
|
|
144
|
+
}
|
|
145
|
+
if (crc32(data) !== entry.crc) {
|
|
146
|
+
throw broken(`${entry.name} fails its checksum`);
|
|
147
|
+
}
|
|
148
|
+
return data;
|
|
149
|
+
}
|
|
150
|
+
function inflate(raw, entry) {
|
|
151
|
+
try {
|
|
152
|
+
return new Uint8Array(inflateRawSync(raw, { maxOutputLength: Math.max(1, entry.size) }));
|
|
153
|
+
}
|
|
154
|
+
catch (err) {
|
|
155
|
+
if (isOverflow(err)) {
|
|
156
|
+
throw broken(`${entry.name} inflates past its declared size`);
|
|
157
|
+
}
|
|
158
|
+
throw broken(`${entry.name} does not inflate`);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
function isOverflow(err) {
|
|
162
|
+
const code = errorCode(err);
|
|
163
|
+
return code === 'ERR_BUFFER_TOO_LARGE' || code === 'LIMIT_EXCEEDED';
|
|
164
|
+
}
|
|
165
|
+
export function read(bytes, limits) {
|
|
166
|
+
try {
|
|
167
|
+
return readEntries(bytes, limits);
|
|
168
|
+
}
|
|
169
|
+
catch (err) {
|
|
170
|
+
if (err instanceof DocsError) {
|
|
171
|
+
throw err;
|
|
172
|
+
}
|
|
173
|
+
throw broken(errorMessage(err));
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
function readEntries(bytes, limits) {
|
|
177
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
178
|
+
if (bytes.byteLength < 22) {
|
|
179
|
+
throw broken('too short');
|
|
180
|
+
}
|
|
181
|
+
const directory = findDirectory(view);
|
|
182
|
+
const entries = [];
|
|
183
|
+
for (let i = 0, at = directory.offset; i < directory.count; i++) {
|
|
184
|
+
const entry = readCentral(bytes, view, at);
|
|
185
|
+
entries.push(entry);
|
|
186
|
+
at = entry.next;
|
|
187
|
+
}
|
|
188
|
+
checkLimits(entries, limits);
|
|
189
|
+
return entries
|
|
190
|
+
.filter((entry) => !entry.name.endsWith('/'))
|
|
191
|
+
.map((entry) => ({ name: entry.name, data: extract(bytes, view, entry) }));
|
|
192
|
+
}
|
|
193
|
+
function encodeEntry(entry) {
|
|
194
|
+
const compressed = entry.compress && entry.data.length > 0;
|
|
195
|
+
return {
|
|
196
|
+
name: utf8.encode(entry.name),
|
|
197
|
+
data: entry.data,
|
|
198
|
+
raw: compressed ? new Uint8Array(deflateRawSync(entry.data, { level: 6 })) : entry.data,
|
|
199
|
+
crc: crc32(entry.data),
|
|
200
|
+
method: compressed ? 8 : 0
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
function header(size, fill) {
|
|
204
|
+
const out = new Uint8Array(size);
|
|
205
|
+
fill(new DataView(out.buffer));
|
|
206
|
+
return out;
|
|
207
|
+
}
|
|
208
|
+
function localHeader(e) {
|
|
209
|
+
return header(30, (v) => {
|
|
210
|
+
v.setUint32(0, LOCAL, true);
|
|
211
|
+
v.setUint16(4, 20, true);
|
|
212
|
+
v.setUint16(6, UTF8_FLAG, true);
|
|
213
|
+
v.setUint16(8, e.method, true);
|
|
214
|
+
v.setUint16(12, DOS_DATE, true);
|
|
215
|
+
v.setUint32(14, e.crc, true);
|
|
216
|
+
v.setUint32(18, e.raw.length, true);
|
|
217
|
+
v.setUint32(22, e.data.length, true);
|
|
218
|
+
v.setUint16(26, e.name.length, true);
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
function centralHeader(e, offset) {
|
|
222
|
+
return header(46, (v) => {
|
|
223
|
+
v.setUint32(0, CENTRAL, true);
|
|
224
|
+
v.setUint16(4, 20, true);
|
|
225
|
+
v.setUint16(6, 20, true);
|
|
226
|
+
v.setUint16(8, UTF8_FLAG, true);
|
|
227
|
+
v.setUint16(10, e.method, true);
|
|
228
|
+
v.setUint16(14, DOS_DATE, true);
|
|
229
|
+
v.setUint32(16, e.crc, true);
|
|
230
|
+
v.setUint32(20, e.raw.length, true);
|
|
231
|
+
v.setUint32(24, e.data.length, true);
|
|
232
|
+
v.setUint16(28, e.name.length, true);
|
|
233
|
+
v.setUint32(42, offset, true);
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
function concat(parts) {
|
|
237
|
+
const out = new Uint8Array(parts.reduce((n, p) => n + p.length, 0));
|
|
238
|
+
let at = 0;
|
|
239
|
+
for (const part of parts) {
|
|
240
|
+
out.set(part, at);
|
|
241
|
+
at += part.length;
|
|
242
|
+
}
|
|
243
|
+
return out;
|
|
244
|
+
}
|
|
245
|
+
export function write(entries) {
|
|
246
|
+
const encoded = entries.map(encodeEntry);
|
|
247
|
+
const body = [];
|
|
248
|
+
const central = [];
|
|
249
|
+
let offset = 0;
|
|
250
|
+
for (const e of encoded) {
|
|
251
|
+
central.push(centralHeader(e, offset), e.name);
|
|
252
|
+
body.push(localHeader(e), e.name, e.raw);
|
|
253
|
+
offset += 30 + e.name.length + e.raw.length;
|
|
254
|
+
}
|
|
255
|
+
const directory = concat(central);
|
|
256
|
+
const end = header(22, (v) => {
|
|
257
|
+
v.setUint32(0, EOCD, true);
|
|
258
|
+
v.setUint16(8, encoded.length, true);
|
|
259
|
+
v.setUint16(10, encoded.length, true);
|
|
260
|
+
v.setUint32(12, directory.length, true);
|
|
261
|
+
v.setUint32(16, offset, true);
|
|
262
|
+
});
|
|
263
|
+
return concat([...body, directory, end]);
|
|
264
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Box, Insets } from './inherit.ts';
|
|
2
|
+
export interface SizedParagraph {
|
|
3
|
+
text: string;
|
|
4
|
+
level: number;
|
|
5
|
+
size: number;
|
|
6
|
+
}
|
|
7
|
+
export interface Estimate {
|
|
8
|
+
overflow: boolean;
|
|
9
|
+
fontScale: number;
|
|
10
|
+
lineReduction: number;
|
|
11
|
+
}
|
|
12
|
+
export declare function estimate(paragraphs: SizedParagraph[], box: Box, insets: Insets): Estimate;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const EMU_PER_POINT = 12700;
|
|
2
|
+
const LEVEL_INDENT = 342900;
|
|
3
|
+
const FLOOR = { overflow: true, fontScale: 0.25, lineReduction: 0.2 };
|
|
4
|
+
function paragraphHeight(p, width, squeeze) {
|
|
5
|
+
const size = p.size * squeeze.scale * EMU_PER_POINT;
|
|
6
|
+
const available = Math.max(width - p.level * LEVEL_INDENT, width * 0.3);
|
|
7
|
+
const perLine = Math.max(1, Math.floor(available / (size * 0.5)));
|
|
8
|
+
let lines = 0;
|
|
9
|
+
for (const line of p.text.split('\n')) {
|
|
10
|
+
lines += Math.max(1, Math.ceil(line.length / perLine));
|
|
11
|
+
}
|
|
12
|
+
return lines * size * 1.2 * (1 - squeeze.reduction);
|
|
13
|
+
}
|
|
14
|
+
function neededHeight(paragraphs, width, squeeze) {
|
|
15
|
+
return paragraphs.reduce((total, p) => total + paragraphHeight(p, width, squeeze), 0);
|
|
16
|
+
}
|
|
17
|
+
export function estimate(paragraphs, box, insets) {
|
|
18
|
+
const width = box.width - insets.left - insets.right;
|
|
19
|
+
const height = box.height - insets.top - insets.bottom;
|
|
20
|
+
if (width <= 0 || height <= 0) {
|
|
21
|
+
return FLOOR;
|
|
22
|
+
}
|
|
23
|
+
if (neededHeight(paragraphs, width, { scale: 1, reduction: 0 }) <= height) {
|
|
24
|
+
return { overflow: false, fontScale: 1, lineReduction: 0 };
|
|
25
|
+
}
|
|
26
|
+
for (let scale = 0.975; scale >= 0.25; scale -= 0.025) {
|
|
27
|
+
const reduction = scale < 0.7 ? 0.2 : 0.1;
|
|
28
|
+
if (neededHeight(paragraphs, width, { scale, reduction }) <= height) {
|
|
29
|
+
return {
|
|
30
|
+
overflow: true,
|
|
31
|
+
fontScale: Math.round(scale * 1000) / 1000,
|
|
32
|
+
lineReduction: reduction
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return FLOOR;
|
|
37
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Presentation } from './presentation.ts';
|
|
2
|
+
import type { OpenOptions } from '../opc/package.ts';
|
|
3
|
+
import type { CreateOptions } from './template.ts';
|
|
4
|
+
export { Presentation } from './presentation.ts';
|
|
5
|
+
export type * from './types.ts';
|
|
6
|
+
export type { CreateOptions, SlideSize, ThemeColor, ThemeFonts } from './template.ts';
|
|
7
|
+
export declare function open(bytes: Uint8Array, opts?: OpenOptions): Presentation;
|
|
8
|
+
export declare function create(opts?: CreateOptions): Presentation;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Element } from '../xml.ts';
|
|
2
|
+
import type { Package } from '../opc/package.ts';
|
|
3
|
+
export interface Box {
|
|
4
|
+
x: number;
|
|
5
|
+
y: number;
|
|
6
|
+
width: number;
|
|
7
|
+
height: number;
|
|
8
|
+
}
|
|
9
|
+
export interface Insets {
|
|
10
|
+
left: number;
|
|
11
|
+
right: number;
|
|
12
|
+
top: number;
|
|
13
|
+
bottom: number;
|
|
14
|
+
}
|
|
15
|
+
export interface PlaceholderKey {
|
|
16
|
+
type: string;
|
|
17
|
+
idx: string | null;
|
|
18
|
+
}
|
|
19
|
+
export interface ShapeInSlide {
|
|
20
|
+
pkg: Package;
|
|
21
|
+
slide: string;
|
|
22
|
+
el: Element;
|
|
23
|
+
}
|
|
24
|
+
export declare function placeholderOf(el: Element): PlaceholderKey | null;
|
|
25
|
+
export declare function xfrmOf(el: Element): Element | null;
|
|
26
|
+
export declare function explicitBox(el: Element): Box | null;
|
|
27
|
+
export declare function box(shape: ShapeInSlide): Box | null;
|
|
28
|
+
export declare function insets(shape: ShapeInSlide): Insets;
|
|
29
|
+
export declare function fontSize(shape: ShapeInSlide, level: number): number;
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import * as xml from '../xml.js';
|
|
2
|
+
const { a: A, p: P } = xml.ns;
|
|
3
|
+
const REL_BASE = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/';
|
|
4
|
+
const TITLE_TYPES = new Set(['title', 'ctrTitle']);
|
|
5
|
+
const DEFAULT_INSET = 91440;
|
|
6
|
+
const INSET_NAMES = {
|
|
7
|
+
left: 'lIns',
|
|
8
|
+
right: 'rIns',
|
|
9
|
+
top: 'tIns',
|
|
10
|
+
bottom: 'bIns'
|
|
11
|
+
};
|
|
12
|
+
const SIDES = ['left', 'right', 'top', 'bottom'];
|
|
13
|
+
export function placeholderOf(el) {
|
|
14
|
+
const nv = xml.children(el)[0];
|
|
15
|
+
const nvPr = nv ? xml.child(nv, P, 'nvPr') : null;
|
|
16
|
+
const ph = nvPr ? xml.child(nvPr, P, 'ph') : null;
|
|
17
|
+
if (!ph) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
return { type: ph.getAttribute('type') || 'obj', idx: ph.getAttribute('idx') || null };
|
|
21
|
+
}
|
|
22
|
+
export function xfrmOf(el) {
|
|
23
|
+
if (el.localName === 'graphicFrame') {
|
|
24
|
+
return xml.child(el, P, 'xfrm');
|
|
25
|
+
}
|
|
26
|
+
const props = xml.child(el, P, el.localName === 'grpSp' ? 'grpSpPr' : 'spPr');
|
|
27
|
+
return props ? xml.child(props, A, 'xfrm') : null;
|
|
28
|
+
}
|
|
29
|
+
export function explicitBox(el) {
|
|
30
|
+
const xfrm = xfrmOf(el);
|
|
31
|
+
const off = xfrm ? xml.child(xfrm, A, 'off') : null;
|
|
32
|
+
const ext = xfrm ? xml.child(xfrm, A, 'ext') : null;
|
|
33
|
+
if (!off || !ext) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
x: Number(off.getAttribute('x')),
|
|
38
|
+
y: Number(off.getAttribute('y')),
|
|
39
|
+
width: Number(ext.getAttribute('cx')),
|
|
40
|
+
height: Number(ext.getAttribute('cy'))
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function spTreeShapes(doc) {
|
|
44
|
+
const tree = xml.descendants(doc, P, 'spTree')[0];
|
|
45
|
+
return tree ? xml.children(tree, P, 'sp') : [];
|
|
46
|
+
}
|
|
47
|
+
function matchLayout(doc, key) {
|
|
48
|
+
const shapes = spTreeShapes(doc).flatMap((el) => {
|
|
49
|
+
const ph = placeholderOf(el);
|
|
50
|
+
return ph ? [{ el, ph }] : [];
|
|
51
|
+
});
|
|
52
|
+
const byIdx = key.idx === null ? undefined : shapes.find((s) => s.ph.idx === key.idx);
|
|
53
|
+
if (byIdx) {
|
|
54
|
+
return byIdx.el;
|
|
55
|
+
}
|
|
56
|
+
return shapes.find((s) => s.ph.type === key.type)?.el ?? null;
|
|
57
|
+
}
|
|
58
|
+
function masterType(type) {
|
|
59
|
+
if (TITLE_TYPES.has(type))
|
|
60
|
+
return 'title';
|
|
61
|
+
if (['dt', 'ftr', 'sldNum'].includes(type))
|
|
62
|
+
return type;
|
|
63
|
+
return 'body';
|
|
64
|
+
}
|
|
65
|
+
function matchMaster(doc, key) {
|
|
66
|
+
const wanted = masterType(key.type);
|
|
67
|
+
const found = spTreeShapes(doc).find((el) => {
|
|
68
|
+
const ph = placeholderOf(el);
|
|
69
|
+
return ph !== null && masterType(ph.type) === wanted;
|
|
70
|
+
});
|
|
71
|
+
return found ?? null;
|
|
72
|
+
}
|
|
73
|
+
function layoutOf(pkg, slide) {
|
|
74
|
+
return pkg.related(slide, REL_BASE + 'slideLayout')[0];
|
|
75
|
+
}
|
|
76
|
+
function masterOf(pkg, layout) {
|
|
77
|
+
return pkg.related(layout, REL_BASE + 'slideMaster')[0];
|
|
78
|
+
}
|
|
79
|
+
function chain(shape) {
|
|
80
|
+
const { pkg, slide, el } = shape;
|
|
81
|
+
const key = placeholderOf(el);
|
|
82
|
+
const out = [el];
|
|
83
|
+
const layout = key ? layoutOf(pkg, slide) : undefined;
|
|
84
|
+
if (!key || !layout) {
|
|
85
|
+
return out;
|
|
86
|
+
}
|
|
87
|
+
const layoutShape = matchLayout(pkg.xml(layout), key);
|
|
88
|
+
if (layoutShape) {
|
|
89
|
+
out.push(layoutShape);
|
|
90
|
+
}
|
|
91
|
+
const master = masterOf(pkg, layout);
|
|
92
|
+
const masterShape = master ? matchMaster(pkg.xml(master), key) : null;
|
|
93
|
+
if (masterShape) {
|
|
94
|
+
out.push(masterShape);
|
|
95
|
+
}
|
|
96
|
+
return out;
|
|
97
|
+
}
|
|
98
|
+
export function box(shape) {
|
|
99
|
+
for (const node of chain(shape)) {
|
|
100
|
+
const found = explicitBox(node);
|
|
101
|
+
if (found) {
|
|
102
|
+
return found;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
function bodyPrOf(node) {
|
|
108
|
+
const txBody = xml.child(node, P, 'txBody');
|
|
109
|
+
return txBody ? xml.child(txBody, A, 'bodyPr') : null;
|
|
110
|
+
}
|
|
111
|
+
export function insets(shape) {
|
|
112
|
+
const out = {
|
|
113
|
+
left: DEFAULT_INSET,
|
|
114
|
+
right: DEFAULT_INSET,
|
|
115
|
+
top: DEFAULT_INSET / 2,
|
|
116
|
+
bottom: DEFAULT_INSET / 2
|
|
117
|
+
};
|
|
118
|
+
const nodes = chain(shape);
|
|
119
|
+
for (const side of SIDES) {
|
|
120
|
+
const found = nodes.map(bodyPrOf).find((bodyPr) => bodyPr?.hasAttribute(INSET_NAMES[side]));
|
|
121
|
+
if (found) {
|
|
122
|
+
out[side] = Number(found.getAttribute(INSET_NAMES[side]));
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return out;
|
|
126
|
+
}
|
|
127
|
+
function levelSize(list, level) {
|
|
128
|
+
const lvl = list ? xml.child(list, A, `lvl${level + 1}pPr`) : null;
|
|
129
|
+
const def = lvl ? xml.child(lvl, A, 'defRPr') : null;
|
|
130
|
+
return def?.hasAttribute('sz') ? Number(def.getAttribute('sz')) / 100 : null;
|
|
131
|
+
}
|
|
132
|
+
function styleName(key) {
|
|
133
|
+
if (!key)
|
|
134
|
+
return 'otherStyle';
|
|
135
|
+
if (masterType(key.type) === 'title')
|
|
136
|
+
return 'titleStyle';
|
|
137
|
+
return ['body', 'obj', 'subTitle'].includes(key.type) ? 'bodyStyle' : 'otherStyle';
|
|
138
|
+
}
|
|
139
|
+
export function fontSize(shape, level) {
|
|
140
|
+
for (const node of chain(shape)) {
|
|
141
|
+
const txBody = xml.child(node, P, 'txBody');
|
|
142
|
+
const size = levelSize(txBody ? xml.child(txBody, A, 'lstStyle') : null, level);
|
|
143
|
+
if (size) {
|
|
144
|
+
return size;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
const layout = layoutOf(shape.pkg, shape.slide);
|
|
148
|
+
const master = layout ? masterOf(shape.pkg, layout) : undefined;
|
|
149
|
+
if (!master) {
|
|
150
|
+
return 18;
|
|
151
|
+
}
|
|
152
|
+
const styles = xml.child(shape.pkg.root(master), P, 'txStyles');
|
|
153
|
+
const size = levelSize(styles ? xml.child(styles, P, styleName(placeholderOf(shape.el))) : null, level);
|
|
154
|
+
return size || 18;
|
|
155
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Document, Element } from '../xml.ts';
|
|
2
|
+
import type { Deck } from './slides.ts';
|
|
3
|
+
export declare function notesBody(doc: Document, id: number): Element;
|
|
4
|
+
export declare function writeNotes(deck: Deck, slidePart: string, value: unknown): void;
|
|
5
|
+
export declare function notesText(deck: Deck, slidePart: string): string | null;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import * as xml from '../xml.js';
|
|
2
|
+
import * as text from '../drawingml/text.js';
|
|
3
|
+
import { SHAPE_ORDER, shapesOf, nextShapeId } from './shapes.js';
|
|
4
|
+
import { notesTheme } from './template.js';
|
|
5
|
+
import { PRESENTATION_ORDER } from './slides.js';
|
|
6
|
+
const { a: A, p: P, r: R } = xml.ns;
|
|
7
|
+
const REL_BASE = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/';
|
|
8
|
+
const REL = {
|
|
9
|
+
slide: REL_BASE + 'slide',
|
|
10
|
+
notesSlide: REL_BASE + 'notesSlide',
|
|
11
|
+
notesMaster: REL_BASE + 'notesMaster',
|
|
12
|
+
theme: REL_BASE + 'theme'
|
|
13
|
+
};
|
|
14
|
+
const NOTES_TYPE = 'application/vnd.openxmlformats-officedocument.presentationml.notesSlide+xml';
|
|
15
|
+
const NOTES_MASTER_TYPE = 'application/vnd.openxmlformats-officedocument.presentationml.notesMaster+xml';
|
|
16
|
+
const THEME_TYPE = 'application/vnd.openxmlformats-officedocument.theme+xml';
|
|
17
|
+
const NOTES_XML = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<p:notes xmlns:a="${A}" xmlns:r="${R}" xmlns:p="${P}"><p:cSld><p:spTree><p:nvGrpSpPr><p:cNvPr id="1" name=""/><p:cNvGrpSpPr/><p:nvPr/></p:nvGrpSpPr><p:grpSpPr/><p:sp><p:nvSpPr><p:cNvPr id="2" name="Slide Image Placeholder 1"/><p:cNvSpPr><a:spLocks noGrp="1" noRot="1" noChangeAspect="1"/></p:cNvSpPr><p:nvPr><p:ph type="sldImg"/></p:nvPr></p:nvSpPr><p:spPr/></p:sp></p:spTree></p:cSld><p:clrMapOvr><a:masterClrMapping/></p:clrMapOvr></p:notes>`;
|
|
18
|
+
const NOTES_MASTER_XML = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<p:notesMaster xmlns:a="${A}" xmlns:r="${R}" xmlns:p="${P}"><p:cSld><p:bg><p:bgRef idx="1001"><a:schemeClr val="bg1"/></p:bgRef></p:bg><p:spTree><p:nvGrpSpPr><p:cNvPr id="1" name=""/><p:cNvGrpSpPr/><p:nvPr/></p:nvGrpSpPr><p:grpSpPr/><p:sp><p:nvSpPr><p:cNvPr id="2" name="Slide Image Placeholder 1"/><p:cNvSpPr><a:spLocks noGrp="1" noRot="1" noChangeAspect="1"/></p:cNvSpPr><p:nvPr><p:ph type="sldImg" idx="2"/></p:nvPr></p:nvSpPr><p:spPr><a:xfrm><a:off x="381000" y="685800"/><a:ext cx="6096000" cy="3429000"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom><a:noFill/><a:ln w="12700"><a:solidFill><a:prstClr val="black"/></a:solidFill></a:ln></p:spPr></p:sp><p:sp><p:nvSpPr><p:cNvPr id="3" name="Notes Placeholder 2"/><p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr><p:nvPr><p:ph type="body" sz="quarter" idx="3"/></p:nvPr></p:nvSpPr><p:spPr><a:xfrm><a:off x="685800" y="4343400"/><a:ext cx="5486400" cy="4114800"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></p:spPr><p:txBody><a:bodyPr vert="horz" lIns="91440" tIns="45720" rIns="91440" bIns="45720" rtlCol="0"/><a:lstStyle/><a:p><a:pPr lvl="0"/><a:r><a:rPr lang="en-US"/><a:t>Click to edit Master text styles</a:t></a:r></a:p></p:txBody></p:sp></p:spTree></p:cSld><p:clrMap bg1="lt1" tx1="dk1" bg2="lt2" tx2="dk2" accent1="accent1" accent2="accent2" accent3="accent3" accent4="accent4" accent5="accent5" accent6="accent6" hlink="hlink" folHlink="folHlink"/><p:notesStyle><a:lvl1pPr marL="0" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1"><a:defRPr sz="1200" kern="1200"><a:solidFill><a:schemeClr val="tx1"/></a:solidFill><a:latin typeface="+mn-lt"/><a:ea typeface="+mn-ea"/><a:cs typeface="+mn-cs"/></a:defRPr></a:lvl1pPr></p:notesStyle></p:notesMaster>`;
|
|
19
|
+
export function notesBody(doc, id) {
|
|
20
|
+
const p = xml.builder(doc, P);
|
|
21
|
+
const sp = p('sp');
|
|
22
|
+
const nv = xml.append(sp, p('nvSpPr'));
|
|
23
|
+
nv.appendChild(p('cNvPr', { id, name: `Notes Placeholder ${id - 1}` }));
|
|
24
|
+
xml.append(nv, p('cNvSpPr')).appendChild(xml.builder(doc, A)('spLocks', { noGrp: 1 }));
|
|
25
|
+
xml.append(nv, p('nvPr')).appendChild(p('ph', { type: 'body', idx: 1 }));
|
|
26
|
+
sp.appendChild(p('spPr'));
|
|
27
|
+
text.ensureTextBody(sp, SHAPE_ORDER);
|
|
28
|
+
return sp;
|
|
29
|
+
}
|
|
30
|
+
function createNotesMaster(deck) {
|
|
31
|
+
const { pkg } = deck;
|
|
32
|
+
const themeSource = pkg.related(deck.main, REL.theme)[0];
|
|
33
|
+
const theme = pkg.freeName('/ppt/theme/theme%d.xml');
|
|
34
|
+
pkg.add(theme, themeSource ? pkg.bytes(themeSource) : notesTheme(), THEME_TYPE);
|
|
35
|
+
const part = pkg.freeName('/ppt/notesMasters/notesMaster%d.xml');
|
|
36
|
+
pkg.add(part, xml.parse(NOTES_MASTER_XML), NOTES_MASTER_TYPE);
|
|
37
|
+
pkg.rels(part).add(REL.theme, theme);
|
|
38
|
+
const rId = pkg.rels(deck.main).add(REL.notesMaster, part);
|
|
39
|
+
const top = pkg.root(deck.main);
|
|
40
|
+
const p = xml.builder(xml.owner(top), P);
|
|
41
|
+
const list = xml.child(top, P, 'notesMasterIdLst') ??
|
|
42
|
+
xml.insertOrdered(top, p('notesMasterIdLst'), PRESENTATION_ORDER);
|
|
43
|
+
const ref = xml.append(list, p('notesMasterId'));
|
|
44
|
+
xml.setNsAttribute(ref, { namespace: R, local: 'id' }, rId);
|
|
45
|
+
pkg.touch(deck.main);
|
|
46
|
+
return part;
|
|
47
|
+
}
|
|
48
|
+
function createNotes(deck, slidePart) {
|
|
49
|
+
const { pkg } = deck;
|
|
50
|
+
const master = pkg.related(deck.main, REL.notesMaster)[0] ?? createNotesMaster(deck);
|
|
51
|
+
const part = pkg.freeName('/ppt/notesSlides/notesSlide%d.xml');
|
|
52
|
+
const doc = xml.parse(NOTES_XML);
|
|
53
|
+
xml.descendants(doc, P, 'spTree')[0]?.appendChild(notesBody(doc, 3));
|
|
54
|
+
pkg.add(part, doc, NOTES_TYPE);
|
|
55
|
+
pkg.rels(part).add(REL.notesMaster, master);
|
|
56
|
+
pkg.rels(part).add(REL.slide, slidePart);
|
|
57
|
+
pkg.rels(slidePart).add(REL.notesSlide, part);
|
|
58
|
+
return part;
|
|
59
|
+
}
|
|
60
|
+
function bodyOf(doc) {
|
|
61
|
+
const existing = shapesOf(doc).find((s) => s.placeholder === 'body');
|
|
62
|
+
if (existing) {
|
|
63
|
+
return existing.el;
|
|
64
|
+
}
|
|
65
|
+
const el = notesBody(doc, nextShapeId(doc));
|
|
66
|
+
xml.descendants(doc, P, 'spTree')[0]?.appendChild(el);
|
|
67
|
+
return el;
|
|
68
|
+
}
|
|
69
|
+
export function writeNotes(deck, slidePart, value) {
|
|
70
|
+
text.normalizeParagraphs(value);
|
|
71
|
+
const notes = deck.pkg.related(slidePart, REL.notesSlide)[0] ?? createNotes(deck, slidePart);
|
|
72
|
+
const txBody = text.ensureTextBody(bodyOf(deck.pkg.xml(notes)), SHAPE_ORDER);
|
|
73
|
+
text.writeParagraphs(txBody, value);
|
|
74
|
+
deck.pkg.touch(notes);
|
|
75
|
+
}
|
|
76
|
+
export function notesText(deck, slidePart) {
|
|
77
|
+
const notes = deck.pkg.related(slidePart, REL.notesSlide)[0];
|
|
78
|
+
if (!notes) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
const body = shapesOf(deck.pkg.xml(notes)).find((s) => s.placeholder === 'body');
|
|
82
|
+
const txBody = body ? xml.child(body.el, P, 'txBody') : null;
|
|
83
|
+
const value = txBody ? text.readText(txBody).trim() : '';
|
|
84
|
+
return value || null;
|
|
85
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Package, type OpenOptions } from '../opc/package.ts';
|
|
2
|
+
import type { Box } from './inherit.ts';
|
|
3
|
+
import type { SaveOptions } from '../opc/properties.ts';
|
|
4
|
+
import type { CreateOptions, SlideSize } from './template.ts';
|
|
5
|
+
import type { TextInput, Style } from '../drawingml/text.ts';
|
|
6
|
+
import type { DataResult, ChartData, Changed as ChartChanged } from '../drawingml/chart.ts';
|
|
7
|
+
import type { ShapeRef, CellRef, ReadOptions, SlideInfo, LayoutInfo, TextResult, FitOptions, StyleOptions, RunCount, AddSlideOptions, AddedSlide, PictureOptions, TextBoxOptions, TableOptions, ChartOptions, PlacedShape, ReplaceOptions, ReplacedPicture, MoveOptions, Moved, Deleted, Remaining, Changed } from './types.ts';
|
|
8
|
+
export declare class Presentation {
|
|
9
|
+
package: Package;
|
|
10
|
+
main: string;
|
|
11
|
+
private slidesChanged;
|
|
12
|
+
private touchedSlides;
|
|
13
|
+
constructor(pkg: Package);
|
|
14
|
+
static open(bytes: Uint8Array, opts?: OpenOptions): Presentation;
|
|
15
|
+
static create(opts?: CreateOptions): Presentation;
|
|
16
|
+
get changed(): boolean;
|
|
17
|
+
get slideCount(): number;
|
|
18
|
+
get slideSize(): SlideSize;
|
|
19
|
+
layouts(): LayoutInfo[];
|
|
20
|
+
read(opts?: ReadOptions): SlideInfo[];
|
|
21
|
+
setText(target: ShapeRef, value: TextInput, opts?: FitOptions): TextResult;
|
|
22
|
+
setCellText(cell: CellRef, value: TextInput): TextResult;
|
|
23
|
+
setStyle(target: ShapeRef, style: Style, opts?: StyleOptions): RunCount;
|
|
24
|
+
format(target: ShapeRef, style: Style, opts?: StyleOptions): RunCount;
|
|
25
|
+
addSlide(opts?: AddSlideOptions): AddedSlide;
|
|
26
|
+
addPicture(slide: number, bytes: Uint8Array, opts?: PictureOptions): PlacedShape;
|
|
27
|
+
addTextBox(slide: number, opts?: TextBoxOptions): PlacedShape;
|
|
28
|
+
addTable(slide: number, opts: TableOptions): PlacedShape;
|
|
29
|
+
addChart(slide: number, spec: ChartOptions): PlacedShape;
|
|
30
|
+
setChartData(target: ShapeRef, data: ChartData): DataResult;
|
|
31
|
+
setChartTitle(target: ShapeRef, title: TextInput | null): ChartChanged;
|
|
32
|
+
setBackground(slide: number, color: string | null): Changed;
|
|
33
|
+
deleteShape(target: ShapeRef): Deleted;
|
|
34
|
+
setBox(target: ShapeRef, input: Partial<Box>): PlacedShape;
|
|
35
|
+
replacePicture(target: ShapeRef, bytes: Uint8Array, opts?: ReplaceOptions): ReplacedPicture;
|
|
36
|
+
setNotes(slide: number, value: TextInput): Changed;
|
|
37
|
+
deleteSlide(slide: number): Remaining;
|
|
38
|
+
moveSlide(slide: number, opts: MoveOptions): Moved;
|
|
39
|
+
save(opts?: SaveOptions): Uint8Array;
|
|
40
|
+
private get deck();
|
|
41
|
+
private spTree;
|
|
42
|
+
private slideInfo;
|
|
43
|
+
private shapeInfo;
|
|
44
|
+
private insertSlide;
|
|
45
|
+
private refuseLinked;
|
|
46
|
+
private touchSlide;
|
|
47
|
+
private locate;
|
|
48
|
+
private write;
|
|
49
|
+
private estimate;
|
|
50
|
+
private chartOf;
|
|
51
|
+
private chartPart;
|
|
52
|
+
private box;
|
|
53
|
+
private pictureBox;
|
|
54
|
+
}
|