@openpresentation/cli 0.8.0 → 0.8.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 +214 -50
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -8149,13 +8149,13 @@ import path2 from "path";
|
|
|
8149
8149
|
// ../javascript/dist/index.js
|
|
8150
8150
|
init_define_OPF_SKILLS();
|
|
8151
8151
|
|
|
8152
|
-
// ../javascript/dist/chunk-
|
|
8152
|
+
// ../javascript/dist/chunk-EWJNRHXA.js
|
|
8153
8153
|
init_define_OPF_SKILLS();
|
|
8154
8154
|
|
|
8155
|
-
// ../javascript/dist/chunk-
|
|
8155
|
+
// ../javascript/dist/chunk-ZIL7MGZU.js
|
|
8156
8156
|
init_define_OPF_SKILLS();
|
|
8157
8157
|
|
|
8158
|
-
// ../javascript/dist/chunk-
|
|
8158
|
+
// ../javascript/dist/chunk-PQJRDNA6.js
|
|
8159
8159
|
init_define_OPF_SKILLS();
|
|
8160
8160
|
var record = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
8161
8161
|
function tableGrid(value, path3 = "table") {
|
|
@@ -8263,8 +8263,105 @@ var headings = /* @__PURE__ */ new Set(["title", "subtitle", "tag"]);
|
|
|
8263
8263
|
var rows = ["top", "middle", "bottom"];
|
|
8264
8264
|
var columns = ["left", "center", "right"];
|
|
8265
8265
|
var record2 = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
8266
|
-
var kind = (field) => field === "items"
|
|
8266
|
+
var kind = (field) => field === "items" ? "list" : field === "bullets" ? "text" : field;
|
|
8267
8267
|
var round = (value) => Math.round(value * 1e6) / 1e6 || value;
|
|
8268
|
+
function layoutFurniture(input, options = {}) {
|
|
8269
|
+
const slide = record2(input), width = options.width ?? 1280, height = options.height ?? 720, scale = Math.min(width, height) / 720;
|
|
8270
|
+
const settings = { ...record2(record2(options.layout).composition), ...record2(slide.composition) };
|
|
8271
|
+
assertComposition(settings);
|
|
8272
|
+
const minimum = (settings.minFontSize ?? 16) * scale, size = Math.max(13 * scale, minimum), padding = (options.textRasterPadding ?? 2) * scale;
|
|
8273
|
+
if (![width, height, scale, minimum, padding].every(Number.isFinite) || width <= 0 || height <= 0 || minimum <= 0 || padding < 0) throw new RangeError("Furniture requires finite positive dimensions and nonnegative raster padding.");
|
|
8274
|
+
const number = options.slideNumber ?? (options.slideIndex ?? 0) + 1;
|
|
8275
|
+
if (!Number.isSafeInteger(number) || number < 1) throw new RangeError("Displayed slide number must be a positive safe integer.");
|
|
8276
|
+
const outlines = options.textMeasurement?.outlineBounds !== void 0, parts2 = [], diagnostics = [];
|
|
8277
|
+
const sourceRoot = `slides.${options.slideIndex ?? 0}`, organizations = Array.isArray(options.presentation?.organization) ? options.presentation.organization : [options.presentation?.organization];
|
|
8278
|
+
const primaryIndex = organizations.findIndex((item) => record2(item).role === "primary"), organizationIndex = primaryIndex >= 0 ? primaryIndex : organizations.findIndex(Boolean);
|
|
8279
|
+
const organization = record2(organizations[organizationIndex]), organizationPath = Array.isArray(options.presentation?.organization) ? `organization.${organizationIndex}.name` : "organization.name";
|
|
8280
|
+
const fontFamily = options.fonts?.body ?? "sans-serif";
|
|
8281
|
+
let headerBottom = 0, footerTop = height, configured = false;
|
|
8282
|
+
const error = (path3, message, code = "text-overflow") => diagnostics.push({ code, path: path3, message });
|
|
8283
|
+
for (const kind2 of ["header", "footer"]) {
|
|
8284
|
+
const local = record2(slide.design)[kind2] !== void 0, value = local ? record2(slide.design)[kind2] : options.presentation?.design?.[kind2];
|
|
8285
|
+
if (value === void 0 || value === false) continue;
|
|
8286
|
+
const root = local ? `${sourceRoot}.design.${kind2}` : `design.${kind2}`;
|
|
8287
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) throw new TypeError("Header/footer content must be an object or false.");
|
|
8288
|
+
configured = true;
|
|
8289
|
+
const zones = [];
|
|
8290
|
+
for (const [index2, zone] of ["left", "center", "right"].entries()) {
|
|
8291
|
+
const content = record2(record2(value)[zone]), path3 = `${root}.${zone}`, x = width * (0.07 + index2 * 0.3), zoneWidth = width * 0.26, zoneParts = [];
|
|
8292
|
+
let y = 0;
|
|
8293
|
+
const add = (field, text, generated = false, sourcePath) => {
|
|
8294
|
+
if (text === void 0) return;
|
|
8295
|
+
if (typeof text !== "string") throw new TypeError(`Furniture field ${path3}.${field} requires string content.`);
|
|
8296
|
+
const partPath = `${path3}.${field}`, style = resolveTextStyle({ fontFamily, fontWeight: 400, italic: false, path: partPath }, options.textMeasurement);
|
|
8297
|
+
const fit = fitText(text, { width: Math.max(Number.MIN_VALUE, zoneWidth - (outlines ? 2 * padding : 0)), height: Number.MAX_VALUE }, size, size, textWidthMeasurer(style, options.textMeasurement));
|
|
8298
|
+
const ink = fit.sourceLines.map((line, index22) => {
|
|
8299
|
+
let outline = null;
|
|
8300
|
+
if (outlines) {
|
|
8301
|
+
for (const segment of line.segments) if (segment.kind === "text") {
|
|
8302
|
+
const bounds = measureTextOutline(text.slice(segment.start, segment.end), size, style, options.textMeasurement);
|
|
8303
|
+
if (bounds) {
|
|
8304
|
+
const next = { ...bounds, x: bounds.x + segment.x };
|
|
8305
|
+
if (!outline) outline = next;
|
|
8306
|
+
else {
|
|
8307
|
+
const right = Math.max(outline.x + outline.width, next.x + next.width), bottom = Math.max(outline.y + outline.height, next.y + next.height);
|
|
8308
|
+
outline.x = Math.min(outline.x, next.x);
|
|
8309
|
+
outline.y = Math.min(outline.y, next.y);
|
|
8310
|
+
outline.width = right - outline.x;
|
|
8311
|
+
outline.height = bottom - outline.y;
|
|
8312
|
+
}
|
|
8313
|
+
}
|
|
8314
|
+
}
|
|
8315
|
+
}
|
|
8316
|
+
return { width: line.width, y: index22 * fit.lineHeight, baseline: size + index22 * fit.lineHeight, height: fit.lineHeight, outline };
|
|
8317
|
+
});
|
|
8318
|
+
const natural = outlines ? placeTextLines(ink, { x, y, width: zoneWidth, height: Number.MAX_VALUE }, zone, padding) : void 0;
|
|
8319
|
+
const partHeight = natural?.height ?? fit.sourceLines.length * fit.lineHeight;
|
|
8320
|
+
if (!Number.isFinite(partHeight)) throw new RangeError("Furniture exceeds finite layout coordinates.");
|
|
8321
|
+
const box = { x, y, width: zoneWidth, height: Math.max(scale, partHeight) }, placement = outlines ? placeTextLines(ink, box, zone, padding) : void 0;
|
|
8322
|
+
const accepted = { ...fit, ...placement ? { placement } : {}, overflow: fit.overflow || !!placement?.overflow };
|
|
8323
|
+
zoneParts.push({ type: "text", kind: kind2, zone, field, path: partPath, sourcePath: sourcePath ?? (!generated ? partPath : void 0), generated, text, style, requestedFontSize: 13 * scale, minFontSize: minimum, box, alignment: zone, fit: accepted });
|
|
8324
|
+
if (accepted.overflow) error(partPath, "Repeated text exceeds its zone at the selected readability floor; change the furniture or slide design.");
|
|
8325
|
+
y += box.height;
|
|
8326
|
+
};
|
|
8327
|
+
if (content.image !== void 0) {
|
|
8328
|
+
const box = { x, y, width: zoneWidth, height: Math.max(32 * scale, Math.min(height * 0.05, 72 * scale)) };
|
|
8329
|
+
zoneParts.push({ type: "image", kind: kind2, zone, field: "image", path: `${path3}.image`, sourcePath: `${path3}.image`, generated: false, image: content.image, box, alignment: zone });
|
|
8330
|
+
y += box.height;
|
|
8331
|
+
}
|
|
8332
|
+
add("text", content.text);
|
|
8333
|
+
if (content.organization === true) {
|
|
8334
|
+
if (typeof organization.name === "string") add("organization", organization.name, true, organizationPath);
|
|
8335
|
+
else error(`${path3}.organization`, "Generated organization name needs a named organization in the presentation.", "unresolved-content");
|
|
8336
|
+
}
|
|
8337
|
+
if (content.section === true) {
|
|
8338
|
+
if (typeof slide.section === "string") add("section", slide.section, true, `${sourceRoot}.section`);
|
|
8339
|
+
else error(`${path3}.section`, "Generated section needs a literal slide section.", "unresolved-content");
|
|
8340
|
+
}
|
|
8341
|
+
if (content.slideNumber === true) add("slideNumber", String(number), true);
|
|
8342
|
+
if (content.date === true) error(`${path3}.date`, "Use a literal date string for deterministic header/footer content.", "unresolved-content");
|
|
8343
|
+
else if (typeof content.date === "string") add("date", content.date);
|
|
8344
|
+
zones.push(zoneParts);
|
|
8345
|
+
}
|
|
8346
|
+
const tallest = Math.max(0, ...zones.map((zone) => zone.reduce((sum, part) => sum + part.box.height, 0)));
|
|
8347
|
+
if (!tallest) continue;
|
|
8348
|
+
const top = kind2 === "header" ? height * 0.025 : Math.max(height * 0.025, height - height * 0.04 - tallest);
|
|
8349
|
+
if (kind2 === "header") headerBottom = top + tallest;
|
|
8350
|
+
else footerTop = top;
|
|
8351
|
+
for (const zone of zones) for (const part of zone) {
|
|
8352
|
+
part.box.y += top;
|
|
8353
|
+
if (part.type === "text" && part.fit.placement) for (const line of part.fit.placement.lines) {
|
|
8354
|
+
line.y += top;
|
|
8355
|
+
line.baseline += top;
|
|
8356
|
+
if (line.outline) line.outline.y += top;
|
|
8357
|
+
}
|
|
8358
|
+
if (part.box.y + part.box.height > height - height * 0.04 + 0.01) error(part.path, "Repeated header/footer content extends beyond the usable slide height. Change its content or design before pagination.");
|
|
8359
|
+
parts2.push(part);
|
|
8360
|
+
}
|
|
8361
|
+
}
|
|
8362
|
+
if (headerBottom > footerTop + 0.01) error(parts2.find((part) => part.kind === "footer")?.path ?? sourceRoot, "Header and footer content overlap; repeated content cannot be repaired by splitting body content.");
|
|
8363
|
+
return { algorithm: "furniture-flow-v2", configured, textMeasurement: options.textMeasurement ? "provided" : "estimated", textOutlines: outlines ? "provided" : "unavailable", parts: parts2, headerBottom, footerTop, diagnostics, overflow: diagnostics.length > 0 };
|
|
8364
|
+
}
|
|
8268
8365
|
var textSegments = new Intl.Segmenter("und", { granularity: "grapheme" });
|
|
8269
8366
|
function measureText(text, fontSize) {
|
|
8270
8367
|
let units = 0;
|
|
@@ -9192,7 +9289,11 @@ function composeSlide(input, options = {}) {
|
|
|
9192
9289
|
const fitContent = (field, value, text, box, size, minimum, path22) => field === "text" ? fitPlacedText(field, value, text, box, size, minimum, path22) : field === "items" || field === "bullets" ? fitList(value, box, size, minimum, { style: styleFor(field, path22), textMeasurement: options.textMeasurement }) : fitText(text, box, size, minimum, widthFor(field, path22));
|
|
9193
9290
|
const path3 = `slides.${options.slideIndex ?? 0}`;
|
|
9194
9291
|
const items = [], diagnostics = [];
|
|
9195
|
-
|
|
9292
|
+
const measuredFurniture = layoutFurniture(slide, options);
|
|
9293
|
+
const furniture = measuredFurniture.configured || measuredFurniture.diagnostics.length ? measuredFurniture : void 0;
|
|
9294
|
+
if (furniture) diagnostics.push(...furniture.diagnostics);
|
|
9295
|
+
const bodyBottom = Math.min(height - padding, furniture && furniture.footerTop < height ? furniture.footerTop - gap * 0.5 : height - padding);
|
|
9296
|
+
let y = Math.max(padding, furniture?.headerBottom ? furniture.headerBottom + gap * 0.5 : padding);
|
|
9196
9297
|
for (const field of ["tag", "title", "subtitle"]) {
|
|
9197
9298
|
if (!slide[field]) continue;
|
|
9198
9299
|
const requested = (field === "title" ? 54 : field === "tag" ? 16 : 25) * scale;
|
|
@@ -9200,11 +9301,12 @@ function composeSlide(input, options = {}) {
|
|
|
9200
9301
|
const box = { x: padding, y, width: width - padding * 2, height: maxHeight };
|
|
9201
9302
|
const text = fitPlacedText(field, slide[field], String(slide[field]), box, requested, minSize, `${path3}.${field}`);
|
|
9202
9303
|
box.height = Math.min(maxHeight, Math.max(text.lines.length * text.lineHeight, text.placement?.height ?? 0));
|
|
9304
|
+
if (furniture && box.y + box.height > bodyBottom + 0.01) diagnostics.push({ code: "text-overflow", path: `${path3}.${field}`, message: "Repeated furniture leaves too little room for this heading. Change the header/footer or slide design." });
|
|
9203
9305
|
items.push({ path: `${path3}.${field}`, field, type: "text", value: slide[field], payload: { text: slide[field] }, box, text, textStyle: styleFor(field, `${path3}.${field}`), composition });
|
|
9204
9306
|
y += box.height + gap * 0.5;
|
|
9205
9307
|
}
|
|
9206
9308
|
if (items.length) y += gap * 0.5;
|
|
9207
|
-
const contentBox = { x: padding, y, width: width - padding * 2, height: Math.max(scale,
|
|
9309
|
+
const contentBox = { x: padding, y, width: width - padding * 2, height: Math.max(scale, bodyBottom - y) };
|
|
9208
9310
|
const collect = (host, basePath, depth = 0, ancestors = []) => {
|
|
9209
9311
|
if (Array.isArray(host.blocks)) {
|
|
9210
9312
|
if (depth >= MAX_COMPOSITION_DEPTH || ancestors.includes(host)) throw new RangeError(`Content groups must be acyclic and nest at most ${MAX_COMPOSITION_DEPTH} levels.`);
|
|
@@ -9399,6 +9501,7 @@ function composeSlide(input, options = {}) {
|
|
|
9399
9501
|
for (const group of groups) for (const box of [group.box, group.contentBox]) for (const key of ["x", "y", "width", "height"]) box[key] = round(box[key]);
|
|
9400
9502
|
const strictPaths = new Set(items.filter((item) => item.composition.overflow === "error").map((item) => item.path));
|
|
9401
9503
|
const failures = diagnostics.filter((diagnostic) => {
|
|
9504
|
+
if (composition.overflow === "error") return true;
|
|
9402
9505
|
let path22 = diagnostic.path;
|
|
9403
9506
|
while (path22) {
|
|
9404
9507
|
if (strictPaths.has(path22)) return true;
|
|
@@ -9409,7 +9512,7 @@ function composeSlide(input, options = {}) {
|
|
|
9409
9512
|
return false;
|
|
9410
9513
|
});
|
|
9411
9514
|
const explanation = decisions ? {
|
|
9412
|
-
algorithm: "grid-score-
|
|
9515
|
+
algorithm: "grid-score-v9",
|
|
9413
9516
|
textMeasurement: options.textMeasurement ? "provided" : "estimated",
|
|
9414
9517
|
textOutlines: options.textMeasurement?.outlineBounds ? "provided" : "unavailable",
|
|
9415
9518
|
textRasterPadding: rasterPadding,
|
|
@@ -9417,7 +9520,7 @@ function composeSlide(input, options = {}) {
|
|
|
9417
9520
|
unmeasuredPayloads: items.filter((item) => !headings.has(item.field) && !item.quoteLayout && !item.codeLayout && !item.metricLayout && !item.timelineLayout && !["text", "items", "bullets", "table"].includes(item.field)).map((item) => item.path)
|
|
9418
9521
|
} : void 0;
|
|
9419
9522
|
if (failures.length) throw new OPFCompositionError(failures, explanation);
|
|
9420
|
-
return { width, height, contentBox, items, groups, flows, diagnostics, composition, ...explanation ? { explanation } : {} };
|
|
9523
|
+
return { width, height, contentBox, items, groups, flows, diagnostics, composition, ...furniture ? { furniture } : {}, ...explanation ? { explanation } : {} };
|
|
9421
9524
|
}
|
|
9422
9525
|
function resolveCanvasDimensions(input) {
|
|
9423
9526
|
const presets = {
|
|
@@ -9437,7 +9540,7 @@ function resolveCanvasDimensions(input) {
|
|
|
9437
9540
|
return { width, height };
|
|
9438
9541
|
}
|
|
9439
9542
|
|
|
9440
|
-
// ../javascript/dist/chunk-
|
|
9543
|
+
// ../javascript/dist/chunk-D3GQIREP.js
|
|
9441
9544
|
init_define_OPF_SKILLS();
|
|
9442
9545
|
var presentation = {
|
|
9443
9546
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
@@ -14313,9 +14416,15 @@ var layout = {
|
|
|
14313
14416
|
"List",
|
|
14314
14417
|
"Image",
|
|
14315
14418
|
"Number",
|
|
14316
|
-
"
|
|
14419
|
+
"Metric",
|
|
14420
|
+
"Chart",
|
|
14421
|
+
"Table",
|
|
14422
|
+
"Code",
|
|
14423
|
+
"Video",
|
|
14424
|
+
"Quote",
|
|
14425
|
+
"Timeline"
|
|
14317
14426
|
],
|
|
14318
|
-
"description": "Primary kind of content the layout holds. Drives pickers and AI placement decisions."
|
|
14427
|
+
"description": "Primary kind of content the layout holds. Drives pickers and AI placement decisions. Metric is the canonical numeric/KPI category; Number remains an accepted legacy label."
|
|
14319
14428
|
},
|
|
14320
14429
|
"contentMultiple": {
|
|
14321
14430
|
"type": "string",
|
|
@@ -14523,6 +14632,9 @@ var layout = {
|
|
|
14523
14632
|
"subtitle",
|
|
14524
14633
|
"tag",
|
|
14525
14634
|
"text",
|
|
14635
|
+
"metric",
|
|
14636
|
+
"quote",
|
|
14637
|
+
"timeline",
|
|
14526
14638
|
"list",
|
|
14527
14639
|
"chart",
|
|
14528
14640
|
"picture",
|
|
@@ -14531,7 +14643,7 @@ var layout = {
|
|
|
14531
14643
|
"diagram",
|
|
14532
14644
|
"code"
|
|
14533
14645
|
],
|
|
14534
|
-
"description": "OPF placeholder kind. 'text' and 'list' are flexible textual content regions. The named kinds describe a specific content role used by pickers, AI generation, and engine defaulting."
|
|
14646
|
+
"description": "OPF placeholder kind. 'text' and 'list' are flexible textual content regions. 'metric' is a numeric/KPI content region filled by a metric payload, including its optional label, description, unit, delta, and trend. The named kinds describe a specific content role used by pickers, AI generation, and engine defaulting. 'picture' and legacy 'diagram' use image payloads; 'media' uses video. Quote and timeline use their corresponding payload fields."
|
|
14535
14647
|
}
|
|
14536
14648
|
}
|
|
14537
14649
|
},
|
|
@@ -15311,7 +15423,7 @@ var narrative = {
|
|
|
15311
15423
|
"quote",
|
|
15312
15424
|
"timeline"
|
|
15313
15425
|
],
|
|
15314
|
-
"description": "Default content kind for the beat's slide.
|
|
15426
|
+
"description": "Default content kind for the beat's slide. Uses ContentPayload.type names to help engines choose a layout. The legacy shape value is retained for compatibility and requests an image representation; it is not a native ContentPayload type."
|
|
15315
15427
|
},
|
|
15316
15428
|
"layoutHint": {
|
|
15317
15429
|
"type": "string",
|
|
@@ -16113,7 +16225,7 @@ var schemaEntries = [
|
|
|
16113
16225
|
{ name: "fontScheme", file: "schemas/font-scheme.schema.json", schema: fontScheme }
|
|
16114
16226
|
];
|
|
16115
16227
|
|
|
16116
|
-
// ../javascript/dist/chunk-
|
|
16228
|
+
// ../javascript/dist/chunk-TU7I3KSB.js
|
|
16117
16229
|
init_define_OPF_SKILLS();
|
|
16118
16230
|
var audiences = [
|
|
16119
16231
|
{
|
|
@@ -17293,7 +17405,7 @@ var layouts = [
|
|
|
17293
17405
|
"type": "title"
|
|
17294
17406
|
},
|
|
17295
17407
|
{
|
|
17296
|
-
"type": "
|
|
17408
|
+
"type": "metric"
|
|
17297
17409
|
}
|
|
17298
17410
|
]
|
|
17299
17411
|
},
|
|
@@ -17306,10 +17418,10 @@ var layouts = [
|
|
|
17306
17418
|
"type": "title"
|
|
17307
17419
|
},
|
|
17308
17420
|
{
|
|
17309
|
-
"type": "
|
|
17421
|
+
"type": "metric"
|
|
17310
17422
|
},
|
|
17311
17423
|
{
|
|
17312
|
-
"type": "
|
|
17424
|
+
"type": "metric"
|
|
17313
17425
|
}
|
|
17314
17426
|
],
|
|
17315
17427
|
"composition": {
|
|
@@ -17325,13 +17437,13 @@ var layouts = [
|
|
|
17325
17437
|
"type": "title"
|
|
17326
17438
|
},
|
|
17327
17439
|
{
|
|
17328
|
-
"type": "
|
|
17440
|
+
"type": "metric"
|
|
17329
17441
|
},
|
|
17330
17442
|
{
|
|
17331
|
-
"type": "
|
|
17443
|
+
"type": "metric"
|
|
17332
17444
|
},
|
|
17333
17445
|
{
|
|
17334
|
-
"type": "
|
|
17446
|
+
"type": "metric"
|
|
17335
17447
|
}
|
|
17336
17448
|
],
|
|
17337
17449
|
"composition": {
|
|
@@ -17347,16 +17459,16 @@ var layouts = [
|
|
|
17347
17459
|
"type": "title"
|
|
17348
17460
|
},
|
|
17349
17461
|
{
|
|
17350
|
-
"type": "
|
|
17462
|
+
"type": "metric"
|
|
17351
17463
|
},
|
|
17352
17464
|
{
|
|
17353
|
-
"type": "
|
|
17465
|
+
"type": "metric"
|
|
17354
17466
|
},
|
|
17355
17467
|
{
|
|
17356
|
-
"type": "
|
|
17468
|
+
"type": "metric"
|
|
17357
17469
|
},
|
|
17358
17470
|
{
|
|
17359
|
-
"type": "
|
|
17471
|
+
"type": "metric"
|
|
17360
17472
|
}
|
|
17361
17473
|
],
|
|
17362
17474
|
"composition": {
|
|
@@ -17373,19 +17485,19 @@ var layouts = [
|
|
|
17373
17485
|
"type": "title"
|
|
17374
17486
|
},
|
|
17375
17487
|
{
|
|
17376
|
-
"type": "
|
|
17488
|
+
"type": "metric"
|
|
17377
17489
|
},
|
|
17378
17490
|
{
|
|
17379
|
-
"type": "
|
|
17491
|
+
"type": "metric"
|
|
17380
17492
|
},
|
|
17381
17493
|
{
|
|
17382
|
-
"type": "
|
|
17494
|
+
"type": "metric"
|
|
17383
17495
|
},
|
|
17384
17496
|
{
|
|
17385
|
-
"type": "
|
|
17497
|
+
"type": "metric"
|
|
17386
17498
|
},
|
|
17387
17499
|
{
|
|
17388
|
-
"type": "
|
|
17500
|
+
"type": "metric"
|
|
17389
17501
|
}
|
|
17390
17502
|
],
|
|
17391
17503
|
"composition": {
|
|
@@ -17402,22 +17514,22 @@ var layouts = [
|
|
|
17402
17514
|
"type": "title"
|
|
17403
17515
|
},
|
|
17404
17516
|
{
|
|
17405
|
-
"type": "
|
|
17517
|
+
"type": "metric"
|
|
17406
17518
|
},
|
|
17407
17519
|
{
|
|
17408
|
-
"type": "
|
|
17520
|
+
"type": "metric"
|
|
17409
17521
|
},
|
|
17410
17522
|
{
|
|
17411
|
-
"type": "
|
|
17523
|
+
"type": "metric"
|
|
17412
17524
|
},
|
|
17413
17525
|
{
|
|
17414
|
-
"type": "
|
|
17526
|
+
"type": "metric"
|
|
17415
17527
|
},
|
|
17416
17528
|
{
|
|
17417
|
-
"type": "
|
|
17529
|
+
"type": "metric"
|
|
17418
17530
|
},
|
|
17419
17531
|
{
|
|
17420
|
-
"type": "
|
|
17532
|
+
"type": "metric"
|
|
17421
17533
|
}
|
|
17422
17534
|
],
|
|
17423
17535
|
"composition": {
|
|
@@ -17425,6 +17537,19 @@ var layouts = [
|
|
|
17425
17537
|
"columns": 3
|
|
17426
17538
|
}
|
|
17427
17539
|
},
|
|
17540
|
+
{
|
|
17541
|
+
"$schema": "https://openpresentation.org/schema/opf-layout/v1",
|
|
17542
|
+
"id": "quote-1x",
|
|
17543
|
+
"name": "Quote 1x",
|
|
17544
|
+
"placeholders": [
|
|
17545
|
+
{
|
|
17546
|
+
"type": "title"
|
|
17547
|
+
},
|
|
17548
|
+
{
|
|
17549
|
+
"type": "quote"
|
|
17550
|
+
}
|
|
17551
|
+
]
|
|
17552
|
+
},
|
|
17428
17553
|
{
|
|
17429
17554
|
"$schema": "https://openpresentation.org/schema/opf-layout/v1",
|
|
17430
17555
|
"id": "table-1x",
|
|
@@ -17498,6 +17623,19 @@ var layouts = [
|
|
|
17498
17623
|
"mode": "row"
|
|
17499
17624
|
}
|
|
17500
17625
|
},
|
|
17626
|
+
{
|
|
17627
|
+
"$schema": "https://openpresentation.org/schema/opf-layout/v1",
|
|
17628
|
+
"id": "timeline-1x",
|
|
17629
|
+
"name": "Timeline 1x",
|
|
17630
|
+
"placeholders": [
|
|
17631
|
+
{
|
|
17632
|
+
"type": "title"
|
|
17633
|
+
},
|
|
17634
|
+
{
|
|
17635
|
+
"type": "timeline"
|
|
17636
|
+
}
|
|
17637
|
+
]
|
|
17638
|
+
},
|
|
17501
17639
|
{
|
|
17502
17640
|
"$schema": "https://openpresentation.org/schema/opf-layout/v1",
|
|
17503
17641
|
"id": "title",
|
|
@@ -31678,6 +31816,11 @@ var catalogIndexes = {
|
|
|
31678
31816
|
"name": "Number 6x",
|
|
31679
31817
|
"file": "number-6x.json"
|
|
31680
31818
|
},
|
|
31819
|
+
{
|
|
31820
|
+
"id": "quote-1x",
|
|
31821
|
+
"name": "Quote 1x",
|
|
31822
|
+
"file": "quote-1x.json"
|
|
31823
|
+
},
|
|
31681
31824
|
{
|
|
31682
31825
|
"id": "table-1x",
|
|
31683
31826
|
"name": "Table 1x",
|
|
@@ -31698,6 +31841,11 @@ var catalogIndexes = {
|
|
|
31698
31841
|
"name": "Text 3x",
|
|
31699
31842
|
"file": "text-3x.json"
|
|
31700
31843
|
},
|
|
31844
|
+
{
|
|
31845
|
+
"id": "timeline-1x",
|
|
31846
|
+
"name": "Timeline 1x",
|
|
31847
|
+
"file": "timeline-1x.json"
|
|
31848
|
+
},
|
|
31701
31849
|
{
|
|
31702
31850
|
"id": "title",
|
|
31703
31851
|
"name": "Title",
|
|
@@ -34347,10 +34495,12 @@ var catalogEntries = [
|
|
|
34347
34495
|
"number-4x.json",
|
|
34348
34496
|
"number-5x.json",
|
|
34349
34497
|
"number-6x.json",
|
|
34498
|
+
"quote-1x.json",
|
|
34350
34499
|
"table-1x.json",
|
|
34351
34500
|
"text-1x.json",
|
|
34352
34501
|
"text-2x.json",
|
|
34353
34502
|
"text-3x.json",
|
|
34503
|
+
"timeline-1x.json",
|
|
34354
34504
|
"title.json",
|
|
34355
34505
|
"title-subtitle.json"
|
|
34356
34506
|
], records: layouts, index: catalogIndexes.layouts },
|
|
@@ -34689,7 +34839,7 @@ var catalogEntries = [
|
|
|
34689
34839
|
], records: fontSchemes, index: catalogIndexes.fontSchemes }
|
|
34690
34840
|
];
|
|
34691
34841
|
|
|
34692
|
-
// ../javascript/dist/chunk-
|
|
34842
|
+
// ../javascript/dist/chunk-ZIL7MGZU.js
|
|
34693
34843
|
var import__ = __toESM(require__(), 1);
|
|
34694
34844
|
var import_ajv_formats = __toESM(require_dist(), 1);
|
|
34695
34845
|
var catalogIds = {
|
|
@@ -34754,10 +34904,12 @@ var catalogIds = {
|
|
|
34754
34904
|
"number-4x",
|
|
34755
34905
|
"number-5x",
|
|
34756
34906
|
"number-6x",
|
|
34907
|
+
"quote-1x",
|
|
34757
34908
|
"table-1x",
|
|
34758
34909
|
"text-1x",
|
|
34759
34910
|
"text-2x",
|
|
34760
34911
|
"text-3x",
|
|
34912
|
+
"timeline-1x",
|
|
34761
34913
|
"title",
|
|
34762
34914
|
"title-subtitle"
|
|
34763
34915
|
],
|
|
@@ -36695,7 +36847,7 @@ function printParseErrorCode(code) {
|
|
|
36695
36847
|
return "<unknown ParseErrorCode>";
|
|
36696
36848
|
}
|
|
36697
36849
|
|
|
36698
|
-
// ../javascript/dist/chunk-
|
|
36850
|
+
// ../javascript/dist/chunk-EWJNRHXA.js
|
|
36699
36851
|
var own = (value, key) => Object.hasOwn(value, key);
|
|
36700
36852
|
var object = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
36701
36853
|
var primitive = (value) => value === null || typeof value === "string" || typeof value === "boolean" || typeof value === "number" && Number.isFinite(value);
|
|
@@ -37430,7 +37582,7 @@ function createDataContent(input, options) {
|
|
|
37430
37582
|
return { chart: { type: options.chartType ?? "column", data: { columns: names, rows: rows2 } } };
|
|
37431
37583
|
}
|
|
37432
37584
|
|
|
37433
|
-
// ../javascript/dist/chunk-
|
|
37585
|
+
// ../javascript/dist/chunk-FHGJX5QK.js
|
|
37434
37586
|
init_define_OPF_SKILLS();
|
|
37435
37587
|
var OPFPaginationError = class extends Error {
|
|
37436
37588
|
constructor(message, diagnostics = []) {
|
|
@@ -37512,14 +37664,23 @@ function paginateSlide(input, options = {}) {
|
|
|
37512
37664
|
};
|
|
37513
37665
|
source = withReadability(source);
|
|
37514
37666
|
let evaluations = 0;
|
|
37515
|
-
const geometry = (slide) => {
|
|
37667
|
+
const geometry = (slide, pageIndex = 0) => {
|
|
37516
37668
|
if (++evaluations > 2e4) throw new OPFPaginationError("Pagination exceeded its layout evaluation limit. Split the input into smaller sections.");
|
|
37517
|
-
return composeSlide(withReadability(slide, true), options);
|
|
37669
|
+
return composeSlide(withReadability(slide, true), { ...options, slideNumber: (options.slideNumber ?? sourceIndex + 1) + pageIndex });
|
|
37518
37670
|
};
|
|
37519
37671
|
const initial = geometry(source);
|
|
37520
|
-
|
|
37521
|
-
|
|
37522
|
-
|
|
37672
|
+
const repeatedMappings = (pageIndex) => {
|
|
37673
|
+
if (!initial.furniture) return [];
|
|
37674
|
+
const paths = new Set(initial.items.filter((item) => headingFields.has(item.field)).map((item) => item.path));
|
|
37675
|
+
for (const part of initial.furniture?.parts ?? []) {
|
|
37676
|
+
paths.add(part.path);
|
|
37677
|
+
if (part.sourcePath) paths.add(part.sourcePath);
|
|
37678
|
+
}
|
|
37679
|
+
return [...paths].map((sourcePath) => ({ sourcePath, outputPath: sourcePath.startsWith(`${sourceBase}.`) ? `slides.${sourceIndex + pageIndex}${sourcePath.slice(sourceBase.length)}` : sourcePath }));
|
|
37680
|
+
};
|
|
37681
|
+
if (!initial.diagnostics.length) return { slides: [source], pages: [{ slideIndex: sourceIndex, mappings: initial.items.map((item) => ({ sourcePath: item.path, outputPath: item.path })), ...initial.furniture ? { repeatedMappings: repeatedMappings(0) } : {} }] };
|
|
37682
|
+
const headerIssues = initial.diagnostics.filter((issue) => headingFields.has(issue.path.slice(sourceBase.length + 1)) || initial.furniture?.diagnostics.includes(issue));
|
|
37683
|
+
if (headerIssues.length) throw new OPFPaginationError("Repeated headings or header/footer content cannot fit or resolve. Change the repeated content or slide design before pagination.", headerIssues);
|
|
37523
37684
|
const leaves = initial.items.filter((item) => !headingFields.has(item.field)).map((item) => leafFor(item.path, item.field, item.value));
|
|
37524
37685
|
const leafPaths = new Set(leaves.map((leaf) => leaf.path));
|
|
37525
37686
|
const slides = [], pages = [];
|
|
@@ -37564,11 +37725,13 @@ function paginateSlide(input, options = {}) {
|
|
|
37564
37725
|
if (pageIndex > 0) delete slide.notes;
|
|
37565
37726
|
return { slide, mappings };
|
|
37566
37727
|
};
|
|
37567
|
-
const diagnosticsFor = (portions) => geometry(project(portions, slides.length).slide).diagnostics;
|
|
37728
|
+
const diagnosticsFor = (portions) => geometry(project(portions, slides.length).slide, slides.length).diagnostics;
|
|
37568
37729
|
const finish = () => {
|
|
37569
37730
|
if (!selected.size) return;
|
|
37570
37731
|
if (slides.length >= maxSlides) throw new OPFPaginationError(`Pagination needs more than ${maxSlides} slides. No partial result was returned.`);
|
|
37571
37732
|
const { slide, mappings } = project(selected, slides.length);
|
|
37733
|
+
const issues = geometry(slide, slides.length).diagnostics;
|
|
37734
|
+
if (issues.length) throw new OPFPaginationError("A continuation page does not fit at its final page number. No partial result was returned.", issues);
|
|
37572
37735
|
if (slides.length && typeof source.id === "string") {
|
|
37573
37736
|
let suffix = slides.length + 1, id = `${source.id}--${suffix}`;
|
|
37574
37737
|
while (reservedIds.has(id)) id = `${source.id}--${++suffix}`;
|
|
@@ -37577,7 +37740,7 @@ function paginateSlide(input, options = {}) {
|
|
|
37577
37740
|
}
|
|
37578
37741
|
assertValidPresentation({ slides: [slide] });
|
|
37579
37742
|
slides.push(slide);
|
|
37580
|
-
pages.push({ slideIndex: sourceIndex + slides.length - 1, mappings });
|
|
37743
|
+
pages.push({ slideIndex: sourceIndex + slides.length - 1, mappings, ...initial.furniture ? { repeatedMappings: repeatedMappings(slides.length - 1) } : {} });
|
|
37581
37744
|
selected = /* @__PURE__ */ new Map();
|
|
37582
37745
|
};
|
|
37583
37746
|
for (const leaf of leaves) {
|
|
@@ -37647,10 +37810,11 @@ function paginatePresentation(input, options = {}) {
|
|
|
37647
37810
|
const fontReference = design.fontScheme ?? theme2.fontScheme ?? "roboto";
|
|
37648
37811
|
const fontScheme2 = typeof fontReference === "string" ? resolve2("fontSchemes", fontReference) : { ...resolve2("fontSchemes", fontReference.id), ...fontReference };
|
|
37649
37812
|
const fonts = resolveFontFamilies(fontScheme2);
|
|
37650
|
-
const result = paginateSlide(slide, { ...resolveCanvasDimensions(design.dimensions ?? theme2.dimensions), layout: layout2, fonts, contentAlignment: design.contentAlignment, titleAlignment: design.titleAlignment, contentBox: design.contentBox, textMeasurement: options.textMeasurement, textRasterPadding: options.textRasterPadding, ...overrides, slideIndex: index2, maxSlides: maxSlides - output.length, minFontSize: options.minFontSize, reservedIds });
|
|
37813
|
+
const result = paginateSlide(slide, { ...resolveCanvasDimensions(design.dimensions ?? theme2.dimensions), layout: layout2, fonts, contentAlignment: design.contentAlignment, titleAlignment: design.titleAlignment, contentBox: design.contentBox, textMeasurement: options.textMeasurement, textRasterPadding: options.textRasterPadding, ...overrides, presentation: presentation2, slideIndex: index2, slideNumber: output.length + 1, maxSlides: maxSlides - output.length, minFontSize: options.minFontSize, reservedIds });
|
|
37651
37814
|
const outputStart = output.length;
|
|
37652
37815
|
result.pages.forEach((page, pageIndex) => {
|
|
37653
|
-
|
|
37816
|
+
const remap = (mapping) => ({ ...mapping, outputPath: mapping.outputPath.replace(/^slides\.\d+/, `slides.${outputStart + pageIndex}`) });
|
|
37817
|
+
pages.push({ sourceSlideIndex: index2, slideIndex: outputStart + pageIndex, mappings: page.mappings.map(remap), ...page.repeatedMappings ? { repeatedMappings: page.repeatedMappings.map(remap) } : {} });
|
|
37654
37818
|
});
|
|
37655
37819
|
output.push(...result.slides);
|
|
37656
37820
|
reservedIds.push(...result.slides.map((slide2) => slide2.id).filter(Boolean));
|
|
@@ -38157,7 +38321,7 @@ async function main(argv) {
|
|
|
38157
38321
|
return;
|
|
38158
38322
|
}
|
|
38159
38323
|
if (argv.length === 1 && argv[0] === "--version") {
|
|
38160
|
-
print({ cli: "0.8.
|
|
38324
|
+
print({ cli: "0.8.1", opf: "0.10.1" });
|
|
38161
38325
|
return;
|
|
38162
38326
|
}
|
|
38163
38327
|
const [command, ...args] = argv;
|
|
@@ -38168,7 +38332,7 @@ async function main(argv) {
|
|
|
38168
38332
|
if (command === "skills") {
|
|
38169
38333
|
const { positional, options } = parse2(args, ["agent", "global", "directory"]);
|
|
38170
38334
|
arity(positional, 1);
|
|
38171
|
-
print(await manageSkills(positional[0], define_OPF_SKILLS_default, "0.8.
|
|
38335
|
+
print(await manageSkills(positional[0], define_OPF_SKILLS_default, "0.8.1", { agent: options.agent, global: !!options.global, directory: options.directory }));
|
|
38172
38336
|
return;
|
|
38173
38337
|
}
|
|
38174
38338
|
if (command === "create") {
|
|
@@ -38203,7 +38367,7 @@ async function main(argv) {
|
|
|
38203
38367
|
print({
|
|
38204
38368
|
...result,
|
|
38205
38369
|
sha256: hash(raw),
|
|
38206
|
-
opfVersion: "0.10.
|
|
38370
|
+
opfVersion: "0.10.1",
|
|
38207
38371
|
...config ? { context: { file: path2.resolve(String(options.config)), sha256: hash(config.raw) } } : {}
|
|
38208
38372
|
});
|
|
38209
38373
|
if (!result.valid || options.strict && result.counts.warning) process.exitCode = 1;
|