@openpresentation/opf 0.24.2 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/dist/browser.js +16 -16
  2. package/dist/{chunk-JHSTEBPC.js → chunk-3OE6PZIC.js} +5 -5
  3. package/dist/{chunk-33OBLTKZ.js → chunk-EQ6S5SEZ.js} +1 -1
  4. package/dist/{chunk-BN3A5TVI.js → chunk-F4HFDP6I.js} +206 -123
  5. package/dist/{chunk-ZFNKRZZQ.js → chunk-F5ABHDUX.js} +6 -6
  6. package/dist/{chunk-UIKXX5EX.js → chunk-FITOGMR3.js} +2 -2
  7. package/dist/{chunk-5PHLSH4E.js → chunk-GS37EBPQ.js} +1 -1
  8. package/dist/{chunk-RP2KIC7W.js → chunk-IC6OPLMU.js} +2 -2
  9. package/dist/{chunk-RE4F2USA.js → chunk-IWFXFWGD.js} +1 -1
  10. package/dist/{chunk-RQACV2FR.js → chunk-IY5SCRTV.js} +1 -1
  11. package/dist/{chunk-RXKXY75X.js → chunk-LU6XM5JQ.js} +1 -1
  12. package/dist/{chunk-H77YYHPL.js → chunk-MJ57RSYO.js} +5 -5
  13. package/dist/{chunk-F6CDJTSE.js → chunk-P7S3ORB4.js} +9 -9
  14. package/dist/{chunk-4I3XPRAO.js → chunk-TKQ2VFV5.js} +1 -1
  15. package/dist/{chunk-6WDLGY25.js → chunk-WW62PPYV.js} +4 -4
  16. package/dist/{chunk-H5GFPQAS.js → chunk-X7RANZWP.js} +2 -2
  17. package/dist/{chunk-N3ZPLGK5.js → chunk-XRMV2GMB.js} +365 -266
  18. package/dist/{chunk-DRCN5PFH.js → chunk-YJNFNRZS.js} +6 -6
  19. package/dist/{composition-qX-igJe5.d.ts → composition-Daqvi-GV.d.ts} +47 -28
  20. package/dist/composition.d.ts +1 -1
  21. package/dist/composition.js +1 -1
  22. package/dist/{conversion-O0XSW0ZV.d.ts → conversion-BOQWy6ex.d.ts} +5 -5
  23. package/dist/conversion-I67NMZEW.js +19 -0
  24. package/dist/convert.d.ts +2 -2
  25. package/dist/convert.js +7 -7
  26. package/dist/data.d.ts +1 -1
  27. package/dist/data.js +2 -2
  28. package/dist/{deck-report-CJ6gd_6-.d.ts → deck-report-DHaboWbM.d.ts} +2 -2
  29. package/dist/deck.d.ts +5 -5
  30. package/dist/deck.js +10 -10
  31. package/dist/diff.js +5 -5
  32. package/dist/docs.js +20 -14
  33. package/dist/examples.d.ts +1 -1
  34. package/dist/examples.js +9555 -15758
  35. package/dist/format.js +2 -2
  36. package/dist/index.d.ts +11 -11
  37. package/dist/index.js +20 -20
  38. package/dist/markdown.d.ts +3 -3
  39. package/dist/markdown.js +7 -7
  40. package/dist/node-engine.d.ts +7 -7
  41. package/dist/node-engine.js +20 -20
  42. package/dist/{pagination-LiWxhbsz.d.ts → pagination-R8YFwVj7.d.ts} +1 -1
  43. package/dist/pagination.d.ts +2 -2
  44. package/dist/pagination.js +4 -4
  45. package/dist/patch.js +4 -4
  46. package/dist/{presentation-Dn-fm0iY.d.ts → presentation-Bwo8Ko6D.d.ts} +1 -1
  47. package/dist/repo-readme.js +1 -1
  48. package/dist/schemas.d.ts +8 -0
  49. package/dist/schemas.js +1 -1
  50. package/dist/spec/README.md +1 -1
  51. package/dist/spec/schemas/layout.schema.json +175 -88
  52. package/dist/spec/schemas/opf.schema.json +4 -4
  53. package/dist/types.d.ts +72 -24
  54. package/dist/{validation-types-CzPKoKWo.d.ts → validation-types-JW8e06ee.d.ts} +1 -1
  55. package/dist/{validator-BuAV_HUo.d.ts → validator-Dym2zYVK.d.ts} +3 -3
  56. package/dist/validator.d.ts +4 -4
  57. package/dist/validator.js +3 -3
  58. package/dist/yaml.d.ts +3 -3
  59. package/dist/yaml.js +7 -7
  60. package/package.json +6 -6
  61. package/dist/conversion-MTGISXNM.js +0 -19
