@openpresentation/opf-pptx 0.12.0 → 0.12.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.
- package/dist/index.js +16 -1
- package/dist/master-themes.js +49 -0
- package/dist/package-fonts.js +6 -4
- package/dist/script-fonts.js +60 -3
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import {autoNumScheme, deriveListNumbering, withDisplayedNumbers} from './number
|
|
|
3
3
|
import {isFaceStyleSuffix} from './font-weights.js';
|
|
4
4
|
import {importTableFrames} from './table-import.js';
|
|
5
5
|
import {applyChartFonts, applyPitchFamilies, finalizeFontsUsed, fontPitchFamilies} from './package-fonts.js';
|
|
6
|
+
import {giveNotesMastersOwnThemes} from './master-themes.js';
|
|
6
7
|
import {readChartCategoryHeading,writeChartCategoryHeading} from './chart-workbook.js';
|
|
7
8
|
import {CHARTEX_FALLBACK,resolveChartType,chartTypeFromNative,applyChartConstruct,NATIVE_CHART_ELEMENTS} from './chart-types.js';
|
|
8
9
|
import {attachChartexParts,chartFromChartex,CHARTEX_GRAPHIC_DATA_URI} from './chartex.js';
|
|
@@ -34,7 +35,7 @@ import {placeLogos, importLogo, importLogoPlaceholders, logoName, LOGO_TAG} from
|
|
|
34
35
|
import {nativeBackgroundFill, nativeImageBackgroundFill, nativePatternPreset} from './background.js';
|
|
35
36
|
import {importBackground} from './background-import.js';
|
|
36
37
|
import {themeSlotColors, writeThemeColors, schemeColorValue, schemeBackgroundFill, schemeBackgroundValue, defaultTextSchemeValues, tableTextSchemeValue, solidColorXml, writeMasterBackground, inheritLayoutBackground, readThemeSlotColors, recoverColorScheme, recoverTheme, presentationThemePath} from './theme-colors.js';
|
|
37
|
-
import {languageDiagnostics, observeLanguage, observedRtl, partScriptFonts, physicalAlignment, planScriptFonts, reconcileLanguage} from './script-fonts.js';
|
|
38
|
+
import {languageDiagnostics, observeLanguage, observedRtl, partScriptFonts, physicalAlignment, planScriptFonts, reconcileLanguage, stripRunScriptFonts, themeEastAsianFromLatin} from './script-fonts.js';
|
|
38
39
|
import { webpToPng, svgToPng, readLocalFile } from '#image-fallback';
|
|
39
40
|
import { prepareSvg, svgDataUriBytes, svgRasterScale, svgBlipRelationship, attachSvgPictures } from './svg-image.js';
|
|
40
41
|
import { rasterMetadata, pictureTransform, normalizeImageOrientation } from './image-geometry.js';
|
|
@@ -3322,6 +3323,7 @@ async function normalizePptxZip(raw, context) {
|
|
|
3322
3323
|
}
|
|
3323
3324
|
|
|
3324
3325
|
writeNativeFurnitureMasters(output, context);
|
|
3326
|
+
giveNotesMastersOwnThemes(output);
|
|
3325
3327
|
finalizeFontsUsed(output);
|
|
3326
3328
|
// Document references record evidence from the final normalized parts.
|
|
3327
3329
|
if (context.documentProvenance) {
|
|
@@ -3400,6 +3402,7 @@ function normalizePartBytes(path, bytes, context, renameMaps, entries, imageMeta
|
|
|
3400
3402
|
if (/^ppt\/slideMasters\/slideMaster\d+\.xml$/.test(path)) xml = themeMasterBulletFonts(xml);
|
|
3401
3403
|
if (context.masterBackground && path === 'ppt/slideMasters/slideMaster1.xml') xml = writeMasterBackground(xml, context.masterBackground);
|
|
3402
3404
|
if (context.masterBackground && /^ppt\/slideLayouts\/slideLayout\d+\.xml$/.test(path)) xml = inheritLayoutBackground(xml);
|
|
3405
|
+
if (path === 'ppt/presentation.xml') xml = presentationInSchemaOrder(xml);
|
|
3403
3406
|
if (path === 'ppt/theme/theme1.xml') xml = writeThemeColors(xml, {colors: context.themeColors, schemeName: context.schemeName, themeName: context.themeName});
|
|
3404
3407
|
if (/^ppt\/slides\/slide\d+\.xml$/.test(path)) {
|
|
3405
3408
|
xml = writeLinkSentinels(xml, context.linkSentinels);
|
|
@@ -3544,6 +3547,8 @@ function normalizePartBytes(path, bytes, context, renameMaps, entries, imageMeta
|
|
|
3544
3547
|
}
|
|
3545
3548
|
// theme1.xml: FF-24 colors and names above, then FF-07 fonts here; they touch disjoint elements.
|
|
3546
3549
|
if (context.scriptFonts) xml = partScriptFonts(path, xml, context.scriptFonts, context.partSlides.get(path) ?? 0);
|
|
3550
|
+
else if (/^ppt\/theme\/theme\d+\.xml$/.test(path)) xml = themeEastAsianFromLatin(xml);
|
|
3551
|
+
if (/^ppt\/(?:slides\/slide|notesSlides\/notesSlide)\d+\.xml$/.test(path)) xml = stripRunScriptFonts(xml);
|
|
3547
3552
|
return encodeText(normalizePartReferences(xml, renameMaps));
|
|
3548
3553
|
}
|
|
3549
3554
|
return bytes;
|
|
@@ -3562,6 +3567,16 @@ function themeMasterBulletFonts(xml) {
|
|
|
3562
3567
|
bodyStyle.split(VENDOR_MASTER_BULLET_FONT).join(THEME_MINOR_BULLET_FONT));
|
|
3563
3568
|
}
|
|
3564
3569
|
|
|
3570
|
+
// FF-05: PptxGenJS 4.0.1 writes p:notesMasterIdLst after p:sldIdLst, but CT_Presentation is a sequence
|
|
3571
|
+
// (sldMasterIdLst, notesMasterIdLst, handoutMasterIdLst, sldIdLst, sldSz, ...). PowerPoint reads the out-of-order
|
|
3572
|
+
// list as no notes master and lists a default-theme font (Aptos) in Presentation.Fonts; schema order restores
|
|
3573
|
+
// the exporter's own notes master. Only the list's position changes.
|
|
3574
|
+
function presentationInSchemaOrder(xml) {
|
|
3575
|
+
const notes = /<p:notesMasterIdLst>[\s\S]*?<\/p:notesMasterIdLst>/.exec(xml)?.[0];
|
|
3576
|
+
if (!notes || xml.indexOf(notes) < xml.indexOf('</p:sldMasterIdLst>')) return xml;
|
|
3577
|
+
return xml.replace(notes, '').replace('</p:sldMasterIdLst>', `</p:sldMasterIdLst>${notes}`);
|
|
3578
|
+
}
|
|
3579
|
+
|
|
3565
3580
|
function isXmlPart(path) {
|
|
3566
3581
|
return path.endsWith(".xml") || path.endsWith(".rels") || path === "[Content_Types].xml";
|
|
3567
3582
|
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
const decoder = new TextDecoder(), encoder = new TextEncoder();
|
|
2
|
+
const text = bytes => decoder.decode(bytes);
|
|
3
|
+
|
|
4
|
+
const THEME_TYPE = 'application/vnd.openxmlformats-officedocument.theme+xml';
|
|
5
|
+
const THEME_TARGET = /Target="\.\.\/theme\/(theme\d+\.xml)"/;
|
|
6
|
+
const NOTES_MASTER = /^ppt\/notesMasters\/notesMaster\d+\.xml$/;
|
|
7
|
+
const SLIDE_MASTER = /^ppt\/slideMasters\/slideMaster\d+\.xml$/;
|
|
8
|
+
|
|
9
|
+
const relsOf = path => path.replace(/([^/]+)$/, '_rels/$1.rels');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* FF-05 (font-fidelity-everywhere). PptxGenJS 4.0.1 points the notes master at the slide master's theme part
|
|
13
|
+
* (`ppt/theme/theme1.xml`). Every master owns its theme part in a PowerPoint package (theme1 for the slide master,
|
|
14
|
+
* theme2 for the notes master, theme3 for a handout master), and PowerPoint refuses to read a package whose notes
|
|
15
|
+
* master it recognises when that master shares the slide theme ("The file or directory is corrupted and unreadable",
|
|
16
|
+
* 0x80070570). The vendored `p:notesMasterIdLst` sits after `p:sldIdLst` (see presentationInSchemaOrder in index.js),
|
|
17
|
+
* which PowerPoint ignored; it then synthesised a default notes master with the default Office theme, and that
|
|
18
|
+
* made the default font (Aptos) appear in Presentation.Fonts although no part names it.
|
|
19
|
+
*
|
|
20
|
+
* Each notes master that shares a theme part with another master gets its own copy of that theme, with the same
|
|
21
|
+
* fonts, colours and format scheme, a relationship to it and a content-type override. The copy is taken after
|
|
22
|
+
* every theme rewrite, so it carries the deck's final fonts. Copies are numbered after the existing themes.
|
|
23
|
+
*/
|
|
24
|
+
export function giveNotesMastersOwnThemes(output) {
|
|
25
|
+
const types = output['[Content_Types].xml'];
|
|
26
|
+
if (!types) return;
|
|
27
|
+
const used = new Set();
|
|
28
|
+
const themeOf = master => THEME_TARGET.exec(text(output[relsOf(master)]?.[0] ?? new Uint8Array()))?.[1];
|
|
29
|
+
for (const master of Object.keys(output).filter(path => SLIDE_MASTER.test(path))) {
|
|
30
|
+
const theme = themeOf(master);
|
|
31
|
+
if (theme) used.add(theme);
|
|
32
|
+
}
|
|
33
|
+
let next = Math.max(0, ...Object.keys(output).map(path => Number(/^ppt\/theme\/theme(\d+)\.xml$/.exec(path)?.[1] ?? 0))) + 1;
|
|
34
|
+
let overrides = '';
|
|
35
|
+
for (const master of Object.keys(output).filter(path => NOTES_MASTER.test(path)).sort()) {
|
|
36
|
+
const theme = themeOf(master);
|
|
37
|
+
if (!theme) continue;
|
|
38
|
+
if (!used.has(theme)) { used.add(theme); continue; }
|
|
39
|
+
const source = output[`ppt/theme/${theme}`];
|
|
40
|
+
if (!source) continue;
|
|
41
|
+
const name = `theme${next++}.xml`;
|
|
42
|
+
output[`ppt/theme/${name}`] = [source[0], source[1]];
|
|
43
|
+
const rels = relsOf(master);
|
|
44
|
+
output[rels] = [encoder.encode(text(output[rels][0]).replace(THEME_TARGET, `Target="../theme/${name}"`)), output[rels][1]];
|
|
45
|
+
overrides += `<Override PartName="/ppt/theme/${name}" ContentType="${THEME_TYPE}"/>`;
|
|
46
|
+
used.add(name);
|
|
47
|
+
}
|
|
48
|
+
if (overrides) output['[Content_Types].xml'] = [encoder.encode(text(types[0]).replace('</Types>', `${overrides}</Types>`)), types[1]];
|
|
49
|
+
}
|
package/dist/package-fonts.js
CHANGED
|
@@ -122,7 +122,7 @@ export function applyPitchFamilies(entries, pitch) {
|
|
|
122
122
|
// docProps/app.xml: regenerate the "Fonts Used" group of HeadingPairs and
|
|
123
123
|
// TitlesOfParts from the fonts the finished package uses, and name the theme
|
|
124
124
|
// the way the theme part does. Other groups (slide titles) are kept.
|
|
125
|
-
export function writeFontsUsed(appXml, fonts,
|
|
125
|
+
export function writeFontsUsed(appXml, fonts, themeNames) {
|
|
126
126
|
const pairs = headingPairs(appXml), titles = titlesOfParts(appXml);
|
|
127
127
|
if (!pairs || !titles) return appXml;
|
|
128
128
|
const groups = [];
|
|
@@ -135,7 +135,8 @@ export function writeFontsUsed(appXml, fonts, themeName) {
|
|
|
135
135
|
if (fontsGroup) fontsGroup[1] = fonts;
|
|
136
136
|
else groups.unshift(['Fonts Used', fonts]);
|
|
137
137
|
const themeGroup = groups.find(([name]) => name === 'Theme');
|
|
138
|
-
|
|
138
|
+
const names = [themeNames ?? []].flat();
|
|
139
|
+
if (themeGroup && names.length) themeGroup[1] = names;
|
|
139
140
|
const kept = groups.filter(([, items]) => items.length);
|
|
140
141
|
const variants = kept.map(([name, items]) => `<vt:variant><vt:lpstr>${escapeXml(name)}</vt:lpstr></vt:variant><vt:variant><vt:i4>${items.length}</vt:i4></vt:variant>`).join('');
|
|
141
142
|
const items = kept.flatMap(([, list]) => list).map(item => `<vt:lpstr>${escapeXml(item)}</vt:lpstr>`).join('');
|
|
@@ -152,8 +153,9 @@ export function finalizeFontsUsed(output) {
|
|
|
152
153
|
const parts = {};
|
|
153
154
|
for (const [path, [bytes]] of Object.entries(output)) if (/^ppt\/.*\.xml$/.test(path)) parts[path] = bytes;
|
|
154
155
|
const fonts = packageFontsUsed(inventoryPptxTypefaces(parts, {nested: false}));
|
|
155
|
-
const
|
|
156
|
-
|
|
156
|
+
const themeNames = Object.keys(parts).filter(path => /^ppt\/theme\/theme\d+\.xml$/.test(path)).sort((a, b) => Number(a.match(/\d+/)[0]) - Number(b.match(/\d+/)[0]))
|
|
157
|
+
.map(path => /<a:theme\b[^>]*\bname="([^"]*)"/.exec(text(parts[path]))?.[1]).filter(name => name !== undefined).map(unescapeFace);
|
|
158
|
+
output['docProps/app.xml'] = [encoder.encode(writeFontsUsed(text(app[0]), fonts, themeNames)), app[1]];
|
|
157
159
|
}
|
|
158
160
|
|
|
159
161
|
function unescapeFace(value) {
|
package/dist/script-fonts.js
CHANGED
|
@@ -57,7 +57,37 @@ export function planScriptFonts(presentation, report) {
|
|
|
57
57
|
report?.({code: "paragraph-direction-unavailable", path: "language",
|
|
58
58
|
message: "The installed @openpresentation/opf has no paragraphDirection, so right-to-left paragraphs are not marked; the preview and export must share that rule. Use a core release that exports it."});
|
|
59
59
|
}
|
|
60
|
-
return {deck, slides, lang: deck.lang, rtl};
|
|
60
|
+
return {deck, slides, lang: deck.lang, rtl, contentEastAsian: contentEastAsianFonts(presentation, deck, report)};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// FF-05: East Asian characters in a deck whose own language has no East Asian font (an English deck with Japanese
|
|
64
|
+
// text) still need a real East Asian theme font; an empty slot reads as an unresolved +mn-ea in PowerPoint. The
|
|
65
|
+
// script of the text picks the language core resolves it for: kana is Japanese, hangul Korean, Han alone Simplified
|
|
66
|
+
// Chinese. Returns {heading, body} families, or null when the deck language already selects one or the text has none.
|
|
67
|
+
const KANA = /[\p{Script=Hiragana}\p{Script=Katakana}]/u, HANGUL = /\p{Script=Hangul}/u, HAN = /\p{Script=Han}/u;
|
|
68
|
+
function contentEastAsianFonts(presentation, deck, report) {
|
|
69
|
+
if (deck.sources.eastAsian !== "latin") return null;
|
|
70
|
+
let kana = false, hangul = false, han = false;
|
|
71
|
+
const seen = new Set();
|
|
72
|
+
const walk = value => {
|
|
73
|
+
if (typeof value === "string") {
|
|
74
|
+
kana ||= KANA.test(value); hangul ||= HANGUL.test(value); han ||= HAN.test(value);
|
|
75
|
+
} else if (value && typeof value === "object" && !seen.has(value)) {
|
|
76
|
+
seen.add(value);
|
|
77
|
+
for (const item of Object.values(value)) walk(item);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
walk(presentation.slides);
|
|
81
|
+
const language = kana ? "japanese" : hangul ? "korean" : han ? "chinese-simplified" : null;
|
|
82
|
+
if (!language) return null;
|
|
83
|
+
try {
|
|
84
|
+
const resolved = resolver({...presentation, language}, {slideIndex: 0});
|
|
85
|
+
return resolved.sources.eastAsian === "latin" ? null : {heading: resolved.heading.eastAsian, body: resolved.body.eastAsian};
|
|
86
|
+
} catch (error) {
|
|
87
|
+
report?.({code: "language-export-unavailable", path: "language",
|
|
88
|
+
message: `East Asian theme fonts for the East Asian text could not be resolved (${error instanceof Error ? error.message : String(error)}); the theme names the latin family for them.`});
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
61
91
|
}
|
|
62
92
|
|
|
63
93
|
const escapeAttribute = value => String(value).replace(/[&<>"']/g, char => ({"&": "&", "<": "<", ">": ">", "\"": """, "'": "'"}[char]));
|
|
@@ -82,8 +112,12 @@ export function themeScriptFonts(xml, plan) {
|
|
|
82
112
|
for (const [tag, slots, family] of [["majorFont", heading, supplement?.heading], ["minorFont", body, supplement?.body]]) {
|
|
83
113
|
xml = xml.replace(new RegExp(`<a:${tag}>[\\s\\S]*?</a:${tag}>`), block => {
|
|
84
114
|
for (const [element, slot] of SCRIPT_SLOTS) {
|
|
85
|
-
|
|
86
|
-
|
|
115
|
+
// FF-05: the East Asian slot always names a font (a script font, a font for the East Asian text, else the latin
|
|
116
|
+
// family): PowerPoint lists an empty slot as an empty-name font through every paragraph end mark. Complex script
|
|
117
|
+
// stays empty unless a script font is selected.
|
|
118
|
+
const content = element === "ea" && plan.deck.sources[slot] === "latin" ? plan.contentEastAsian?.[tag === "majorFont" ? "heading" : "body"] : undefined;
|
|
119
|
+
if (plan.deck.sources[slot] === "latin" && element !== "ea") continue;
|
|
120
|
+
const face = escapeAttribute(content ?? slots[slot]);
|
|
87
121
|
block = block.replace(new RegExp(`<a:${element}\\b[^>]*/>`), `<a:${element} typeface="${face}"/>`);
|
|
88
122
|
}
|
|
89
123
|
if (supplement && family) {
|
|
@@ -364,3 +398,26 @@ export function languageDiagnostics(imported, observed, report) {
|
|
|
364
398
|
}
|
|
365
399
|
}
|
|
366
400
|
}
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* FF-05: PptxGenJS writes every run's East Asian and complex-script font as a copy of the Latin face, with the
|
|
404
|
+
* charsets of other scripts (-122, -120). PowerPoint lists such a run font as an empty-name font in
|
|
405
|
+
* Presentation.Fonts and hides the real one (the charset is not the cause: a bare typeface does the same).
|
|
406
|
+
* PowerPoint's own runs name only the Latin face; East Asian and complex-script faces come from the paragraph or
|
|
407
|
+
* master style and the theme slots (+mn-ea, +mn-cs), which the exporter writes. A run keeps no explicit ea/cs
|
|
408
|
+
* typeface; theme references stay.
|
|
409
|
+
*/
|
|
410
|
+
export function stripRunScriptFonts(xml) {
|
|
411
|
+
return xml.replace(/<a:(?:ea|cs)\s+typeface="(?!\+)[^"]*"[^>]*\/>/g, "");
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* Without core's resolver the theme's East Asian slot still repeats the latin family of its font group, which keeps
|
|
416
|
+
* the paragraph end marks from reading an empty font (see themeScriptFonts).
|
|
417
|
+
*/
|
|
418
|
+
export function themeEastAsianFromLatin(xml) {
|
|
419
|
+
return xml.replace(/<a:(majorFont|minorFont)>[\s\S]*?<\/a:\1>/g, block => {
|
|
420
|
+
const latin = /<a:latin\b[^>]*\btypeface="([^"]+)"/.exec(block)?.[1];
|
|
421
|
+
return latin ? block.replace(/<a:ea typeface=""\/>/, `<a:ea typeface="${latin}"/>`) : block;
|
|
422
|
+
});
|
|
423
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openpresentation/opf-pptx",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.1",
|
|
4
4
|
"description": "Pure local OPF to PPTX export and PPTX to OPF import tooling.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
"sideEffects": false,
|
|
38
38
|
"scripts": {
|
|
39
39
|
"build": "node scripts/build.mjs",
|
|
40
|
-
"typecheck": "node --check src/index.js && node --check src/annotation-export.js && node --check src/annotation-provenance.js && node --check test/annotations.mjs && node --check test/region-reading-order.mjs && node --check test/symbol-fonts.mjs && node --check test/math-emoji.mjs && node --check src/svg-image.js && node --check test/svg-image.mjs && node --check test/native-svg-decks.mjs && node --check src/chart-types.js && node --check src/chartex.js && node --check src/chart-options.js && node --check test/chart-options.mjs && node --check test/chartex.mjs && node --check test/chart-text-size.mjs && node --check test/chart-types.mjs && node --check test/design-alignment.mjs && node --check src/color-ref.js && node --check src/theme-colors.js && node --check test/theme-colors.mjs && node --check test/tag-colour.mjs && node --check test/table-theme-colors.mjs && node --check scripts/build.mjs && node --check scripts/validate-package.mjs && node --check test/smoke.mjs && node --check src/image-geometry.js && node --check src/slide-image-provenance.js && node --check test/slide-image.mjs && node --check test/slide-image-treatments.mjs && node --check src/watermark-provenance.js && node --check src/logo-provenance.js && node --check test/design-fields.mjs && node --check src/media-dedupe.js && node --check test/media-dedupe.mjs && node --check test/watermark.mjs && node --check test/image-fit.mjs && node --check test/image-orientation.mjs && node --check test/table-layout.mjs && node --check test/table-import.mjs && node --check test/object-ids.mjs && node --check test/export-corpus.mjs && node --check test/image-media-type.mjs && node --check src/image-fallback-node.js && node --check src/image-fallback-browser.js && node --check test/webp-fallback.mjs && node --check scripts/build-browser-check.mjs && node --check test/webp-fallback-browser.js && node --check test/image-fallback-boundary.mjs && node --check src/background.js && node --check test/background.mjs && node --check src/image-import.js && node --check test/image-import.mjs && node --check test/native-background.mjs && node --check src/background-import.js && node --check test/background-inheritance.mjs && node --check test/rich-table.mjs && node --check src/table-import.js && node --check test/rich-table-import.mjs && node --check test/rich-table-import-browser.js && node --check test/table-row-sizing.mjs && node --check test/table-styles.mjs && node --check test/table-styles-browser.js && node --check test/styled-table.mjs && node --check src/table-cell-import.js && node --check test/styled-table-import.mjs && node --check test/styled-table-import-browser.js && node --check src/table-border-import.js && node --check test/table-border-styles.mjs && node --check src/card-provenance.js && node --check test/content-cards.mjs && node --check src/chart-workbook.js && node --check test/chart-colors.mjs && node --check test/single-series-colour.mjs && node --check test/chart-workbook.mjs && node --check test/single-column-chart.mjs && node --check test/native-chart-colors.mjs && node --check src/heading-provenance.js && node --check test/accepted-text.mjs && node --check test/heading-provenance.mjs && node --check src/text-provenance.js && node --check test/plain-whitespace.mjs && node --check src/timeline-provenance.js && node --check src/quote-provenance.js && node --check test/quote-provenance.mjs && node --check test/shared-timeline.mjs && node --check test/shared-furniture.mjs && node --check src/furniture-provenance.js && node --check src/document-provenance.js && node --check src/content-topology.js && node --check src/sections.js && node --check test/document-provenance.mjs && node --check test/content-topology.mjs && node --check test/sections.mjs && node --check test/provenance-interop.mjs && node --check test/furniture-provenance.mjs && node --check src/furniture-fields.js && node --check test/furniture-fields.mjs && node --check src/native-furniture.js && node --check test/native-furniture.mjs && node --check test/furniture-wrapped-date.mjs && node --check test/native-picture.mjs && node --check test/compare-native-picture.mjs && node --check test/compare-native-picture-edit.mjs && node --check test/compare-native-picture-edit-controls.mjs && node --check test/native-font-embed-audit.mjs && node --check test/native-font-embed-controls.mjs && node --check test/native-font-embed-fixture-source.mjs && node --check test/native-font-edit-fixture.mjs && node --check test/native-mixed-edit-audit.mjs && node --check test/native-mixed-edit-controls.mjs && node --check test/master-bullet-font.mjs && node --check test/native-font-inventory-audit.mjs && node --check test/native-font-inventory-controls.mjs && node --check test/default-font-scheme.mjs && node --check test/export-chosen-fonts.mjs && node --check test/background-fills.mjs && node --check src/typeface-inventory.js && node --check src/package-fonts.js && node --check test/typeface-inventory.mjs && node --check src/script-fonts.js && node --check test/script-fonts.mjs && node --check test/rtl-layout.mjs && node --check test/theme-script-slots.mjs && node --check test/powershell-scan.mjs && node --check test/powershell-scan-probes.mjs && node --check test/socials-furniture.mjs && node --check src/media-provenance.js && node --check test/layout-parity.mjs && node --check test/cover-centering.mjs && node --check test/media-placeholder.mjs && node --check test/image-placeholder.mjs && node --check test/svg-image-degrade.mjs && node --check test/background-colorref.mjs && node --check test/import-fabrications.mjs && node --check src/run-colors.js && node --check test/hard-line-breaks.mjs && node --check test/import-details.mjs && node --check test/list-shape-names.mjs && node --check src/numbered-list.js && node --check test/numbered-lists.mjs && node --check test/layout-intent.mjs && node --check test/chart-cache-import.mjs && node --check test/zip-date.mjs && node --check test/native-text-whitespace.mjs && node --check test/native-underline.mjs && node --check src/native-text-style.js && node --check src/font-weights.js && node --check test/font-weight-import.mjs && node --check src/body-text-import.js && node --check test/native-body-rich-text.mjs && node --check test/native-body-rich-text-browser.js && node --check test/native-quote-import-contract.mjs && node --check test/native-quote-import-controls.mjs && node --check test/native-quote.mjs && node --check test/determinism.mjs && node --check test/determinism-fixtures.mjs && node --check test/table-frame-furniture-order.mjs && node --check test/shape-border-widths.mjs && node --check test/gallery-layout-alignment.mjs && node --check src/import-signals.js && node --check test/import-signals.mjs && node --check test/signals-deck.mjs && node --check test/rr-07-preview-polish.mjs && node --check scripts/rr07-native-set.mjs",
|
|
41
|
-
"test": "npm run build && node test/annotations.mjs && node test/region-reading-order.mjs && node test/symbol-fonts.mjs && node test/math-emoji.mjs && node test/chart-types.mjs && node test/chartex.mjs && node test/chart-options.mjs && node test/chart-text-size.mjs && node test/zip-date.mjs && node test/background-fills.mjs && node test/rr-07-preview-polish.mjs && npm run test:furniture && node test/slide-image.mjs && node test/slide-image-treatments.mjs && node test/watermark.mjs && node test/design-fields.mjs && node test/media-dedupe.mjs && node test/document-provenance.mjs && node test/content-topology.mjs && node test/sections.mjs && node test/layout-intent.mjs && node test/master-bullet-font.mjs && node test/default-font-scheme.mjs && node test/script-fonts.mjs && node test/rtl-layout.mjs && node test/theme-script-slots.mjs && node test/export-chosen-fonts.mjs && node test/typeface-inventory.mjs && node test/color-ref-export.mjs && node test/theme-colors.mjs && node test/tag-colour.mjs && node test/table-theme-colors.mjs && node test/plain-whitespace.mjs && node test/native-text-whitespace.mjs && node test/native-body-rich-text.mjs && node test/native-underline.mjs && node test/font-weight-import.mjs && node test/design-alignment.mjs && node test/accepted-text.mjs && node test/heading-provenance.mjs && node test/native-quote-import-controls.mjs && node test/chart-colors.mjs && node test/single-series-colour.mjs && node test/content-cards.mjs && node test/chart-workbook.mjs && node test/single-column-chart.mjs && node --test test/chart-cache-import.mjs && node test/dependency-boundary.mjs && npm run build:browser-check && npm run test:styled-table && node test/content-layout.mjs && node test/layout-parity.mjs && node test/gallery-layout-alignment.mjs && node test/cover-centering.mjs && node test/table-frame-furniture-order.mjs && node test/media-placeholder.mjs && node test/shape-border-widths.mjs && node test/image-placeholder.mjs && node test/svg-image-degrade.mjs && node test/svg-image.mjs && node test/background-colorref.mjs && node test/import-fabrications.mjs && node test/hard-line-breaks.mjs && node test/import-details.mjs && node test/list-shape-names.mjs && node test/numbered-lists.mjs && node test/shared-quote.mjs && node test/quote-provenance.mjs && node test/import-signals.mjs && npm run test:timeline && npm run test:determinism && node test/template-variables.mjs",
|
|
40
|
+
"typecheck": "node --check src/index.js && node --check src/annotation-export.js && node --check src/annotation-provenance.js && node --check test/annotations.mjs && node --check test/region-reading-order.mjs && node --check test/symbol-fonts.mjs && node --check test/math-emoji.mjs && node --check src/svg-image.js && node --check test/svg-image.mjs && node --check test/native-svg-decks.mjs && node --check src/chart-types.js && node --check src/chartex.js && node --check src/chart-options.js && node --check test/chart-options.mjs && node --check test/chartex.mjs && node --check test/chart-text-size.mjs && node --check test/chart-types.mjs && node --check test/design-alignment.mjs && node --check src/color-ref.js && node --check src/theme-colors.js && node --check test/theme-colors.mjs && node --check test/tag-colour.mjs && node --check test/table-theme-colors.mjs && node --check scripts/build.mjs && node --check scripts/validate-package.mjs && node --check test/smoke.mjs && node --check src/image-geometry.js && node --check src/slide-image-provenance.js && node --check test/slide-image.mjs && node --check test/slide-image-treatments.mjs && node --check src/watermark-provenance.js && node --check src/logo-provenance.js && node --check test/design-fields.mjs && node --check src/media-dedupe.js && node --check test/media-dedupe.mjs && node --check test/watermark.mjs && node --check test/image-fit.mjs && node --check test/image-orientation.mjs && node --check test/table-layout.mjs && node --check test/table-import.mjs && node --check test/object-ids.mjs && node --check test/export-corpus.mjs && node --check test/image-media-type.mjs && node --check src/image-fallback-node.js && node --check src/image-fallback-browser.js && node --check test/webp-fallback.mjs && node --check scripts/build-browser-check.mjs && node --check test/webp-fallback-browser.js && node --check test/image-fallback-boundary.mjs && node --check src/background.js && node --check test/background.mjs && node --check src/image-import.js && node --check test/image-import.mjs && node --check test/native-background.mjs && node --check src/background-import.js && node --check test/background-inheritance.mjs && node --check test/rich-table.mjs && node --check src/table-import.js && node --check test/rich-table-import.mjs && node --check test/rich-table-import-browser.js && node --check test/table-row-sizing.mjs && node --check test/table-styles.mjs && node --check test/table-styles-browser.js && node --check test/styled-table.mjs && node --check src/table-cell-import.js && node --check test/styled-table-import.mjs && node --check test/styled-table-import-browser.js && node --check src/table-border-import.js && node --check test/table-border-styles.mjs && node --check src/card-provenance.js && node --check test/content-cards.mjs && node --check src/chart-workbook.js && node --check test/chart-colors.mjs && node --check test/single-series-colour.mjs && node --check test/chart-workbook.mjs && node --check test/single-column-chart.mjs && node --check test/native-chart-colors.mjs && node --check src/heading-provenance.js && node --check test/accepted-text.mjs && node --check test/heading-provenance.mjs && node --check src/text-provenance.js && node --check test/plain-whitespace.mjs && node --check src/timeline-provenance.js && node --check src/quote-provenance.js && node --check test/quote-provenance.mjs && node --check test/shared-timeline.mjs && node --check test/shared-furniture.mjs && node --check src/furniture-provenance.js && node --check src/document-provenance.js && node --check src/content-topology.js && node --check src/sections.js && node --check test/document-provenance.mjs && node --check test/content-topology.mjs && node --check test/sections.mjs && node --check test/provenance-interop.mjs && node --check test/furniture-provenance.mjs && node --check src/furniture-fields.js && node --check test/furniture-fields.mjs && node --check src/native-furniture.js && node --check test/native-furniture.mjs && node --check test/furniture-wrapped-date.mjs && node --check test/native-picture.mjs && node --check test/compare-native-picture.mjs && node --check test/compare-native-picture-edit.mjs && node --check test/compare-native-picture-edit-controls.mjs && node --check test/native-font-embed-audit.mjs && node --check test/native-font-embed-controls.mjs && node --check test/native-font-embed-fixture-source.mjs && node --check test/native-font-edit-fixture.mjs && node --check test/native-mixed-edit-audit.mjs && node --check test/native-mixed-edit-controls.mjs && node --check test/master-bullet-font.mjs && node --check test/native-font-inventory-audit.mjs && node --check test/native-font-inventory-controls.mjs && node --check test/default-font-scheme.mjs && node --check test/export-chosen-fonts.mjs && node --check test/background-fills.mjs && node --check src/typeface-inventory.js && node --check src/package-fonts.js && node --check test/typeface-inventory.mjs && node --check src/script-fonts.js && node --check test/script-fonts.mjs && node --check test/rtl-layout.mjs && node --check test/theme-script-slots.mjs && node --check src/master-themes.js && node --check test/presentation-order.mjs && node --check test/notes-master-theme.mjs && node --check test/powershell-scan.mjs && node --check test/powershell-scan-probes.mjs && node --check test/socials-furniture.mjs && node --check src/media-provenance.js && node --check test/layout-parity.mjs && node --check test/cover-centering.mjs && node --check test/media-placeholder.mjs && node --check test/image-placeholder.mjs && node --check test/svg-image-degrade.mjs && node --check test/background-colorref.mjs && node --check test/import-fabrications.mjs && node --check src/run-colors.js && node --check test/hard-line-breaks.mjs && node --check test/import-details.mjs && node --check test/list-shape-names.mjs && node --check src/numbered-list.js && node --check test/numbered-lists.mjs && node --check test/layout-intent.mjs && node --check test/chart-cache-import.mjs && node --check test/zip-date.mjs && node --check test/native-text-whitespace.mjs && node --check test/native-underline.mjs && node --check src/native-text-style.js && node --check src/font-weights.js && node --check test/font-weight-import.mjs && node --check src/body-text-import.js && node --check test/native-body-rich-text.mjs && node --check test/native-body-rich-text-browser.js && node --check test/native-quote-import-contract.mjs && node --check test/native-quote-import-controls.mjs && node --check test/native-quote.mjs && node --check test/determinism.mjs && node --check test/determinism-fixtures.mjs && node --check test/table-frame-furniture-order.mjs && node --check test/shape-border-widths.mjs && node --check test/gallery-layout-alignment.mjs && node --check src/import-signals.js && node --check test/import-signals.mjs && node --check test/signals-deck.mjs && node --check test/rr-07-preview-polish.mjs && node --check scripts/rr07-native-set.mjs",
|
|
41
|
+
"test": "npm run build && node test/annotations.mjs && node test/region-reading-order.mjs && node test/symbol-fonts.mjs && node test/math-emoji.mjs && node test/chart-types.mjs && node test/chartex.mjs && node test/chart-options.mjs && node test/chart-text-size.mjs && node test/zip-date.mjs && node test/background-fills.mjs && node test/rr-07-preview-polish.mjs && npm run test:furniture && node test/slide-image.mjs && node test/slide-image-treatments.mjs && node test/watermark.mjs && node test/design-fields.mjs && node test/media-dedupe.mjs && node test/document-provenance.mjs && node test/content-topology.mjs && node test/sections.mjs && node test/layout-intent.mjs && node test/master-bullet-font.mjs && node test/default-font-scheme.mjs && node test/script-fonts.mjs && node test/rtl-layout.mjs && node test/theme-script-slots.mjs && node test/presentation-order.mjs && node test/notes-master-theme.mjs && node test/export-chosen-fonts.mjs && node test/typeface-inventory.mjs && node test/color-ref-export.mjs && node test/theme-colors.mjs && node test/tag-colour.mjs && node test/table-theme-colors.mjs && node test/plain-whitespace.mjs && node test/native-text-whitespace.mjs && node test/native-body-rich-text.mjs && node test/native-underline.mjs && node test/font-weight-import.mjs && node test/design-alignment.mjs && node test/accepted-text.mjs && node test/heading-provenance.mjs && node test/native-quote-import-controls.mjs && node test/chart-colors.mjs && node test/single-series-colour.mjs && node test/content-cards.mjs && node test/chart-workbook.mjs && node test/single-column-chart.mjs && node --test test/chart-cache-import.mjs && node test/dependency-boundary.mjs && npm run build:browser-check && npm run test:styled-table && node test/content-layout.mjs && node test/layout-parity.mjs && node test/gallery-layout-alignment.mjs && node test/cover-centering.mjs && node test/table-frame-furniture-order.mjs && node test/media-placeholder.mjs && node test/shape-border-widths.mjs && node test/image-placeholder.mjs && node test/svg-image-degrade.mjs && node test/svg-image.mjs && node test/background-colorref.mjs && node test/import-fabrications.mjs && node test/hard-line-breaks.mjs && node test/import-details.mjs && node test/list-shape-names.mjs && node test/numbered-lists.mjs && node test/shared-quote.mjs && node test/quote-provenance.mjs && node test/import-signals.mjs && npm run test:timeline && npm run test:determinism && node test/template-variables.mjs",
|
|
42
42
|
"validate": "node scripts/validate-package.mjs",
|
|
43
43
|
"test:packed": "node test/packed-install.mjs && node test/provenance-interop.mjs",
|
|
44
44
|
"test:compare-published": "node test/compare-published.mjs",
|