@openpresentation/opf 0.27.0 → 0.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.js +18 -18
- package/dist/{catalog-refs-BSfGELpt.d.ts → catalog-refs-kAefsZWT.d.ts} +2 -1
- package/dist/{catalog-schemas-DoxA2BgY.d.ts → catalog-schemas-CC1d_h8s.d.ts} +3 -2
- package/dist/{chart-data-BnNqgnC-.d.ts → chart-data-Ci9s_NDN.d.ts} +2 -1
- package/dist/{chunk-EO3JWEO5.js → chunk-5OMZW44K.js} +1 -1
- package/dist/{chunk-4ZM5G3XX.js → chunk-5Q4IYLMW.js} +30 -14
- package/dist/{chunk-WJ4XTCOD.js → chunk-7UO6H32I.js} +3 -3
- package/dist/{chunk-4ACS57MG.js → chunk-ARFAQNOH.js} +2 -2
- package/dist/{chunk-GNKESMZT.js → chunk-F5QC7E2O.js} +6 -6
- package/dist/{chunk-SYW4BCGZ.js → chunk-HRKV43GC.js} +2 -2
- package/dist/{chunk-TMREBZBQ.js → chunk-I6G32TB5.js} +3 -3
- package/dist/{chunk-O3SA5SJ4.js → chunk-KELC4K62.js} +1 -1
- package/dist/{chunk-ABFDFZIW.js → chunk-KOCXV7H3.js} +1 -1
- package/dist/{chunk-PAGVSTVF.js → chunk-M7YZU3DX.js} +149 -26
- package/dist/{chunk-JSHMFTSY.js → chunk-P5E3FNYO.js} +1 -1
- package/dist/{chunk-ZGTOZA2S.js → chunk-R455YZNO.js} +6 -6
- package/dist/{chunk-OSM3LZ2Y.js → chunk-SYCHWS7C.js} +4 -4
- package/dist/{chunk-353VBJ6K.js → chunk-UKWNHK62.js} +5 -5
- package/dist/{chunk-LRTQXGJO.js → chunk-W3SEWSO5.js} +543 -94
- package/dist/{chunk-CXPBU5W4.js → chunk-W7KPMUJF.js} +1 -1
- package/dist/{chunk-APLNGCEZ.js → chunk-WHDOOLIO.js} +2 -2
- package/dist/{chunk-KZPZRHL6.js → chunk-XG4JKFZ6.js} +6 -6
- package/dist/{chunk-7XUEKIXH.js → chunk-Z7XNHIW7.js} +2 -2
- package/dist/chunk-ZROVYWGU.js +1 -0
- package/dist/{composition-BGmpe5e4.d.ts → composition-C-hd_Ci3.d.ts} +84 -10
- package/dist/composition.d.ts +3 -3
- package/dist/composition.js +1 -1
- package/dist/{conversion-8SQD4dqu.d.ts → conversion-CCAmVKp8.d.ts} +9 -8
- package/dist/conversion-KV2WWCMK.js +24 -0
- package/dist/convert.d.ts +6 -5
- package/dist/convert.js +7 -7
- package/dist/data.d.ts +4 -3
- package/dist/data.js +2 -2
- package/dist/{deck-report-BaKgPh_N.d.ts → deck-report-DQMsvyBI.d.ts} +5 -4
- package/dist/deck.d.ts +10 -9
- package/dist/deck.js +11 -11
- package/dist/diff.d.ts +3 -2
- package/dist/diff.js +4 -4
- package/dist/docs.d.ts +2 -1
- package/dist/docs.js +29 -17
- package/dist/examples.d.ts +3 -2
- package/dist/examples.js +90 -50
- package/dist/{explain-JSuESV-Y.d.ts → explain-iZeNOUc6.d.ts} +2 -1
- package/dist/{finding-Bh56sGtF.d.ts → finding-l9dlQ2NF.d.ts} +1 -1
- package/dist/font-policy.d.ts +2 -1
- package/dist/format.d.ts +2 -1
- package/dist/format.js +2 -2
- package/dist/ids.d.ts +3 -2
- package/dist/ids.js +4 -4
- package/dist/index.d.ts +38 -17
- package/dist/index.js +22 -22
- package/dist/markdown.d.ts +8 -7
- package/dist/markdown.js +8 -8
- package/dist/node-engine.d.ts +34 -11
- package/dist/node-engine.js +35 -29
- package/dist/{pagination-BsUTsQvk.d.ts → pagination-DyAKYpXu.d.ts} +4 -3
- package/dist/pagination.d.ts +4 -4
- package/dist/pagination.js +4 -4
- package/dist/patch.d.ts +4 -2
- package/dist/patch.js +3 -3
- package/dist/precompiled.d.ts +1 -1
- package/dist/precompiled.js +2 -2
- package/dist/{presentation-C-nHZyMw.d.ts → presentation-8jLSTFqL.d.ts} +10 -10
- package/dist/repo-readme.js +1 -1
- package/dist/schema-engine-ajv.js +1 -1
- package/dist/schema-engine-precompiled.js +2 -2
- package/dist/schema.d.ts +4 -3
- package/dist/schema.js +3 -3
- package/dist/schemas.d.ts +2 -1
- package/dist/schemas.js +1 -1
- package/dist/source.d.ts +5 -4
- package/dist/source.js +10 -10
- package/dist/spec/README.md +1 -1
- package/dist/spec/schemas/audience.schema.json +1 -0
- package/dist/spec/schemas/catalog-index.schema.json +1 -0
- package/dist/spec/schemas/catalog-manifest.schema.json +1 -0
- package/dist/spec/schemas/chart-type.schema.json +1 -0
- package/dist/spec/schemas/color-scheme.schema.json +1 -0
- package/dist/spec/schemas/finding.schema.json +1 -0
- package/dist/spec/schemas/font-scheme.schema.json +1 -0
- package/dist/spec/schemas/language.schema.json +1 -0
- package/dist/spec/schemas/layout-preview-index.schema.json +1 -0
- package/dist/spec/schemas/layout.schema.json +8 -6
- package/dist/spec/schemas/narrative.schema.json +1 -0
- package/dist/spec/schemas/opf.schema.json +8 -7
- package/dist/spec/schemas/purpose.schema.json +1 -0
- package/dist/spec/schemas/social-platform.schema.json +1 -0
- package/dist/spec/schemas/theme.schema.json +3 -1
- package/dist/spec/schemas/tone.schema.json +1 -0
- package/dist/spec-files.d.ts +2 -1
- package/dist/symbol-font-encodings.d.ts +2 -1
- package/dist/types.d.ts +10 -10
- package/dist/{validation-types-6_jEaHeE.d.ts → validation-types-mNmfcY9A.d.ts} +5 -4
- package/dist/validator.d.ts +8 -8
- package/dist/validator.js +3 -3
- package/dist/yaml.d.ts +8 -7
- package/dist/yaml.js +7 -7
- package/package.json +7 -7
- package/dist/chunk-GJO5NUVT.js +0 -1
- package/dist/conversion-LN6PFRZL.js +0 -24
|
@@ -2068,11 +2068,28 @@ var u32be = (b, i) => (at2(b, i) << 24 | at2(b, i + 1) << 16 | at2(b, i + 2) <<
|
|
|
2068
2068
|
var u16le = (b, i) => at2(b, i) | at2(b, i + 1) << 8;
|
|
2069
2069
|
var u24le = (b, i) => at2(b, i) | at2(b, i + 1) << 8 | at2(b, i + 2) << 16;
|
|
2070
2070
|
var ascii = (b, i, n) => String.fromCharCode(...b.subarray(i, i + n));
|
|
2071
|
+
function exifOrientation(b, start, end) {
|
|
2072
|
+
if (end > b.length || ascii(b, start, 4) !== "Exif" || at2(b, start + 4) !== 0) return void 0;
|
|
2073
|
+
const tiff = start + 6, little = ascii(b, tiff, 2) === "II";
|
|
2074
|
+
if (!little && ascii(b, tiff, 2) !== "MM") return void 0;
|
|
2075
|
+
const u16 = (index) => little ? u16le(b, index) : u16be(b, index);
|
|
2076
|
+
const u32 = (index) => little ? (u16le(b, index) | u16le(b, index + 2) << 16) >>> 0 : u32be(b, index);
|
|
2077
|
+
const directory = tiff + u32(tiff + 4);
|
|
2078
|
+
if (directory + 2 > end) return void 0;
|
|
2079
|
+
for (let entry = 0, count = u16(directory); entry < count && directory + 2 + entry * 12 + 12 <= end; entry++) {
|
|
2080
|
+
const at12 = directory + 2 + entry * 12;
|
|
2081
|
+
if (u16(at12) === 274) {
|
|
2082
|
+
const value = u16(at12 + 8);
|
|
2083
|
+
return value >= 1 && value <= 8 ? value : void 0;
|
|
2084
|
+
}
|
|
2085
|
+
}
|
|
2086
|
+
return void 0;
|
|
2087
|
+
}
|
|
2071
2088
|
function rasterDimensions(b) {
|
|
2072
2089
|
if (b.length >= 24 && u32be(b, 0) === 2303741511 && ascii(b, 12, 4) === "IHDR") return { width: u32be(b, 16), height: u32be(b, 20) };
|
|
2073
2090
|
if (b.length >= 10 && (ascii(b, 0, 6) === "GIF87a" || ascii(b, 0, 6) === "GIF89a")) return { width: u16le(b, 6), height: u16le(b, 8) };
|
|
2074
2091
|
if (b.length >= 4 && b[0] === 255 && b[1] === 216) {
|
|
2075
|
-
let i = 2;
|
|
2092
|
+
let i = 2, orientation = 1;
|
|
2076
2093
|
while (i + 9 < b.length) {
|
|
2077
2094
|
if (at2(b, i) !== 255) {
|
|
2078
2095
|
i++;
|
|
@@ -2087,7 +2104,11 @@ function rasterDimensions(b) {
|
|
|
2087
2104
|
i += 2;
|
|
2088
2105
|
continue;
|
|
2089
2106
|
}
|
|
2090
|
-
if (marker
|
|
2107
|
+
if (marker === 225) orientation = exifOrientation(b, i + 4, i + 2 + u16be(b, i + 2)) ?? orientation;
|
|
2108
|
+
if (marker >= 192 && marker <= 207 && marker !== 196 && marker !== 200 && marker !== 204) {
|
|
2109
|
+
const height = u16be(b, i + 5), width = u16be(b, i + 7);
|
|
2110
|
+
return orientation >= 5 ? { width: height, height: width } : { width, height };
|
|
2111
|
+
}
|
|
2091
2112
|
i += 2 + u16be(b, i + 2);
|
|
2092
2113
|
}
|
|
2093
2114
|
return void 0;
|
|
@@ -2167,7 +2188,7 @@ var VALUES = {
|
|
|
2167
2188
|
contentDirection: ["horizontal", "vertical"],
|
|
2168
2189
|
chartPrimary: ["none", "top", "bottom", "left", "right"],
|
|
2169
2190
|
imageFit: ["cover", "contain", "stretch"],
|
|
2170
|
-
listBullet: ["character", "image"],
|
|
2191
|
+
listBullet: ["character", "image", "none"],
|
|
2171
2192
|
mirror: "boolean"
|
|
2172
2193
|
};
|
|
2173
2194
|
var themeKeys = new Set(THEME_DESIGN_KEYS);
|
|
@@ -2395,6 +2416,8 @@ function parse(layout) {
|
|
|
2395
2416
|
}
|
|
2396
2417
|
};
|
|
2397
2418
|
order(children);
|
|
2419
|
+
const stackAnchor = anchorOf(value.anchor);
|
|
2420
|
+
const stack = direction === "column" && children.length > 0 && children.every((node) => node.size === "auto") && stackAnchor !== void 0 && stackAnchor !== "top" ? stackAnchor : void 0;
|
|
2398
2421
|
const overflowRegion = typeof value.overflowRegion === "string" ? value.overflowRegion : regions.find((entry) => entry.role === "primary" && entry.flow !== "none")?.name;
|
|
2399
2422
|
return {
|
|
2400
2423
|
issues,
|
|
@@ -2406,7 +2429,8 @@ function parse(layout) {
|
|
|
2406
2429
|
regions,
|
|
2407
2430
|
...overflowRegion !== void 0 ? { overflowRegion } : {},
|
|
2408
2431
|
title: names.has("title"),
|
|
2409
|
-
subtitle: names.has("subtitle")
|
|
2432
|
+
subtitle: names.has("subtitle"),
|
|
2433
|
+
...stack ? { stack } : {}
|
|
2410
2434
|
}
|
|
2411
2435
|
};
|
|
2412
2436
|
}
|
|
@@ -2755,19 +2779,32 @@ function listColumnBreaks(heights, levels, count) {
|
|
|
2755
2779
|
return solve(0, count).breaks;
|
|
2756
2780
|
}
|
|
2757
2781
|
function allocateRows(rows3, total, gap) {
|
|
2758
|
-
const auto = rows3.map((row) => row.size === "auto" ? Math.max(0, Math.min(row.need, row.kind === "
|
|
2782
|
+
const auto = rows3.map((row) => row.size === "auto" ? Math.max(0, Math.min(row.need, row.kind === "heading" ? total / 2 : total)) : 0);
|
|
2759
2783
|
const visible = rows3.filter((row, index) => row.size !== "auto" || auto[index] > 0).length;
|
|
2760
2784
|
const headings2 = rows3.reduce((sum, row, index) => sum + (row.kind === "heading" ? auto[index] : 0), 0);
|
|
2761
2785
|
const space = Math.max(0, total - headings2 - Math.max(0, visible - 1) * gap);
|
|
2762
2786
|
const numeric = rows3.reduce((sum, row) => sum + (row.size === "auto" ? 0 : row.size), 0);
|
|
2763
2787
|
const numericNeed = rows3.reduce((sum, row) => sum + (row.size === "auto" ? 0 : Math.max(0, row.need)), 0);
|
|
2764
2788
|
const reserve = numeric > 0 ? Math.min(numericNeed, space / 2) : 0;
|
|
2765
|
-
const
|
|
2766
|
-
const
|
|
2767
|
-
const heights = rows3.map((row, index) => row.size === "auto" ? row.kind === "heading" ? auto[index] :
|
|
2789
|
+
const bodyRows = rows3.flatMap((row, index) => row.size === "auto" && row.kind !== "heading" ? [index] : []);
|
|
2790
|
+
const fitted = shareHeights(bodyRows.map((index) => auto[index]), bodyRows.map((index) => rows3[index].floor ?? 0), Math.max(0, space - reserve));
|
|
2791
|
+
const heights = rows3.map((row, index) => row.size === "auto" ? row.kind === "heading" ? auto[index] : fitted[bodyRows.indexOf(index)] : 0);
|
|
2768
2792
|
const rest = Math.max(0, space - heights.reduce((sum, height, index) => sum + (rows3[index].kind === "heading" ? 0 : height), 0));
|
|
2769
2793
|
return rows3.map((row, index) => row.size === "auto" ? heights[index] : numeric > 0 ? rest * row.size / numeric : 0);
|
|
2770
2794
|
}
|
|
2795
|
+
function shareHeights(needs, floors, total) {
|
|
2796
|
+
const space = Math.max(0, total);
|
|
2797
|
+
const need = needs.map((value) => Number.isFinite(value) ? Math.max(0, value) : 0);
|
|
2798
|
+
const floor = need.map((value, index) => Math.min(value, Math.max(0, Number.isFinite(floors[index]) ? floors[index] : 0)));
|
|
2799
|
+
const sum = (values) => values.reduce((a, b) => a + b, 0);
|
|
2800
|
+
const needed = sum(need), lowest = sum(floor);
|
|
2801
|
+
if (needed <= space) return need;
|
|
2802
|
+
if (lowest < space) {
|
|
2803
|
+
const give = (needed - space) / (needed - lowest);
|
|
2804
|
+
return need.map((value, index) => value - give * (value - floor[index]));
|
|
2805
|
+
}
|
|
2806
|
+
return lowest > 0 ? floor.map((value) => value * space / lowest) : need.map(() => 0);
|
|
2807
|
+
}
|
|
2771
2808
|
|
|
2772
2809
|
// src/direction.ts
|
|
2773
2810
|
var strongRtl = /[\u200F\u061C]|(?=\p{L})[\p{Script=Arabic}\p{Script=Hebrew}\p{Script=Syriac}\p{Script=Thaana}\p{Script=Nko}\p{Script=Adlam}\p{Script=Hanifi_Rohingya}\p{Script=Mandaic}\p{Script=Samaritan}\p{Script=Mende_Kikakui}\p{Script=Imperial_Aramaic}\p{Script=Phoenician}\p{Script=Kharoshthi}\p{Script=Old_South_Arabian}\p{Script=Old_North_Arabian}\p{Script=Avestan}\p{Script=Inscriptional_Parthian}\p{Script=Inscriptional_Pahlavi}\p{Script=Psalter_Pahlavi}\p{Script=Old_Turkic}\p{Script=Old_Hungarian}\p{Script=Nabataean}\p{Script=Palmyrene}\p{Script=Hatran}\p{Script=Manichaean}\p{Script=Sogdian}\p{Script=Old_Sogdian}\p{Script=Elymaic}\p{Script=Chorasmian}\p{Script=Yezidi}\p{Script=Cypriot}\p{Script=Lydian}\p{Script=Meroitic_Cursive}\p{Script=Meroitic_Hieroglyphs}\u{10F70}-\u{10FAF}\u{10D40}-\u{10D8F}]/u;
|
|
@@ -3354,6 +3391,93 @@ function resolveSlideDirection(presentation, slideIndex) {
|
|
|
3354
3391
|
}
|
|
3355
3392
|
}
|
|
3356
3393
|
|
|
3394
|
+
// src/quote-marks.ts
|
|
3395
|
+
var marks = (open, close) => ({ open, close });
|
|
3396
|
+
var ENGLISH = marks("\u201C", "\u201D");
|
|
3397
|
+
var GUILLEMETS = marks("\xAB", "\xBB");
|
|
3398
|
+
var LOW_HIGH = marks("\u201E", "\u201C");
|
|
3399
|
+
var LOW_RIGHT = marks("\u201E", "\u201D");
|
|
3400
|
+
var RIGHT_ONLY = marks("\u201D", "\u201D");
|
|
3401
|
+
var CORNER = marks("\u300C", "\u300D");
|
|
3402
|
+
var REVERSED = marks("\xBB", "\xAB");
|
|
3403
|
+
var QUOTE_MARKS = {
|
|
3404
|
+
en: ENGLISH,
|
|
3405
|
+
es: GUILLEMETS,
|
|
3406
|
+
fr: GUILLEMETS,
|
|
3407
|
+
de: LOW_HIGH,
|
|
3408
|
+
it: GUILLEMETS,
|
|
3409
|
+
pt: ENGLISH,
|
|
3410
|
+
nl: ENGLISH,
|
|
3411
|
+
ca: GUILLEMETS,
|
|
3412
|
+
gl: GUILLEMETS,
|
|
3413
|
+
eu: GUILLEMETS,
|
|
3414
|
+
sv: RIGHT_ONLY,
|
|
3415
|
+
fi: RIGHT_ONLY,
|
|
3416
|
+
da: REVERSED,
|
|
3417
|
+
nb: GUILLEMETS,
|
|
3418
|
+
nn: GUILLEMETS,
|
|
3419
|
+
no: GUILLEMETS,
|
|
3420
|
+
is: LOW_HIGH,
|
|
3421
|
+
pl: LOW_RIGHT,
|
|
3422
|
+
hu: LOW_RIGHT,
|
|
3423
|
+
ro: LOW_RIGHT,
|
|
3424
|
+
cs: LOW_HIGH,
|
|
3425
|
+
sk: LOW_HIGH,
|
|
3426
|
+
sl: LOW_HIGH,
|
|
3427
|
+
hr: LOW_HIGH,
|
|
3428
|
+
sr: LOW_HIGH,
|
|
3429
|
+
bg: LOW_HIGH,
|
|
3430
|
+
lt: LOW_HIGH,
|
|
3431
|
+
lv: LOW_HIGH,
|
|
3432
|
+
et: LOW_HIGH,
|
|
3433
|
+
ru: GUILLEMETS,
|
|
3434
|
+
uk: GUILLEMETS,
|
|
3435
|
+
el: GUILLEMETS,
|
|
3436
|
+
tr: ENGLISH,
|
|
3437
|
+
ga: ENGLISH,
|
|
3438
|
+
cy: ENGLISH,
|
|
3439
|
+
ja: CORNER,
|
|
3440
|
+
zh: ENGLISH,
|
|
3441
|
+
"zh-tw": CORNER,
|
|
3442
|
+
"zh-hk": CORNER,
|
|
3443
|
+
"zh-hant": CORNER,
|
|
3444
|
+
ko: ENGLISH,
|
|
3445
|
+
ar: GUILLEMETS,
|
|
3446
|
+
fa: GUILLEMETS,
|
|
3447
|
+
he: ENGLISH,
|
|
3448
|
+
ur: ENGLISH,
|
|
3449
|
+
hi: ENGLISH,
|
|
3450
|
+
th: ENGLISH,
|
|
3451
|
+
vi: ENGLISH,
|
|
3452
|
+
id: ENGLISH,
|
|
3453
|
+
ms: ENGLISH,
|
|
3454
|
+
"de-ch": GUILLEMETS,
|
|
3455
|
+
"fr-ch": GUILLEMETS,
|
|
3456
|
+
"pt-pt": GUILLEMETS
|
|
3457
|
+
};
|
|
3458
|
+
var ASCII_QUOTE_MARKS = marks('"', '"');
|
|
3459
|
+
function quoteMarksFor(tag) {
|
|
3460
|
+
if (tag === void 0 || tag === "") return ENGLISH;
|
|
3461
|
+
const lower = tag.toLowerCase().replaceAll("_", "-"), primary = lower.split("-")[0];
|
|
3462
|
+
return QUOTE_MARKS[lower] ?? QUOTE_MARKS[primary] ?? ASCII_QUOTE_MARKS;
|
|
3463
|
+
}
|
|
3464
|
+
function quoteLanguage(presentation, slideIndex) {
|
|
3465
|
+
if (presentation === null || typeof presentation !== "object" || presentation.language === void 0) return void 0;
|
|
3466
|
+
try {
|
|
3467
|
+
const resolved = resolveScriptFonts(presentation, Number.isInteger(slideIndex) ? { slideIndex } : {});
|
|
3468
|
+
return resolved.languageSource === "document" ? resolved.bcp47 : void 0;
|
|
3469
|
+
} catch {
|
|
3470
|
+
return void 0;
|
|
3471
|
+
}
|
|
3472
|
+
}
|
|
3473
|
+
var PAIRS = new Set(Object.values(QUOTE_MARKS).concat(ASCII_QUOTE_MARKS).map((entry) => entry.open + entry.close));
|
|
3474
|
+
function isWrappedInQuoteMarks(text2) {
|
|
3475
|
+
return text2.length >= 2 && PAIRS.has(text2[0] + text2.at(-1));
|
|
3476
|
+
}
|
|
3477
|
+
function unwrapQuoteMarks(text2) {
|
|
3478
|
+
return isWrappedInQuoteMarks(text2) ? text2.slice(1, -1) : text2;
|
|
3479
|
+
}
|
|
3480
|
+
|
|
3357
3481
|
// src/numbering.ts
|
|
3358
3482
|
var NUMBERING_STYLES = ["arabic", "roman-upper", "roman-lower", "alpha-upper", "alpha-lower"];
|
|
3359
3483
|
var NUMBERING_SUFFIXES = ["period", "paren", "paren-both"];
|
|
@@ -5340,7 +5464,7 @@ function fitImage(frame, fit, aspect, focus = { x: 0.5, y: 0.5 }) {
|
|
|
5340
5464
|
right: round2((image.x + width - frame.x - frame.width) / width),
|
|
5341
5465
|
bottom: round2((image.y + height - frame.y - frame.height) / height)
|
|
5342
5466
|
};
|
|
5343
|
-
for (const key of ["left", "top", "right", "bottom"]) if (
|
|
5467
|
+
for (const key of ["left", "top", "right", "bottom"]) if (Math.abs(crop[key]) < 1e-9) crop[key] = 0;
|
|
5344
5468
|
return { image: roundBox(image), crop };
|
|
5345
5469
|
}
|
|
5346
5470
|
function imageBackground(value) {
|
|
@@ -5375,17 +5499,29 @@ function composeOverlay(value, frame, shape, path, mirrorSide, diagnostics) {
|
|
|
5375
5499
|
const box = !edge ? frame : edge === "top" ? { ...frame, height: round2(frame.height * part) } : edge === "bottom" ? { ...frame, y: round2(frame.y + frame.height * (1 - part)), height: round2(frame.height * part) } : edge === "left" ? { ...frame, width: round2(frame.width * part) } : { ...frame, x: round2(frame.x + frame.width * (1 - part)), width: round2(frame.width * part) };
|
|
5376
5500
|
return { path, color: overlay.color, opacity, ...edge ? { edge } : {}, box, shape: edge ? imageShape("rectangle", box) : shape };
|
|
5377
5501
|
}
|
|
5502
|
+
function anchoredOffset(spare, anchor) {
|
|
5503
|
+
return Math.max(0, anchor === "middle" ? spare / 2 : anchor === "bottom" ? spare : 0);
|
|
5504
|
+
}
|
|
5505
|
+
function containedBox(cell, aspect, anchor) {
|
|
5506
|
+
const width = Math.min(cell.width, cell.height * aspect), height = width / aspect;
|
|
5507
|
+
return { x: cell.x + (cell.width - width) / 2, y: cell.y + anchoredOffset(cell.height - height, anchor), width, height };
|
|
5508
|
+
}
|
|
5378
5509
|
function composeImage(host, hostPath, region, frameArea, context) {
|
|
5379
5510
|
const kindName = Object.hasOwn(IMAGE_SHAPES, host.shape) ? host.shape : "rectangle";
|
|
5380
5511
|
const { scale: scale2 } = context;
|
|
5512
|
+
const fit = IMAGE_FITS.includes(host.fit) ? host.fit : context.fit ?? "cover";
|
|
5513
|
+
const pictureAspect = intrinsicImageAspect(host.image, context.assets);
|
|
5381
5514
|
let box = { ...frameArea };
|
|
5382
5515
|
const aspect = kindName === "circle" ? 1 : finite(host.aspectRatio, Number.MIN_VALUE, 10);
|
|
5383
5516
|
if (aspect) {
|
|
5384
5517
|
const frameWidth = Math.min(box.width, box.height * aspect), frameHeight = frameWidth / aspect;
|
|
5385
5518
|
box = { x: box.x + (box.width - frameWidth) / 2, y: box.y + (box.height - frameHeight) / 2, width: frameWidth, height: frameHeight };
|
|
5519
|
+
} else if (context.anchor && fit === "contain" && pictureAspect) {
|
|
5520
|
+
const frameWidth = Math.min(box.width, box.height * pictureAspect);
|
|
5521
|
+
box = { x: box.x + (box.width - frameWidth) / 2, y: box.y, width: frameWidth, height: frameWidth / pictureAspect };
|
|
5386
5522
|
}
|
|
5523
|
+
if (context.anchor && fit === "contain" && !aspect && box.height < frameArea.height) box.y = frameArea.y + anchoredOffset(frameArea.height - box.height, context.anchor);
|
|
5387
5524
|
box = roundBox(box);
|
|
5388
|
-
const fit = IMAGE_FITS.includes(host.fit) ? host.fit : context.fit ?? "cover";
|
|
5389
5525
|
const focus = imageFocus(host.focus);
|
|
5390
5526
|
const shape = imageShape(kindName, box, finite(host.cornerRadius, 0, 0.5));
|
|
5391
5527
|
const result = { region: roundBox(region), box, fit, focus, shape };
|
|
@@ -5398,7 +5534,6 @@ function composeImage(host, hostPath, region, frameArea, context) {
|
|
|
5398
5534
|
const overlay = composeOverlay(host.overlay, box, shape, `${hostPath}.overlay`, context.mirrorSide, context.diagnostics);
|
|
5399
5535
|
if (overlay) result.overlay = overlay;
|
|
5400
5536
|
if (context.placement) result.placement = context.placement;
|
|
5401
|
-
const pictureAspect = intrinsicImageAspect(host.image, context.assets);
|
|
5402
5537
|
if (pictureAspect) result.picture = fitImage(box, fit, pictureAspect, focus);
|
|
5403
5538
|
return result;
|
|
5404
5539
|
}
|
|
@@ -5622,7 +5757,72 @@ function layoutFurniture(input, options = {}) {
|
|
|
5622
5757
|
return { algorithm: "furniture-flow-v2", configured, textMeasurement: options.textMeasurement ? "provided" : "estimated", textOutlines: outlines ? "provided" : "unavailable", parts, headerBottom, footerTop, diagnostics, overflow: diagnostics.length > 0 };
|
|
5623
5758
|
}
|
|
5624
5759
|
var textSegments = new Intl.Segmenter("und", { granularity: "grapheme" });
|
|
5760
|
+
var PROSE_NOMINAL_SIZE = 28;
|
|
5761
|
+
var LIST_NOMINAL_SIZE = 32;
|
|
5762
|
+
var LEAD_NOMINAL_SIZE = 32;
|
|
5763
|
+
var TABLE_NOMINAL_SIZE = 25;
|
|
5764
|
+
var QUOTE_NOMINAL_SIZE = 40;
|
|
5765
|
+
var CODE_NOMINAL_SIZE = 22;
|
|
5766
|
+
var LEGACY_CODE_NOMINAL_SIZE = 18;
|
|
5767
|
+
var QUOTE_SOURCE_SEPARATOR = " \u2013 ";
|
|
5768
|
+
var PROSE_MEASURE_CHARS = 70;
|
|
5769
|
+
var AVERAGE_CHARACTER_EM = 0.5;
|
|
5625
5770
|
var WRAP_TOLERANCE = 0.01;
|
|
5771
|
+
var SENTENCE_END = /[.!?\u2026\u3002\uff01\uff1f]["'\u201d\u2019)\]\u00bb]*$/u;
|
|
5772
|
+
var CLAUSE_END = /[,;:\u2013\u2014\u060c\u061b\uff0c\u3001\uff1b\uff1a]["'\u201d\u2019)\]\u00bb]*$/u;
|
|
5773
|
+
var BALANCE_MAX_WORDS = 48;
|
|
5774
|
+
function balancedBreaks(text2, lines, widthOf, boxWidth) {
|
|
5775
|
+
const forced = /* @__PURE__ */ new Set();
|
|
5776
|
+
const paragraph = (group2) => {
|
|
5777
|
+
const count = group2.length;
|
|
5778
|
+
if (count < 2) return;
|
|
5779
|
+
const from = group2[0].start, to = group2.at(-1).end;
|
|
5780
|
+
const words = [...text2.slice(from, to).matchAll(/(?:[^\s]|\u00a0|\u202f|\ufeff)+/gu)].map((match) => ({ start: from + match.index, end: from + match.index + match[0].length, text: match[0] }));
|
|
5781
|
+
const total = words.length;
|
|
5782
|
+
if (total < count || total > BALANCE_MAX_WORDS) return;
|
|
5783
|
+
const cache2 = /* @__PURE__ */ new Map(), span = (first, last) => {
|
|
5784
|
+
const key = first * (BALANCE_MAX_WORDS + 1) + last;
|
|
5785
|
+
let value = cache2.get(key);
|
|
5786
|
+
if (value === void 0) {
|
|
5787
|
+
value = widthOf(words[first].start, words[last - 1].end);
|
|
5788
|
+
cache2.set(key, value);
|
|
5789
|
+
}
|
|
5790
|
+
return value;
|
|
5791
|
+
};
|
|
5792
|
+
const target = span(0, total) / count;
|
|
5793
|
+
if (!(target > 0)) return;
|
|
5794
|
+
const credit = (last) => last >= total ? 0 : SENTENCE_END.test(words[last - 1].text) ? 0.02 : CLAUSE_END.test(words[last - 1].text) ? 0.01 : 0;
|
|
5795
|
+
const best = Array.from({ length: count + 1 }, () => Array(total + 1).fill(Infinity)), from_ = Array.from({ length: count + 1 }, () => Array(total + 1).fill(-1));
|
|
5796
|
+
best[0][0] = 0;
|
|
5797
|
+
for (let line2 = 1; line2 <= count; line2++) for (let last = line2; last <= total - (count - line2); last++) for (let first = line2 - 1; first < last; first++) {
|
|
5798
|
+
const before = best[line2 - 1][first];
|
|
5799
|
+
if (before === Infinity) continue;
|
|
5800
|
+
const width = span(first, last);
|
|
5801
|
+
if (width > boxWidth + WRAP_TOLERANCE) continue;
|
|
5802
|
+
const cost = before + ((width - target) / target) ** 2 - credit(last);
|
|
5803
|
+
if (cost < best[line2][last]) {
|
|
5804
|
+
best[line2][last] = cost;
|
|
5805
|
+
from_[line2][last] = first;
|
|
5806
|
+
}
|
|
5807
|
+
}
|
|
5808
|
+
if (best[count][total] === Infinity) return;
|
|
5809
|
+
for (let line2 = count, last = total; line2 > 1; line2--) {
|
|
5810
|
+
const first = from_[line2][last];
|
|
5811
|
+
forced.add(words[first].start);
|
|
5812
|
+
last = first;
|
|
5813
|
+
}
|
|
5814
|
+
};
|
|
5815
|
+
let group = [];
|
|
5816
|
+
for (const line2 of lines) {
|
|
5817
|
+
group.push(line2);
|
|
5818
|
+
if (line2.hard) {
|
|
5819
|
+
paragraph(group);
|
|
5820
|
+
group = [];
|
|
5821
|
+
}
|
|
5822
|
+
}
|
|
5823
|
+
paragraph(group);
|
|
5824
|
+
return forced.size ? forced : void 0;
|
|
5825
|
+
}
|
|
5626
5826
|
var HANGING_SPACE = /[^\S\r\n\u00a0\u202f\ufeff]/u;
|
|
5627
5827
|
var SCRIPT_WIDTH_FACTORS = [
|
|
5628
5828
|
[/\p{Script=Tamil}/u, 1.53],
|
|
@@ -5632,25 +5832,40 @@ var SCRIPT_WIDTH_FACTORS = [
|
|
|
5632
5832
|
[/\p{Script=Ethiopic}/u, 1.13],
|
|
5633
5833
|
[/\p{Script=Georgian}/u, 1.28]
|
|
5634
5834
|
];
|
|
5835
|
+
var ZERO_WIDTH_MARK = /\p{Mn}|\p{Me}|\u200d|\ufe0f/u;
|
|
5836
|
+
var SPACING_MARK = /\p{Mc}/u;
|
|
5837
|
+
var LATIN_CJK = /\p{Script=Latin}|\p{Script=Han}|\p{Script=Hangul}|\p{Script=Hiragana}|\p{Script=Katakana}/u;
|
|
5838
|
+
function characterUnits(character) {
|
|
5839
|
+
if (ZERO_WIDTH_MARK.test(character)) return Number.NaN;
|
|
5840
|
+
if (SPACING_MARK.test(character) && LATIN_CJK.test(character)) return Number.NaN;
|
|
5841
|
+
const base = character === " " ? 0.32 : /[A-Z0-9]/.test(character) ? 0.62 : character.codePointAt(0) > 11904 ? 1 : 0.54;
|
|
5842
|
+
const factor = SCRIPT_WIDTH_FACTORS.find(([script]) => script.test(character))?.[1] ?? 1;
|
|
5843
|
+
return base * factor;
|
|
5844
|
+
}
|
|
5845
|
+
var ASCII_UNITS = Array.from({ length: 128 }, (_, code) => characterUnits(String.fromCharCode(code)));
|
|
5846
|
+
var characterUnitCache = /* @__PURE__ */ new Map();
|
|
5847
|
+
var CHARACTER_UNIT_CACHE_LIMIT = 65536;
|
|
5635
5848
|
function measureText(text2, fontSize) {
|
|
5636
5849
|
let units = 0;
|
|
5637
5850
|
for (const character of text2) {
|
|
5638
|
-
|
|
5639
|
-
|
|
5640
|
-
|
|
5641
|
-
|
|
5642
|
-
|
|
5851
|
+
const code = character.charCodeAt(0);
|
|
5852
|
+
let advance = code < 128 ? ASCII_UNITS[code] : characterUnitCache.get(character);
|
|
5853
|
+
if (advance === void 0) {
|
|
5854
|
+
advance = characterUnits(character);
|
|
5855
|
+
if (characterUnitCache.size < CHARACTER_UNIT_CACHE_LIMIT) characterUnitCache.set(character, advance);
|
|
5856
|
+
}
|
|
5857
|
+
if (!Number.isNaN(advance)) units += advance;
|
|
5643
5858
|
}
|
|
5644
5859
|
return units * fontSize;
|
|
5645
5860
|
}
|
|
5646
5861
|
function wrapText(text2, width, fontSize, measure = measureText) {
|
|
5647
5862
|
return fitSourceText(text2, { width, height: Number.MAX_VALUE }, fontSize, fontSize, 1, measure, true, false).lines;
|
|
5648
5863
|
}
|
|
5649
|
-
function fitText(text2, box, requestedSize =
|
|
5864
|
+
function fitText(text2, box, requestedSize = PROSE_NOMINAL_SIZE, minFontSize = 16, measure = measureText, direction, balance = false) {
|
|
5650
5865
|
if (![box.width, box.height, requestedSize, minFontSize].every(Number.isFinite) || box.width <= 0 || box.height <= 0 || requestedSize <= 0 || minFontSize <= 0) {
|
|
5651
5866
|
throw new RangeError("Text dimensions and font sizes must be finite and positive.");
|
|
5652
5867
|
}
|
|
5653
|
-
return fitSourceText(text2, box, Math.max(requestedSize, minFontSize), minFontSize, 1, measure, true, true, direction);
|
|
5868
|
+
return fitSourceText(text2, box, Math.max(requestedSize, minFontSize), minFontSize, 1, measure, true, true, direction, balance);
|
|
5654
5869
|
}
|
|
5655
5870
|
var FONT_SIZE_GRID_PER_PX = 75;
|
|
5656
5871
|
var FONT_GRID_EPSILON = 1e-6;
|
|
@@ -5675,11 +5890,11 @@ function fitAtSizes(layout, requested, minimum, step = 1, snap = true) {
|
|
|
5675
5890
|
}
|
|
5676
5891
|
var PHOTO_RATIO = 3;
|
|
5677
5892
|
var PHOTO_GAP = 0.75;
|
|
5678
|
-
function quoteBodyRuns(runs) {
|
|
5679
|
-
if (!runs.length) return [
|
|
5893
|
+
function quoteBodyRuns(runs, marks2) {
|
|
5894
|
+
if (!runs.length) return [marks2.open + marks2.close];
|
|
5680
5895
|
const last = runs.length - 1;
|
|
5681
5896
|
return runs.map((run, index) => {
|
|
5682
|
-
const before = index === 0 ?
|
|
5897
|
+
const before = index === 0 ? marks2.open : "", after = index === last ? marks2.close : "";
|
|
5683
5898
|
return typeof run === "string" ? before + run + after : { ...run, text: before + run.text + after };
|
|
5684
5899
|
});
|
|
5685
5900
|
}
|
|
@@ -5714,23 +5929,24 @@ function layoutQuote(value, box, options = {}) {
|
|
|
5714
5929
|
for (const field of ["attribution", "role", "source"]) {
|
|
5715
5930
|
const text2 = quote[field];
|
|
5716
5931
|
if (!text2) continue;
|
|
5717
|
-
if (footer) footer += field === "role" ? "\n" :
|
|
5932
|
+
if (footer) footer += field === "role" ? "\n" : QUOTE_SOURCE_SEPARATOR;
|
|
5718
5933
|
footerSources.push(source(`${path}.${field}`, text2, footer.length));
|
|
5719
5934
|
footer += text2;
|
|
5720
5935
|
}
|
|
5721
5936
|
const hasPhoto = photoValue !== void 0, hasFooter = footer !== "", hasBlock = hasPhoto || hasFooter;
|
|
5722
5937
|
const photoPath = `${path}.photo`, rtl = options.direction === "rtl";
|
|
5723
5938
|
const bodyPath = shorthand ? path : `${path}.text`;
|
|
5939
|
+
const marks2 = quoteMarksFor(options.language);
|
|
5724
5940
|
const body = add(
|
|
5725
5941
|
"body",
|
|
5726
|
-
|
|
5727
|
-
[source(bodyPath, quoteText,
|
|
5942
|
+
`${marks2.open}${quoteText}${marks2.close}`,
|
|
5943
|
+
[source(bodyPath, quoteText, marks2.open.length)],
|
|
5728
5944
|
{ x: box.x + 18, y: box.y + 18, width: box.width - 36, height: box.height - (hasBlock ? 94 : 36) },
|
|
5729
|
-
|
|
5945
|
+
QUOTE_NOMINAL_SIZE,
|
|
5730
5946
|
options.fontFamilies?.accent ?? options.fontFamilies?.heading ?? "sans-serif",
|
|
5731
5947
|
600,
|
|
5732
5948
|
bodyPath,
|
|
5733
|
-
richBody ? quoteBodyRuns(richBody) : void 0
|
|
5949
|
+
richBody ? quoteBodyRuns(richBody, marks2) : void 0
|
|
5734
5950
|
);
|
|
5735
5951
|
const attribution = hasFooter ? add(
|
|
5736
5952
|
"footer",
|
|
@@ -5852,7 +6068,7 @@ function layoutMetric(value, box, options = {}) {
|
|
|
5852
6068
|
const sourceValue = metric[role];
|
|
5853
6069
|
if (sourceValue === void 0) continue;
|
|
5854
6070
|
const text2 = String(sourceValue), path = scalar ? sourcePath : `${sourcePath}.${role}`;
|
|
5855
|
-
const nominal = role === "value" ?
|
|
6071
|
+
const nominal = (role === "value" ? 76 : role === "description" ? 20 : role === "trend" ? 18 : 23) * scale2;
|
|
5856
6072
|
const requestedStyle = { fontFamily: (role === "value" ? options.fontFamilies?.heading : options.fontFamilies?.body) ?? "sans-serif", fontWeight: role === "value" ? 800 : role === "description" ? 400 : 500, italic: false, path };
|
|
5857
6073
|
const part = {
|
|
5858
6074
|
role,
|
|
@@ -6167,9 +6383,9 @@ function layoutTimeline(value, box, options = {}) {
|
|
|
6167
6383
|
function fitCodeText(text2, box, size, minimum, step, measure, direction) {
|
|
6168
6384
|
return fitSourceText(text2, box, size, minimum, step, measure, false, true, direction);
|
|
6169
6385
|
}
|
|
6170
|
-
function fitSourceText(text2, box, size, minimum, step, measure, prose = false, snap = true, direction) {
|
|
6386
|
+
function fitSourceText(text2, box, size, minimum, step, measure, prose = false, snap = true, direction, balance = false) {
|
|
6171
6387
|
const directionAt = direction === "rtl" ? paragraphDirectionAt(text2, "rtl") : void 0;
|
|
6172
|
-
const layout = (fontSize) => {
|
|
6388
|
+
const layout = (fontSize, forced) => {
|
|
6173
6389
|
const tabWidth = measure(" ", fontSize) * 4;
|
|
6174
6390
|
if (!Number.isFinite(tabWidth) || text2.includes(" ") && tabWidth <= 0) throw new RangeError("Text tabs require a positive finite measured space advance.");
|
|
6175
6391
|
const measureLine = (start2, end2, record8 = false) => {
|
|
@@ -6210,6 +6426,7 @@ function fitSourceText(text2, box, size, minimum, step, measure, prose = false,
|
|
|
6210
6426
|
push(a, b, "hard");
|
|
6211
6427
|
continue;
|
|
6212
6428
|
}
|
|
6429
|
+
if (forced?.has(a) && end > start && /\S/u.test(text2.slice(start, end))) push(a, a, "soft");
|
|
6213
6430
|
if (width(start, b) <= box.width + WRAP_TOLERANCE) {
|
|
6214
6431
|
end = b;
|
|
6215
6432
|
continue;
|
|
@@ -6247,7 +6464,22 @@ function fitSourceText(text2, box, size, minimum, step, measure, prose = false,
|
|
|
6247
6464
|
overflow: sourceLines.length * lineHeight > box.height + 0.01 || sourceLines.some((line2) => line2.width > box.width + 0.01)
|
|
6248
6465
|
};
|
|
6249
6466
|
};
|
|
6250
|
-
|
|
6467
|
+
const balanced = (fontSize) => {
|
|
6468
|
+
const greedy = layout(fontSize);
|
|
6469
|
+
if (!balance || greedy.overflow || greedy.sourceLines.length < 2) return greedy;
|
|
6470
|
+
const widthOf = (start, end) => {
|
|
6471
|
+
let x = 0;
|
|
6472
|
+
for (const [index, segment2] of text2.slice(start, end).split(" ").entries()) {
|
|
6473
|
+
if (index) x = (Math.floor(x / (measure(" ", fontSize) * 4) + 1e-9) + 1) * measure(" ", fontSize) * 4;
|
|
6474
|
+
if (segment2) x += measure(segment2, fontSize);
|
|
6475
|
+
}
|
|
6476
|
+
return x;
|
|
6477
|
+
};
|
|
6478
|
+
const forced = balancedBreaks(text2, greedy.sourceLines.map((line2) => ({ start: line2.start, end: line2.end, hard: line2.boundary !== "soft" })), widthOf, box.width);
|
|
6479
|
+
const result = forced ? layout(fontSize, forced) : greedy;
|
|
6480
|
+
return result.sourceLines.length === greedy.sourceLines.length && !result.overflow ? result : greedy;
|
|
6481
|
+
};
|
|
6482
|
+
return fitAtSizes(balance ? balanced : layout, size, minimum, step, snap);
|
|
6251
6483
|
}
|
|
6252
6484
|
function layoutCode(value, box, options = {}) {
|
|
6253
6485
|
const shorthand = typeof value === "string", code = shorthand ? { source: value } : value;
|
|
@@ -6270,7 +6502,7 @@ function layoutCode(value, box, options = {}) {
|
|
|
6270
6502
|
sources: generated ? [] : [{ path: partPath, start: 0, end: text2.length }],
|
|
6271
6503
|
generated,
|
|
6272
6504
|
box: { ...inner },
|
|
6273
|
-
requestedFontSize: gridFontSize((role === "body" ?
|
|
6505
|
+
requestedFontSize: gridFontSize((role === "body" ? CODE_NOMINAL_SIZE : 14) * scale2, minimum),
|
|
6274
6506
|
minFontSize: minimum,
|
|
6275
6507
|
requestedStyle,
|
|
6276
6508
|
style: resolveTextStyle({ ...requestedStyle }, options.textMeasurement)
|
|
@@ -6283,7 +6515,16 @@ function layoutCode(value, box, options = {}) {
|
|
|
6283
6515
|
if (!parts.length) add("language", "code", path, true);
|
|
6284
6516
|
const body = add("body", code.source, shorthand ? path : `${path}.source`), headers = parts.filter((part) => part !== body);
|
|
6285
6517
|
const usable2 = (area2) => [area2.x, area2.y, area2.width, area2.height].every(Number.isFinite) && area2.width > 0 && area2.height > 0;
|
|
6286
|
-
const
|
|
6518
|
+
const measureCode = textWidthMeasurer(body.style, options.textMeasurement);
|
|
6519
|
+
const fit = (part, area2, size = part.requestedFontSize, floor = minimum) => {
|
|
6520
|
+
if (!usable2(area2)) return void 0;
|
|
6521
|
+
const wanted = fitCodeText(part.text, area2, size, floor, scale2, textWidthMeasurer(part.style, options.textMeasurement));
|
|
6522
|
+
const wraps = (value2) => value2.sourceLines.filter((line2) => line2.boundary === "soft").length;
|
|
6523
|
+
const legacy = gridFontSize(LEGACY_CODE_NOMINAL_SIZE * scale2, minimum);
|
|
6524
|
+
if (part.role !== "body" || part.requestedFontSize <= legacy || !wraps(wanted)) return wanted;
|
|
6525
|
+
const earlier = fitCodeText(part.text, area2, legacy, floor, scale2, measureCode);
|
|
6526
|
+
return !earlier.overflow && wraps(earlier) < wraps(wanted) ? earlier : wanted;
|
|
6527
|
+
};
|
|
6287
6528
|
if (usable2(inner)) {
|
|
6288
6529
|
const combinations = headers.reduce((choices, part) => choices.flatMap((choice) => [.../* @__PURE__ */ new Set([part.requestedFontSize, minimum])].map((size) => [...choice, { part, size }])), [[]]);
|
|
6289
6530
|
let selected;
|
|
@@ -6306,6 +6547,7 @@ function layoutCode(value, box, options = {}) {
|
|
|
6306
6547
|
part.box = box2;
|
|
6307
6548
|
part.fit = fit2;
|
|
6308
6549
|
}
|
|
6550
|
+
if (selected && !selected.overflow && body.fit) body.box = { ...body.box, height: Math.min(body.box.height, body.fit.lines.length * body.fit.lineHeight) };
|
|
6309
6551
|
}
|
|
6310
6552
|
const report = (reason, part, roles, message) => diagnostics.push({ code: "text-overflow", reason, path: part.path, parts: roles, message });
|
|
6311
6553
|
for (const part of parts) {
|
|
@@ -6323,9 +6565,11 @@ function layoutCode(value, box, options = {}) {
|
|
|
6323
6565
|
}
|
|
6324
6566
|
}
|
|
6325
6567
|
if (diagnostics.length && options.overflow === "error") throw new OPFCompositionError(diagnostics);
|
|
6326
|
-
|
|
6568
|
+
const bottom = body.fit && !body.fit.overflow ? body.box.y + body.box.height + 18 : box.y + box.height;
|
|
6569
|
+
const bounds = { x: box.x, y: box.y, width: box.width, height: Math.min(box.height, Math.max(bottom - box.y, 0)) };
|
|
6570
|
+
return { bounds, algorithm: "code-flow-v1", textMeasurement: options.textMeasurement ? "provided" : "estimated", parts, diagnostics, overflow: diagnostics.length > 0 };
|
|
6327
6571
|
}
|
|
6328
|
-
function fitRichText(input, box, requestedSize =
|
|
6572
|
+
function fitRichText(input, box, requestedSize = PROSE_NOMINAL_SIZE, minFontSize = 16, options = { style: { fontFamily: "sans-serif", fontWeight: 400 } }) {
|
|
6329
6573
|
if (![box.width, box.height, requestedSize, minFontSize].every((value) => Number.isFinite(value) && value > 0)) throw new RangeError("Rich text dimensions and font sizes must be finite and positive.");
|
|
6330
6574
|
const layout = richTextLayouter(input, box, requestedSize, options, minFontSize);
|
|
6331
6575
|
return fitAtSizes(layout, requestedSize, richMinimum(input, requestedSize, minFontSize));
|
|
@@ -6342,7 +6586,7 @@ function richMinimum(input, requested, minimum) {
|
|
|
6342
6586
|
return visible ? floor : minimum;
|
|
6343
6587
|
}
|
|
6344
6588
|
function richTextLayouter(input, box, requestedSize, options, minimum = 0) {
|
|
6345
|
-
let offset = 0;
|
|
6589
|
+
let offset = 0, lastWidth = () => 0, lastRanges = [];
|
|
6346
6590
|
const source = input.map((value, runIndex) => {
|
|
6347
6591
|
const run = typeof value === "string" ? { text: value } : value;
|
|
6348
6592
|
if (typeof run?.text !== "string" || run.fontSize !== void 0 && (!Number.isFinite(run.fontSize) || run.fontSize <= 0)) throw new RangeError("Rich text runs need text and a positive finite font size.");
|
|
@@ -6356,7 +6600,7 @@ function richTextLayouter(input, box, requestedSize, options, minimum = 0) {
|
|
|
6356
6600
|
const whole = source.map((entry) => entry.run.text).join("");
|
|
6357
6601
|
const paint = (raw) => raw >= minimum - 1e-6 ? gridFontSize(raw, minimum) : snapFontSizeDown(raw);
|
|
6358
6602
|
const directionAt = options.direction === "rtl" ? paragraphDirectionAt(whole, "rtl") : void 0;
|
|
6359
|
-
const
|
|
6603
|
+
const build = (rawFontSize, forced) => {
|
|
6360
6604
|
const fontSize = paint(rawFontSize), ratio = rawFontSize / requestedSize;
|
|
6361
6605
|
const fragments = (start, end) => {
|
|
6362
6606
|
let x = 0;
|
|
@@ -6411,6 +6655,7 @@ function richTextLayouter(input, box, requestedSize, options, minimum = 0) {
|
|
|
6411
6655
|
lineEnd = end;
|
|
6412
6656
|
continue;
|
|
6413
6657
|
}
|
|
6658
|
+
if (forced?.has(start) && lineEnd > lineStart && /\S/u.test(whole.slice(lineStart, lineEnd))) push(start);
|
|
6414
6659
|
if (width(lineStart, end) <= box.width + WRAP_TOLERANCE) {
|
|
6415
6660
|
lineEnd = end;
|
|
6416
6661
|
continue;
|
|
@@ -6454,7 +6699,7 @@ function richTextLayouter(input, box, requestedSize, options, minimum = 0) {
|
|
|
6454
6699
|
y += height;
|
|
6455
6700
|
}
|
|
6456
6701
|
}
|
|
6457
|
-
|
|
6702
|
+
const fit = {
|
|
6458
6703
|
lines: ranges.map((range) => whole.slice(range.start, range.end)),
|
|
6459
6704
|
fontSize,
|
|
6460
6705
|
lineHeight: Math.max(fontSize * 1.22, ...richLines.map((line2) => line2.height)),
|
|
@@ -6463,12 +6708,22 @@ function richTextLayouter(input, box, requestedSize, options, minimum = 0) {
|
|
|
6463
6708
|
overflow: y > box.height + 0.01 || richLines.some((line2) => line2.width > box.width + 0.01),
|
|
6464
6709
|
...directionAt ? { directions: ranges.map((range) => directionAt(range.start)) } : {}
|
|
6465
6710
|
};
|
|
6711
|
+
lastWidth = width;
|
|
6712
|
+
lastRanges = ranges;
|
|
6713
|
+
return fit;
|
|
6714
|
+
};
|
|
6715
|
+
const layout = (rawFontSize) => {
|
|
6716
|
+
const greedy = build(rawFontSize);
|
|
6717
|
+
if (!options.balance || greedy.overflow || greedy.richLines.length < 2) return greedy;
|
|
6718
|
+
const forced = balancedBreaks(whole, lastRanges.map((range) => ({ start: range.start, end: range.end, hard: /^[\r\n]/.test(whole.slice(range.end, range.end + 1)) || range.end >= whole.length })), lastWidth, box.width);
|
|
6719
|
+
const result = forced ? build(rawFontSize, forced) : greedy;
|
|
6720
|
+
return result.richLines.length === greedy.richLines.length && !result.overflow ? result : greedy;
|
|
6466
6721
|
};
|
|
6467
6722
|
return layout;
|
|
6468
6723
|
}
|
|
6469
6724
|
var PICTURE_BULLET_SCALE = 0.65;
|
|
6470
6725
|
function contentNominalSize(field) {
|
|
6471
|
-
return field === "items" || field === "bullets" ?
|
|
6726
|
+
return field === "items" || field === "bullets" ? LIST_NOMINAL_SIZE : field === "table" ? TABLE_NOMINAL_SIZE : PROSE_NOMINAL_SIZE;
|
|
6472
6727
|
}
|
|
6473
6728
|
function fitList(input, box, requestedSize = contentNominalSize("items"), minFontSize = 16, options = { style: { fontFamily: "sans-serif", fontWeight: 400 } }) {
|
|
6474
6729
|
if (!Array.isArray(input) || ![box.width, box.height, requestedSize, minFontSize].every((value) => Number.isFinite(value) && value > 0)) throw new RangeError("List content, dimensions and font sizes must be valid.");
|
|
@@ -6493,10 +6748,11 @@ function fitList(input, box, requestedSize = contentNominalSize("items"), minFon
|
|
|
6493
6748
|
const entries = [], lines = [], directions = [];
|
|
6494
6749
|
const markerStyles = numbers ? source.map((item) => resolveTextStyle(markerStyleFor(item), options.textMeasurement)) : [];
|
|
6495
6750
|
const markerWidths = numbers ? numbers.map((number, index) => textWidthMeasurer(markerStyles[index], options.textMeasurement)(number.text, fontSize)) : [];
|
|
6751
|
+
const none = options.bullet === "none" && !numbers;
|
|
6496
6752
|
const hanging = numbers ? Math.max(fontSize * 1.1, Math.max(0, ...markerWidths) + fontSize * 0.3) : fontSize * 1.1;
|
|
6497
6753
|
for (const item of source) {
|
|
6498
6754
|
const rtl = item.direction === "rtl";
|
|
6499
|
-
const indent = hanging, offset = Math.min(box.width, item.level *
|
|
6755
|
+
const indent = none ? 0 : hanging, offset = Math.min(box.width, item.level * hanging), x = rtl ? box.x : box.x + offset + indent, width = Math.max(1, rtl ? box.width - offset - indent : box.x + box.width - x);
|
|
6500
6756
|
if (offset + indent >= box.width) overflow = true;
|
|
6501
6757
|
const textBox = { x, y, width, height: box.height };
|
|
6502
6758
|
const style = { ...options.style, path: item.textPath };
|
|
@@ -6517,7 +6773,7 @@ function fitList(input, box, requestedSize = contentNominalSize("items"), minFon
|
|
|
6517
6773
|
}
|
|
6518
6774
|
overflow ||= text2.overflow || !!description?.overflow;
|
|
6519
6775
|
const number = numbers?.[item.index];
|
|
6520
|
-
const marker = { text: number ? number.text : ["\u2022", "\u25E6", "\u25AA"][item.level % 3], x: rtl ? box.x + box.width - offset : box.x + offset, y: textBox.y + (text2.richLines[0]?.baseline ?? fontSize), fontSize, style: number ? markerStyles[item.index] : resolveTextStyle(style, options.textMeasurement), indent, ...number ? { number, width: markerWidths[item.index] } : {}, ...rtl ? { anchor: "end" } : {} }, side = fontSize * PICTURE_BULLET_SCALE;
|
|
6776
|
+
const marker = { text: number ? number.text : none ? "" : ["\u2022", "\u25E6", "\u25AA"][item.level % 3], x: rtl ? box.x + box.width - offset : box.x + offset, y: textBox.y + (text2.richLines[0]?.baseline ?? fontSize), fontSize, style: number ? markerStyles[item.index] : resolveTextStyle(style, options.textMeasurement), indent, ...number ? { number, width: markerWidths[item.index] } : {}, ...none ? { none: true } : {}, ...rtl ? { anchor: "end" } : {} }, side = fontSize * PICTURE_BULLET_SCALE;
|
|
6521
6777
|
entries.push({
|
|
6522
6778
|
index: item.index,
|
|
6523
6779
|
level: item.level,
|
|
@@ -6531,7 +6787,7 @@ function fitList(input, box, requestedSize = contentNominalSize("items"), minFon
|
|
|
6531
6787
|
descriptionBox,
|
|
6532
6788
|
marker,
|
|
6533
6789
|
...item.direction ? { direction: item.direction } : {},
|
|
6534
|
-
...options.bulletImage && !number ? { bulletImage: options.bulletImage, bulletBox: { x: rtl ? marker.x - side : marker.x, y: marker.y - side, width: side, height: side } } : {}
|
|
6790
|
+
...options.bulletImage && !number && !none ? { bulletImage: options.bulletImage, bulletBox: { x: rtl ? marker.x - side : marker.x, y: marker.y - side, width: side, height: side } } : {}
|
|
6535
6791
|
});
|
|
6536
6792
|
if (item.index < source.length - 1) y += fontSize * 0.28;
|
|
6537
6793
|
}
|
|
@@ -6798,14 +7054,15 @@ function composeSlide(input, options = {}) {
|
|
|
6798
7054
|
const minSize = snapFontSizeUp((composition.minFontSize ?? 16) * scale2);
|
|
6799
7055
|
const rasterPadding = (options.textRasterPadding ?? 1) * scale2;
|
|
6800
7056
|
if (!Number.isFinite(rasterPadding) || rasterPadding < 0) throw new RangeError("Text raster padding must be finite and nonnegative.");
|
|
6801
|
-
let
|
|
6802
|
-
const alignmentFor = (field) => (field === "title" || (field === "tag" ||
|
|
7057
|
+
let subtitleInGroup = true;
|
|
7058
|
+
const alignmentFor = (field) => (field === "title" || (field === "tag" || subtitleInGroup && field === "subtitle") && hints.sources.contentAlignment !== "slide" ? hints.titleAlignment : hints.contentAlignment) ?? (field === "metric" ? "center" : "left");
|
|
6803
7059
|
const styleFor = (field, path2) => resolveTextStyle({
|
|
6804
7060
|
fontFamily: (field === "title" ? options.fontFamilies?.heading : field === "code" ? options.fontFamilies?.code : field === "tag" ? options.fontFamilies?.accent ?? options.fontFamilies?.body : options.fontFamilies?.body) ?? (field === "code" ? "monospace" : "sans-serif"),
|
|
6805
7061
|
fontWeight: field === "title" ? 700 : 400,
|
|
6806
7062
|
path: path2
|
|
6807
7063
|
}, options.textMeasurement);
|
|
6808
7064
|
const listBullet = hints.listBullet !== void 0 ? { value: hints.listBullet, path: hints.paths.listBullet } : void 0;
|
|
7065
|
+
const noListBullet = listBullet?.value === "none";
|
|
6809
7066
|
const bulletImage = listBullet?.value === "image" ? (() => {
|
|
6810
7067
|
const resolved = resolveLogo(options.presentation, slide, { shape: "icon", onDark: options.darkBackground, slideIndex: options.slideIndex });
|
|
6811
7068
|
return resolved ? { source: resolved.source, path: resolved.path } : void 0;
|
|
@@ -6816,13 +7073,14 @@ function composeSlide(input, options = {}) {
|
|
|
6816
7073
|
const richOptions = (style) => ({ style, textMeasurement: options.textMeasurement, ...options.fontFamilies?.code ? { codeFontFamily: options.fontFamilies.code } : {}, ...citationMarker ? { citationMarker } : {}, ...rtl ? { direction: "rtl" } : {} });
|
|
6817
7074
|
const fitPlacedText = (field, value, text2, box, size, minimum, path2, explicitAlignment) => {
|
|
6818
7075
|
const style = styleFor(field, path2), rich = (field === "text" || headings.has(field)) && Array.isArray(value);
|
|
6819
|
-
|
|
7076
|
+
const balance = field === "title" || field === "subtitle", textOptions = balance ? { ...richOptions(style), balance } : richOptions(style);
|
|
7077
|
+
if (!options.textMeasurement?.outlineBounds) return rich ? fitRichText(value, box, size, minimum, textOptions) : fitText(text2, box, size, minimum, textWidthMeasurer(style, options.textMeasurement), textDirection, balance);
|
|
6820
7078
|
const alignment = explicitAlignment ?? alignmentFor(field);
|
|
6821
|
-
const richLayout = rich ? richTextLayouter(value, box, size,
|
|
7079
|
+
const richLayout = rich ? richTextLayouter(value, box, size, textOptions, minimum) : void 0;
|
|
6822
7080
|
const measure = textWidthMeasurer(style, options.textMeasurement), floor = snapFontSizeUp(rich ? richMinimum(value, size, minimum) : minimum), start = Math.max(size, floor);
|
|
6823
7081
|
for (let trial = 0; trial <= 64; trial++) {
|
|
6824
7082
|
const raw = start - trial * scale2, last = trial === 64 || raw <= floor, fontSize = last ? floor : gridFontSize(raw, floor);
|
|
6825
|
-
const fit = richLayout ? richLayout(fontSize) : fitText(text2, box, fontSize, fontSize, measure, textDirection);
|
|
7083
|
+
const fit = richLayout ? richLayout(fontSize) : fitText(text2, box, fontSize, fontSize, measure, textDirection, balance);
|
|
6826
7084
|
const richLines = "richLines" in fit ? fit.richLines : void 0;
|
|
6827
7085
|
const lines = richLines ? richLines.map((line2) => {
|
|
6828
7086
|
let outline = null;
|
|
@@ -6864,7 +7122,7 @@ function composeSlide(input, options = {}) {
|
|
|
6864
7122
|
}
|
|
6865
7123
|
throw new Error("Text placement did not evaluate its bounded floor trial.");
|
|
6866
7124
|
};
|
|
6867
|
-
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);
|
|
7125
|
+
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 } : noListBullet ? { bullet: "none" } : {} }) : fitText(text2, box, size, minimum, widthFor(field, path2), field === "code" ? void 0 : textDirection);
|
|
6868
7126
|
const path = `slides.${options.slideIndex ?? 0}`;
|
|
6869
7127
|
const annotationFit = (value, box, requestedSize, minFontSize, fitPath, alignment) => fitPlacedText("text", value, annotationText(value), box, requestedSize, minFontSize, fitPath, alignment);
|
|
6870
7128
|
const annotationOptions = { scale: scale2, minFontSize: minSize, fit: annotationFit, textStyle: (fitPath) => styleFor("text", fitPath) };
|
|
@@ -6873,7 +7131,7 @@ function composeSlide(input, options = {}) {
|
|
|
6873
7131
|
const backgroundImage = resolveBackgroundImage(slide, options.presentation, options.themeBackground, width, height, path, mirrorSide, imageDiagnostics);
|
|
6874
7132
|
const regions = Object.keys(slide).filter((key) => regionParts(key)).sort();
|
|
6875
7133
|
const assets = record7(options.presentation).assets;
|
|
6876
|
-
const imageContext = (placement) => ({ fit: hints.imageFit, scale: scale2, mirrorSide, diagnostics: imageDiagnostics, assets, ...placement ? { placement } : {} });
|
|
7134
|
+
const imageContext = (placement, anchor) => ({ fit: hints.imageFit ?? (!placement && autoComposition() ? "contain" : void 0), scale: scale2, mirrorSide, diagnostics: imageDiagnostics, assets, ...placement ? { placement } : {}, ...anchor ? { anchor } : {} });
|
|
6877
7135
|
const area2 = { left: 0, top: 0, right: width, bottom: height };
|
|
6878
7136
|
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 }] : [];
|
|
6879
7137
|
const placed = [], usedEdges = /* @__PURE__ */ new Set();
|
|
@@ -6915,8 +7173,9 @@ function composeSlide(input, options = {}) {
|
|
|
6915
7173
|
const flowBlocks = Array.isArray(slide.blocks) ? slide.blocks.filter((_, index) => !placedBlocks.has(index)) : slide.blocks;
|
|
6916
7174
|
const hasBodyPayload = regions.some((key) => !emptyHost(record7(slide[key]))) || !emptyPayload(flowBlocks) || fields.some((field) => !(placedRoot && field === "image") && !emptyPayload(slide[field]));
|
|
6917
7175
|
const useTemplate = template !== void 0 && !regions.length;
|
|
7176
|
+
const autoComposition = () => !hasLayoutRecord && !regions.length;
|
|
6918
7177
|
const isCover = !hasBodyPayload && (useTemplate || !hasLayoutRecord);
|
|
6919
|
-
|
|
7178
|
+
subtitleInGroup = !(useTemplate && template?.subtitle === true);
|
|
6920
7179
|
let logo;
|
|
6921
7180
|
if (isCover && options[LAYOUT_MASTER] !== true) {
|
|
6922
7181
|
const resolved = resolveLogo(options.presentation, slide, { shape: "full", onDark: options.darkBackground, slideIndex: options.slideIndex });
|
|
@@ -6931,7 +7190,7 @@ function composeSlide(input, options = {}) {
|
|
|
6931
7190
|
const headingItems = [];
|
|
6932
7191
|
for (const field of useTemplate ? [] : ["tag", "title", "subtitle"]) {
|
|
6933
7192
|
if (!slide[field] || Array.isArray(slide[field]) && !annotationText(slide[field])) continue;
|
|
6934
|
-
const requested = (field === "title" ? 54 : field === "tag" ? 16 :
|
|
7193
|
+
const requested = (field === "title" ? 54 : field === "tag" ? 16 : PROSE_NOMINAL_SIZE) * scale2;
|
|
6935
7194
|
const maxHeight = Math.max(height * (field === "title" ? 0.26 : field === "subtitle" ? 0.12 : 0.045), minSize * 1.22 + 2 * rasterPadding);
|
|
6936
7195
|
const box = { x: area2.left + padding, y, width: area2.right - area2.left - padding * 2, height: maxHeight };
|
|
6937
7196
|
const text2 = fitPlacedText(field, slide[field], annotationText(slide[field]), box, requested, minSize, `${path}.${field}`);
|
|
@@ -7008,6 +7267,8 @@ function composeSlide(input, options = {}) {
|
|
|
7008
7267
|
const regionsInReadingOrder = visualReadingOrder(regions.map((key) => ({ key, box: regionBox(regionParts(key), contentBox, gap) }))).map((entry) => entry.key);
|
|
7009
7268
|
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);
|
|
7010
7269
|
const groups = [], flows = [];
|
|
7270
|
+
const peerSets = [];
|
|
7271
|
+
const range = (from, to) => Array.from({ length: to - from }, (_, index) => from + index);
|
|
7011
7272
|
const decisions = options.explain ? [] : void 0;
|
|
7012
7273
|
const inheritedSettings = (parent, own3 = {}) => ({
|
|
7013
7274
|
minFontSize: parent.minFontSize,
|
|
@@ -7024,6 +7285,11 @@ function composeSlide(input, options = {}) {
|
|
|
7024
7285
|
const frame = acceptedBox(box), padding2 = Math.min(12 * scale2, frame.width / 4, frame.height / 4);
|
|
7025
7286
|
return acceptedBox({ x: frame.x + padding2, y: frame.y + padding2, width: frame.width - 2 * padding2, height: frame.height - 2 * padding2 });
|
|
7026
7287
|
};
|
|
7288
|
+
let languageTag = null;
|
|
7289
|
+
const deckLanguage = () => {
|
|
7290
|
+
if (languageTag === null) languageTag = quoteLanguage(options.presentation, options.slideIndex);
|
|
7291
|
+
return languageTag;
|
|
7292
|
+
};
|
|
7027
7293
|
const measureQuote = (node, box, settings) => layoutQuote(node.value, acceptedBox(box), {
|
|
7028
7294
|
fontFamilies: options.fontFamilies,
|
|
7029
7295
|
textMeasurement: options.textMeasurement,
|
|
@@ -7031,7 +7297,8 @@ function composeSlide(input, options = {}) {
|
|
|
7031
7297
|
minFontSize: settings.minFontSize,
|
|
7032
7298
|
path: node.path,
|
|
7033
7299
|
direction: textDirection,
|
|
7034
|
-
...citationMarker ? { citationMarker } : {}
|
|
7300
|
+
...citationMarker ? { citationMarker } : {},
|
|
7301
|
+
...deckLanguage() !== void 0 ? { language: deckLanguage() } : {}
|
|
7035
7302
|
});
|
|
7036
7303
|
const measureCode = (node, box, settings) => layoutCode(node.value, acceptedBox(box), {
|
|
7037
7304
|
fontFamilies: options.fontFamilies,
|
|
@@ -7060,14 +7327,21 @@ function composeSlide(input, options = {}) {
|
|
|
7060
7327
|
direction: textDirection
|
|
7061
7328
|
});
|
|
7062
7329
|
const captionOf = (node, box) => node.caption !== void 0 && node.captionPath ? layoutCaption(node.caption, box, node.captionPath, annotationOptions) : void 0;
|
|
7330
|
+
const wholePictureAspect = (node) => {
|
|
7331
|
+
const host = node.host;
|
|
7332
|
+
if (node.field !== "image" || !host || !autoComposition() || host.aspectRatio !== void 0 || host.shape === "circle") return void 0;
|
|
7333
|
+
const fit = IMAGE_FITS.includes(host.fit) ? host.fit : hints.imageFit ?? "contain";
|
|
7334
|
+
return fit === "contain" ? intrinsicImageAspect(host.image, assets) : void 0;
|
|
7335
|
+
};
|
|
7063
7336
|
const leafScore = (node, box, settings, penalties) => {
|
|
7064
7337
|
box = payloadBox(box);
|
|
7065
7338
|
const captioned = captionOf(node, box);
|
|
7066
7339
|
if (captioned) box = captioned.mediaBox;
|
|
7067
7340
|
const text2 = contentText(node.field, node.value);
|
|
7068
|
-
|
|
7341
|
+
const proportions = Math.abs(Math.log(box.width / box.height / (wholePictureAspect(node) ?? 1.6)));
|
|
7342
|
+
let score = proportions + (captioned?.overflow ? 1e3 : 0);
|
|
7069
7343
|
if (penalties) {
|
|
7070
|
-
penalties.cellProportions +=
|
|
7344
|
+
penalties.cellProportions += proportions;
|
|
7071
7345
|
if (captioned?.overflow) penalties.textOverflow += 1e3;
|
|
7072
7346
|
}
|
|
7073
7347
|
if (node.field === "quote" || node.field === "code" || node.field === "metric" || node.field === "timeline") {
|
|
@@ -7079,8 +7353,9 @@ function composeSlide(input, options = {}) {
|
|
|
7079
7353
|
penalties.textOverflow += internal.overflow ? 1e3 : 0;
|
|
7080
7354
|
}
|
|
7081
7355
|
} else if (text2) {
|
|
7082
|
-
const
|
|
7083
|
-
const
|
|
7356
|
+
const prose = proseMeasure(node, box.width);
|
|
7357
|
+
const fit = fitContent(node.field, node.value, text2, { ...box, width: prose.width }, prose.size, snapFontSizeUp((settings.minFontSize ?? 16) * scale2), node.path, node.payload.numbering);
|
|
7358
|
+
const reduction = Math.max(0, snapFontSizeDown(prose.size) - fit.fontSize) / scale2;
|
|
7084
7359
|
score += reduction + (fit.overflow ? 1e3 : 0);
|
|
7085
7360
|
if (penalties) {
|
|
7086
7361
|
penalties.fontReduction += reduction;
|
|
@@ -7109,6 +7384,74 @@ function composeSlide(input, options = {}) {
|
|
|
7109
7384
|
const boxes = gridBoxes(slotCount, area3, cols, (own3.gap ?? 1 / 30) * Math.min(box.width, box.height), own3.weights ?? [], modeFor(own3) === "column");
|
|
7110
7385
|
return node.children.reduce((score, child, index) => score + scoreNode(child, boxes[index], own3, penalties), 0);
|
|
7111
7386
|
};
|
|
7387
|
+
const contentSized = /* @__PURE__ */ new WeakSet();
|
|
7388
|
+
const stackedBoxes = (nodes, area3, requestedGap, settings, cards = hasCards, anchor = "top") => {
|
|
7389
|
+
const between = Math.max(0, Math.min(requestedGap, area3.width / 2, area3.height / (nodes.length * 2)));
|
|
7390
|
+
const space = Math.max(0, area3.height - between * (nodes.length - 1)), share = space / nodes.length;
|
|
7391
|
+
const elastic = nodes.map((node) => !measuredNode(node)), stretch = elastic.filter(Boolean).length;
|
|
7392
|
+
const needs = nodes.map((node, index) => elastic[index] ? share : naturalHeight(node, area3.width, cards, void 0, settings));
|
|
7393
|
+
const floors = nodes.map((node, index) => elastic[index] ? share : naturalHeight(node, area3.width, cards, void 0, settings, true));
|
|
7394
|
+
let heights = shareHeights(needs, floors, space);
|
|
7395
|
+
const textual = nodes.every((node) => !node.children && node.caption === void 0 && (node.field === "text" || node.field === "items" || node.field === "bullets"));
|
|
7396
|
+
if (textual && nodes.length > 1 && needs.reduce((sum, size) => sum + size, 0) > space + 1e-6) {
|
|
7397
|
+
const floor = snapFontSizeUp((settings.minFontSize ?? 16) * scale2), start = Math.max(...nodes.map((node) => proseMeasure(node, area3.width).size));
|
|
7398
|
+
for (let size = start; ; size -= scale2) {
|
|
7399
|
+
const trial = Math.max(floor, snapFontSizeDown(size));
|
|
7400
|
+
const natural = nodes.map((node) => naturalHeight(node, area3.width, cards, void 0, settings, false, Math.min(trial, proseMeasure(node, area3.width).size)));
|
|
7401
|
+
if (natural.reduce((sum, height2) => sum + height2, 0) <= space + 1e-6) {
|
|
7402
|
+
heights = natural;
|
|
7403
|
+
break;
|
|
7404
|
+
}
|
|
7405
|
+
if (trial <= floor) break;
|
|
7406
|
+
}
|
|
7407
|
+
}
|
|
7408
|
+
if (stretch && heights.some((size, index) => elastic[index] && size < share - 1e-9)) {
|
|
7409
|
+
const measured = nodes.flatMap((_, index) => elastic[index] ? [] : [index]);
|
|
7410
|
+
const rest = shareHeights(measured.map((index) => needs[index]), measured.map((index) => floors[index]), space - stretch * share);
|
|
7411
|
+
heights = nodes.map((_, index) => elastic[index] ? share : rest[measured.indexOf(index)]);
|
|
7412
|
+
}
|
|
7413
|
+
const spare = space - heights.reduce((sum, size) => sum + size, 0);
|
|
7414
|
+
if (stretch && spare > 0) heights = heights.map((size, index) => elastic[index] ? size + spare / stretch : size);
|
|
7415
|
+
const used = heights.reduce((sum, size) => sum + size, 0) + between * (nodes.length - 1);
|
|
7416
|
+
nodes.forEach((node, index) => {
|
|
7417
|
+
if (!node.children && !elastic[index] && heights[index] >= needs[index] - 1e-6) contentSized.add(node);
|
|
7418
|
+
});
|
|
7419
|
+
let y2 = area3.y + Math.max(0, anchor === "middle" ? (area3.height - used) / 2 : anchor === "bottom" ? area3.height - used : 0);
|
|
7420
|
+
return heights.map((size) => {
|
|
7421
|
+
const box = { x: area3.x, y: y2, width: area3.width, height: size };
|
|
7422
|
+
y2 += size + between;
|
|
7423
|
+
return box;
|
|
7424
|
+
});
|
|
7425
|
+
};
|
|
7426
|
+
const WEIGHTED_DEMAND_RATIO = 2.5, WEIGHTED_SHARES = [0.55, 0.6, 0.65, 0.7];
|
|
7427
|
+
const autoRowWeights = (nodes, count, cols, area3, rowGap, settings) => {
|
|
7428
|
+
if (!autoComposition() || settings.weights?.length || count < 2 || count > 3 || cols !== count || nodes.length !== count) return void 0;
|
|
7429
|
+
const equal = gridGeometry(count, area3, cols, rowGap, [], false).boxes;
|
|
7430
|
+
const wholeWidths = nodes.map((node, index) => {
|
|
7431
|
+
const aspect = node.caption === void 0 ? wholePictureAspect(node) : void 0;
|
|
7432
|
+
return aspect === void 0 ? void 0 : Math.min(equal[index].width, equal[index].height * aspect);
|
|
7433
|
+
});
|
|
7434
|
+
const media = wholeWidths.flatMap((width2, index) => width2 !== void 0 && width2 < equal[index].width - scale2 ? [index] : []);
|
|
7435
|
+
const others = nodes.flatMap((_, index) => wholeWidths[index] === void 0 ? [index] : []);
|
|
7436
|
+
if (media.length && others.length) {
|
|
7437
|
+
const freed = media.reduce((sum, index) => sum + equal[index].width - wholeWidths[index], 0);
|
|
7438
|
+
return nodes.map((_, index) => media.includes(index) ? wholeWidths[index] : equal[index].width + freed / others.length);
|
|
7439
|
+
}
|
|
7440
|
+
const prose = (node) => !node.children && node.caption === void 0 && (node.field === "text" || node.field === "items" || node.field === "bullets");
|
|
7441
|
+
if (count !== 2 || !nodes.every(prose)) return void 0;
|
|
7442
|
+
const need = (node, width2) => naturalHeight(node, width2, hasCards, void 0, settings);
|
|
7443
|
+
const heights = nodes.map((node, index) => need(node, equal[index].width));
|
|
7444
|
+
const long = heights[0] >= heights[1] ? 0 : 1, short = 1 - long;
|
|
7445
|
+
if (heights[long] < WEIGHTED_DEMAND_RATIO * heights[short]) return void 0;
|
|
7446
|
+
const total = equal[0].width + equal[1].width, line2 = contentNominalSize(nodes[short].field) * scale2 * 1.3;
|
|
7447
|
+
let best;
|
|
7448
|
+
for (const share of WEIGHTED_SHARES) {
|
|
7449
|
+
const longHeight = need(nodes[long], total * share), shortHeight = need(nodes[short], total * (1 - share));
|
|
7450
|
+
if (shortHeight > heights[short] + line2 || longHeight > heights[long] - line2 * 0.5) continue;
|
|
7451
|
+
if (!best || longHeight < best.height - 1e-6) best = { share, height: longHeight };
|
|
7452
|
+
}
|
|
7453
|
+
return best ? long === 0 ? [best.share, 1 - best.share] : [1 - best.share, best.share] : void 0;
|
|
7454
|
+
};
|
|
7112
7455
|
const arrange = (nodes, area3, settings, reserved2 = 0, gapOverride, containerPath = path, recorded = true) => {
|
|
7113
7456
|
const count = Math.max(nodes.length, reserved2);
|
|
7114
7457
|
if (!count) return;
|
|
@@ -7116,7 +7459,12 @@ function composeSlide(input, options = {}) {
|
|
|
7116
7459
|
const actualGap = gapOverride ?? (settings === rootSettings ? gap : localGap);
|
|
7117
7460
|
let cols = defaultColumns(count, area3, settings);
|
|
7118
7461
|
const hasRegions = nodes.some((node) => node.region);
|
|
7462
|
+
if (!hasRegions && (mode === "auto" || nodes.length === 1)) for (const node of nodes) {
|
|
7463
|
+
node.auto = true;
|
|
7464
|
+
node.lone = nodes.length === 1 && reserved2 === 0;
|
|
7465
|
+
}
|
|
7119
7466
|
const candidates = decisions && recorded ? [] : void 0;
|
|
7467
|
+
const stacks = !hasRegions && count === nodes.length && count > 1 && !(mode === "column" && settings.weights?.length);
|
|
7120
7468
|
if (mode === "auto" && !hasRegions) {
|
|
7121
7469
|
let best = Infinity;
|
|
7122
7470
|
for (let candidate = 1; candidate <= Math.min(count, settings.columns ?? 6); candidate++) {
|
|
@@ -7138,14 +7486,24 @@ function composeSlide(input, options = {}) {
|
|
|
7138
7486
|
...hasRegions ? {} : { selectedColumns: cols },
|
|
7139
7487
|
candidates: candidates ?? []
|
|
7140
7488
|
});
|
|
7141
|
-
const grid = gridGeometry(count, area3, cols, actualGap, settings.weights ?? [], mode === "column");
|
|
7489
|
+
const grid = gridGeometry(count, area3, cols, actualGap, (mode === "auto" && !hasRegions ? autoRowWeights(nodes, count, cols, area3, actualGap, settings) : void 0) ?? settings.weights ?? [], mode === "column");
|
|
7490
|
+
if (cols === 1 && stacks) {
|
|
7491
|
+
grid.boxes = stackedBoxes(nodes, area3, actualGap, settings);
|
|
7492
|
+
grid.rows = grid.boxes.map((box) => ({ offset: box.y - area3.y, size: box.height }));
|
|
7493
|
+
}
|
|
7142
7494
|
const mirrored = (box) => rtl ? { ...box, x: area3.x + area3.width - (box.x - area3.x) - box.width } : box;
|
|
7143
7495
|
const boxes = grid.boxes.map(mirrored);
|
|
7144
7496
|
if (recorded && !hasRegions) flows.push({ path: containerPath, box: { ...area3 }, composition: { ...settings }, columns: rtl ? grid.columns.map((track) => ({ offset: area3.width - track.offset - track.size, size: track.size })) : grid.columns, rows: grid.rows, gap: grid.gap, itemCount: nodes.length, slotCount: count });
|
|
7497
|
+
const rowItems = /* @__PURE__ */ new Map(), stack = [];
|
|
7145
7498
|
nodes.forEach((node, index) => {
|
|
7146
7499
|
const box = node.region ? mirrored(regionBox(node.region, area3, actualGap)) : boxes[index];
|
|
7500
|
+
const first = items.length;
|
|
7147
7501
|
placeNode(node, box, settings);
|
|
7502
|
+
if (!hasRegions && cols > 1 && !node.children) rowItems.set(Math.floor(index / cols), [...rowItems.get(Math.floor(index / cols)) ?? [], ...range(first, items.length)]);
|
|
7503
|
+
else if (!hasRegions && cols === 1 && stacks && !node.children) stack.push(...range(first, items.length));
|
|
7148
7504
|
});
|
|
7505
|
+
for (const set2 of rowItems.values()) peerSets.push(set2);
|
|
7506
|
+
if (stack.length > 1) peerSets.push(stack);
|
|
7149
7507
|
};
|
|
7150
7508
|
let regionTag, templateCell = false;
|
|
7151
7509
|
const composeChart = (node, box, settings) => {
|
|
@@ -7153,7 +7511,15 @@ function composeSlide(input, options = {}) {
|
|
|
7153
7511
|
const valueAxis = chartValueAxis(node.value, resolved, { width: box.width, height: box.height, scale: scale2, minFontSize: settings.minFontSize });
|
|
7154
7512
|
return valueAxis ? { valueAxis } : void 0;
|
|
7155
7513
|
};
|
|
7156
|
-
const
|
|
7514
|
+
const VIDEO_ASPECT = 16 / 9, CHART_MAX_ASPECT_RATIO = 3 / 4;
|
|
7515
|
+
const settleCaption = (caption, frame, anchor) => {
|
|
7516
|
+
if (caption.position === "above" || anchor !== "top") return;
|
|
7517
|
+
const target = round2(frame.y + frame.height + caption.fontSize * 0.4), dy = target - caption.box.y;
|
|
7518
|
+
if (dy >= -0.01) return;
|
|
7519
|
+
caption.box = { ...caption.box, y: target };
|
|
7520
|
+
caption.fit = translateTextFit(caption.fit, dy);
|
|
7521
|
+
};
|
|
7522
|
+
const placeNode = (node, box, settings, cards = hasCards, listColumns, metricReferenceHeight, anchor = "top") => {
|
|
7157
7523
|
if (node.children) {
|
|
7158
7524
|
const own3 = inheritedSettings(settings, node.composition), inner = inset(box, own3);
|
|
7159
7525
|
if (!node.synthetic) groups.push({ path: node.path, box, contentBox: inner, composition: own3 });
|
|
@@ -7175,8 +7541,24 @@ function composeSlide(input, options = {}) {
|
|
|
7175
7541
|
const timelineLayout = node.field === "timeline" ? measureTimeline(node, box, settings) : void 0;
|
|
7176
7542
|
const internal = quoteLayout ?? codeLayout ?? metricLayout ?? timelineLayout, body = internal?.parts.find((part) => part.role === "body" || part.role === "value");
|
|
7177
7543
|
const columns2 = textValue !== void 0 && !internal ? listColumnsFor(node, box, settings, listColumns) : void 0;
|
|
7178
|
-
const
|
|
7179
|
-
const
|
|
7544
|
+
const floorSize = snapFontSizeUp((settings.minFontSize ?? 16) * scale2);
|
|
7545
|
+
const prose = textValue !== void 0 && !internal ? proseMeasure(node, box.width) : void 0, wholeBox = box;
|
|
7546
|
+
if (prose && prose.width < box.width - 0.5) {
|
|
7547
|
+
const side = alignmentFor(node.field), atEnd = rtl ? side === "left" : side === "right";
|
|
7548
|
+
box = { ...box, x: side === "center" ? box.x + (box.width - prose.width) / 2 : atEnd ? box.x + box.width - prose.width : box.x, width: prose.width };
|
|
7549
|
+
}
|
|
7550
|
+
let text2 = internal ? body?.fit : columns2 ? columns2.length > 1 ? mergeListColumns(columns2) : columns2[0].text : textValue !== void 0 ? fitContent(node.field, node.value, textValue, box, prose?.size ?? contentNominalSize(node.field) * scale2, floorSize, node.path, node.payload.numbering) : void 0;
|
|
7551
|
+
if (prose && box !== wholeBox && text2 && textValue !== void 0) {
|
|
7552
|
+
const wide = fitContent(node.field, node.value, textValue, wholeBox, prose.size, floorSize, node.path, node.payload.numbering);
|
|
7553
|
+
if (wide.fontSize > text2.fontSize + 1e-9 || text2.overflow && !wide.overflow) {
|
|
7554
|
+
text2 = wide;
|
|
7555
|
+
box = wholeBox;
|
|
7556
|
+
}
|
|
7557
|
+
}
|
|
7558
|
+
if (node.field === "video") box = roundBox(containedBox(box, VIDEO_ASPECT, anchor));
|
|
7559
|
+
else if (node.field === "chart" && !templateCell && modeFor(settings) === "auto" && box.height > box.width * CHART_MAX_ASPECT_RATIO) box = roundBox({ ...box, height: box.width * CHART_MAX_ASPECT_RATIO });
|
|
7560
|
+
const image = node.field === "image" ? composeImage(node.host ?? {}, node.hostPath ?? node.path, box, box, imageContext(void 0, anchor)) : void 0;
|
|
7561
|
+
if (caption) settleCaption(caption, image?.box ?? box, anchor);
|
|
7180
7562
|
const chart = node.field === "chart" ? composeChart(node, box, settings) : void 0;
|
|
7181
7563
|
items.push({
|
|
7182
7564
|
path: node.path,
|
|
@@ -7184,7 +7566,7 @@ function composeSlide(input, options = {}) {
|
|
|
7184
7566
|
type: node.type,
|
|
7185
7567
|
value: node.value,
|
|
7186
7568
|
payload: node.payload,
|
|
7187
|
-
box: internal ? acceptedBox(box) : box,
|
|
7569
|
+
box: codeLayout && !codeLayout.overflow ? { ...acceptedBox(box), height: Math.min(acceptedBox(box).height, round2(codeLayout.bounds.height)) } : internal ? acceptedBox(box) : box,
|
|
7188
7570
|
...image ? { image } : {},
|
|
7189
7571
|
...chart ? { chart } : {},
|
|
7190
7572
|
...frameBox ? { frameBox } : {},
|
|
@@ -7201,7 +7583,7 @@ function composeSlide(input, options = {}) {
|
|
|
7201
7583
|
...regionTag !== void 0 ? { region: regionTag } : {},
|
|
7202
7584
|
...columns2 && columns2.length > 1 ? { listColumns: columns2 } : {}
|
|
7203
7585
|
});
|
|
7204
|
-
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." });
|
|
7586
|
+
if (box.width < 100 * scale2 || !templateCell && !contentSized.has(node) && 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." });
|
|
7205
7587
|
};
|
|
7206
7588
|
const listColumnsFor = (node, box, settings, regionMode) => {
|
|
7207
7589
|
if (node.field !== "items" && node.field !== "bullets") return void 0;
|
|
@@ -7212,7 +7594,7 @@ function composeSlide(input, options = {}) {
|
|
|
7212
7594
|
if (mode === void 0 || mode === 1) return void 0;
|
|
7213
7595
|
const start = contentNominalSize(node.field) * scale2, floor = snapFontSizeUp((settings.minFontSize ?? 16) * scale2);
|
|
7214
7596
|
const numbering = node.payload.numbering;
|
|
7215
|
-
const listOptions = { ...richOptions(styleFor(node.field, node.path)), ...numbering !== void 0 ? { numbering } : bulletImage ? { bulletImage } : {} };
|
|
7597
|
+
const listOptions = { ...richOptions(styleFor(node.field, node.path)), ...numbering !== void 0 ? { numbering } : bulletImage ? { bulletImage } : noListBullet ? { bullet: "none" } : {} };
|
|
7216
7598
|
const columnGap = (count2) => Math.min(gap, box.width / (count2 * 2));
|
|
7217
7599
|
const columnBoxes = (count2) => {
|
|
7218
7600
|
const between = columnGap(count2), columnWidth = (box.width - between * (count2 - 1)) / count2;
|
|
@@ -7248,7 +7630,7 @@ function composeSlide(input, options = {}) {
|
|
|
7248
7630
|
const size = Math.min(...shrunk.map((column) => column.text.fontSize));
|
|
7249
7631
|
return shrunk.map((column) => ({ ...column, text: renumber(fitList(chunk(column.start, column.end), column.box, size, size, listOptions), column.start) }));
|
|
7250
7632
|
};
|
|
7251
|
-
const LONG_LINES = 6, LONG_CODE_LINES = 12, startSize =
|
|
7633
|
+
const LONG_LINES = 6, LONG_CODE_LINES = 12, startSize = PROSE_NOMINAL_SIZE * scale2;
|
|
7252
7634
|
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);
|
|
7253
7635
|
const isLong = (node, cellWidth) => {
|
|
7254
7636
|
if (node.children) return node.children.some((child) => isLong(child, cellWidth));
|
|
@@ -7272,22 +7654,37 @@ function composeSlide(input, options = {}) {
|
|
|
7272
7654
|
if (node.field === "code") return String(typeof node.value === "string" ? node.value : record7(node.value).source ?? "").split("\n").length > LONG_CODE_LINES;
|
|
7273
7655
|
return false;
|
|
7274
7656
|
};
|
|
7275
|
-
const
|
|
7657
|
+
const proseMeasure = (node, cellWidth) => {
|
|
7658
|
+
const role = contentNominalSize(node.field) * scale2;
|
|
7659
|
+
if (node.field !== "text" || node.children || !node.auto) return { size: role, width: cellWidth };
|
|
7660
|
+
const linesAt = (width2, size) => estimatedLines(node.value, width2, size);
|
|
7661
|
+
const measureAt = (size) => Math.min(cellWidth, PROSE_MEASURE_CHARS * AVERAGE_CHARACTER_EM * size);
|
|
7662
|
+
const lead = LEAD_NOMINAL_SIZE * scale2;
|
|
7663
|
+
if (node.lone && lead > role && linesAt(measureAt(lead), lead) <= 2) return { size: lead, width: linesAt(cellWidth, lead) <= 1 ? cellWidth : measureAt(lead) };
|
|
7664
|
+
return { size: role, width: linesAt(cellWidth, role) <= 1 ? cellWidth : measureAt(role) };
|
|
7665
|
+
};
|
|
7666
|
+
const MEASURED_FIELDS = /* @__PURE__ */ new Set(["text", "items", "bullets", "quote", "metric", "code"]);
|
|
7667
|
+
const measuredNode = (node) => node.children ? node.children.length > 0 && node.children.every(measuredNode) : MEASURED_FIELDS.has(node.field);
|
|
7668
|
+
const naturalHeight = (node, cellWidth, cards, metricReferenceHeight, naturalSettings = composition, atFloor = false, sizeOverride) => {
|
|
7276
7669
|
const pad = cards ? 2 * Math.min(12 * scale2, cellWidth / 4) : 0, inner = Math.max(scale2, cellWidth - pad);
|
|
7277
|
-
if (node.children) return node.children.reduce((sum, child) => sum + naturalHeight(child, cellWidth, false), 0) + gap * Math.max(0, node.children.length - 1) + pad;
|
|
7670
|
+
if (node.children) return node.children.reduce((sum, child) => sum + naturalHeight(child, cellWidth, false, void 0, naturalSettings, atFloor), 0) + gap * Math.max(0, node.children.length - 1) + pad;
|
|
7671
|
+
const floorSize = snapFontSizeUp((naturalSettings.minFontSize ?? 16) * scale2);
|
|
7278
7672
|
let content;
|
|
7279
7673
|
if (node.field === "text" || node.field === "items" || node.field === "bullets") {
|
|
7280
|
-
const
|
|
7281
|
-
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);
|
|
7282
|
-
content = "height" in fit && typeof fit.height === "number" ? fit.height : fit.lines.length * fit.lineHeight;
|
|
7674
|
+
const prose = proseMeasure(node, inner), size = sizeOverride ?? (atFloor ? floorSize : prose.size);
|
|
7675
|
+
const fit = fitContent(node.field, node.value, contentText(node.field, node.value) ?? "", { x: 0, y: 0, width: atFloor || sizeOverride !== void 0 ? inner : prose.width, height: 1e6 }, size, size, node.path, node.payload.numbering);
|
|
7676
|
+
content = Math.max("height" in fit && typeof fit.height === "number" ? fit.height : fit.lines.length * fit.lineHeight, fit.placement?.height ?? 0);
|
|
7283
7677
|
} else if (node.field === "quote") content = measureQuote(node, { x: 0, y: 0, width: inner, height: 1e6 }, naturalSettings).bounds.height + 18;
|
|
7284
|
-
else if (node.field === "code")
|
|
7285
|
-
|
|
7678
|
+
else if (node.field === "code") {
|
|
7679
|
+
const code = measureCode(node, { x: 0, y: 0, width: inner, height: 1e6 }, naturalSettings), source = code.parts.find((part) => part.role === "body");
|
|
7680
|
+
content = source?.fit ? source.box.y + source.fit.lines.length * source.fit.lineHeight + 18 : 1e6;
|
|
7681
|
+
} 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;
|
|
7286
7682
|
else if (node.field === "timeline") content = 170 * scale2;
|
|
7287
7683
|
else if (node.field === "table") {
|
|
7288
7684
|
const value = record7(node.value);
|
|
7289
7685
|
content = ((Array.isArray(value.rows) ? value.rows.length : 4) + 1) * 36 * scale2;
|
|
7290
7686
|
} else content = inner / 1.6;
|
|
7687
|
+
if (atFloor && !(node.field === "text" || node.field === "items" || node.field === "bullets")) content *= Math.min(1, floorSize / startSize);
|
|
7291
7688
|
return content + (node.caption !== void 0 ? 32 * scale2 : 0) + pad;
|
|
7292
7689
|
};
|
|
7293
7690
|
const templateRegions = [], headingAreas = [];
|
|
@@ -7302,6 +7699,13 @@ function composeSlide(input, options = {}) {
|
|
|
7302
7699
|
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 };
|
|
7303
7700
|
};
|
|
7304
7701
|
const contents = new Map(binding.regions.map((entry) => [entry.name, [...entry.blocks, ...entry.overflow].map(unitOf)]));
|
|
7702
|
+
for (const region of plan2.regions) {
|
|
7703
|
+
const units = contents.get(region.name) ?? [];
|
|
7704
|
+
if (region.flow === "auto") for (const unit of units) {
|
|
7705
|
+
unit.auto = true;
|
|
7706
|
+
unit.lone = units.length === 1;
|
|
7707
|
+
}
|
|
7708
|
+
}
|
|
7305
7709
|
const BELOW = "(below)";
|
|
7306
7710
|
const belowUnits = binding.below.map(unitOf);
|
|
7307
7711
|
const belowRegion = { name: BELOW, accepts: [], role: "supporting", flow: "auto", max: belowUnits.length, bleed: false, listColumns: 1, anchor: "top", empty: "collapse" };
|
|
@@ -7340,7 +7744,7 @@ function composeSlide(input, options = {}) {
|
|
|
7340
7744
|
const list = [];
|
|
7341
7745
|
let top = y2;
|
|
7342
7746
|
for (const field of fields2) {
|
|
7343
|
-
const requested = (field === "title" ? 54 : field === "tag" ? 16 :
|
|
7747
|
+
const requested = (field === "title" ? 54 : field === "tag" ? 16 : PROSE_NOMINAL_SIZE) * scale2;
|
|
7344
7748
|
const maxHeight = Math.max(height * (field === "title" ? 0.26 : field === "subtitle" ? 0.12 : 0.045), minSize * 1.22 + 2 * rasterPadding);
|
|
7345
7749
|
const box = { x, y: top, width: areaWidth, height: maxHeight };
|
|
7346
7750
|
const text2 = fitPlacedText(field, slide[field], annotationText(slide[field]), box, requested, minSize, `${path}.${field}`);
|
|
@@ -7361,33 +7765,35 @@ function composeSlide(input, options = {}) {
|
|
|
7361
7765
|
const cellWidth = (cell.width - gap2 * (shape.columns - 1)) / shape.columns - (cards ? 2 * Math.min(12 * scale2, cell.width / 4) : 0);
|
|
7362
7766
|
return units.some((unit) => isLong(unit, cellWidth)) ? "column" : "grid";
|
|
7363
7767
|
};
|
|
7364
|
-
const regionNeed = (name, areaWidth) => {
|
|
7768
|
+
const regionNeed = (name, areaWidth, atFloor = false) => {
|
|
7365
7769
|
const units = unitsOf(name), region = name === BELOW ? belowRegion : regionOf.get(name);
|
|
7366
|
-
if (!units.length) return region.empty === "keep" ? 2 * startSize * 1.22 + (hasCards && !region.bleed ? 2 * Math.min(12 * scale2, areaWidth / 4) : 0) : 0;
|
|
7770
|
+
if (!units.length) return region.empty === "keep" && !atFloor ? 2 * (region.flow === "auto" ? LEAD_NOMINAL_SIZE * scale2 : startSize) * 1.22 + (hasCards && !region.bleed ? 2 * Math.min(12 * scale2, areaWidth / 4) : 0) : 0;
|
|
7367
7771
|
const shape = flowShape(arrangementOf(region, units, { width: areaWidth, height: areaWidth / 4 }), units.length, true);
|
|
7368
7772
|
const cellWidth = (areaWidth - gap2 * (shape.columns - 1)) / shape.columns, cards = hasCards && !region.bleed;
|
|
7369
7773
|
let total = 0, index = 0;
|
|
7370
7774
|
for (const count of shape.perRow) {
|
|
7371
7775
|
let row = 0;
|
|
7372
|
-
for (let k = 0; k < count; k++) row = Math.max(row, naturalHeight(units[index++], cellWidth, cards));
|
|
7776
|
+
for (let k = 0; k < count; k++) row = Math.max(row, naturalHeight(units[index++], cellWidth, cards, void 0, composition, atFloor));
|
|
7373
7777
|
total += row;
|
|
7374
7778
|
}
|
|
7375
7779
|
return total + gap2 * Math.max(0, shape.rows - 1);
|
|
7376
7780
|
};
|
|
7377
7781
|
const areaNeed = (name, rect) => name === "title" ? groupHeight(headingItemsAt(titleFields, 0, 0, spanWidth(rect))) : name === "subtitle" ? groupHeight(headingItemsAt(subtitleFields, 0, 0, spanWidth(rect))) : regionNeed(name, spanWidth(rect));
|
|
7378
7782
|
const demands = rowSizes.map((size, row) => {
|
|
7379
|
-
let need = 0, heading = false, below = false;
|
|
7783
|
+
let need = 0, floor = 0, heading = false, below = false;
|
|
7380
7784
|
for (const [name, rect] of rects) {
|
|
7381
|
-
|
|
7785
|
+
const autoSpan = size === "auto" && rect.rowSpan > 1 && rect.row === row && rowSizes.slice(rect.row, rect.row + rect.rowSpan).every((entry) => entry === "auto");
|
|
7786
|
+
if (size === "auto" ? rect.row !== row || rect.rowSpan !== 1 && !autoSpan : row < rect.row || row >= rect.row + rect.rowSpan) continue;
|
|
7382
7787
|
if (size !== "auto" && rect.rowSpan > 1 && rowSizes.slice(rect.row, rect.row + rect.rowSpan).some((entry) => entry === "auto")) continue;
|
|
7383
|
-
const value = areaNeed(name, rect) / rect.rowSpan;
|
|
7788
|
+
const value = areaNeed(name, rect) / (autoSpan ? 1 : rect.rowSpan);
|
|
7789
|
+
if (size === "auto" && name !== "title" && name !== "subtitle") floor = Math.max(floor, regionNeed(name, spanWidth(rect), true));
|
|
7384
7790
|
if (value > need) {
|
|
7385
7791
|
need = value;
|
|
7386
7792
|
heading = name === "title" || name === "subtitle";
|
|
7387
7793
|
below = name === BELOW;
|
|
7388
7794
|
}
|
|
7389
7795
|
}
|
|
7390
|
-
return { size, need, kind: heading ? "heading" : below ? "below" : "body" };
|
|
7796
|
+
return { size, need, ...size === "auto" && !heading ? { floor } : {}, kind: heading ? "heading" : below ? "below" : "body" };
|
|
7391
7797
|
});
|
|
7392
7798
|
const heights = allocateRows(demands, frame.height, gap2);
|
|
7393
7799
|
const rowY = [];
|
|
@@ -7395,9 +7801,11 @@ function composeSlide(input, options = {}) {
|
|
|
7395
7801
|
rowY.push(size > 0 || !heights.slice(0, row).some((above) => above > 0) ? y2 : y2 - gap2);
|
|
7396
7802
|
return size > 0 ? y2 + size + gap2 : y2;
|
|
7397
7803
|
}, 0);
|
|
7804
|
+
const stackUsed = heights.reduce((sum, size) => sum + size, 0) + gap2 * Math.max(0, heights.filter((size) => size > 0).length - 1);
|
|
7805
|
+
const stackShift = plan2.stack === void 0 ? 0 : Math.max(0, frame.height - stackUsed) * (plan2.stack === "middle" ? 0.5 : 1);
|
|
7398
7806
|
const logical = (rect) => {
|
|
7399
|
-
const last = rect.row + rect.rowSpan - 1, y2 = frame.y + rowY[rect.row];
|
|
7400
|
-
return { x: frame.x + columnX[rect.column], y: y2, width: spanWidth(rect), height: Math.max(0, frame.y + rowY[last] + heights[last] - y2) };
|
|
7807
|
+
const last = rect.row + rect.rowSpan - 1, y2 = frame.y + stackShift + rowY[rect.row];
|
|
7808
|
+
return { x: frame.x + columnX[rect.column], y: y2, width: spanWidth(rect), height: Math.max(0, frame.y + stackShift + rowY[last] + heights[last] - y2) };
|
|
7401
7809
|
};
|
|
7402
7810
|
const flip = hints.mirror === true !== rtl;
|
|
7403
7811
|
const physical = (cell) => flip ? { ...cell, x: frame.x + frame.width - (cell.x - frame.x) - cell.width } : cell;
|
|
@@ -7454,18 +7862,8 @@ function composeSlide(input, options = {}) {
|
|
|
7454
7862
|
const arrangement = arrangementOf(region, units, cell);
|
|
7455
7863
|
let boxes = flowCells(flowShape(arrangement, units.length, cell.width >= cell.height), cell, gap2).cells;
|
|
7456
7864
|
const referenceHeights = boxes.map((box) => box.height);
|
|
7457
|
-
|
|
7458
|
-
|
|
7459
|
-
const used = naturals.reduce((a, b) => a + b, 0) + gap2 * (units.length - 1);
|
|
7460
|
-
if (used < cell.height) {
|
|
7461
|
-
let y2 = cell.y + (region.anchor === "middle" ? (cell.height - used) / 2 : cell.height - used);
|
|
7462
|
-
boxes = naturals.map((size) => {
|
|
7463
|
-
const next = { x: cell.x, y: y2, width: cell.width, height: size };
|
|
7464
|
-
y2 += size + gap2;
|
|
7465
|
-
return next;
|
|
7466
|
-
});
|
|
7467
|
-
}
|
|
7468
|
-
}
|
|
7865
|
+
const stacked = arrangement === "column" && !(units.length === 1 && region.anchor === "top");
|
|
7866
|
+
if (stacked) boxes = stackedBoxes(units, cell, gap2, settings, cards, region.anchor);
|
|
7469
7867
|
if ((arrangement === "grid" || arrangement === "row") && region.anchor !== "top") {
|
|
7470
7868
|
const naturals = boxes.map((box, index) => {
|
|
7471
7869
|
const unit = units[index];
|
|
@@ -7480,22 +7878,44 @@ function composeSlide(input, options = {}) {
|
|
|
7480
7878
|
});
|
|
7481
7879
|
}
|
|
7482
7880
|
if (rtl) boxes = boxes.map((box) => ({ ...box, x: cell.x + cell.width - (box.x - cell.x) - box.width }));
|
|
7881
|
+
const shape = flowShape(arrangement, units.length, cell.width >= cell.height), rowItems = shape.perRow.map(() => []);
|
|
7882
|
+
const rowOf = (index) => {
|
|
7883
|
+
let row = 0;
|
|
7884
|
+
for (let seen = shape.perRow[0] ?? 0; index >= seen; seen += shape.perRow[++row] ?? Infinity) ;
|
|
7885
|
+
return row;
|
|
7886
|
+
};
|
|
7887
|
+
const stack = [];
|
|
7483
7888
|
units.forEach((unit, index) => {
|
|
7484
|
-
|
|
7889
|
+
const first = items.length;
|
|
7890
|
+
placeNode(unit, boxes[index], settings, cards, region.listColumns, region.anchor === "top" || stacked ? void 0 : referenceHeights[index], region.anchor);
|
|
7891
|
+
if (!unit.children) {
|
|
7892
|
+
rowItems[rowOf(index)]?.push(...range(first, items.length));
|
|
7893
|
+
leafItems.push(...range(first, items.length));
|
|
7894
|
+
stack.push(...range(first, items.length));
|
|
7895
|
+
}
|
|
7485
7896
|
});
|
|
7897
|
+
if (arrangement !== "column") peerSets.push(...rowItems.filter((_, row) => (shape.perRow[row] ?? 0) > 1));
|
|
7898
|
+
else if (stacked && stack.length > 1) peerSets.push(stack);
|
|
7486
7899
|
return arrangement;
|
|
7487
7900
|
} finally {
|
|
7488
7901
|
regionTag = void 0;
|
|
7489
7902
|
templateCell = false;
|
|
7490
7903
|
}
|
|
7491
7904
|
};
|
|
7905
|
+
const bands = /* @__PURE__ */ new Map();
|
|
7906
|
+
let leafItems = [];
|
|
7492
7907
|
for (const region of plan2.regions) {
|
|
7493
7908
|
const units = unitsOf(region.name), bound = binding.regions.find((entry) => entry.name === region.name);
|
|
7494
7909
|
const rect = rects.get(region.name);
|
|
7495
7910
|
let cell = physical(logical(rect ?? ownRects.get(region.name)));
|
|
7496
7911
|
const areaBox = region.bleed && rect ? roundBox(cell) : void 0;
|
|
7497
7912
|
if (region.bleed && rect) cell = bleed(cell);
|
|
7913
|
+
leafItems = [];
|
|
7498
7914
|
const arrangement = units.length && rect ? placeRegion(region, units, cell) : void 0;
|
|
7915
|
+
if (arrangement && rect) {
|
|
7916
|
+
const band = `${rect.row}:${rect.rowSpan}:${region.role}`;
|
|
7917
|
+
bands.set(band, [...bands.get(band) ?? [], leafItems]);
|
|
7918
|
+
}
|
|
7499
7919
|
templateRegions.push({
|
|
7500
7920
|
name: region.name,
|
|
7501
7921
|
box: roundBox(cell),
|
|
@@ -7512,8 +7932,36 @@ function composeSlide(input, options = {}) {
|
|
|
7512
7932
|
...areaBox ? { areaBox } : {}
|
|
7513
7933
|
});
|
|
7514
7934
|
}
|
|
7935
|
+
for (const members of bands.values()) if (members.length > 1) peerSets.push(members.flat());
|
|
7515
7936
|
if (belowUnits.length) placeRegion(belowRegion, belowUnits, physical(logical(rects.get(BELOW))));
|
|
7516
7937
|
};
|
|
7938
|
+
const sharePeerSizes = () => {
|
|
7939
|
+
const parent = /* @__PURE__ */ new Map();
|
|
7940
|
+
const find = (index) => {
|
|
7941
|
+
let root = index;
|
|
7942
|
+
while (parent.has(root) && parent.get(root) !== root) root = parent.get(root);
|
|
7943
|
+
parent.set(index, root);
|
|
7944
|
+
return root;
|
|
7945
|
+
};
|
|
7946
|
+
for (const set2 of peerSets) for (const index of set2) parent.set(find(index), find(set2[0]));
|
|
7947
|
+
const kindOf = (item) => !item.text || item.quoteLayout || item.codeLayout || item.metricLayout || item.timelineLayout || item.listColumns ? void 0 : item.field === "text" ? "text" : item.field === "items" || item.field === "bullets" ? "list" : void 0;
|
|
7948
|
+
const sets = /* @__PURE__ */ new Map();
|
|
7949
|
+
for (const index of parent.keys()) {
|
|
7950
|
+
const item = items[index], kind2 = item && kindOf(item);
|
|
7951
|
+
if (kind2) sets.set(`${find(index)}:${kind2}`, [...sets.get(`${find(index)}:${kind2}`) ?? [], index]);
|
|
7952
|
+
}
|
|
7953
|
+
for (const members of sets.values()) {
|
|
7954
|
+
if (members.length < 2) continue;
|
|
7955
|
+
const size = Math.min(...members.map((index) => items[index].text.fontSize));
|
|
7956
|
+
for (const index of members) {
|
|
7957
|
+
const item = items[index];
|
|
7958
|
+
if (item.text.fontSize <= size + 1e-9) continue;
|
|
7959
|
+
const text2 = contentText(item.field, item.value) ?? "";
|
|
7960
|
+
const refit = fitContent(item.field, item.value, text2, item.box, size, snapFontSizeUp((item.composition.minFontSize ?? 16) * scale2), item.path, item.payload.numbering);
|
|
7961
|
+
if (!refit.overflow && Math.abs(refit.fontSize - size) < 1e-9) item.text = refit;
|
|
7962
|
+
}
|
|
7963
|
+
}
|
|
7964
|
+
};
|
|
7517
7965
|
const ownMode = record7(slide.composition).mode;
|
|
7518
7966
|
const direction = hints.contentDirection;
|
|
7519
7967
|
const directionMode = direction === "vertical" ? "column" : direction === "horizontal" ? "row" : "auto";
|
|
@@ -7529,6 +7977,7 @@ function composeSlide(input, options = {}) {
|
|
|
7529
7977
|
const support = { field: "blocks", type: "group", value: rest.map((node) => node.payload), path, payload: {}, children: rest, composition: {}, synthetic: true };
|
|
7530
7978
|
arrange(firstChart ? [primary, support] : [support, primary], contentBox, rootSettings, 0);
|
|
7531
7979
|
} else arrange(pending, contentBox, rootSettings, 0);
|
|
7980
|
+
sharePeerSizes();
|
|
7532
7981
|
if (listBullet?.value === "image" && !bulletImage && items.some((item) => (item.field === "items" || item.field === "bullets") && item.payload.numbering === void 0)) {
|
|
7533
7982
|
diagnostics.push({ code: "unresolved-content", path: listBullet.path, message: "Picture bullets (listBullet: image) need an organization logo (the primary organization, or the one design.logo names); the marker glyph is drawn instead." });
|
|
7534
7983
|
}
|
|
@@ -7591,4 +8040,4 @@ function resolveCanvasDimensions(input) {
|
|
|
7591
8040
|
return { width, height };
|
|
7592
8041
|
}
|
|
7593
8042
|
|
|
7594
|
-
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_LEAD_MIN_CONTRAST, CHART_MAX_INTERVALS, CHART_MIN_TICK_SPACING_PX, CHART_SERIES_MIN_DIFFERENCE, CHART_SERIES_MIN_LIGHTNESS_STEP, CHART_SERIES_TIER_SIZE, CHART_SERIES_TINT_MIX, CHART_TEXT_FLOOR_PX, 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, METRIC_VALUE_MIN_CONTRAST, 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, chartIntervalsFor, chartLabelText, chartLeadFromScheme, 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, metricValueColor, 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 };
|
|
8043
|
+
export { ASCII_QUOTE_MARKS, 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_LEAD_MIN_CONTRAST, CHART_MAX_INTERVALS, CHART_MIN_TICK_SPACING_PX, CHART_SERIES_MIN_DIFFERENCE, CHART_SERIES_MIN_LIGHTNESS_STEP, CHART_SERIES_TIER_SIZE, CHART_SERIES_TINT_MIX, CHART_TEXT_FLOOR_PX, CHART_TEXT_PX, CHART_TYPES, CITATION_MARKER_RAISE, CITATION_MARKER_SCALE, CODE_HIGHLIGHT_LANGUAGES, CODE_HIGHLIGHT_MAX_LENGTH, CODE_NOMINAL_SIZE, 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, LEAD_NOMINAL_SIZE, LIST_NOMINAL_SIZE, 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, METRIC_VALUE_MIN_CONTRAST, 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, PROSE_NOMINAL_SIZE, QUOTE_MARKS, QUOTE_NOMINAL_SIZE, QUOTE_SOURCE_SEPARATOR, REGION_ANCHORS, REGION_FLOWS, REGION_KINDS, REGION_ROLES, RESERVED_REGION_NAMES, SLIDE_SCOPED_BUILTINS, SOCIAL_PLATFORMS, SURFACE_ALT_MIN_CONTRAST, SURFACE_ALT_MIX, TABLE_NOMINAL_SIZE, 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, chartIntervalsFor, chartLabelText, chartLeadFromScheme, 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, isWrappedInQuoteMarks, 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, metricValueColor, niceScale, normalizeColorVariant, normalizeHexColor, normalizeLanguageFamily, numberFormatError, numberingAtLevel, numberingFindings, numberingStyleDraws, paragraphDirection, paragraphDirectionAt, parseReference, pathFor, patternBitmap, patternRuns, physicalAlignment, placeTextLines, placedImageBlocks, pointerPath, promotedRegionKeys, provenanceOf, quoteLanguage, quoteMarksFor, 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, shareHeights, sliceNumberedItems, slideCitations, slideTokenSpans, snapFontSizeDown, snapFontSizeUp, stackCategoryValues, suggestChartNumberFix, surfaceAltColor, tableCellDisplayValue, tableGrid, tableRowBoundaries, textColorForFill, textWidthMeasurer, timelineMarkerShapes, timelineTextColor, toExcelNumberFormat, tokenizeCode, unresolvedReference, unusedDatasets, unwrapQuoteMarks, usesSlideBuiltin, variableDeclarations, visitContentPayloads, visualReadingOrder, walkCitationRuns, wrapText };
|