@@ -1878,10 +1878,10 @@ function tableCellDisplayValue(cell, columnFormat2) {
1878
1878
  // src/chart-axis.ts
1879
1879
  var CHART_TEXT_PX = 20;
1880
1880
  function chartTextSize(geometry) {
1881
- const { width, height, scale } = geometry;
1881
+ const { width, height, scale: scale2 } = geometry;
1882
1882
  const minimum = geometry.minFontSize ?? 16;
1883
- if (![width, height, scale].every(Number.isFinite) || width <= 0 || height <= 0 || scale <= 0) return Math.max(CHART_TEXT_PX, minimum);
1884
- return Math.max(Math.floor(Math.min(CHART_TEXT_PX, height / scale / 18, width / scale / 30)), minimum);
1883
+ if (![width, height, scale2].every(Number.isFinite) || width <= 0 || height <= 0 || scale2 <= 0) return Math.max(CHART_TEXT_PX, minimum);
1884
+ return Math.max(Math.floor(Math.min(CHART_TEXT_PX, height / scale2 / 18, width / scale2 / 30)), minimum);
1885
1885
  }
1886
1886
  function clean(value) {
1887
1887
  const rounded = Number(value.toPrecision(12));
@@ -2001,8 +2001,8 @@ function chartValueAxis(chart, resolved, geometry) {
2001
2001
  const id = typeof type === "string" ? type.trim().toLowerCase() : "";
2002
2002
  const spec = Object.hasOwn(CATEGORY_CHARTS, id) ? CATEGORY_CHARTS[id] : void 0;
2003
2003
  if (!spec || !resolved.ok || resolved.combo) return void 0;
2004
- const { scale, width, height } = geometry;
2005
- if (![width, height, scale].every(Number.isFinite) || width <= 0 || height <= 0 || scale <= 0) return void 0;
2004
+ const { scale: scale2, width, height } = geometry;
2005
+ if (![width, height, scale2].every(Number.isFinite) || width <= 0 || height <= 0 || scale2 <= 0) return void 0;
2006
2006
  const series = resolved.columns.slice(1).map((_, offset) => ({ values: resolved.rows.map((row) => chartNumber(row[offset + 1])) }));
2007
2007
  if (!series.length || !resolved.rows.length) return void 0;
2008
2008
  const percent = spec.grouping === "percentStacked";
@@ -2017,8 +2017,8 @@ function chartValueAxis(chart, resolved, geometry) {
2017
2017
  const anchor = spec.kind === "bar" || spec.kind === "area" ? [0] : [];
2018
2018
  const dataMin = extents.length ? Math.min(...extents, ...anchor) : 0;
2019
2019
  const dataMax = extents.length ? Math.max(...extents, ...anchor) : 1;
2020
- const pad = 10 * scale;
2021
- const fontPx = chartTextSize(geometry) * scale;
2020
+ const pad = 10 * scale2;
2021
+ const fontPx = chartTextSize(geometry) * scale2;
2022
2022
  const lineHeight = fontPx * 1.5;
2023
2023
  const options = resolveChartOptions(chart, chartOptionTarget(id));
2024
2024
  const legendBand = options.legend === "top" || options.legend === "bottom" ? lineHeight + pad : 0;
@@ -2212,6 +2212,8 @@ var REGION_ANCHORS = ["top", "middle", "bottom"];
2212
2212
  var HEADING_AREAS = ["title", "subtitle"];
2213
2213
  var RESERVED_REGION_NAMES = ["title", "subtitle", "tag", "auto", "left", "center", "right", "top", "middle", "bottom"];
2214
2214
  var MAX_TEMPLATE_TRACKS = 12;
2215
+ var MAX_REGION_ENTRIES = 12;
2216
+ var MAX_REGION_DEPTH = 3;
2215
2217
  var MAX_REGION_BLOCKS = 12;
2216
2218
  var AUTO_LAYOUT = "auto";
2217
2219
  var OPFLayoutTemplateError = class extends RangeError {
@@ -2225,16 +2227,17 @@ var OPFLayoutTemplateError = class extends RangeError {
2225
2227
  };
2226
2228
  var NAME = /^[a-z][a-z0-9-]*$/;
2227
2229
  var record4 = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
2228
- var pointerSegment = (segment2) => segment2.replaceAll("~", "~0").replaceAll("/", "~1");
2229
2230
  var reserved = new Set(RESERVED_REGION_NAMES);
2230
2231
  var headingNames = new Set(HEADING_AREAS);
2231
2232
  var positive = (value) => typeof value === "number" && Number.isFinite(value) && value > 0;
2233
+ var validSize = (value) => value === "auto" || positive(value) && value <= 100;
2234
+ var EPSILON = 1e-9;
2232
2235
  function isLayoutTemplate(layout) {
2233
- return Object.hasOwn(record4(layout), "areas");
2236
+ return Object.hasOwn(record4(layout), "regions");
2234
2237
  }
2235
- function layoutRegion(name, value) {
2238
+ function layoutRegion(name, value, inherited) {
2236
2239
  const entry = record4(value);
2237
- const accepts2 = Array.isArray(entry.accepts) ? [...new Set(entry.accepts.filter((kind2) => REGION_KINDS.includes(kind2)))] : [];
2240
+ const accepts2 = Array.isArray(entry.accepts) ? [...new Set(entry.accepts.filter((kind2) => REGION_KINDS.includes(kind2)))] : [...REGION_KINDS];
2238
2241
  const flow = REGION_FLOWS.includes(entry.flow) ? entry.flow : "auto";
2239
2242
  const max = Number.isInteger(entry.max) && entry.max >= 1 && entry.max <= MAX_REGION_BLOCKS ? entry.max : flow === "none" ? 1 : 6;
2240
2243
  return {
@@ -2245,116 +2248,224 @@ function layoutRegion(name, value) {
2245
2248
  max,
2246
2249
  bleed: entry.bleed === true,
2247
2250
  listColumns: entry.listColumns === "auto" ? "auto" : 1,
2248
- anchor: REGION_ANCHORS.includes(entry.anchor) ? entry.anchor : "top",
2251
+ anchor: REGION_ANCHORS.includes(entry.anchor) ? entry.anchor : inherited ?? "top",
2249
2252
  empty: entry.empty === "keep" ? "keep" : "collapse"
2250
2253
  };
2251
2254
  }
2255
+ var anchorOf = (value) => REGION_ANCHORS.includes(value) ? value : void 0;
2256
+ var isSplitEntry = (entry) => entry.name === void 0 && (entry.regions !== void 0 || entry.direction !== void 0);
2257
+ function layoutEntries(layout) {
2258
+ const value = record4(layout), out = [], seen = /* @__PURE__ */ new Set();
2259
+ const walk2 = (list, inherited, depth) => {
2260
+ if (!Array.isArray(list) || depth > MAX_REGION_DEPTH) return;
2261
+ for (const raw of list) {
2262
+ const entry = record4(raw);
2263
+ if (typeof entry.name === "string") {
2264
+ if (seen.has(entry.name)) continue;
2265
+ seen.add(entry.name);
2266
+ out.push(headingNames.has(entry.name) ? { name: entry.name, heading: true } : { name: entry.name, heading: false, region: layoutRegion(entry.name, entry, inherited) });
2267
+ } else if (isSplitEntry(entry)) walk2(entry.regions, anchorOf(entry.anchor) ?? inherited, depth + 1);
2268
+ }
2269
+ };
2270
+ walk2(value.regions, anchorOf(value.anchor), 1);
2271
+ return out;
2272
+ }
2273
+ function withRegionRules(layout, rules) {
2274
+ const rewrite = (list) => Array.isArray(list) ? list.map((raw) => {
2275
+ const entry = record4(raw);
2276
+ if (typeof entry.name === "string") return headingNames.has(entry.name) ? entry : { ...entry, ...rules };
2277
+ return isSplitEntry(entry) ? { ...entry, regions: rewrite(entry.regions) } : raw;
2278
+ }) : list;
2279
+ const value = record4(layout);
2280
+ return { ...value, regions: rewrite(value.regions) };
2281
+ }
2252
2282
  function parse(layout) {
2253
2283
  const value = record4(layout);
2254
2284
  const issues = [];
2255
- const grid = (code, path, message) => issues.push({ code, path, message });
2256
- const areas = value.areas;
2257
- if (!Array.isArray(areas) || !areas.length) {
2258
- grid("layout-template", "/areas", "a template needs 1 to 12 rows of area names");
2259
- return { issues };
2260
- }
2261
- if (areas.length > MAX_TEMPLATE_TRACKS) grid("layout-template", "/areas", `a template has at most ${MAX_TEMPLATE_TRACKS} rows; this one has ${areas.length}`);
2262
- const cells = areas.map((row, index) => {
2263
- if (!Array.isArray(row)) {
2264
- grid("layout-template", `/areas/${index}`, "each row is an array of area names; use nested arrays instead of space-separated strings");
2285
+ const add = (code, path, message) => issues.push({ code, path, message });
2286
+ const regions = [];
2287
+ const names = /* @__PURE__ */ new Set();
2288
+ const directionOf = (path, raw, fallback) => {
2289
+ if (raw === void 0) return fallback;
2290
+ if (raw === "row" || raw === "column") return raw;
2291
+ add("layout-template", path, `direction is "row" or "column", not ${JSON.stringify(raw)}`);
2292
+ return fallback;
2293
+ };
2294
+ const anchorCheck = (path, raw) => {
2295
+ if (raw !== void 0 && anchorOf(raw) === void 0) add("layout-template", path, `anchor is one of ${REGION_ANCHORS.join(", ")}, not ${JSON.stringify(raw)}`);
2296
+ };
2297
+ const walk2 = (list, path, depth, direction2, inherited) => {
2298
+ if (!Array.isArray(list) || !list.length || list.length > MAX_REGION_ENTRIES) {
2299
+ add("layout-template", path, `regions is a list of 1 to ${MAX_REGION_ENTRIES} regions and splits${Array.isArray(list) ? `; this one has ${list.length}` : ""}`);
2265
2300
  return [];
2266
2301
  }
2267
- const words = [];
2268
- if (!row.length) grid("layout-template", `/areas/${index}`, 'a row needs at least one area name or "."');
2269
- row.forEach((cell, column) => {
2270
- if (typeof cell !== "string") grid("layout-template", `/areas/${index}/${column}`, 'each cell is one area name or "."');
2271
- else {
2272
- words.push(cell);
2273
- if (cell !== "." && !NAME.test(cell)) grid("layout-template", `/areas/${index}/${column}`, `'${cell}' is not an area name (lowercase letters, digits and hyphens, starting with a letter) or "."`);
2302
+ const out = [];
2303
+ list.forEach((raw, index) => {
2304
+ const at3 = `${path}/${index}`;
2305
+ if (raw === null || typeof raw !== "object" || Array.isArray(raw)) {
2306
+ add("layout-template", at3, 'each entry is a region ({ "name": ... }) or a split ({ "direction": ..., "regions": [...] })');
2307
+ return;
2274
2308
  }
2275
- });
2276
- return words;
2277
- });
2278
- const width = cells[0]?.length ?? 0;
2279
- cells.forEach((row, index) => {
2280
- if (index > 0 && row.length !== width && row.length) grid("layout-template", `/areas/${index}`, `every row has the same number of cells; row ${index + 1} has ${row.length}, row 1 has ${width}`);
2281
- });
2282
- if (width > MAX_TEMPLATE_TRACKS) grid("layout-template", "/areas", `a template has at most ${MAX_TEMPLATE_TRACKS} columns; this one has ${width}`);
2283
- const columns2 = value.columns === void 0 ? Array.from({ length: width }, () => 1) : value.columns;
2284
- const rows3 = value.rows === void 0 ? Array.from({ length: cells.length }, () => 1) : value.rows;
2285
- if (!Array.isArray(columns2) || columns2.length !== width || !columns2.every(positive)) grid("layout-template", "/columns", `columns needs one positive number per cell of a row (${width})`);
2286
- if (!Array.isArray(rows3) || rows3.length !== cells.length || !rows3.every((size) => size === "auto" || positive(size))) grid("layout-template", "/rows", `rows needs one positive number or "auto" per row (${cells.length})`);
2287
- if (issues.length) return { issues };
2288
- const bounds = /* @__PURE__ */ new Map();
2289
- cells.forEach((row, r) => {
2290
- row.forEach((name, c) => {
2291
- if (name === ".") return;
2292
- const found = bounds.get(name);
2293
- if (!found) bounds.set(name, { top: r, left: c, bottom: r, right: c, count: 1 });
2294
- else {
2295
- found.top = Math.min(found.top, r);
2296
- found.left = Math.min(found.left, c);
2297
- found.bottom = Math.max(found.bottom, r);
2298
- found.right = Math.max(found.right, c);
2299
- found.count++;
2309
+ const entry = raw;
2310
+ const split = isSplitEntry(entry);
2311
+ if (!split && typeof entry.name !== "string") {
2312
+ add("layout-template", at3, "a region needs a name; a split needs direction and regions");
2313
+ return;
2300
2314
  }
2315
+ const heading = typeof entry.name === "string" && headingNames.has(entry.name);
2316
+ let size = split || !heading || direction2 === "row" ? 1 : "auto";
2317
+ if (entry.size !== void 0) {
2318
+ if (validSize(entry.size)) size = entry.size;
2319
+ else add("layout-template", `${at3}/size`, `size is a number above 0 and up to 100, or "auto"; not ${JSON.stringify(entry.size)}`);
2320
+ }
2321
+ if (size === "auto" && direction2 !== "column") add("layout-template", `${at3}/size`, '"auto" is allowed only in a column: a region or split in a row has a numeric size');
2322
+ if (split) {
2323
+ if (entry.name !== void 0) add("layout-template", `${at3}/name`, "a split has no name");
2324
+ const inner = directionOf(`${at3}/direction`, entry.direction, "column");
2325
+ if (entry.direction === void 0) add("layout-template", `${at3}/direction`, 'a split needs a direction, "row" or "column"');
2326
+ anchorCheck(`${at3}/anchor`, entry.anchor);
2327
+ if (depth >= MAX_REGION_DEPTH) {
2328
+ add("layout-template", `${at3}/regions`, `regions nest at most ${MAX_REGION_DEPTH} levels deep (the record's list is level 1); this split would be level ${depth + 1}`);
2329
+ return;
2330
+ }
2331
+ out.push({ kind: "split", direction: inner, size, children: walk2(entry.regions, `${at3}/regions`, depth + 1, inner, anchorOf(entry.anchor) ?? inherited) });
2332
+ return;
2333
+ }
2334
+ const name = entry.name;
2335
+ if (names.has(name)) add("layout-region", `${at3}/name`, `region name '${name}' is used twice; names are unique across the whole record`);
2336
+ names.add(name);
2337
+ if (heading) {
2338
+ for (const key of Object.keys(entry)) if (key !== "name" && key !== "size") add("layout-region", `${at3}/${key}`, `'${name}' is a heading region and takes only a size; '${key}' belongs on a body region`);
2339
+ } else {
2340
+ if (reserved.has(name)) add("layout-region", `${at3}/name`, `'${name}' is reserved and cannot name a body region (reserved: ${RESERVED_REGION_NAMES.join(", ")})`);
2341
+ else if (!NAME.test(name)) add("layout-region", `${at3}/name`, `'${name}' is not a region name (lowercase letters, digits and hyphens, starting with a letter)`);
2342
+ if (entry.flow === "none" && entry.max !== void 0 && entry.max !== 1) add("layout-region", `${at3}/max`, `a region with flow "none" holds one block; max must be 1, not ${JSON.stringify(entry.max)}`);
2343
+ anchorCheck(`${at3}/anchor`, entry.anchor);
2344
+ const found = layoutRegion(name, entry, inherited);
2345
+ if (!found.accepts.length) add("layout-region", `${at3}/accepts`, `region '${name}' accepts no content kind`);
2346
+ regions.push(found);
2347
+ }
2348
+ out.push({ kind: "leaf", name, size });
2301
2349
  });
2302
- });
2303
- const list = [];
2304
- for (const [name, box] of bounds) {
2305
- const filled = (box.bottom - box.top + 1) * (box.right - box.left + 1);
2306
- let rectangle = filled === box.count;
2307
- for (let r = box.top; rectangle && r <= box.bottom; r++) for (let c = box.left; c <= box.right; c++) if (cells[r][c] !== name) {
2308
- rectangle = false;
2309
- break;
2310
- }
2311
- if (!rectangle) {
2312
- grid("layout-template", "/areas", `the cells of '${name}' do not form one filled rectangle`);
2313
- continue;
2314
- }
2315
- list.push({ name, row: box.top, column: box.left, rowSpan: box.bottom - box.top + 1, columnSpan: box.right - box.left + 1, heading: headingNames.has(name) });
2350
+ return out;
2351
+ };
2352
+ if (!Array.isArray(value.regions)) {
2353
+ add("layout-template", "/regions", `a template needs a regions list of 1 to ${MAX_REGION_ENTRIES} regions and splits`);
2354
+ return { issues };
2316
2355
  }
2356
+ const direction = directionOf("/direction", value.direction, "column");
2357
+ anchorCheck("/anchor", value.anchor);
2358
+ const children = walk2(value.regions, "/regions", 1, direction, anchorOf(value.anchor));
2359
+ if (names.has("subtitle") && !names.has("title")) add("layout-region", "/regions", "a 'subtitle' region needs a 'title' region");
2360
+ if (value.overflowRegion !== void 0 && !regions.some((entry) => entry.name === value.overflowRegion)) add("layout-region", "/overflowRegion", `overflowRegion ${JSON.stringify(value.overflowRegion)} is not a region of this layout`);
2317
2361
  if (issues.length) return { issues };
2318
- list.sort((a, b) => a.row - b.row || a.column - b.column);
2319
- const entries = record4(value.regions);
2320
- const region = (path, message) => grid("layout-region", path, message);
2321
- if (value.regions !== void 0 && (value.regions === null || typeof value.regions !== "object" || Array.isArray(value.regions))) region("/regions", "regions is an object keyed by region name");
2322
- for (const name of Object.keys(entries)) {
2323
- if (reserved.has(name)) region(`/regions/${pointerSegment(name)}`, `'${name}' is reserved and cannot name a region (reserved: ${RESERVED_REGION_NAMES.join(", ")})`);
2324
- else if (!bounds.has(name)) region(`/regions/${pointerSegment(name)}`, `region '${name}' has no area in areas`);
2325
- }
2326
- for (const area2 of list) {
2327
- if (area2.heading) continue;
2328
- if (reserved.has(area2.name)) {
2329
- if (!Object.hasOwn(entries, area2.name)) region("/areas", `'${area2.name}' is reserved and cannot name a body area (reserved: ${RESERVED_REGION_NAMES.join(", ")})`);
2330
- continue;
2331
- }
2332
- if (!Object.hasOwn(entries, area2.name)) region("/regions", `body area '${area2.name}' has no entry in regions`);
2362
+ const grid = compile({ kind: "split", direction, children });
2363
+ if (grid.rows.length > MAX_TEMPLATE_TRACKS || grid.columns.length > MAX_TEMPLATE_TRACKS) {
2364
+ add("layout-template", "/regions", `the regions compile to a grid of at most ${MAX_TEMPLATE_TRACKS} rows and ${MAX_TEMPLATE_TRACKS} columns; this one has ${grid.rows.length} rows and ${grid.columns.length} columns`);
2365
+ return { issues };
2333
2366
  }
2334
- if (bounds.has("subtitle") && !bounds.has("title")) region("/areas", "a 'subtitle' area needs a 'title' area");
2335
- for (const [name, entry] of Object.entries(entries)) {
2336
- const raw = record4(entry);
2337
- if (raw.flow === "none" && raw.max !== void 0 && raw.max !== 1) region(`/regions/${pointerSegment(name)}/max`, `a region with flow "none" holds one block; max must be 1, not ${JSON.stringify(raw.max)}`);
2367
+ const bounds = /* @__PURE__ */ new Map();
2368
+ for (const [r, row] of grid.cells.entries()) for (const [c, name] of row.entries()) {
2369
+ const found = bounds.get(name);
2370
+ if (!found) bounds.set(name, { top: r, left: c, bottom: r, right: c });
2371
+ else {
2372
+ found.bottom = r;
2373
+ found.right = c;
2374
+ }
2338
2375
  }
2339
- const regions = list.filter((area2) => !area2.heading && !reserved.has(area2.name) && Object.hasOwn(entries, area2.name)).map((area2) => layoutRegion(area2.name, entries[area2.name]));
2340
- for (const entry of regions) if (!entry.accepts.length) region(`/regions/${pointerSegment(entry.name)}/accepts`, `region '${entry.name}' accepts no content kind`);
2341
- if (value.overflowRegion !== void 0 && !regions.some((entry) => entry.name === value.overflowRegion)) region("/overflowRegion", `overflowRegion ${JSON.stringify(value.overflowRegion)} is not a region of this layout`);
2342
- if (issues.length) return { issues };
2376
+ const areas = [];
2377
+ const order = (nodes) => {
2378
+ for (const node of nodes) {
2379
+ if (node.kind === "split") order(node.children);
2380
+ else {
2381
+ const box = bounds.get(node.name) ?? { top: 0, left: 0, bottom: 0, right: 0 };
2382
+ areas.push({ name: node.name, row: box.top, column: box.left, rowSpan: box.bottom - box.top + 1, columnSpan: box.right - box.left + 1, heading: headingNames.has(node.name) });
2383
+ }
2384
+ }
2385
+ };
2386
+ order(children);
2343
2387
  const overflowRegion = typeof value.overflowRegion === "string" ? value.overflowRegion : regions.find((entry) => entry.role === "primary" && entry.flow !== "none")?.name;
2344
2388
  return {
2345
2389
  issues,
2346
2390
  template: {
2347
- rows: rows3.slice(),
2348
- columns: columns2.slice(),
2349
- grid: cells,
2350
- areas: list,
2391
+ rows: grid.rows,
2392
+ columns: grid.columns,
2393
+ grid: grid.cells,
2394
+ areas,
2351
2395
  regions,
2352
2396
  ...overflowRegion !== void 0 ? { overflowRegion } : {},
2353
- title: bounds.has("title"),
2354
- subtitle: bounds.has("subtitle")
2397
+ title: names.has("title"),
2398
+ subtitle: names.has("subtitle")
2355
2399
  }
2356
2400
  };
2357
2401
  }
2402
+ var comparePositions = (x, y) => Math.abs(x.w - y.w) > EPSILON ? x.w - y.w : x.a - y.a;
2403
+ function cutsOf(tracks) {
2404
+ const total = tracks.reduce((sum, size) => sum + (size === "auto" ? 0 : size), 0);
2405
+ const cuts = [];
2406
+ let w = 0, a = 0;
2407
+ tracks.forEach((size, index) => {
2408
+ if (size === "auto") a++;
2409
+ else w += size;
2410
+ if (index < tracks.length - 1) cuts.push({ w: total > 0 ? w / total : 0, a });
2411
+ });
2412
+ return cuts;
2413
+ }
2414
+ var endOf = (tracks) => ({ w: tracks.some((size) => size !== "auto") ? 1 : 0, a: tracks.filter((size) => size === "auto").length });
2415
+ function align(axes) {
2416
+ const cuts = [];
2417
+ for (const axis of axes) for (const cut of cutsOf(axis)) if (!cuts.some((found) => comparePositions(found, cut) === 0)) cuts.push(cut);
2418
+ cuts.sort(comparePositions);
2419
+ const ends = axes.map(endOf);
2420
+ const end = ends.reduce((best, found) => comparePositions(found, best) > 0 ? found : best);
2421
+ const bounds = [{ w: 0, a: 0 }, ...cuts.filter((cut) => comparePositions(cut, end) < 0), end];
2422
+ const tracks = [];
2423
+ for (let index = 1; index < bounds.length; index++) {
2424
+ const share = (bounds[index]?.w ?? 0) - (bounds[index - 1]?.w ?? 0);
2425
+ tracks.push(share > EPSILON ? share : "auto");
2426
+ }
2427
+ const owner = axes.map((axis) => {
2428
+ const own3 = cutsOf(axis);
2429
+ return tracks.map((_, index) => own3.filter((cut) => comparePositions(cut, bounds[index] ?? cut) <= 0).length);
2430
+ });
2431
+ return { tracks, owner };
2432
+ }
2433
+ function scale(tracks, size) {
2434
+ if (size === "auto") return tracks.map(() => "auto");
2435
+ const total = tracks.reduce((sum, track) => sum + (track === "auto" ? 0 : track), 0);
2436
+ return total > 0 ? tracks.map((track) => track === "auto" ? track : track * size / total) : [...tracks];
2437
+ }
2438
+ function fragmentOf(node) {
2439
+ if (node.kind === "leaf") return { rows: [1], columns: [1], cells: [[node.name]] };
2440
+ const kids = node.children.map((child) => ({ size: child.size, fragment: fragmentOf(child) }));
2441
+ if (node.direction === "column") {
2442
+ const { tracks: tracks2, owner: owner2 } = align(kids.map((kid) => kid.fragment.columns));
2443
+ const rows3 = [], cells2 = [];
2444
+ kids.forEach((kid, index) => {
2445
+ rows3.push(...scale(kid.fragment.rows, kid.size));
2446
+ for (const row of kid.fragment.cells) cells2.push(tracks2.map((_, column) => row[owner2[index]?.[column] ?? 0] ?? ""));
2447
+ });
2448
+ return { rows: rows3, columns: tracks2.map((track) => track), cells: cells2 };
2449
+ }
2450
+ const { tracks, owner } = align(kids.map((kid) => kid.fragment.rows));
2451
+ const columns2 = [];
2452
+ for (const kid of kids) columns2.push(...scale(kid.fragment.columns, kid.size));
2453
+ const cells = tracks.map((_, row) => kids.flatMap((kid, index) => kid.fragment.cells[owner[index]?.[row] ?? 0] ?? []));
2454
+ return { rows: tracks, columns: columns2, cells };
2455
+ }
2456
+ function wholeWeights(tracks) {
2457
+ const total = tracks.reduce((sum, track) => sum + (track === "auto" ? 0 : track), 0);
2458
+ if (!(total > 0)) return [...tracks];
2459
+ for (let k = 1; k <= 1e3; k++) {
2460
+ const scaled = tracks.map((track) => track === "auto" ? track : track / total * k);
2461
+ if (scaled.every((track) => track === "auto" || Math.abs(track - Math.round(track)) < 1e-6 && Math.round(track) >= 1)) return scaled.map((track) => track === "auto" ? track : Math.round(track));
2462
+ }
2463
+ return tracks.map((track) => track === "auto" ? track : Math.round(track / total * 1e6) / 1e4);
2464
+ }
2465
+ function compile(root) {
2466
+ const fragment = fragmentOf(root);
2467
+ return { rows: wholeWeights(fragment.rows), columns: wholeWeights(fragment.columns), cells: fragment.cells };
2468
+ }
2358
2469
  function layoutTemplateIssues(layout) {
2359
2470
  return isLayoutTemplate(layout) ? parse(layout).issues : [];
2360
2471
  }
@@ -2825,11 +2936,11 @@ function designSites(sites, design, path) {
2825
2936
  pushObjectReference(sites, "colorSchemes", design.colorScheme, [...path, "colorScheme"]);
2826
2937
  pushObjectReference(sites, "fontSchemes", design.fontScheme, [...path, "fontScheme"]);
2827
2938
  }
2828
- function recordReferenceSites(kind2, record9, path, group) {
2939
+ function recordReferenceSites(kind2, record8, path, group) {
2829
2940
  const sites = [];
2830
- if (kind2 === "themes" && isRec(record9)) {
2831
- pushObjectReference(sites, "colorSchemes", record9.colorScheme, [...path, "colorScheme"], group);
2832
- pushObjectReference(sites, "fontSchemes", record9.fontScheme, [...path, "fontScheme"], group);
2941
+ if (kind2 === "themes" && isRec(record8)) {
2942
+ pushObjectReference(sites, "colorSchemes", record8.colorScheme, [...path, "colorScheme"], group);
2943
+ pushObjectReference(sites, "fontSchemes", record8.fontScheme, [...path, "fontScheme"], group);
2833
2944
  }
2834
2945
  return sites;
2835
2946
  }
@@ -2858,7 +2969,7 @@ function catalogReferenceSites(document, options = {}) {
2858
2969
  for (const [group, value] of Object.entries(groupsOf(document))) {
2859
2970
  if (!isRec(value)) continue;
2860
2971
  for (const kind2 of catalogKinds)
2861
- for (const [id, record9] of Object.entries(rec(value[kind2]))) sites.push(...recordReferenceSites(kind2, record9, ["catalogs", group, kind2, id], group));
2972
+ for (const [id, record8] of Object.entries(rec(value[kind2]))) sites.push(...recordReferenceSites(kind2, record8, ["catalogs", group, kind2, id], group));
2862
2973
  }
2863
2974
  return sites;
2864
2975
  }
@@ -2892,8 +3003,8 @@ function catalogRecords(document, kind2, options = {}) {
2892
3003
  }
2893
3004
  return result;
2894
3005
  }
2895
- function embeddedCopy(record9) {
2896
- return Object.fromEntries(Object.entries(rec(record9)).filter(([key]) => key !== "$schema" && key !== "id" && !key.startsWith("x-")).map(([key, value]) => [key, structuredClone(value)]));
3006
+ function embeddedCopy(record8) {
3007
+ return Object.fromEntries(Object.entries(rec(record8)).filter(([key]) => key !== "$schema" && key !== "id" && !key.startsWith("x-")).map(([key, value]) => [key, structuredClone(value)]));
2897
3008
  }
2898
3009
 
2899
3010
  // src/generated/engine-data.ts
@@ -3657,7 +3768,7 @@ function labToLinear([l, a, b]) {
3657
3768
  var hexOfChannels = (channels2) => `#${channels2.map((channel) => Math.max(0, Math.min(255, Math.round(channel))).toString(16).padStart(2, "0")).join("").toUpperCase()}`;
3658
3769
  function labWithLightness(l, a, b) {
3659
3770
  const chroma = Math.hypot(a, b), hue = Math.atan2(b, a);
3660
- const at3 = (scale) => labToLinear([l, Math.cos(hue) * chroma * scale, Math.sin(hue) * chroma * scale]);
3771
+ const at3 = (scale2) => labToLinear([l, Math.cos(hue) * chroma * scale2, Math.sin(hue) * chroma * scale2]);
3661
3772
  let linear2 = at3(1);
3662
3773
  if (!linear2) {
3663
3774
  let low = 0, high = 1;
@@ -4507,8 +4618,8 @@ function codeSyntaxPalette(theme = {}, options = {}) {
4507
4618
  return palette;
4508
4619
  }
4509
4620
  function codeSyntaxPaletteForScheme(scheme, options = {}) {
4510
- const record9 = scheme && typeof scheme === "object" ? scheme : {};
4511
- const pick = (role, slot, fallback) => normalize(record9[role]) ?? normalize(record9[slot]) ?? fallback;
4621
+ const record8 = scheme && typeof scheme === "object" ? scheme : {};
4622
+ const pick = (role, slot, fallback) => normalize(record8[role]) ?? normalize(record8[slot]) ?? fallback;
4512
4623
  return codeSyntaxPalette({ primary: pick("primary", "accent1", "#2563EB"), secondary: pick("secondary", "accent2", "#0F766E"), accent: pick("accent", "accent3", "#F59E0B") }, options);
4513
4624
  }
4514
4625
  function codeSyntaxPaletteForRoles(roles, options = {}) {
@@ -4667,8 +4778,8 @@ var blend = (from, to, amount) => {
4667
4778
  return toHex(a.map((value, index) => value + (b[index] - value) * amount));
4668
4779
  };
4669
4780
  function codeHighlightColors(scheme, palette = codeSyntaxPaletteForScheme(scheme), panel = CODE_PANEL_BACKGROUND) {
4670
- const record9 = scheme && typeof scheme === "object" ? scheme : {};
4671
- const primary = normalize(record9.primary) ?? normalize(record9.accent1) ?? "#2563EB";
4781
+ const record8 = scheme && typeof scheme === "object" ? scheme : {};
4782
+ const primary = normalize(record8.primary) ?? normalize(record8.accent1) ?? "#2563EB";
4672
4783
  const [hue, saturation] = toHsl(primary);
4673
4784
  const tint = fromHsl(hue, Math.min(saturation, 0.7), 0.45);
4674
4785
  const band = blend(panel, tint, CODE_HIGHLIGHT_BAND_TINT);
@@ -5045,37 +5156,25 @@ function referencesSlide(presentation, options = {}) {
5045
5156
 
5046
5157
  // src/layout-content.ts
5047
5158
  var LAYOUT_BODY_KINDS = ["text", "list", "image", "video", "chart", "table", "code", "metric", "quote", "timeline"];
5048
- var record7 = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
5049
5159
  function layoutStructure(layout) {
5050
5160
  if (!isLayoutTemplate(layout)) return "";
5051
- return templateAreas(layout).map((entry) => entry.region ? `${entry.name} (${entry.region.flow}: ${entry.region.accepts.join(", ")})` : entry.name).join(", ");
5161
+ return layoutEntries(layout).map((entry) => entry.region ? `${entry.name} (${entry.region.flow}: ${entry.region.accepts.join(", ")})` : entry.name).join(", ");
5052
5162
  }
5053
5163
  function layoutContent(layout) {
5054
- const areas = isLayoutTemplate(layout) ? templateAreas(layout) : [];
5164
+ const areas = isLayoutTemplate(layout) ? layoutEntries(layout) : [];
5055
5165
  const regions = areas.flatMap((entry) => entry.region ? [entry.region] : []);
5056
5166
  const lead = regions.find((region) => region.role === "primary") ?? regions[0];
5057
5167
  const leadKind = lead?.accepts.find((kind2) => kind2 !== "group");
5058
5168
  const title = areas.some((entry) => entry.name === "title");
5059
5169
  return { kind: leadKind ?? "title", count: regions.length, heading: { title, subtitle: title || areas.some((entry) => entry.name === "subtitle"), tag: title } };
5060
5170
  }
5061
- function templateAreas(layout) {
5062
- const value = record7(layout), regions = record7(value.regions);
5063
- const rows3 = Array.isArray(value.areas) ? value.areas.filter((row) => Array.isArray(row) && row.every((cell) => typeof cell === "string")) : [];
5064
- const seen = /* @__PURE__ */ new Set(), out = [];
5065
- for (const row of rows3) for (const name of row) {
5066
- if (!name || name === "." || seen.has(name)) continue;
5067
- seen.add(name);
5068
- out.push(name === "title" || name === "subtitle" || !Object.hasOwn(regions, name) ? { name } : { name, region: layoutRegion(name, regions[name]) });
5069
- }
5070
- return out;
5071
- }
5072
5171
 
5073
5172
  // src/composition.ts
5074
5173
  var MAX_COMPOSITION_DEPTH = 32;
5075
5174
  var FALLBACK_CODE_FAMILY = "Roboto Mono";
5076
5175
  var DEFAULT_FONT_FAMILIES = { heading: String(ENGINE_DEFAULT_FONT_SCHEME.major), body: String(ENGINE_DEFAULT_FONT_SCHEME.minor) };
5077
5176
  function resolveFontFamilies(input) {
5078
- const scheme = record8(input);
5177
+ const scheme = record7(input);
5079
5178
  const family = (value) => typeof value === "string" && value ? value : void 0;
5080
5179
  const accent = family(scheme.accent);
5081
5180
  return {
@@ -5161,7 +5260,7 @@ var fields = ["text", "items", "bullets", "image", "video", "chart", "table", "c
5161
5260
  var headings = /* @__PURE__ */ new Set(["title", "subtitle", "tag"]);
5162
5261
  var rows2 = ["top", "middle", "bottom"];
5163
5262
  var columns = ["left", "center", "right"];
5164
- var record8 = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
5263
+ var record7 = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
5165
5264
  var kind = (field) => field === "items" ? "list" : field === "bullets" ? "text" : field;
5166
5265
  var round2 = (value) => Math.round(value * 1e6) / 1e6 || value;
5167
5266
  var PLACEMENT_BAND = 0.5;
@@ -5180,7 +5279,7 @@ var pathNumber = (value) => String(round2(value));
5180
5279
  var IMAGE_SHAPES = { rectangle: "rect", rounded: "roundRect", circle: "ellipse", hexagon: "hexagon" };
5181
5280
  var roundBox = (box) => ({ x: round2(box.x), y: round2(box.y), width: round2(box.width), height: round2(box.height) });
5182
5281
  var imageFocus = (value) => {
5183
- const focus = record8(value), x = finite(focus.x, 0, 1), y = finite(focus.y, 0, 1);
5282
+ const focus = record7(value), x = finite(focus.x, 0, 1), y = finite(focus.y, 0, 1);
5184
5283
  return x !== void 0 && y !== void 0 ? { x, y } : { x: 0.5, y: 0.5 };
5185
5284
  };
5186
5285
  function imageShape(kind2, box, cornerRadius = 1 / 6) {
@@ -5221,7 +5320,7 @@ function fitImage(frame, fit, aspect, focus = { x: 0.5, y: 0.5 }) {
5221
5320
  }
5222
5321
  function imageBackground(value) {
5223
5322
  if (typeof value === "string") return IMAGE_SOURCE.test(value) ? { src: value, fit: "cover", focus: { x: 0.5, y: 0.5 } } : void 0;
5224
- const background = record8(value);
5323
+ const background = record7(value);
5225
5324
  if (background.type !== "image" || typeof background.src !== "string" || !background.src) return void 0;
5226
5325
  const opacity = finite(background.opacity, 0, 1);
5227
5326
  return {
@@ -5236,11 +5335,11 @@ function imageBackground(value) {
5236
5335
  }
5237
5336
  function composeRecolor(value) {
5238
5337
  if (value === "grayscale") return { type: "grayscale" };
5239
- const duotone = record8(value);
5338
+ const duotone = record7(value);
5240
5339
  return duotone.dark !== void 0 && duotone.light !== void 0 ? { type: "duotone", dark: duotone.dark, light: duotone.light } : void 0;
5241
5340
  }
5242
5341
  function composeOverlay(value, frame, shape, path, mirrorSide, diagnostics) {
5243
- const overlay = record8(value), opacity = finite(overlay.opacity, 0, 1);
5342
+ const overlay = record7(value), opacity = finite(overlay.opacity, 0, 1);
5244
5343
  if (overlay.color === void 0 || opacity === void 0) return void 0;
5245
5344
  const edge = IMAGE_EDGES2.includes(overlay.edge) ? mirrorSide(overlay.edge) : void 0;
5246
5345
  if (edge && shape.kind !== "rectangle") {
@@ -5253,7 +5352,7 @@ function composeOverlay(value, frame, shape, path, mirrorSide, diagnostics) {
5253
5352
  }
5254
5353
  function composeImage(host, hostPath, region, frameArea, context) {
5255
5354
  const kindName = Object.hasOwn(IMAGE_SHAPES, host.shape) ? host.shape : "rectangle";
5256
- const { scale } = context;
5355
+ const { scale: scale2 } = context;
5257
5356
  let box = { ...frameArea };
5258
5357
  const aspect = kindName === "circle" ? 1 : finite(host.aspectRatio, Number.MIN_VALUE, 10);
5259
5358
  if (aspect) {
@@ -5265,8 +5364,8 @@ function composeImage(host, hostPath, region, frameArea, context) {
5265
5364
  const focus = imageFocus(host.focus);
5266
5365
  const shape = imageShape(kindName, box, finite(host.cornerRadius, 0, 0.5));
5267
5366
  const result = { region: roundBox(region), box, fit, focus, shape };
5268
- const border = record8(host.border), borderWidth = finite(border.width, 0, 64);
5269
- if (border.color !== void 0 && borderWidth) result.border = { color: border.color, width: round2(borderWidth * scale) };
5367
+ const border = record7(host.border), borderWidth = finite(border.width, 0, 64);
5368
+ if (border.color !== void 0 && borderWidth) result.border = { color: border.color, width: round2(borderWidth * scale2) };
5270
5369
  const opacity = finite(host.opacity, 0, 1);
5271
5370
  if (opacity !== void 0 && opacity < 1) result.opacity = opacity;
5272
5371
  const recolor = composeRecolor(host.recolor);
@@ -5279,7 +5378,7 @@ function composeImage(host, hostPath, region, frameArea, context) {
5279
5378
  return result;
5280
5379
  }
5281
5380
  function resolveBackgroundImage(slide, presentation, themeBackground, width, height, path, mirrorSide, diagnostics) {
5282
- const own3 = record8(slide.design), deck = record8(record8(presentation).design);
5381
+ const own3 = record7(slide.design), deck = record7(record7(presentation).design);
5283
5382
  const [value, at3] = own3.background !== void 0 ? [own3.background, `${path}.design.background`] : deck.background !== void 0 ? [deck.background, "design.background"] : [themeBackground, "theme"];
5284
5383
  const background = imageBackground(value);
5285
5384
  if (!background) return void 0;
@@ -5290,7 +5389,7 @@ function resolveBackgroundImage(slide, presentation, themeBackground, width, hei
5290
5389
  if (recolor) result.recolor = recolor;
5291
5390
  const overlay = composeOverlay(background.overlay, box, imageShape("rectangle", box), `${at3}.overlay`, mirrorSide, diagnostics);
5292
5391
  if (overlay) result.overlay = overlay;
5293
- const aspect = background.fit === "tile" ? void 0 : intrinsicImageAspect(background.src, record8(presentation).assets);
5392
+ const aspect = background.fit === "tile" ? void 0 : intrinsicImageAspect(background.src, record7(presentation).assets);
5294
5393
  if (aspect) result.picture = fitImage(box, background.fit, aspect, background.focus);
5295
5394
  return result;
5296
5395
  }
@@ -5322,12 +5421,12 @@ function breaksInsideWord(text2, fit) {
5322
5421
  });
5323
5422
  }
5324
5423
  function layoutFurniture(input, options = {}) {
5325
- const slide = record8(input), width = options.width ?? 1280, height = options.height ?? 720, scale = Math.min(width, height) / 720;
5326
- const settings = { ...record8(record8(options.layout).composition), ...record8(slide.composition) };
5424
+ const slide = record7(input), width = options.width ?? 1280, height = options.height ?? 720, scale2 = Math.min(width, height) / 720;
5425
+ const settings = { ...record7(record7(options.layout).composition), ...record7(slide.composition) };
5327
5426
  assertComposition(settings);
5328
5427
  const furnitureRtl = (options.direction ?? resolveSlideDirection(options.presentation, options.slideIndex)) === "rtl";
5329
- const minimum = snapFontSizeUp((settings.minFontSize ?? 16) * scale), size = gridFontSize(13 * scale, minimum), padding = (options.textRasterPadding ?? 2) * scale;
5330
- 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.");
5428
+ const minimum = snapFontSizeUp((settings.minFontSize ?? 16) * scale2), size = gridFontSize(13 * scale2, minimum), padding = (options.textRasterPadding ?? 2) * scale2;
5429
+ if (![width, height, scale2, 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.");
5331
5430
  const number = options.slideNumber ?? (options.slideIndex ?? 0) + 1;
5332
5431
  if (!Number.isSafeInteger(number) || number < 1) throw new RangeError("Displayed slide number must be a positive safe integer.");
5333
5432
  const presentationSlides = options.presentation?.slides, slideCount = options.slideCount ?? (Array.isArray(presentationSlides) && presentationSlides.length ? presentationSlides.length : void 0);
@@ -5335,13 +5434,13 @@ function layoutFurniture(input, options = {}) {
5335
5434
  if (options.date !== void 0 && (typeof options.date !== "string" || !parseIsoDate(options.date))) throw new RangeError("The furniture date option must be an ISO YYYY-MM-DD calendar date.");
5336
5435
  const outlines = options.textMeasurement?.outlineBounds !== void 0, parts = [], diagnostics = [];
5337
5436
  const sourceRoot = `slides.${options.slideIndex ?? 0}`, organizations = Array.isArray(options.presentation?.organization) ? options.presentation.organization : [options.presentation?.organization];
5338
- const primaryIndex = organizations.findIndex((item) => record8(item).role === "primary"), organizationIndex2 = primaryIndex >= 0 ? primaryIndex : organizations.findIndex(Boolean);
5339
- const organization = record8(organizations[organizationIndex2]), organizationRoot = Array.isArray(options.presentation?.organization) ? `organization.${organizationIndex2}` : "organization";
5437
+ const primaryIndex = organizations.findIndex((item) => record7(item).role === "primary"), organizationIndex2 = primaryIndex >= 0 ? primaryIndex : organizations.findIndex(Boolean);
5438
+ const organization = record7(organizations[organizationIndex2]), organizationRoot = Array.isArray(options.presentation?.organization) ? `organization.${organizationIndex2}` : "organization";
5340
5439
  const fontFamily = options.fontFamilies?.body ?? "sans-serif";
5341
5440
  let headerBottom = 0, footerTop = height, configured = false;
5342
5441
  const error = (path, message, code = "text-overflow") => diagnostics.push({ code, path, message });
5343
5442
  for (const kind2 of ["header", "footer"]) {
5344
- const local = record8(slide.design)[kind2] !== void 0, value = local ? record8(slide.design)[kind2] : options.presentation?.design?.[kind2];
5443
+ const local = record7(slide.design)[kind2] !== void 0, value = local ? record7(slide.design)[kind2] : options.presentation?.design?.[kind2];
5345
5444
  if (value === void 0 || value === false) continue;
5346
5445
  const root = local ? `${sourceRoot}.design.${kind2}` : `design.${kind2}`;
5347
5446
  if (!value || typeof value !== "object" || Array.isArray(value)) throw new TypeError("Header/footer content must be an object or false.");
@@ -5350,7 +5449,7 @@ function layoutFurniture(input, options = {}) {
5350
5449
  const inset = Math.min((settings.padding ?? 0.08) * Math.min(width, height), width * 0.25), gutter = width * FURNITURE_ZONE_GUTTER, column = (width - 2 * inset - 2 * gutter) / 3;
5351
5450
  const slotOf = (index) => furnitureRtl && index !== 1 ? 2 - index : index;
5352
5451
  const hasContent = (zone) => {
5353
- const item = record8(record8(value)[zone]);
5452
+ const item = record7(record7(value)[zone]);
5354
5453
  return item.image !== void 0 || (typeof item.text === "string" ? item.text.trim() !== "" : item.text !== void 0) || item.socials === true || item.date === true || typeof item.date === "string";
5355
5454
  };
5356
5455
  const slots = ["left", "center", "right"].map((zone, index) => ({ slot: slotOf(index), occupied: hasContent(zone) })).sort((a, b) => a.slot - b.slot);
@@ -5365,7 +5464,7 @@ function layoutFurniture(input, options = {}) {
5365
5464
  };
5366
5465
  for (const [index, zone] of ["left", "center", "right"].entries()) {
5367
5466
  const side = furnitureRtl && zone !== "center" ? zone === "left" ? "right" : "left" : zone;
5368
- const content = record8(record8(value)[zone]), path = `${root}.${zone}`, { x, width: zoneWidth } = interval(slotOf(index));
5467
+ const content = record7(record7(value)[zone]), path = `${root}.${zone}`, { x, width: zoneWidth } = interval(slotOf(index));
5369
5468
  const pending = [];
5370
5469
  const add = (field, text2, generated = false, sourcePath, extras = {}) => {
5371
5470
  if (text2 === void 0) return;
@@ -5374,7 +5473,7 @@ function layoutFurniture(input, options = {}) {
5374
5473
  pending.push({ type: "text", field, text: text2, generated, sourcePath: sourcePath ?? (!generated ? partPath : void 0), extras, partPath, style: resolveTextStyle({ fontFamily, fontWeight: 400, italic: false, path: partPath }, options.textMeasurement) });
5375
5474
  };
5376
5475
  const addImage = (source, sourcePath, reference) => {
5377
- const imageHeight = Math.max(32 * scale, Math.min(height * 0.05, 72 * scale)), imageWidth = Math.min(zoneWidth, imageHeight * (intrinsicImageAspect(source, record8(options.presentation).assets) ?? 1));
5476
+ const imageHeight = Math.max(32 * scale2, Math.min(height * 0.05, 72 * scale2)), imageWidth = Math.min(zoneWidth, imageHeight * (intrinsicImageAspect(source, record7(options.presentation).assets) ?? 1));
5378
5477
  pending.push({ type: "image", sourcePath, image: source, ...reference !== void 0 ? { reference } : {}, width: imageWidth, height: imageHeight });
5379
5478
  };
5380
5479
  if (content.image !== void 0) {
@@ -5393,7 +5492,7 @@ function layoutFurniture(input, options = {}) {
5393
5492
  add("text", resolved.text, false, void 0, { fields: resolved.fields });
5394
5493
  } else add("text", content.text);
5395
5494
  if (content.socials === true) {
5396
- const links = Object.entries(record8(organization.socials)).filter(([, value2]) => typeof value2 === "string" && value2.trim()).map(([platform, value2]) => ({ platform, sourcePath: `${organizationRoot}.socials.${platform}`, ...resolveSocialProfile(platform, value2, "organization") }));
5495
+ const links = Object.entries(record7(organization.socials)).filter(([, value2]) => typeof value2 === "string" && value2.trim()).map(([platform, value2]) => ({ platform, sourcePath: `${organizationRoot}.socials.${platform}`, ...resolveSocialProfile(platform, value2, "organization") }));
5397
5496
  if (links.length) add("socials", links.map((link) => link.text).join("\n"), true, `${organizationRoot}.socials`, { links });
5398
5497
  else error(`${path}.socials`, "Generated social profiles need a primary organization with socials.", "unresolved-content");
5399
5498
  }
@@ -5439,16 +5538,16 @@ function layoutFurniture(input, options = {}) {
5439
5538
  const natural = outlines ? placeTextLines(ink, { x: 0, y: 0, width: boxWidth, height: Number.MAX_VALUE }, side, padding) : void 0;
5440
5539
  const partHeight = natural?.height ?? fit.sourceLines.length * fit.lineHeight;
5441
5540
  if (!Number.isFinite(partHeight)) throw new RangeError("Furniture exceeds finite layout coordinates.");
5442
- return { fit, ink, height: Math.max(scale, partHeight) };
5541
+ return { fit, ink, height: Math.max(scale2, partHeight) };
5443
5542
  };
5444
- const gap = FURNITURE_GAP * scale, gaps = gap * Math.max(0, pending.length - 1);
5445
- const widths = pending.map((part) => part.type === "image" ? pending.length > 1 ? Math.min(part.width, zoneWidth * FURNITURE_IMAGE_SHARE) : part.width : pending.length === 1 ? zoneWidth : Math.max(scale, ...fitPart(part, 1e7).ink.map((line2) => Math.max(line2.width + (outlines ? 2 * padding : 0), line2.outline ? line2.outline.width + 2 * padding : 0))));
5543
+ const gap = FURNITURE_GAP * scale2, gaps = gap * Math.max(0, pending.length - 1);
5544
+ const widths = pending.map((part) => part.type === "image" ? pending.length > 1 ? Math.min(part.width, zoneWidth * FURNITURE_IMAGE_SHARE) : part.width : pending.length === 1 ? zoneWidth : Math.max(scale2, ...fitPart(part, 1e7).ink.map((line2) => Math.max(line2.width + (outlines ? 2 * padding : 0), line2.outline ? line2.outline.width + 2 * padding : 0))));
5446
5545
  if (pending.length > 1 && widths.reduce((sum, entry) => sum + entry, 0) + gaps > zoneWidth + 0.01) {
5447
5546
  const texts = pending.map((_, index2) => index2).filter((index2) => pending[index2].type === "text").sort((a, b) => widths[a] - widths[b]);
5448
5547
  let remaining = zoneWidth - gaps - pending.reduce((sum, part, index2) => sum + (part.type === "image" ? widths[index2] : 0), 0), count = texts.length;
5449
- if (remaining < scale * Math.max(1, count)) error(path, `The parts of this zone (${pending.map((part) => part.type === "image" ? "image" : part.field).join(", ")}) are wider side by side than the zone; remove a part or move one to another zone.`);
5548
+ if (remaining < scale2 * Math.max(1, count)) error(path, `The parts of this zone (${pending.map((part) => part.type === "image" ? "image" : part.field).join(", ")}) are wider side by side than the zone; remove a part or move one to another zone.`);
5450
5549
  for (const index2 of texts) {
5451
- const share = Math.max(scale, remaining / count);
5550
+ const share = Math.max(scale2, remaining / count);
5452
5551
  widths[index2] = Math.min(widths[index2], share);
5453
5552
  remaining -= widths[index2];
5454
5553
  count--;
@@ -5568,8 +5667,8 @@ function layoutQuote(value, box, options = {}) {
5568
5667
  }
5569
5668
  const richBody = Array.isArray(quote.text) ? quote.text : void 0;
5570
5669
  const quoteText = richBody ? annotationText(richBody) : quote.text;
5571
- const scale = options.scale ?? 1, minimum = snapFontSizeUp((options.minFontSize ?? 16) * scale);
5572
- if (![box.x, box.y, box.width, box.height, scale, minimum].every(Number.isFinite) || box.width <= 0 || box.height <= 0 || scale <= 0 || minimum <= 0) {
5670
+ const scale2 = options.scale ?? 1, minimum = snapFontSizeUp((options.minFontSize ?? 16) * scale2);
5671
+ if (![box.x, box.y, box.width, box.height, scale2, minimum].every(Number.isFinite) || box.width <= 0 || box.height <= 0 || scale2 <= 0 || minimum <= 0) {
5573
5672
  throw new RangeError("Quote dimensions, scale and minimum font size must be finite and positive.");
5574
5673
  }
5575
5674
  if (options.overflow !== void 0 && !["warn", "error"].includes(options.overflow)) throw new RangeError("Invalid quote overflow policy.");
@@ -5580,7 +5679,7 @@ function layoutQuote(value, box, options = {}) {
5580
5679
  const add = (role, text2, sources, area2, fontSize, fontFamily, fontWeight, partPath, runs) => {
5581
5680
  const requestedStyle = { fontFamily, fontWeight, italic: false, path: partPath };
5582
5681
  const style = resolveTextStyle({ ...requestedStyle }, options.textMeasurement);
5583
- const requestedFontSize = gridFontSize(fontSize * scale, minimum);
5682
+ const requestedFontSize = gridFontSize(fontSize * scale2, minimum);
5584
5683
  const part = { role, path: partPath, text: text2, sources, box: area2, requestedFontSize, minFontSize: minimum, requestedStyle, style, ...runs ? { runs } : {} };
5585
5684
  parts.push(part);
5586
5685
  return part;
@@ -5618,7 +5717,7 @@ function layoutQuote(value, box, options = {}) {
5618
5717
  500,
5619
5718
  path
5620
5719
  ) : void 0;
5621
- const footerRequested = attribution?.requestedFontSize ?? gridFontSize(17 * scale, minimum);
5720
+ const footerRequested = attribution?.requestedFontSize ?? gridFontSize(17 * scale2, minimum);
5622
5721
  const usable2 = (area2) => [area2.x, area2.y, area2.width, area2.height].every(Number.isFinite) && area2.width > 0 && area2.height > 0;
5623
5722
  const fit = (part, area2, size = part.requestedFontSize, floor = minimum) => !usable2(area2) ? void 0 : part.runs ? fitRichText(part.runs, area2, size, floor, { style: part.style, textMeasurement: options.textMeasurement, ...options.citationMarker ? { citationMarker: options.citationMarker } : {}, ...options.direction ? { direction: options.direction } : {} }) : fitText(part.text, area2, size, floor, textWidthMeasurer(part.style, options.textMeasurement), options.direction);
5624
5723
  const heightOf = (fit2) => "richLines" in fit2 ? fit2.height : fit2.lines.length * fit2.lineHeight;
@@ -5650,7 +5749,7 @@ function layoutQuote(value, box, options = {}) {
5650
5749
  const footerFit = attribution && natural && usable2(footerBox) ? { ...natural, overflow: natural.overflow || naturalHeight > footerHeight + 0.01 } : void 0;
5651
5750
  const fitsPhoto = !hasPhoto || diameter <= footerHeight + 0.01 && (!attribution || usable2(textArea));
5652
5751
  const overflow = !bodyFit || bodyFit.overflow || (attribution ? !footerFit || footerFit.overflow : false) || !fitsPhoto;
5653
- const score = (body.requestedFontSize - (bodyFit?.fontSize ?? minimum) + footerRequested - size) / scale;
5752
+ const score = (body.requestedFontSize - (bodyFit?.fontSize ?? minimum) + footerRequested - size) / scale2;
5654
5753
  if (!selected || !overflow && (selected.overflow || score < selected.score) || overflow && selected.overflow) {
5655
5754
  selected = { bodyBox, footerBox, textBox, photoBox, bodyFit, footerFit, score, overflow, photoFits: fitsPhoto };
5656
5755
  }
@@ -5714,9 +5813,9 @@ function layoutMetric(value, box, options = {}) {
5714
5813
  if (!metric || Array.isArray(metric) || !isValue(metric.value) || [metric.label, metric.description, metric.unit].some((field) => field !== void 0 && typeof field !== "string") || metric.delta !== void 0 && !isValue(metric.delta) || metric.trend !== void 0 && !["up", "down", "flat"].includes(metric.trend) || metric.sentiment !== void 0 && !["positive", "negative", "neutral"].includes(metric.sentiment)) {
5715
5814
  throw new TypeError("Metric content requires a finite numeric or string value and schema-valid display metadata.");
5716
5815
  }
5717
- const scale = options.scale ?? 1, minimum = snapFontSizeUp((options.minFontSize ?? 16) * scale);
5718
- const rasterPadding = (options.textRasterPadding ?? 1) * scale, hasOutlines = options.textMeasurement?.outlineBounds !== void 0;
5719
- if (![box.x, box.y, box.width, box.height, box.x + box.width, box.y + box.height, scale, minimum, Math.max(76 * scale, minimum) * 1.22].every(Number.isFinite) || box.width <= 0 || box.height <= 0 || scale <= 0 || minimum <= 0) {
5816
+ const scale2 = options.scale ?? 1, minimum = snapFontSizeUp((options.minFontSize ?? 16) * scale2);
5817
+ const rasterPadding = (options.textRasterPadding ?? 1) * scale2, hasOutlines = options.textMeasurement?.outlineBounds !== void 0;
5818
+ if (![box.x, box.y, box.width, box.height, box.x + box.width, box.y + box.height, scale2, minimum, Math.max(76 * scale2, minimum) * 1.22].every(Number.isFinite) || box.width <= 0 || box.height <= 0 || scale2 <= 0 || minimum <= 0) {
5720
5819
  throw new RangeError("Metric dimensions, scale and minimum font size must be finite and positive.");
5721
5820
  }
5722
5821
  if (!Number.isFinite(rasterPadding) || rasterPadding < 0) throw new RangeError("Metric raster padding must be finite and nonnegative.");
@@ -5728,7 +5827,7 @@ function layoutMetric(value, box, options = {}) {
5728
5827
  const sourceValue = metric[role];
5729
5828
  if (sourceValue === void 0) continue;
5730
5829
  const text2 = String(sourceValue), path = scalar ? sourcePath : `${sourcePath}.${role}`;
5731
- const nominal = role === "value" ? Math.min(76 * scale, box.height * 0.28) : (role === "description" ? 20 : role === "trend" ? 18 : 23) * scale;
5830
+ const nominal = role === "value" ? Math.min(76 * scale2, box.height * 0.28) : (role === "description" ? 20 : role === "trend" ? 18 : 23) * scale2;
5732
5831
  const requestedStyle = { fontFamily: (role === "value" ? options.fontFamilies?.heading : options.fontFamilies?.body) ?? "sans-serif", fontWeight: role === "value" ? 800 : role === "description" ? 400 : 500, italic: false, path };
5733
5832
  const part = {
5734
5833
  role,
@@ -5751,7 +5850,7 @@ function layoutMetric(value, box, options = {}) {
5751
5850
  const alignment = physicalAlignment(requestedAlignment, metricDirection);
5752
5851
  const usable2 = (area2) => [area2.x, area2.y, area2.width, area2.height, area2.x + area2.width, area2.y + area2.height].every(Number.isFinite) && area2.width > 0 && area2.height > 0;
5753
5852
  const occupied = (fit) => fit.placement?.height ?? fit.lines.length * fit.lineHeight;
5754
- const gap = 8 * scale, primaryGap = 12 * scale;
5853
+ const gap = 8 * scale2, primaryGap = 12 * scale2;
5755
5854
  const lineInk = (part, fit) => fit.sourceLines.map((line2, index) => {
5756
5855
  let outline = null;
5757
5856
  for (const segment2 of line2.segments) {
@@ -5785,7 +5884,7 @@ function layoutMetric(value, box, options = {}) {
5785
5884
  const key = JSON.stringify([part.role, size, width]);
5786
5885
  let fit = cache2.get(key);
5787
5886
  if (!fit) {
5788
- fit = fitCodeText(part.text, { ...box, width: hasOutlines ? Math.max(Number.MIN_VALUE, width - 2 * rasterPadding) : width }, size, size, scale, textWidthMeasurer(part.style, options.textMeasurement), options.direction);
5887
+ fit = fitCodeText(part.text, { ...box, width: hasOutlines ? Math.max(Number.MIN_VALUE, width - 2 * rasterPadding) : width }, size, size, scale2, textWidthMeasurer(part.style, options.textMeasurement), options.direction);
5789
5888
  fit = place(part, fit, width);
5790
5889
  if (!Number.isFinite(occupied(fit))) throw new RangeError("Metric text layout exceeds finite coordinates.");
5791
5890
  cache2.set(key, fit);
@@ -5795,16 +5894,16 @@ function layoutMetric(value, box, options = {}) {
5795
5894
  const fitValue = (area2, singleLine) => {
5796
5895
  if (!usable2(area2)) return void 0;
5797
5896
  for (let step = 0; step <= 76; step++) {
5798
- const size = gridFontSize(primary.requestedFontSize - step * scale, minimum);
5897
+ const size = gridFontSize(primary.requestedFontSize - step * scale2, minimum);
5799
5898
  const natural = measure(primary, size, area2.width);
5800
5899
  const fit = { ...natural, overflow: !!natural.placement?.overflow || singleLine && natural.lines.length !== 1 || occupied(natural) > area2.height + 0.01 || natural.sourceLines.some((line2) => line2.width > area2.width + 0.01) };
5801
5900
  if (!fit.overflow || size === minimum) return fit;
5802
5901
  }
5803
5902
  };
5804
5903
  let selected, attempts = 0;
5805
- const reductions = Math.min(23, Math.ceil(Math.max(0, ...metadata.map((part) => (part.requestedFontSize - minimum) / scale))));
5904
+ const reductions = Math.min(23, Math.ceil(Math.max(0, ...metadata.map((part) => (part.requestedFontSize - minimum) / scale2))));
5806
5905
  for (let reduction = 0; reduction <= reductions; reduction++) {
5807
- const measured = new Map(metadata.map((part) => [part, measure(part, gridFontSize(part.requestedFontSize - reduction * scale, minimum), box.width)]));
5906
+ const measured = new Map(metadata.map((part) => [part, measure(part, gridFontSize(part.requestedFontSize - reduction * scale2, minimum), box.width)]));
5808
5907
  const measuredUnit = unit ? measured.get(unit) : void 0;
5809
5908
  const unitWidth = unit && measuredUnit ? naturalWidth(unit, measuredUnit) : 0;
5810
5909
  const unitFit = unit && measuredUnit && unitWidth > 0 ? place(unit, measuredUnit, unitWidth) : measuredUnit;
@@ -5835,7 +5934,7 @@ function layoutMetric(value, box, options = {}) {
5835
5934
  y += height + gap;
5836
5935
  }
5837
5936
  const overflow = !valueFit || valueFit.overflow || arrangement === "inline-unit" && valueFit.lines.length !== 1 || primaryHeight > area2.height + 0.01 || allocations.some(({ box: area3, fit }) => !fit || fit.overflow || !usable2(area3) || area3.y + area3.height > box.y + box.height + 0.01);
5838
- const score = allocations.reduce((sum, { part, fit }) => sum + (part.requestedFontSize - (fit?.fontSize ?? minimum)) / scale, 0);
5937
+ const score = allocations.reduce((sum, { part, fit }) => sum + (part.requestedFontSize - (fit?.fontSize ?? minimum)) / scale2, 0);
5839
5938
  const candidate = { arrangement, allocations, score, overflow };
5840
5939
  if (!selected || !overflow && (selected.overflow || score < selected.score) || overflow && selected.overflow) selected = candidate;
5841
5940
  }
@@ -5887,8 +5986,8 @@ function layoutTimeline(value, box, options = {}) {
5887
5986
  throw new TypeError("Timeline content requires ordered events with string labels and optional string metadata.");
5888
5987
  }
5889
5988
  if (timeline.events.some((event) => event.status !== void 0 && !TIMELINE_STATUS_VALUES.includes(event.status))) throw new TypeError("Timeline event status must be 'done', 'current' or 'planned'.");
5890
- const scale = options.scale ?? 1, minimum = snapFontSizeUp((options.minFontSize ?? 16) * scale), padding = (options.textRasterPadding ?? 1) * scale;
5891
- if (![box.x, box.y, box.width, box.height, scale, minimum, padding].every(Number.isFinite) || box.width <= 0 || box.height <= 0 || scale <= 0 || minimum <= 0 || padding < 0) throw new RangeError("Timeline dimensions, scale and minimum must be positive, with finite nonnegative raster padding.");
5989
+ const scale2 = options.scale ?? 1, minimum = snapFontSizeUp((options.minFontSize ?? 16) * scale2), padding = (options.textRasterPadding ?? 1) * scale2;
5990
+ if (![box.x, box.y, box.width, box.height, scale2, minimum, padding].every(Number.isFinite) || box.width <= 0 || box.height <= 0 || scale2 <= 0 || minimum <= 0 || padding < 0) throw new RangeError("Timeline dimensions, scale and minimum must be positive, with finite nonnegative raster padding.");
5892
5991
  if (options.overflow !== void 0 && !["warn", "error"].includes(options.overflow)) throw new RangeError("Invalid timeline overflow policy.");
5893
5992
  const outlines = options.textMeasurement?.outlineBounds !== void 0, rtl = options.direction === "rtl";
5894
5993
  if (outlines && typeof options.textMeasurement?.outlineBounds !== "function") throw new TypeError("Text outline provider must be a function.");
@@ -5898,7 +5997,7 @@ function layoutTimeline(value, box, options = {}) {
5898
5997
  if (text2 === void 0) return;
5899
5998
  const status = eventIndex === void 0 ? void 0 : timeline.events[eventIndex].status;
5900
5999
  const requestedStyle = { fontFamily: fonts.body, fontWeight: status === "current" && role === "what" ? 700 : weight, italic: false, path: partPath };
5901
- source.push({ role, eventIndex, ...status ? { status } : {}, path: partPath, text: text2, sources: [{ path: partPath, start: 0, end: text2.length }], box: { ...box }, alignment: "center", requestedFontSize: gridFontSize(size * scale, minimum), minFontSize: minimum, requestedStyle, style: resolveTextStyle({ ...requestedStyle }, options.textMeasurement) });
6000
+ source.push({ role, eventIndex, ...status ? { status } : {}, path: partPath, text: text2, sources: [{ path: partPath, start: 0, end: text2.length }], box: { ...box }, alignment: "center", requestedFontSize: gridFontSize(size * scale2, minimum), minFontSize: minimum, requestedStyle, style: resolveTextStyle({ ...requestedStyle }, options.textMeasurement) });
5902
6001
  };
5903
6002
  add("name", timeline.name, `${path}.name`, 24, 700);
5904
6003
  add("description", timeline.description, `${path}.description`, 18, 400);
@@ -5941,7 +6040,7 @@ function layoutTimeline(value, box, options = {}) {
5941
6040
  };
5942
6041
  let selected, attempts = 0;
5943
6042
  let reductionLimit = 0;
5944
- for (const part of source) reductionLimit = Math.max(reductionLimit, (part.requestedFontSize - minimum) / scale);
6043
+ for (const part of source) reductionLimit = Math.max(reductionLimit, (part.requestedFontSize - minimum) / scale2);
5945
6044
  const reductions = Math.min(24, Math.ceil(reductionLimit));
5946
6045
  for (let reduction = 0; reduction <= reductions; reduction++) {
5947
6046
  for (const arrangement of ["alternating", "vertical"]) {
@@ -5953,8 +6052,8 @@ function layoutTimeline(value, box, options = {}) {
5953
6052
  score2 += Math.max(1, excess);
5954
6053
  };
5955
6054
  const place = (part, x, y2, width, alignment) => {
5956
- const measured = measure(part, gridFontSize(part.requestedFontSize - reduction * scale, minimum), Math.max(scale, width), alignment);
5957
- const area2 = { x, y: y2, width: Math.max(scale, width), height: Math.max(scale, measured.height) }, placement = outlines ? placeTextLines(measured.ink, area2, alignment, padding, measured.fit.directions) : void 0;
6055
+ const measured = measure(part, gridFontSize(part.requestedFontSize - reduction * scale2, minimum), Math.max(scale2, width), alignment);
6056
+ const area2 = { x, y: y2, width: Math.max(scale2, width), height: Math.max(scale2, measured.height) }, placement = outlines ? placeTextLines(measured.ink, area2, alignment, padding, measured.fit.directions) : void 0;
5958
6057
  const fit = { ...measured.fit, ...placement ? { placement } : {}, overflow: measured.fit.overflow || !!placement?.overflow };
5959
6058
  const accepted = { ...part, box: area2, alignment, fit };
5960
6059
  parts.push(accepted);
@@ -5966,10 +6065,10 @@ function layoutTimeline(value, box, options = {}) {
5966
6065
  let y = box.y;
5967
6066
  for (const part of metadata) {
5968
6067
  const placed = place(part, box.x, y, box.width, "center");
5969
- y += placed.box.height + 8 * scale;
6068
+ y += placed.box.height + 8 * scale2;
5970
6069
  }
5971
- const available = box.y + box.height - y, count = events.length, radius = Math.min(9 * scale, box.width / Math.max(2, count) / 5, Math.max(scale, available) * 0.04);
5972
- const statusOf = (index) => timeline.events[index].status, ringRadius = radius * TIMELINE_RING_RATIO, strokeWidth = Math.min(2 * scale, radius / 2);
6070
+ const available = box.y + box.height - y, count = events.length, radius = Math.min(9 * scale2, box.width / Math.max(2, count) / 5, Math.max(scale2, available) * 0.04);
6071
+ const statusOf = (index) => timeline.events[index].status, ringRadius = radius * TIMELINE_RING_RATIO, strokeWidth = Math.min(2 * scale2, radius / 2);
5973
6072
  const hasRing = timeline.events.some((event) => event.status === "current");
5974
6073
  const marker = (index, x, y2) => {
5975
6074
  const status = statusOf(index);
@@ -5977,8 +6076,8 @@ function layoutTimeline(value, box, options = {}) {
5977
6076
  };
5978
6077
  if (arrangement === "alternating") {
5979
6078
  const width = box.width / Math.max(2, count), step = (box.width - width) / Math.max(1, count - 1), start = count === 1 ? box.x + box.width / 2 : box.x + width / 2;
5980
- const fieldGap = 4 * scale, clearance = 24 * scale;
5981
- const heights = events.map((fields2) => fields2.reduce((height, part) => height + measure(part, gridFontSize(part.requestedFontSize - reduction * scale, minimum), width, "center").height, 0) + Math.max(0, fields2.length - 1) * fieldGap);
6079
+ const fieldGap = 4 * scale2, clearance = 24 * scale2;
6080
+ const heights = events.map((fields2) => fields2.reduce((height, part) => height + measure(part, gridFontSize(part.requestedFontSize - reduction * scale2, minimum), width, "center").height, 0) + Math.max(0, fields2.length - 1) * fieldGap);
5982
6081
  const markerExtent = hasRing ? ringRadius + strokeWidth / 2 : radius;
5983
6082
  const upper = Math.max(markerExtent, ...heights.filter((_, index) => index % 2 === 0).map((height) => height + clearance));
5984
6083
  const lower = Math.max(markerExtent, ...heights.filter((_, index) => index % 2 === 1).map((height) => height + clearance));
@@ -5996,7 +6095,7 @@ function layoutTimeline(value, box, options = {}) {
5996
6095
  });
5997
6096
  } else {
5998
6097
  const outlined = timeline.events.some((event) => event.status === "planned");
5999
- const lead = hasRing ? ringRadius + strokeWidth / 2 : radius + (outlined ? strokeWidth / 2 : 0), gap = 2 * lead + 12 * scale;
6098
+ const lead = hasRing ? ringRadius + strokeWidth / 2 : radius + (outlined ? strokeWidth / 2 : 0), gap = 2 * lead + 12 * scale2;
6000
6099
  const x = rtl ? box.x + box.width - lead : box.x + lead, textX = rtl ? box.x : box.x + gap, width = box.width - gap;
6001
6100
  events.forEach((fields2, index) => {
6002
6101
  const top = y;
@@ -6005,10 +6104,10 @@ function layoutTimeline(value, box, options = {}) {
6005
6104
  const placed = place(part, textX, y, width, "left");
6006
6105
  first2 ??= placed;
6007
6106
  y += placed.box.height;
6008
- if (fieldIndex < fields2.length - 1) y += 4 * scale;
6107
+ if (fieldIndex < fields2.length - 1) y += 4 * scale2;
6009
6108
  }
6010
6109
  markers.push(marker(index, x, top + Math.min(first2?.box.height ?? 2 * radius, 2 * radius) / 2));
6011
- y += 16 * scale;
6110
+ y += 16 * scale2;
6012
6111
  });
6013
6112
  }
6014
6113
  for (const marker2 of markers) {
@@ -6037,19 +6136,19 @@ function fitSourceText(text2, box, size, minimum, step, measure, prose = false,
6037
6136
  const layout = (fontSize) => {
6038
6137
  const tabWidth = measure(" ", fontSize) * 4;
6039
6138
  if (!Number.isFinite(tabWidth) || text2.includes(" ") && tabWidth <= 0) throw new RangeError("Text tabs require a positive finite measured space advance.");
6040
- const measureLine = (start2, end2, record9 = false) => {
6139
+ const measureLine = (start2, end2, record8 = false) => {
6041
6140
  let x = 0, offset = start2;
6042
6141
  const segments = [];
6043
6142
  for (const [index, segment2] of text2.slice(start2, end2).split(" ").entries()) {
6044
6143
  if (index) {
6045
6144
  const next = (Math.floor(x / tabWidth + 1e-9) + 1) * tabWidth;
6046
- if (record9) segments.push({ kind: "tab", start: offset, end: offset + 1, x, width: next - x });
6145
+ if (record8) segments.push({ kind: "tab", start: offset, end: offset + 1, x, width: next - x });
6047
6146
  x = next;
6048
6147
  offset++;
6049
6148
  }
6050
6149
  if (segment2) {
6051
6150
  const advance = measure(segment2, fontSize);
6052
- if (record9) segments.push({ kind: "text", start: offset, end: offset + segment2.length, x, width: advance });
6151
+ if (record8) segments.push({ kind: "text", start: offset, end: offset + segment2.length, x, width: advance });
6053
6152
  x += advance;
6054
6153
  offset += segment2.length;
6055
6154
  }
@@ -6119,8 +6218,8 @@ function layoutCode(value, box, options = {}) {
6119
6218
  if (!code || Array.isArray(code) || typeof code.source !== "string" || [code.language, code.filename].some((field) => field !== void 0 && typeof field !== "string")) {
6120
6219
  throw new TypeError("Code content must be a string or source object with optional string language/filename.");
6121
6220
  }
6122
- const scale = options.scale ?? 1, minimum = snapFontSizeUp((options.minFontSize ?? 16) * scale);
6123
- if (![box.x, box.y, box.width, box.height, box.x + box.width, box.y + box.height, scale, minimum, Math.max(18 * scale, minimum) * 1.22].every(Number.isFinite) || box.width <= 0 || box.height <= 0 || scale <= 0 || minimum <= 0) {
6221
+ const scale2 = options.scale ?? 1, minimum = snapFontSizeUp((options.minFontSize ?? 16) * scale2);
6222
+ if (![box.x, box.y, box.width, box.height, box.x + box.width, box.y + box.height, scale2, minimum, Math.max(18 * scale2, minimum) * 1.22].every(Number.isFinite) || box.width <= 0 || box.height <= 0 || scale2 <= 0 || minimum <= 0) {
6124
6223
  throw new RangeError("Code dimensions, scale and minimum font size must be finite and positive.");
6125
6224
  }
6126
6225
  if (options.overflow !== void 0 && !["warn", "error"].includes(options.overflow)) throw new RangeError("Invalid code overflow policy.");
@@ -6135,7 +6234,7 @@ function layoutCode(value, box, options = {}) {
6135
6234
  sources: generated ? [] : [{ path: partPath, start: 0, end: text2.length }],
6136
6235
  generated,
6137
6236
  box: { ...inner },
6138
- requestedFontSize: gridFontSize((role === "body" ? 18 : 14) * scale, minimum),
6237
+ requestedFontSize: gridFontSize((role === "body" ? 18 : 14) * scale2, minimum),
6139
6238
  minFontSize: minimum,
6140
6239
  requestedStyle,
6141
6240
  style: resolveTextStyle({ ...requestedStyle }, options.textMeasurement)
@@ -6148,7 +6247,7 @@ function layoutCode(value, box, options = {}) {
6148
6247
  if (!parts.length) add("language", "code", path, true);
6149
6248
  const body = add("body", code.source, shorthand ? path : `${path}.source`), headers = parts.filter((part) => part !== body);
6150
6249
  const usable2 = (area2) => [area2.x, area2.y, area2.width, area2.height].every(Number.isFinite) && area2.width > 0 && area2.height > 0;
6151
- const fit = (part, area2, size = part.requestedFontSize, floor = minimum) => usable2(area2) ? fitCodeText(part.text, area2, size, floor, scale, textWidthMeasurer(part.style, options.textMeasurement)) : void 0;
6250
+ const fit = (part, area2, size = part.requestedFontSize, floor = minimum) => usable2(area2) ? fitCodeText(part.text, area2, size, floor, scale2, textWidthMeasurer(part.style, options.textMeasurement)) : void 0;
6152
6251
  if (usable2(inner)) {
6153
6252
  const combinations = headers.reduce((choices, part) => choices.flatMap((choice) => [.../* @__PURE__ */ new Set([part.requestedFontSize, minimum])].map((size) => [...choice, { part, size }])), [[]]);
6154
6253
  let selected;
@@ -6156,7 +6255,7 @@ function layoutCode(value, box, options = {}) {
6156
6255
  let y = inner.y;
6157
6256
  const allocations = [];
6158
6257
  for (const [index, { part, size }] of combination.entries()) {
6159
- const measured = fitCodeText(part.text, inner, size, size, scale, textWidthMeasurer(part.style, options.textMeasurement));
6258
+ const measured = fitCodeText(part.text, inner, size, size, scale2, textWidthMeasurer(part.style, options.textMeasurement));
6160
6259
  const area3 = { ...inner, y, height: measured.lines.length * measured.lineHeight };
6161
6260
  allocations.push({ part, box: area3, fit: usable2(area3) ? { ...measured, overflow: measured.sourceLines.some((line2) => line2.width > area3.width + 0.01) } : void 0 });
6162
6261
  y += area3.height + (index < headers.length - 1 ? 8 : 12);
@@ -6164,7 +6263,7 @@ function layoutCode(value, box, options = {}) {
6164
6263
  const area2 = { ...inner, y, height: inner.y + inner.height - y };
6165
6264
  allocations.push({ part: body, box: area2, fit: fit(body, area2) });
6166
6265
  const overflow = allocations.some(({ box: box2, fit: fit2 }) => !fit2 || fit2.overflow || !usable2(box2) || box2.y + box2.height > inner.y + inner.height + 0.01);
6167
- const score = allocations.reduce((sum, { part, fit: fit2 }) => sum + (part.requestedFontSize - (fit2?.fontSize ?? minimum)) / scale, 0);
6266
+ const score = allocations.reduce((sum, { part, fit: fit2 }) => sum + (part.requestedFontSize - (fit2?.fontSize ?? minimum)) / scale2, 0);
6168
6267
  if (!selected || !overflow && (selected.overflow || score < selected.score) || overflow && selected.overflow) selected = { allocations, score, overflow };
6169
6268
  }
6170
6269
  if (selected) for (const { part, box: box2, fit: fit2 } of selected.allocations) {
@@ -6413,17 +6512,17 @@ function fitList(input, box, requestedSize = contentNominalSize("items"), minFon
6413
6512
  function contentText(field, value) {
6414
6513
  if (field === "text" || headings.has(field)) return flatten(value);
6415
6514
  if (field === "items" || field === "bullets") return (Array.isArray(value) ? value : [value]).map((item) => {
6416
- const entry = record8(item);
6515
+ const entry = record7(item);
6417
6516
  return `\u2022 ${flatten(item)}${entry.description ? `
6418
6517
  ${flatten(entry.description)}` : ""}`;
6419
6518
  }).join("\n");
6420
- if (field === "code") return flatten(record8(value).source ?? value);
6421
- if (field === "quote") return flatten(record8(value).text ?? value);
6519
+ if (field === "code") return flatten(record7(value).source ?? value);
6520
+ if (field === "quote") return flatten(record7(value).text ?? value);
6422
6521
  return void 0;
6423
6522
  }
6424
6523
  function layoutTable(value, box, options = {}) {
6425
- const scale = options.scale ?? 1, minimum = snapFontSizeUp((options.minFontSize ?? 16) * scale), requested = gridFontSize(contentNominalSize("table") * scale, minimum);
6426
- if (![box.x, box.y, box.width, box.height, scale, minimum].every(Number.isFinite) || box.width <= 0 || box.height <= 0 || scale <= 0 || minimum <= 0) throw new RangeError("Table dimensions, scale and font sizes must be finite and positive.");
6524
+ const scale2 = options.scale ?? 1, minimum = snapFontSizeUp((options.minFontSize ?? 16) * scale2), requested = gridFontSize(contentNominalSize("table") * scale2, minimum);
6525
+ if (![box.x, box.y, box.width, box.height, scale2, minimum].every(Number.isFinite) || box.width <= 0 || box.height <= 0 || scale2 <= 0 || minimum <= 0) throw new RangeError("Table dimensions, scale and font sizes must be finite and positive.");
6427
6526
  const inline = inlineTableData(value, options.presentation);
6428
6527
  const grid = tableGrid(inline, options.path ?? "table");
6429
6528
  if (grid.issues.length) throw new RangeError(`${grid.issues[0].path}: ${grid.issues[0].message}`);
@@ -6441,7 +6540,7 @@ function layoutTable(value, box, options = {}) {
6441
6540
  const columnCount = grid.columnCount, cellWidth = box.width / columnCount;
6442
6541
  const cells = grid.rows.flat().map((cell) => {
6443
6542
  const padding = { top: 8, right: 10, bottom: 4, left: 10, ...cell.style.padding };
6444
- const width = cellWidth * cell.colSpan - (padding.left + padding.right) * scale;
6543
+ const width = cellWidth * cell.colSpan - (padding.left + padding.right) * scale2;
6445
6544
  const style = { fontFamily: options.fontFamily ?? "sans-serif", fontWeight: cell.header || cell.style.bold ? 700 : 400, italic: false, path: cell.valuePath };
6446
6545
  const numericDefault = numeric.has(cell) || (cell.header || Array.isArray(cell.value)) && cell.colSpan === 1 && numericColumns.has(cell.column);
6447
6546
  const alignment = cell.style.align ?? options.alignment ?? (numericDefault ? options.direction === "rtl" ? "left" : "right" : "left");
@@ -6454,15 +6553,15 @@ function layoutTable(value, box, options = {}) {
6454
6553
  return gridFontSize(Math.max(trial, floor), floor);
6455
6554
  };
6456
6555
  const fitCell = (cell, height) => {
6457
- const textBox = { width: Math.max(scale, cell.width), height: Math.max(scale, height) }, size = cellSize(cell);
6556
+ const textBox = { width: Math.max(scale2, cell.width), height: Math.max(scale2, height) }, size = cellSize(cell);
6458
6557
  return Array.isArray(cell.value) ? richTextLayouter(cell.value, textBox, requested, { style: cell.textStyle, ...options.codeFontFamily ? { codeFontFamily: options.codeFontFamily } : {}, textMeasurement: options.textMeasurement, uniformLineHeight: true, direction: options.direction }, minimum)(size) : fitText(flatten(cell.value), textBox, size, size, textWidthMeasurer(resolveTextStyle(cell.textStyle, options.textMeasurement), options.textMeasurement), options.direction);
6459
6558
  };
6460
6559
  const textHeight = (fit) => "height" in fit ? fit.height : fit.lines.length * fit.lineHeight;
6461
6560
  const required = (cell, natural) => {
6462
6561
  const floor = cellMinimum(cell), size = gridFontSize(natural ? Math.max(trial, floor) : floor, floor);
6463
- const textBox = { width: Math.max(scale, cell.width), height: scale };
6562
+ const textBox = { width: Math.max(scale2, cell.width), height: scale2 };
6464
6563
  const fit = Array.isArray(cell.value) ? richTextLayouter(cell.value, textBox, requested, { style: cell.textStyle, ...options.codeFontFamily ? { codeFontFamily: options.codeFontFamily } : {}, textMeasurement: options.textMeasurement, uniformLineHeight: true }, minimum)(size) : fitText(flatten(cell.value), textBox, size, size, textWidthMeasurer(resolveTextStyle(cell.textStyle, options.textMeasurement), options.textMeasurement));
6465
- return textHeight(fit) + (cell.padding.top + cell.padding.bottom) * scale;
6564
+ return textHeight(fit) + (cell.padding.top + cell.padding.bottom) * scale2;
6466
6565
  };
6467
6566
  const place = () => {
6468
6567
  const natural = Array(grid.rowCount).fill(0), needed = Array(grid.rowCount).fill(0);
@@ -6475,7 +6574,7 @@ function layoutTable(value, box, options = {}) {
6475
6574
  const extra = Math.max(0, required(cell, preferredSize) - current) / cell.rowSpan;
6476
6575
  for (let r = cell.row; r < cell.row + cell.rowSpan; r++) heights2[r] += extra;
6477
6576
  }
6478
- const preferred = natural.map((height) => Math.max(54 * scale, height));
6577
+ const preferred = natural.map((height) => Math.max(54 * scale2, height));
6479
6578
  for (let r = 0; r < needed.length; r++) needed[r] = Math.min(preferred[r], needed[r]);
6480
6579
  const sum = (values) => values.reduce((a, b) => a + b, 0);
6481
6580
  const preferredTotal = sum(preferred), naturalTotal = sum(natural), neededTotal = sum(needed);
@@ -6486,30 +6585,30 @@ function layoutTable(value, box, options = {}) {
6486
6585
  const rows3 = heights.map((height, r) => ({ box: { x: box.x, y: ys[r], width: box.width, height }, cells: [] }));
6487
6586
  for (const cell of cells) {
6488
6587
  const cellBox = { x: box.x + (options.direction === "rtl" ? columnCount - cell.column - cell.colSpan : cell.column) * cellWidth, y: ys[cell.row], width: cell.colSpan * cellWidth, height: ys[cell.row + cell.rowSpan] - ys[cell.row] };
6489
- const available = cellBox.height - (cell.padding.top + cell.padding.bottom) * scale;
6588
+ const available = cellBox.height - (cell.padding.top + cell.padding.bottom) * scale2;
6490
6589
  const fit = fitCell(cell, available), height = textHeight(fit);
6491
6590
  const offset = cell.style.verticalAlign === "bottom" ? Math.max(0, available - height) : cell.style.verticalAlign === "middle" ? Math.max(0, (available - height) / 2) : 0;
6492
- const textBox = { x: cellBox.x + cell.padding.left * scale, y: cellBox.y + cell.padding.top * scale + offset, width: Math.max(scale, cell.width), height: Math.max(scale, available - offset) };
6591
+ const textBox = { x: cellBox.x + cell.padding.left * scale2, y: cellBox.y + cell.padding.top * scale2 + offset, width: Math.max(scale2, cell.width), height: Math.max(scale2, available - offset) };
6493
6592
  overflow ||= cell.width <= 0 || available <= 0 || fit.overflow;
6494
6593
  rows3[cell.row].cells.push({ value: cell.value, input: cell.input, path: cell.valuePath, sourcePath: cell.path, style: cell.style, alignment: cell.alignment, row: cell.row, column: cell.column, rowSpan: cell.rowSpan, colSpan: cell.colSpan, header: cell.header, rich: Array.isArray(cell.value), box: cellBox, textBox, textStyle: resolveTextStyle(cell.textStyle, options.textMeasurement), fit, ...fit.directions ? { direction: fit.directions[0] } : {} });
6495
6594
  }
6496
6595
  return { rows: rows3, columnCount, height: sum(heights), overflow };
6497
6596
  };
6498
6597
  for (let step = 0; ; step++) {
6499
- const raw = requested - step * scale, last = step === 64 || raw <= minimum;
6598
+ const raw = requested - step * scale2, last = step === 64 || raw <= minimum;
6500
6599
  trial = last ? snapFontSizeUp(minimum) : gridFontSize(raw, minimum);
6501
6600
  const layout = place();
6502
6601
  if (last || !layout.overflow) return layout;
6503
6602
  }
6504
6603
  }
6505
- function tableOverflows(value, box, scale, settings, options, path) {
6506
- return box.width <= 0 || box.height <= 0 || layoutTable(value, box, { scale, minFontSize: settings.minFontSize, fontFamily: options.fontFamilies?.body, ...options.fontFamilies?.code ? { codeFontFamily: options.fontFamilies.code } : {}, textMeasurement: options.textMeasurement, path, presentation: options.presentation }).overflow;
6604
+ function tableOverflows(value, box, scale2, settings, options, path) {
6605
+ return box.width <= 0 || box.height <= 0 || layoutTable(value, box, { scale: scale2, minFontSize: settings.minFontSize, fontFamily: options.fontFamilies?.body, ...options.fontFamilies?.code ? { codeFontFamily: options.fontFamilies.code } : {}, textMeasurement: options.textMeasurement, path, presentation: options.presentation }).overflow;
6507
6606
  }
6508
6607
  function flatten(value) {
6509
6608
  if (value == null) return "";
6510
6609
  if (typeof value !== "object") return String(value);
6511
6610
  if (Array.isArray(value)) return value.map(flatten).join("");
6512
- const item = record8(value);
6611
+ const item = record7(value);
6513
6612
  return flatten(item.text ?? item.value ?? item.source ?? JSON.stringify(value));
6514
6613
  }
6515
6614
  function regionParts(key) {
@@ -6571,8 +6670,8 @@ function mergeListColumns(columns2) {
6571
6670
  return { ...first, listEntries: fits.flatMap((fit) => fit.listEntries), lines: fits.flatMap((fit) => fit.lines), height: Math.max(...fits.map((fit) => fit.height)), overflow: fits.some((fit) => fit.overflow), ...first.directions ? { directions } : {} };
6572
6671
  }
6573
6672
  function composeLayoutAreas(layout, options = {}) {
6574
- const template = layoutTemplate(layout), source = record8(layout);
6575
- const kept = { ...source, regions: Object.fromEntries(Object.entries(record8(source.regions)).map(([name, value]) => [name, { ...record8(value), empty: "keep" }])) };
6673
+ const template = layoutTemplate(layout), source = record7(layout);
6674
+ const kept = withRegionRules(source, { empty: "keep" });
6576
6675
  const { mirror, bleed = true, placements = [], ...compose } = options;
6577
6676
  const slide = {
6578
6677
  ...template.title ? { title: "Title", subtitle: "Subtitle" } : {},
@@ -6591,21 +6690,21 @@ function composeLayoutAreas(layout, options = {}) {
6591
6690
  return { contentBox: { ...result.contentBox }, areas };
6592
6691
  }
6593
6692
  function composeSlide(input, options = {}) {
6594
- const slide = record8(input), layout = record8(options.layout);
6693
+ const slide = record7(input), layout = record7(options.layout);
6595
6694
  const width = options.width ?? 1280, height = options.height ?? 720;
6596
6695
  if (![width, height].every((value) => Number.isFinite(value) && value > 0)) throw new RangeError("Canvas dimensions must be finite and positive.");
6597
- const scale = Math.min(width, height) / 720;
6696
+ const scale2 = Math.min(width, height) / 720;
6598
6697
  const deckDirection = options.direction ?? resolveSlideDirection(options.presentation, options.slideIndex);
6599
6698
  const rtl = deckDirection === "rtl", textDirection = rtl ? "rtl" : void 0;
6600
6699
  const template = isLayoutTemplate(layout) ? layoutTemplate(layout) : void 0;
6601
6700
  const hints = resolveDesignHints({ slide, layout, theme: { design: options.themeDesign }, presentation: options.presentation, slideIndex: options.slideIndex, deck: { titleAlignment: options.titleAlignment, contentAlignment: options.contentAlignment, contentBox: options.contentBox } });
6602
6701
  const hasCards = hints.contentBox ?? false;
6603
- const composition = { ...record8(layout.composition), ...record8(slide.composition) };
6702
+ const composition = { ...record7(layout.composition), ...record7(slide.composition) };
6604
6703
  assertComposition(composition);
6605
6704
  const padding = (composition.padding ?? 0.08) * Math.min(width, height);
6606
6705
  const gap = (composition.gap ?? 1 / 30) * Math.min(width, height);
6607
- const minSize = snapFontSizeUp((composition.minFontSize ?? 16) * scale);
6608
- const rasterPadding = (options.textRasterPadding ?? 1) * scale;
6706
+ const minSize = snapFontSizeUp((composition.minFontSize ?? 16) * scale2);
6707
+ const rasterPadding = (options.textRasterPadding ?? 1) * scale2;
6609
6708
  if (!Number.isFinite(rasterPadding) || rasterPadding < 0) throw new RangeError("Text raster padding must be finite and nonnegative.");
6610
6709
  let coverGroup = false;
6611
6710
  const alignmentFor = (field) => (field === "title" || (field === "tag" || coverGroup && field === "subtitle") && hints.sources.contentAlignment !== "slide" ? hints.titleAlignment : hints.contentAlignment) ?? (field === "metric" ? "center" : "left");
@@ -6630,7 +6729,7 @@ function composeSlide(input, options = {}) {
6630
6729
  const richLayout = rich ? richTextLayouter(value, box, size, richOptions(style), minimum) : void 0;
6631
6730
  const measure = textWidthMeasurer(style, options.textMeasurement), floor = snapFontSizeUp(rich ? richMinimum(value, size, minimum) : minimum), start = Math.max(size, floor);
6632
6731
  for (let trial = 0; trial <= 64; trial++) {
6633
- const raw = start - trial * scale, last = trial === 64 || raw <= floor, fontSize = last ? floor : gridFontSize(raw, floor);
6732
+ const raw = start - trial * scale2, last = trial === 64 || raw <= floor, fontSize = last ? floor : gridFontSize(raw, floor);
6634
6733
  const fit = richLayout ? richLayout(fontSize) : fitText(text2, box, fontSize, fontSize, measure, textDirection);
6635
6734
  const richLines = "richLines" in fit ? fit.richLines : void 0;
6636
6735
  const lines = richLines ? richLines.map((line2) => {
@@ -6676,18 +6775,18 @@ function composeSlide(input, options = {}) {
6676
6775
  const fitContent = (field, value, text2, box, size, minimum, path2, numbering) => field === "text" ? fitPlacedText(field, value, text2, box, size, minimum, path2) : field === "items" || field === "bullets" ? fitList(value, box, size, minimum, { ...richOptions(styleFor(field, path2)), ...numbering !== void 0 ? { numbering } : bulletImage ? { bulletImage } : {} }) : fitText(text2, box, size, minimum, widthFor(field, path2), field === "code" ? void 0 : textDirection);
6677
6776
  const path = `slides.${options.slideIndex ?? 0}`;
6678
6777
  const annotationFit = (value, box, requestedSize, minFontSize, fitPath, alignment) => fitPlacedText("text", value, annotationText(value), box, requestedSize, minFontSize, fitPath, alignment);
6679
- const annotationOptions = { scale, minFontSize: minSize, fit: annotationFit, textStyle: (fitPath) => styleFor("text", fitPath) };
6778
+ const annotationOptions = { scale: scale2, minFontSize: minSize, fit: annotationFit, textStyle: (fitPath) => styleFor("text", fitPath) };
6680
6779
  const imageDiagnostics = [];
6681
6780
  const mirrorSide = (side) => !rtl ? side : side === "left" ? "right" : side === "right" ? "left" : side;
6682
6781
  const backgroundImage = resolveBackgroundImage(slide, options.presentation, options.themeBackground, width, height, path, mirrorSide, imageDiagnostics);
6683
6782
  const regions = Object.keys(slide).filter((key) => regionParts(key)).sort();
6684
- const assets = record8(options.presentation).assets;
6685
- const imageContext = (placement) => ({ fit: hints.imageFit, scale, mirrorSide, diagnostics: imageDiagnostics, assets, ...placement ? { placement } : {} });
6783
+ const assets = record7(options.presentation).assets;
6784
+ const imageContext = (placement) => ({ fit: hints.imageFit, scale: scale2, mirrorSide, diagnostics: imageDiagnostics, assets, ...placement ? { placement } : {} });
6686
6785
  const area2 = { left: 0, top: 0, right: width, bottom: height };
6687
- const topImages = regions.length ? [] : Array.isArray(slide.blocks) ? slide.blocks.flatMap((block, index) => !Array.isArray(record8(block).blocks) && record8(block).image !== void 0 ? [{ host: record8(block), hostPath: `${path}.blocks.${index}`, block: index }] : []) : slide.image !== void 0 ? [{ host: { type: "image", image: slide.image }, hostPath: path }] : [];
6786
+ const topImages = regions.length ? [] : Array.isArray(slide.blocks) ? slide.blocks.flatMap((block, index) => !Array.isArray(record7(block).blocks) && record7(block).image !== void 0 ? [{ host: record7(block), hostPath: `${path}.blocks.${index}`, block: index }] : []) : slide.image !== void 0 ? [{ host: { type: "image", image: slide.image }, hostPath: path }] : [];
6688
6787
  const placed = [], usedEdges = /* @__PURE__ */ new Set();
6689
6788
  topImages.forEach((node) => {
6690
- const own3 = node.block !== void 0 && node.host.placement !== void 0 ? record8(node.host.placement) : void 0;
6789
+ const own3 = node.block !== void 0 && node.host.placement !== void 0 ? record7(node.host.placement) : void 0;
6691
6790
  const value = own3;
6692
6791
  if (!value || !IMAGE_EDGES2.includes(value.edge)) return;
6693
6792
  const edge = mirrorSide(value.edge);
@@ -6714,7 +6813,7 @@ function composeSlide(input, options = {}) {
6714
6813
  const headingTop = Math.max(area2.top + padding, furniture?.headerBottom ? furniture.headerBottom + gap * 0.5 : padding);
6715
6814
  let footnotes;
6716
6815
  if (citations) {
6717
- footnotes = layoutFootnotes(citations, { ...annotationOptions, x: area2.left + padding, width: area2.right - area2.left - padding * 2, bottom: bodyBottom, maxHeight: Math.max(minSize * 1.22 + 2 * scale, (bodyBottom - headingTop) * FOOTNOTE_MAX_RATIO), path });
6816
+ footnotes = layoutFootnotes(citations, { ...annotationOptions, x: area2.left + padding, width: area2.right - area2.left - padding * 2, bottom: bodyBottom, maxHeight: Math.max(minSize * 1.22 + 2 * scale2, (bodyBottom - headingTop) * FOOTNOTE_MAX_RATIO), path });
6718
6817
  diagnostics.push(...footnotes.diagnostics);
6719
6818
  bodyBottom = footnotes.box.y - gap * 0.5;
6720
6819
  }
@@ -6722,7 +6821,7 @@ function composeSlide(input, options = {}) {
6722
6821
  const emptyPayload = (value) => value === void 0 || value === null || value === "" || Array.isArray(value) && value.length === 0;
6723
6822
  const emptyHost = (host) => emptyPayload(host.blocks) && fields.every((field) => emptyPayload(host[field]));
6724
6823
  const flowBlocks = Array.isArray(slide.blocks) ? slide.blocks.filter((_, index) => !placedBlocks.has(index)) : slide.blocks;
6725
- const hasBodyPayload = regions.some((key) => !emptyHost(record8(slide[key]))) || !emptyPayload(flowBlocks) || fields.some((field) => !(placedRoot && field === "image") && !emptyPayload(slide[field]));
6824
+ const hasBodyPayload = regions.some((key) => !emptyHost(record7(slide[key]))) || !emptyPayload(flowBlocks) || fields.some((field) => !(placedRoot && field === "image") && !emptyPayload(slide[field]));
6726
6825
  const useTemplate = template !== void 0 && !regions.length;
6727
6826
  const isCover = !hasBodyPayload && (useTemplate || !hasLayoutRecord);
6728
6827
  coverGroup = isCover;
@@ -6730,8 +6829,8 @@ function composeSlide(input, options = {}) {
6730
6829
  if (isCover && options[LAYOUT_MASTER] !== true) {
6731
6830
  const resolved = resolveLogo(options.presentation, slide, { shape: "full", onDark: options.darkBackground, slideIndex: options.slideIndex });
6732
6831
  if (resolved) {
6733
- const logoHeight = 56 * scale;
6734
- const logoWidth = Math.max(scale, Math.min(4 * logoHeight, area2.right - area2.left - 2 * padding));
6832
+ const logoHeight = 56 * scale2;
6833
+ const logoWidth = Math.max(scale2, Math.min(4 * logoHeight, area2.right - area2.left - 2 * padding));
6735
6834
  const box = { x: round2(rtl ? area2.right - padding - logoWidth : area2.left + padding), y: round2(headingTop), width: round2(logoWidth), height: round2(logoHeight) };
6736
6835
  logo = { box, shape: resolved.shape, path: resolved.path, source: resolved.source, variant: resolved.variant, reference: resolved.reference, anchor: rtl ? "right" : "left" };
6737
6836
  }
@@ -6740,7 +6839,7 @@ function composeSlide(input, options = {}) {
6740
6839
  const headingItems = [];
6741
6840
  for (const field of useTemplate ? [] : ["tag", "title", "subtitle"]) {
6742
6841
  if (!slide[field] || Array.isArray(slide[field]) && !annotationText(slide[field])) continue;
6743
- const requested = (field === "title" ? 54 : field === "tag" ? 16 : 25) * scale;
6842
+ const requested = (field === "title" ? 54 : field === "tag" ? 16 : 25) * scale2;
6744
6843
  const maxHeight = Math.max(height * (field === "title" ? 0.26 : field === "subtitle" ? 0.12 : 0.045), minSize * 1.22 + 2 * rasterPadding);
6745
6844
  const box = { x: area2.left + padding, y, width: area2.right - area2.left - padding * 2, height: maxHeight };
6746
6845
  const text2 = fitPlacedText(field, slide[field], annotationText(slide[field]), box, requested, minSize, `${path}.${field}`);
@@ -6764,7 +6863,7 @@ function composeSlide(input, options = {}) {
6764
6863
  }
6765
6864
  for (const entry of placed) {
6766
6865
  const { host, hostPath, region, placement } = entry;
6767
- let frameArea = placement.inset ? { x: region.x + padding, y: region.y + padding, width: Math.max(scale, region.width - 2 * padding), height: Math.max(scale, region.height - 2 * padding) } : { ...region };
6866
+ let frameArea = placement.inset ? { x: region.x + padding, y: region.y + padding, width: Math.max(scale2, region.width - 2 * padding), height: Math.max(scale2, region.height - 2 * padding) } : { ...region };
6768
6867
  const caption = host.caption !== void 0 && entry.block !== void 0 ? layoutCaption(host.caption, roundBox(frameArea), `${hostPath}.caption`, annotationOptions) : void 0;
6769
6868
  if (caption) {
6770
6869
  frameArea = caption.mediaBox;
@@ -6786,11 +6885,11 @@ function composeSlide(input, options = {}) {
6786
6885
  ...caption ? { caption } : {}
6787
6886
  });
6788
6887
  }
6789
- const contentBox = { x: area2.left + padding, y, width: area2.right - area2.left - padding * 2, height: Math.max(scale, bodyBottom - y) };
6888
+ const contentBox = { x: area2.left + padding, y, width: area2.right - area2.left - padding * 2, height: Math.max(scale2, bodyBottom - y) };
6790
6889
  const collect = (host, basePath, depth = 0, ancestors = []) => {
6791
6890
  if (Array.isArray(host.blocks)) {
6792
6891
  if (depth >= MAX_COMPOSITION_DEPTH || ancestors.includes(host)) throw new RangeError(`Content groups must be acyclic and nest at most ${MAX_COMPOSITION_DEPTH} levels.`);
6793
- const settings = record8(host.composition);
6892
+ const settings = record7(host.composition);
6794
6893
  assertComposition(settings);
6795
6894
  return [{
6796
6895
  field: "blocks",
@@ -6799,7 +6898,7 @@ function composeSlide(input, options = {}) {
6799
6898
  path: basePath,
6800
6899
  payload: host,
6801
6900
  composition: settings,
6802
- children: host.blocks.flatMap((block, index) => collect(record8(block), `${basePath}.blocks.${index}`, depth + 1, [...ancestors, host]))
6901
+ children: host.blocks.flatMap((block, index) => collect(record7(block), `${basePath}.blocks.${index}`, depth + 1, [...ancestors, host]))
6803
6902
  }];
6804
6903
  }
6805
6904
  const captioned = host.caption !== void 0 ? fields.filter((field) => host[field] !== void 0 && CAPTIONABLE_FIELDS.includes(field)) : [];
@@ -6815,7 +6914,7 @@ function composeSlide(input, options = {}) {
6815
6914
  }));
6816
6915
  };
6817
6916
  const regionsInReadingOrder = visualReadingOrder(regions.map((key) => ({ key, box: regionBox(regionParts(key), contentBox, gap) }))).map((entry) => entry.key);
6818
- const pending = regions.length ? regionsInReadingOrder.flatMap((key) => collect(record8(slide[key]), `${path}.${key}`).map((item) => ({ ...item, region: regionParts(key) }))) : Array.isArray(slide.blocks) ? slide.blocks.flatMap((block, index) => placedBlocks.has(index) ? [] : collect(record8(block), `${path}.blocks.${index}`)) : collect(placedRoot ? { ...slide, image: void 0 } : slide, path);
6917
+ const pending = regions.length ? regionsInReadingOrder.flatMap((key) => collect(record7(slide[key]), `${path}.${key}`).map((item) => ({ ...item, region: regionParts(key) }))) : Array.isArray(slide.blocks) ? slide.blocks.flatMap((block, index) => placedBlocks.has(index) ? [] : collect(record7(block), `${path}.blocks.${index}`)) : collect(placedRoot ? { ...slide, image: void 0 } : slide, path);
6819
6918
  const groups = [], flows = [];
6820
6919
  const decisions = options.explain ? [] : void 0;
6821
6920
  const inheritedSettings = (parent, own3 = {}) => ({
@@ -6830,13 +6929,13 @@ function composeSlide(input, options = {}) {
6830
6929
  const acceptedBox = (box) => ({ x: round2(box.x), y: round2(box.y), width: round2(box.width), height: round2(box.height) });
6831
6930
  const payloadBox = (box, cards = hasCards) => {
6832
6931
  if (!cards) return box;
6833
- const frame = acceptedBox(box), padding2 = Math.min(12 * scale, frame.width / 4, frame.height / 4);
6932
+ const frame = acceptedBox(box), padding2 = Math.min(12 * scale2, frame.width / 4, frame.height / 4);
6834
6933
  return acceptedBox({ x: frame.x + padding2, y: frame.y + padding2, width: frame.width - 2 * padding2, height: frame.height - 2 * padding2 });
6835
6934
  };
6836
6935
  const measureQuote = (node, box, settings) => layoutQuote(node.value, acceptedBox(box), {
6837
6936
  fontFamilies: options.fontFamilies,
6838
6937
  textMeasurement: options.textMeasurement,
6839
- scale,
6938
+ scale: scale2,
6840
6939
  minFontSize: settings.minFontSize,
6841
6940
  path: node.path,
6842
6941
  direction: textDirection,
@@ -6845,14 +6944,14 @@ function composeSlide(input, options = {}) {
6845
6944
  const measureCode = (node, box, settings) => layoutCode(node.value, acceptedBox(box), {
6846
6945
  fontFamilies: options.fontFamilies,
6847
6946
  textMeasurement: options.textMeasurement,
6848
- scale,
6947
+ scale: scale2,
6849
6948
  minFontSize: settings.minFontSize,
6850
6949
  path: node.path
6851
6950
  });
6852
6951
  const measureMetric = (node, box, settings) => layoutMetric(node.value, acceptedBox(box), {
6853
6952
  fontFamilies: options.fontFamilies,
6854
6953
  textMeasurement: options.textMeasurement,
6855
- scale,
6954
+ scale: scale2,
6856
6955
  minFontSize: settings.minFontSize,
6857
6956
  path: node.path,
6858
6957
  textRasterPadding: options.textRasterPadding,
@@ -6862,7 +6961,7 @@ function composeSlide(input, options = {}) {
6862
6961
  const measureTimeline = (node, box, settings) => layoutTimeline(node.value, acceptedBox(box), {
6863
6962
  fontFamilies: options.fontFamilies,
6864
6963
  textMeasurement: options.textMeasurement,
6865
- scale,
6964
+ scale: scale2,
6866
6965
  minFontSize: settings.minFontSize,
6867
6966
  path: node.path,
6868
6967
  textRasterPadding: options.textRasterPadding,
@@ -6881,26 +6980,26 @@ function composeSlide(input, options = {}) {
6881
6980
  }
6882
6981
  if (node.field === "quote" || node.field === "code" || node.field === "metric" || node.field === "timeline") {
6883
6982
  const internal = node.field === "quote" ? measureQuote(node, box, settings) : node.field === "code" ? measureCode(node, box, settings) : node.field === "metric" ? measureMetric(node, box, settings) : measureTimeline(node, box, settings);
6884
- const reduction = internal.parts.reduce((sum, part) => sum + (part.fit ? (part.requestedFontSize - part.fit.fontSize) / scale : 0), 0);
6983
+ const reduction = internal.parts.reduce((sum, part) => sum + (part.fit ? (part.requestedFontSize - part.fit.fontSize) / scale2 : 0), 0);
6885
6984
  score += reduction + (internal.overflow ? 1e3 : 0);
6886
6985
  if (penalties) {
6887
6986
  penalties.fontReduction += reduction;
6888
6987
  penalties.textOverflow += internal.overflow ? 1e3 : 0;
6889
6988
  }
6890
6989
  } else if (text2) {
6891
- const fit = fitContent(node.field, node.value, text2, box, contentNominalSize(node.field) * scale, snapFontSizeUp((settings.minFontSize ?? 16) * scale), node.path, node.payload.numbering);
6892
- const reduction = Math.max(0, snapFontSizeDown(contentNominalSize(node.field) * scale) - fit.fontSize) / scale;
6990
+ const fit = fitContent(node.field, node.value, text2, box, contentNominalSize(node.field) * scale2, snapFontSizeUp((settings.minFontSize ?? 16) * scale2), node.path, node.payload.numbering);
6991
+ const reduction = Math.max(0, snapFontSizeDown(contentNominalSize(node.field) * scale2) - fit.fontSize) / scale2;
6893
6992
  score += reduction + (fit.overflow ? 1e3 : 0);
6894
6993
  if (penalties) {
6895
6994
  penalties.fontReduction += reduction;
6896
6995
  penalties.textOverflow += fit.overflow ? 1e3 : 0;
6897
6996
  }
6898
6997
  }
6899
- if (node.field === "table" && tableOverflows(node.value, box, scale, settings, options, node.path)) {
6998
+ if (node.field === "table" && tableOverflows(node.value, box, scale2, settings, options, node.path)) {
6900
6999
  score += 1e3;
6901
7000
  if (penalties) penalties.tableOverflow += 1e3;
6902
7001
  }
6903
- if (box.width < 100 * scale || box.height < 60 * scale) {
7002
+ if (box.width < 100 * scale2 || box.height < 60 * scale2) {
6904
7003
  score += 100;
6905
7004
  if (penalties) penalties.smallCells += 100;
6906
7005
  }
@@ -6959,7 +7058,7 @@ function composeSlide(input, options = {}) {
6959
7058
  let regionTag, templateCell = false;
6960
7059
  const composeChart = (node, box, settings) => {
6961
7060
  const resolved = resolveChartData(node.value, options.presentation, { path: node.path });
6962
- const valueAxis = chartValueAxis(node.value, resolved, { width: box.width, height: box.height, scale, minFontSize: settings.minFontSize });
7061
+ const valueAxis = chartValueAxis(node.value, resolved, { width: box.width, height: box.height, scale: scale2, minFontSize: settings.minFontSize });
6963
7062
  return valueAxis ? { valueAxis } : void 0;
6964
7063
  };
6965
7064
  const placeNode = (node, box, settings, cards = hasCards, listColumns, metricReferenceHeight) => {
@@ -6984,7 +7083,7 @@ function composeSlide(input, options = {}) {
6984
7083
  const timelineLayout = node.field === "timeline" ? measureTimeline(node, box, settings) : void 0;
6985
7084
  const internal = quoteLayout ?? codeLayout ?? metricLayout ?? timelineLayout, body = internal?.parts.find((part) => part.role === "body" || part.role === "value");
6986
7085
  const columns2 = textValue !== void 0 && !internal ? listColumnsFor(node, box, settings, listColumns) : void 0;
6987
- const text2 = internal ? body?.fit : columns2 ? columns2.length > 1 ? mergeListColumns(columns2) : columns2[0].text : textValue !== void 0 ? fitContent(node.field, node.value, textValue, box, contentNominalSize(node.field) * scale, snapFontSizeUp((settings.minFontSize ?? 16) * scale), node.path, node.payload.numbering) : void 0;
7086
+ const text2 = internal ? body?.fit : columns2 ? columns2.length > 1 ? mergeListColumns(columns2) : columns2[0].text : textValue !== void 0 ? fitContent(node.field, node.value, textValue, box, contentNominalSize(node.field) * scale2, snapFontSizeUp((settings.minFontSize ?? 16) * scale2), node.path, node.payload.numbering) : void 0;
6988
7087
  const image = node.field === "image" ? composeImage(node.host ?? {}, node.hostPath ?? node.path, box, box, imageContext()) : void 0;
6989
7088
  const chart = node.field === "chart" ? composeChart(node, box, settings) : void 0;
6990
7089
  items.push({
@@ -7010,7 +7109,7 @@ function composeSlide(input, options = {}) {
7010
7109
  ...regionTag !== void 0 ? { region: regionTag } : {},
7011
7110
  ...columns2 && columns2.length > 1 ? { listColumns: columns2 } : {}
7012
7111
  });
7013
- if (box.width < 100 * scale || !templateCell && box.height < 60 * scale) diagnostics.push({ code: "small-cell", path: node.path, message: "Content cell is too small for comfortable reading; use fewer blocks or a different composition." });
7112
+ if (box.width < 100 * scale2 || !templateCell && box.height < 60 * scale2) diagnostics.push({ code: "small-cell", path: node.path, message: "Content cell is too small for comfortable reading; use fewer blocks or a different composition." });
7014
7113
  };
7015
7114
  const listColumnsFor = (node, box, settings, regionMode) => {
7016
7115
  if (node.field !== "items" && node.field !== "bullets") return void 0;
@@ -7019,7 +7118,7 @@ function composeSlide(input, options = {}) {
7019
7118
  const own3 = node.payload.columns;
7020
7119
  const mode = own3 === "auto" || own3 === 1 || own3 === 2 || own3 === 3 ? own3 : regionMode;
7021
7120
  if (mode === void 0 || mode === 1) return void 0;
7022
- const start = contentNominalSize(node.field) * scale, floor = snapFontSizeUp((settings.minFontSize ?? 16) * scale);
7121
+ const start = contentNominalSize(node.field) * scale2, floor = snapFontSizeUp((settings.minFontSize ?? 16) * scale2);
7023
7122
  const numbering = node.payload.numbering;
7024
7123
  const listOptions = { ...richOptions(styleFor(node.field, node.path)), ...numbering !== void 0 ? { numbering } : bulletImage ? { bulletImage } : {} };
7025
7124
  const columnGap = (count2) => Math.min(gap, box.width / (count2 * 2));
@@ -7057,13 +7156,13 @@ function composeSlide(input, options = {}) {
7057
7156
  const size = Math.min(...shrunk.map((column) => column.text.fontSize));
7058
7157
  return shrunk.map((column) => ({ ...column, text: renumber(fitList(chunk(column.start, column.end), column.box, size, size, listOptions), column.start) }));
7059
7158
  };
7060
- const LONG_LINES = 6, LONG_CODE_LINES = 12, startSize = 25 * scale;
7159
+ const LONG_LINES = 6, LONG_CODE_LINES = 12, startSize = 25 * scale2;
7061
7160
  const estimatedLines = (value, cellWidth, size) => flatten(value).split("\n").reduce((sum, paragraph) => sum + Math.max(1, wrapText(paragraph, Math.max(1, cellWidth), size).length), 0);
7062
7161
  const isLong = (node, cellWidth) => {
7063
7162
  if (node.children) return node.children.some((child) => isLong(child, cellWidth));
7064
7163
  if (node.field === "text") return estimatedLines(node.value, cellWidth, startSize) > LONG_LINES;
7065
7164
  if (node.field === "items" || node.field === "bullets") {
7066
- const listSize = contentNominalSize(node.field) * scale;
7165
+ const listSize = contentNominalSize(node.field) * scale2;
7067
7166
  let lines = 0;
7068
7167
  for (const entry of Array.isArray(node.value) ? node.value : []) {
7069
7168
  const object2 = entry !== null && typeof entry === "object" && !Array.isArray(entry) ? entry : void 0;
@@ -7073,31 +7172,31 @@ function composeSlide(input, options = {}) {
7073
7172
  }
7074
7173
  return lines > LONG_LINES;
7075
7174
  }
7076
- if (node.field === "quote") return estimatedLines(typeof node.value === "string" ? node.value : record8(node.value).text, cellWidth, startSize) > LONG_LINES;
7175
+ if (node.field === "quote") return estimatedLines(typeof node.value === "string" ? node.value : record7(node.value).text, cellWidth, startSize) > LONG_LINES;
7077
7176
  if (node.field === "table") {
7078
- const value = record8(node.value);
7177
+ const value = record7(node.value);
7079
7178
  return (Array.isArray(value.rows) ? value.rows.length + (Array.isArray(value.columns) ? 1 : 0) : 0) > LONG_LINES;
7080
7179
  }
7081
- if (node.field === "code") return String(typeof node.value === "string" ? node.value : record8(node.value).source ?? "").split("\n").length > LONG_CODE_LINES;
7180
+ if (node.field === "code") return String(typeof node.value === "string" ? node.value : record7(node.value).source ?? "").split("\n").length > LONG_CODE_LINES;
7082
7181
  return false;
7083
7182
  };
7084
7183
  const naturalHeight = (node, cellWidth, cards, metricReferenceHeight, naturalSettings = composition) => {
7085
- const pad = cards ? 2 * Math.min(12 * scale, cellWidth / 4) : 0, inner = Math.max(scale, cellWidth - pad);
7184
+ const pad = cards ? 2 * Math.min(12 * scale2, cellWidth / 4) : 0, inner = Math.max(scale2, cellWidth - pad);
7086
7185
  if (node.children) return node.children.reduce((sum, child) => sum + naturalHeight(child, cellWidth, false), 0) + gap * Math.max(0, node.children.length - 1) + pad;
7087
7186
  let content;
7088
7187
  if (node.field === "text" || node.field === "items" || node.field === "bullets") {
7089
- const size = contentNominalSize(node.field) * scale;
7188
+ const size = contentNominalSize(node.field) * scale2;
7090
7189
  const fit = fitContent(node.field, node.value, contentText(node.field, node.value) ?? "", { x: 0, y: 0, width: inner, height: 1e6 }, size, size, node.path, node.payload.numbering);
7091
7190
  content = "height" in fit && typeof fit.height === "number" ? fit.height : fit.lines.length * fit.lineHeight;
7092
7191
  } else if (node.field === "quote") content = measureQuote(node, { x: 0, y: 0, width: inner, height: 1e6 }, naturalSettings).bounds.height + 18;
7093
- else if (node.field === "code") content = String(typeof node.value === "string" ? node.value : record8(node.value).source ?? "").split("\n").length * 18 * 1.4 * scale + 24 * scale;
7094
- else if (node.field === "metric") content = measureMetric(node, { x: 0, y: 0, width: inner, height: metricReferenceHeight === void 0 ? 1e6 : Math.max(scale, metricReferenceHeight - pad) }, naturalSettings).bounds.height;
7095
- else if (node.field === "timeline") content = 170 * scale;
7192
+ else if (node.field === "code") content = String(typeof node.value === "string" ? node.value : record7(node.value).source ?? "").split("\n").length * 18 * 1.4 * scale2 + 24 * scale2;
7193
+ else if (node.field === "metric") content = measureMetric(node, { x: 0, y: 0, width: inner, height: metricReferenceHeight === void 0 ? 1e6 : Math.max(scale2, metricReferenceHeight - pad) }, naturalSettings).bounds.height;
7194
+ else if (node.field === "timeline") content = 170 * scale2;
7096
7195
  else if (node.field === "table") {
7097
- const value = record8(node.value);
7098
- content = ((Array.isArray(value.rows) ? value.rows.length : 4) + 1) * 36 * scale;
7196
+ const value = record7(node.value);
7197
+ content = ((Array.isArray(value.rows) ? value.rows.length : 4) + 1) * 36 * scale2;
7099
7198
  } else content = inner / 1.6;
7100
- return content + (node.caption !== void 0 ? 32 * scale : 0) + pad;
7199
+ return content + (node.caption !== void 0 ? 32 * scale2 : 0) + pad;
7101
7200
  };
7102
7201
  const templateRegions = [], headingAreas = [];
7103
7202
  const requestedTemplateGap = gap;
@@ -7106,7 +7205,7 @@ function composeSlide(input, options = {}) {
7106
7205
  const binding = bindRegions(slide, layout, { slideIndex: options.slideIndex ?? 0 });
7107
7206
  for (const entry of binding.diagnostics) diagnostics.push({ code: entry.code, path: entry.path, message: entry.message, ...entry.region !== void 0 ? { region: entry.region } : {} });
7108
7207
  const unitOf = (bound) => {
7109
- const host = bound.block !== void 0 ? record8(slide.blocks[bound.block]) : { ...Object.fromEntries((bound.fields ?? []).map((field) => [field, slide[field]])), ...Object.fromEntries(["type", "caption", "numbering"].filter((key) => slide[key] !== void 0).map((key) => [key, slide[key]])) };
7208
+ const host = bound.block !== void 0 ? record7(slide.blocks[bound.block]) : { ...Object.fromEntries((bound.fields ?? []).map((field) => [field, slide[field]])), ...Object.fromEntries(["type", "caption", "numbering"].filter((key) => slide[key] !== void 0).map((key) => [key, slide[key]])) };
7110
7209
  const parts = collect(host, bound.block !== void 0 ? `${path}.blocks.${bound.block}` : path);
7111
7210
  return parts.length === 1 ? parts[0] : { field: "blocks", type: "group", value: parts.map((part) => part.payload), path: bound.path, payload: {}, children: parts, composition: { mode: "column" }, synthetic: true };
7112
7211
  };
@@ -7149,7 +7248,7 @@ function composeSlide(input, options = {}) {
7149
7248
  const list = [];
7150
7249
  let top = y2;
7151
7250
  for (const field of fields2) {
7152
- const requested = (field === "title" ? 54 : field === "tag" ? 16 : 25) * scale;
7251
+ const requested = (field === "title" ? 54 : field === "tag" ? 16 : 25) * scale2;
7153
7252
  const maxHeight = Math.max(height * (field === "title" ? 0.26 : field === "subtitle" ? 0.12 : 0.045), minSize * 1.22 + 2 * rasterPadding);
7154
7253
  const box = { x, y: top, width: areaWidth, height: maxHeight };
7155
7254
  const text2 = fitPlacedText(field, slide[field], annotationText(slide[field]), box, requested, minSize, `${path}.${field}`);
@@ -7167,12 +7266,12 @@ function composeSlide(input, options = {}) {
7167
7266
  if (flow === "grid") return "grid";
7168
7267
  const shape = gridFlowShape(units.length, cell.width >= cell.height);
7169
7268
  const cards = hasCards && !region.bleed;
7170
- const cellWidth = (cell.width - gap2 * (shape.columns - 1)) / shape.columns - (cards ? 2 * Math.min(12 * scale, cell.width / 4) : 0);
7269
+ const cellWidth = (cell.width - gap2 * (shape.columns - 1)) / shape.columns - (cards ? 2 * Math.min(12 * scale2, cell.width / 4) : 0);
7171
7270
  return units.some((unit) => isLong(unit, cellWidth)) ? "column" : "grid";
7172
7271
  };
7173
7272
  const regionNeed = (name, areaWidth) => {
7174
7273
  const units = unitsOf(name), region = name === BELOW ? belowRegion : regionOf.get(name);
7175
- if (!units.length) return region.empty === "keep" ? 2 * startSize * 1.22 + (hasCards && !region.bleed ? 2 * Math.min(12 * scale, areaWidth / 4) : 0) : 0;
7274
+ if (!units.length) return region.empty === "keep" ? 2 * startSize * 1.22 + (hasCards && !region.bleed ? 2 * Math.min(12 * scale2, areaWidth / 4) : 0) : 0;
7176
7275
  const shape = flowShape(arrangementOf(region, units, { width: areaWidth, height: areaWidth / 4 }), units.length, true);
7177
7276
  const cellWidth = (areaWidth - gap2 * (shape.columns - 1)) / shape.columns, cards = hasCards && !region.bleed;
7178
7277
  let total = 0, index = 0;
@@ -7247,12 +7346,12 @@ function composeSlide(input, options = {}) {
7247
7346
  };
7248
7347
  placeHeadings("title", titleFields);
7249
7348
  if (plan2.subtitle) placeHeadings("subtitle", subtitleFields);
7250
- const slideComposition = record8(slide.composition);
7349
+ const slideComposition = record7(slide.composition);
7251
7350
  const overridden = ["mode", "columns", "weights"].some((key) => slideComposition[key] !== void 0) ? plan2.regions.find((region) => region.role === "primary" && region.flow !== "none")?.name : void 0;
7252
7351
  const settings = { ...composition };
7253
7352
  const placeRegion = (region, units, area3) => {
7254
7353
  regionTag = region.name === BELOW ? void 0 : region.name;
7255
- const cell = { ...area3, width: Math.max(scale, area3.width), height: Math.max(scale, area3.height) };
7354
+ const cell = { ...area3, width: Math.max(scale2, area3.width), height: Math.max(scale2, area3.height) };
7256
7355
  templateCell = true;
7257
7356
  try {
7258
7357
  const cards = hasCards && !region.bleed;
@@ -7264,7 +7363,7 @@ function composeSlide(input, options = {}) {
7264
7363
  let boxes = flowCells(flowShape(arrangement, units.length, cell.width >= cell.height), cell, gap2).cells;
7265
7364
  const referenceHeights = boxes.map((box) => box.height);
7266
7365
  if (arrangement === "column" && region.anchor !== "top" && units.every((unit) => !unit.children && (unit.field === "text" || unit.field === "items" || unit.field === "bullets" || !unit.caption && (unit.field === "quote" || unit.field === "metric")))) {
7267
- const naturals = units.map((unit, index) => naturalHeight(unit, cell.width, cards, referenceHeights[index], settings) + 2 * rasterPadding + scale);
7366
+ const naturals = units.map((unit, index) => naturalHeight(unit, cell.width, cards, referenceHeights[index], settings) + 2 * rasterPadding + scale2);
7268
7367
  const used = naturals.reduce((a, b) => a + b, 0) + gap2 * (units.length - 1);
7269
7368
  if (used < cell.height) {
7270
7369
  let y2 = cell.y + (region.anchor === "middle" ? (cell.height - used) / 2 : cell.height - used);
@@ -7278,7 +7377,7 @@ function composeSlide(input, options = {}) {
7278
7377
  if ((arrangement === "grid" || arrangement === "row") && region.anchor !== "top") {
7279
7378
  const naturals = boxes.map((box, index) => {
7280
7379
  const unit = units[index];
7281
- return unit.children || unit.caption || !["text", "items", "bullets", "quote", "metric"].includes(unit.field) ? void 0 : naturalHeight(unit, box.width, cards, referenceHeights[index], settings) + 2 * rasterPadding + scale;
7380
+ return unit.children || unit.caption || !["text", "items", "bullets", "quote", "metric"].includes(unit.field) ? void 0 : naturalHeight(unit, box.width, cards, referenceHeights[index], settings) + 2 * rasterPadding + scale2;
7282
7381
  });
7283
7382
  boxes = boxes.map((box, index) => {
7284
7383
  const height2 = naturals[index];
@@ -7323,7 +7422,7 @@ function composeSlide(input, options = {}) {
7323
7422
  }
7324
7423
  if (belowUnits.length) placeRegion(belowRegion, belowUnits, physical(logical(rects.get(BELOW))));
7325
7424
  };
7326
- const ownMode = record8(slide.composition).mode;
7425
+ const ownMode = record7(slide.composition).mode;
7327
7426
  const direction = hints.contentDirection;
7328
7427
  const directionMode = direction === "vertical" ? "column" : direction === "horizontal" ? "row" : "auto";
7329
7428
  const chartHint = hints.chartPrimary;
@@ -7344,7 +7443,7 @@ function composeSlide(input, options = {}) {
7344
7443
  const numberingDiagnostics = [];
7345
7444
  for (const item of items) {
7346
7445
  for (const key of ["x", "y", "width", "height"]) item.box[key] = round2(item.box[key]);
7347
- if (item.field === "table" && tableOverflows(item.value, item.box, scale, item.composition, options, item.path)) diagnostics.push({ code: "text-overflow", path: item.path, message: "Table cells do not fit; use fewer rows, fewer columns, or split the table across slides." });
7446
+ if (item.field === "table" && tableOverflows(item.value, item.box, scale2, item.composition, options, item.path)) diagnostics.push({ code: "text-overflow", path: item.path, message: "Table cells do not fit; use fewer rows, fewer columns, or split the table across slides." });
7348
7447
  if (item.quoteLayout) diagnostics.push(...item.quoteLayout.diagnostics);
7349
7448
  else if (item.codeLayout) diagnostics.push(...item.codeLayout.diagnostics);
7350
7449
  else if (item.metricLayout) diagnostics.push(...item.metricLayout.diagnostics);
@@ -7392,7 +7491,7 @@ function resolveCanvasDimensions(input) {
7392
7491
  letter: [11, 8.5],
7393
7492
  a4: [11.69, 8.27]
7394
7493
  };
7395
- const value = record8(input);
7494
+ const value = record7(input);
7396
7495
  const preset = presets[typeof input === "string" ? input : value.preset] ?? presets.widescreen;
7397
7496
  const width = (value.widthInches ?? preset[0]) * 96;
7398
7497
  const height = (value.heightInches ?? preset[1]) * 96;
@@ -7400,4 +7499,4 @@ function resolveCanvasDimensions(input) {
7400
7499
  return { width, height };
7401
7500
  }
7402
7501
 
7403
- export { AUTO_LAYOUT, CAPTIONABLE_FIELDS, CAPTION_FONT_RATIO, CAPTION_MAX_RATIO, CATALOG_GROUP_PATTERN, CATALOG_REFERENCE_PATTERN, CHART_HIGHLIGHT_MUTED_MIN_CONTRAST, CHART_HIGHLIGHT_MUTED_MIX, CHART_SERIES_MIN_DIFFERENCE, CHART_SERIES_MIN_LIGHTNESS_STEP, CHART_SERIES_TIER_SIZE, CHART_SERIES_TINT_MIX, CHART_TEXT_PX, CHART_TYPES, CITATION_MARKER_RAISE, CITATION_MARKER_SCALE, CODE_HIGHLIGHT_LANGUAGES, CODE_HIGHLIGHT_MAX_LENGTH, CODE_PANEL_BACKGROUND, CODE_PANEL_FOREGROUND, CODE_SYNTAX_MIN_CONTRAST, DARK_BACKGROUND_LUMINANCE, DEFAULT_CHART_LABEL_SEPARATOR, DEFAULT_FURNITURE_DATE_FORMAT, DEFAULT_VARIABLE_DATE_FORMAT, DESIGN_HINT_KEYS, ENGINE_DEFAULT_CHART_TYPES, ENGINE_DEFAULT_COLOR_SCHEME, ENGINE_DEFAULT_FONT_SCHEME, ENGINE_DEFAULT_THEME, FONT_SIZE_GRID_PER_PX, FOOTNOTE_MAX_RATIO, FURNITURE_GAP, FURNITURE_IMAGE_SHARE, FURNITURE_ZONE_GUTTER, HEADING_AREAS, LANGUAGES, LAYOUT_BODY_KINDS, LOGO_SHAPES, MAX_COMPOSITION_DEPTH, MAX_NUMBERING_LEVELS, MAX_NUMBERING_VALUE, MAX_REGION_BLOCKS, MAX_ROMAN_VALUE, MAX_TEMPLATE_TRACKS, METRIC_TREND_MIN_CONTRAST, METRIC_TREND_SHAPES, NEUTRAL_SHARES, NUMBERING_STYLES, NUMBERING_SUFFIXES, OPFCatalogsOptionError, OPFCompositionError, OPFLayoutTemplateError, OPFUnresolvedReferenceError, OPFVariableError, PATTERN_PRESETS, PATTERN_PRESET_ALIASES, PATTERN_TILE_SIZE, PICTURE_BULLET_SCALE, PROMOTED_REGION_KEY, REGION_ANCHORS, REGION_FLOWS, REGION_KINDS, REGION_ROLES, RESERVED_REGION_NAMES, SLIDE_SCOPED_BUILTINS, SOCIAL_PLATFORMS, SURFACE_ALT_MIN_CONTRAST, SURFACE_ALT_MIX, THEME_DESIGN_KEYS, TIMELINE_OUTLINE_MIN_CONTRAST, TIMELINE_STATUSES, TIMELINE_TEXT_MIN_CONTRAST, VARIABLE_KINDS, allocateRows, annotationText, applyLuminance, bindRegions, blockKind, captionSettings, catalogGroupDeclared, catalogGroupSource, catalogKinds, catalogRecords, catalogReferenceSites, chartColorForFill, chartHighlightColors, chartHighlightMarks, chartLabelText, chartNumber, chartNumberFixesByCell, chartOptionSupport, chartOptionTarget, chartPaletteForFill, chartSeriesPalette, chartTextSize, chartValueAxis, checkCatalogsOption, citationMarkerText, clrMapAttributes, codeHighlightBands, codeHighlightColors, codeHighlightLines, codeHighlightSlice, codeLineNumbers, codeLineRuns, codeSyntaxPalette, codeSyntaxPaletteForRoles, codeSyntaxPaletteForScheme, coerceVariableValue, collectCitations, colorContrast, colorMapFor, composeLayoutAreas, composeSlide, datasetDiagnostics, defaultSlideBackground, dottedPath, embeddedCopy, fitImage, fitList, fitRichText, fitText, formatChartLabelNumber, formatChartLabelPercent, formatDataNumber, formatFurnitureDate, formatListNumber, formatVariableNumber, fromExcelNumberFormat, gridFlowShape, hasContentVariables, imageBackground, imageShape, inlineChartData, inlineDatasets, inlineTableData, instantiateForValidation, intrinsicImageAspect, intrinsicImageSize, isColorVariant, isDarkColor, isDatasetRef, isLayoutTemplate, isRecord, isTemplate, isXYChartType, layoutCaption, layoutCode, layoutContent, layoutFootnotes, layoutFurniture, layoutMetric, layoutQuote, layoutRegion, layoutStructure, layoutTable, layoutTemplate, layoutTemplateIssues, layoutTimeline, layoutWatermark, listBuiltinVariables, listColumnBreaks, listNumbers, listVariables, maxIntervalsFor, measureText, measureTextOutline, metricTrendColor, metricTrendMark, metricTrendPoints, niceScale, normalizeColorVariant, normalizeHexColor, normalizeLanguageFamily, numberFormatError, numberingAtLevel, numberingFindings, numberingStyleDraws, paragraphDirection, paragraphDirectionAt, parseReference, pathFor, patternBitmap, patternRuns, physicalAlignment, placeTextLines, placedImageBlocks, pointerPath, promotedRegionKeys, provenanceOf, readableSchemeColor, readingRows, recordReferenceSites, referencesSlide, regionAccepts, regionRoleRank, registeredCatalog, resolveCanvasDimensions, resolveChartColors, resolveChartData, resolveChartOptions, resolveCodeLanguage, resolveColorRef, resolveColorRoles, resolveDesignHints, resolveDesignRecords, resolveFontFamilies, resolveFontScheme, resolveLogo, resolveNumbering, resolvePatternPreset, resolveReference, resolveScriptFonts, resolveSlideDirection, resolveSlideVariables, resolveSocialProfile, resolveTableData, resolveTextStyle, resolveVariables, rootNodes, scriptFontRole, sliceNumberedItems, slideCitations, slideTokenSpans, snapFontSizeDown, snapFontSizeUp, stackCategoryValues, suggestChartNumberFix, surfaceAltColor, tableCellDisplayValue, tableGrid, tableRowBoundaries, textColorForFill, textWidthMeasurer, timelineMarkerShapes, timelineTextColor, toExcelNumberFormat, tokenizeCode, unresolvedReference, unusedDatasets, usesSlideBuiltin, variableDeclarations, visitContentPayloads, visualReadingOrder, walkCitationRuns, wrapText };
7502
+ export { AUTO_LAYOUT, CAPTIONABLE_FIELDS, CAPTION_FONT_RATIO, CAPTION_MAX_RATIO, CATALOG_GROUP_PATTERN, CATALOG_REFERENCE_PATTERN, CHART_HIGHLIGHT_MUTED_MIN_CONTRAST, CHART_HIGHLIGHT_MUTED_MIX, CHART_SERIES_MIN_DIFFERENCE, CHART_SERIES_MIN_LIGHTNESS_STEP, CHART_SERIES_TIER_SIZE, CHART_SERIES_TINT_MIX, CHART_TEXT_PX, CHART_TYPES, CITATION_MARKER_RAISE, CITATION_MARKER_SCALE, CODE_HIGHLIGHT_LANGUAGES, CODE_HIGHLIGHT_MAX_LENGTH, CODE_PANEL_BACKGROUND, CODE_PANEL_FOREGROUND, CODE_SYNTAX_MIN_CONTRAST, DARK_BACKGROUND_LUMINANCE, DEFAULT_CHART_LABEL_SEPARATOR, DEFAULT_FURNITURE_DATE_FORMAT, DEFAULT_VARIABLE_DATE_FORMAT, DESIGN_HINT_KEYS, ENGINE_DEFAULT_CHART_TYPES, ENGINE_DEFAULT_COLOR_SCHEME, ENGINE_DEFAULT_FONT_SCHEME, ENGINE_DEFAULT_THEME, FONT_SIZE_GRID_PER_PX, FOOTNOTE_MAX_RATIO, FURNITURE_GAP, FURNITURE_IMAGE_SHARE, FURNITURE_ZONE_GUTTER, HEADING_AREAS, LANGUAGES, LAYOUT_BODY_KINDS, LOGO_SHAPES, MAX_COMPOSITION_DEPTH, MAX_NUMBERING_LEVELS, MAX_NUMBERING_VALUE, MAX_REGION_BLOCKS, MAX_REGION_DEPTH, MAX_REGION_ENTRIES, MAX_ROMAN_VALUE, MAX_TEMPLATE_TRACKS, METRIC_TREND_MIN_CONTRAST, METRIC_TREND_SHAPES, NEUTRAL_SHARES, NUMBERING_STYLES, NUMBERING_SUFFIXES, OPFCatalogsOptionError, OPFCompositionError, OPFLayoutTemplateError, OPFUnresolvedReferenceError, OPFVariableError, PATTERN_PRESETS, PATTERN_PRESET_ALIASES, PATTERN_TILE_SIZE, PICTURE_BULLET_SCALE, PROMOTED_REGION_KEY, REGION_ANCHORS, REGION_FLOWS, REGION_KINDS, REGION_ROLES, RESERVED_REGION_NAMES, SLIDE_SCOPED_BUILTINS, SOCIAL_PLATFORMS, SURFACE_ALT_MIN_CONTRAST, SURFACE_ALT_MIX, THEME_DESIGN_KEYS, TIMELINE_OUTLINE_MIN_CONTRAST, TIMELINE_STATUSES, TIMELINE_TEXT_MIN_CONTRAST, VARIABLE_KINDS, allocateRows, annotationText, applyLuminance, bindRegions, blockKind, captionSettings, catalogGroupDeclared, catalogGroupSource, catalogKinds, catalogRecords, catalogReferenceSites, chartColorForFill, chartHighlightColors, chartHighlightMarks, chartLabelText, chartNumber, chartNumberFixesByCell, chartOptionSupport, chartOptionTarget, chartPaletteForFill, chartSeriesPalette, chartTextSize, chartValueAxis, checkCatalogsOption, citationMarkerText, clrMapAttributes, codeHighlightBands, codeHighlightColors, codeHighlightLines, codeHighlightSlice, codeLineNumbers, codeLineRuns, codeSyntaxPalette, codeSyntaxPaletteForRoles, codeSyntaxPaletteForScheme, coerceVariableValue, collectCitations, colorContrast, colorMapFor, composeLayoutAreas, composeSlide, datasetDiagnostics, defaultSlideBackground, dottedPath, embeddedCopy, fitImage, fitList, fitRichText, fitText, formatChartLabelNumber, formatChartLabelPercent, formatDataNumber, formatFurnitureDate, formatListNumber, formatVariableNumber, fromExcelNumberFormat, gridFlowShape, hasContentVariables, imageBackground, imageShape, inlineChartData, inlineDatasets, inlineTableData, instantiateForValidation, intrinsicImageAspect, intrinsicImageSize, isColorVariant, isDarkColor, isDatasetRef, isLayoutTemplate, isRecord, isTemplate, isXYChartType, layoutCaption, layoutCode, layoutContent, layoutEntries, layoutFootnotes, layoutFurniture, layoutMetric, layoutQuote, layoutRegion, layoutStructure, layoutTable, layoutTemplate, layoutTemplateIssues, layoutTimeline, layoutWatermark, listBuiltinVariables, listColumnBreaks, listNumbers, listVariables, maxIntervalsFor, measureText, measureTextOutline, metricTrendColor, metricTrendMark, metricTrendPoints, niceScale, normalizeColorVariant, normalizeHexColor, normalizeLanguageFamily, numberFormatError, numberingAtLevel, numberingFindings, numberingStyleDraws, paragraphDirection, paragraphDirectionAt, parseReference, pathFor, patternBitmap, patternRuns, physicalAlignment, placeTextLines, placedImageBlocks, pointerPath, promotedRegionKeys, provenanceOf, readableSchemeColor, readingRows, recordReferenceSites, referencesSlide, regionAccepts, regionRoleRank, registeredCatalog, resolveCanvasDimensions, resolveChartColors, resolveChartData, resolveChartOptions, resolveCodeLanguage, resolveColorRef, resolveColorRoles, resolveDesignHints, resolveDesignRecords, resolveFontFamilies, resolveFontScheme, resolveLogo, resolveNumbering, resolvePatternPreset, resolveReference, resolveScriptFonts, resolveSlideDirection, resolveSlideVariables, resolveSocialProfile, resolveTableData, resolveTextStyle, resolveVariables, rootNodes, scriptFontRole, sliceNumberedItems, slideCitations, slideTokenSpans, snapFontSizeDown, snapFontSizeUp, stackCategoryValues, suggestChartNumberFix, surfaceAltColor, tableCellDisplayValue, tableGrid, tableRowBoundaries, textColorForFill, textWidthMeasurer, timelineMarkerShapes, timelineTextColor, toExcelNumberFormat, tokenizeCode, unresolvedReference, unusedDatasets, usesSlideBuiltin, variableDeclarations, visitContentPayloads, visualReadingOrder, walkCitationRuns, wrapText };