@dloizides/poster-render 0.1.0 → 0.2.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/index.mjs CHANGED
@@ -29,6 +29,11 @@ var LayoutId = /* @__PURE__ */ ((LayoutId2) => {
29
29
  LayoutId2["PictureLeft"] = "picture-left";
30
30
  LayoutId2["PictureBottom"] = "picture-bottom";
31
31
  LayoutId2["List"] = "list";
32
+ LayoutId2["Arch"] = "arch";
33
+ LayoutId2["PhoneClockSafe"] = "phone-clock-safe";
34
+ LayoutId2["PhoneArch"] = "phone-arch";
35
+ LayoutId2["DesktopSafe"] = "desktop-safe";
36
+ LayoutId2["DesktopArch"] = "desktop-arch";
32
37
  return LayoutId2;
33
38
  })(LayoutId || {});
34
39
 
@@ -60,10 +65,10 @@ var FORMAT_SIZES = {
60
65
 
61
66
  // src/palettes.ts
62
67
  var PALETTES = {
63
- ["sand" /* Sand */]: { background: "#f5f4f2", tint: "#ece8e3", title: "#958a80", accent: "#e9b47f", ink: "#5f564f", soft: "#b3a89e", card: "#ffffff" },
64
- ["night" /* Night */]: { background: "#1c1a17", tint: "#25221e", title: "#e8dccb", accent: "#e9b47f", ink: "#f4efe8", soft: "#9c9284", card: "#2c2824" },
65
- ["sea" /* Sea */]: { background: "#eef4f3", tint: "#e1ecea", title: "#4f7d7a", accent: "#e07a5f", ink: "#2f3e46", soft: "#8aa3a1", card: "#ffffff" },
66
- ["rose" /* Rose */]: { background: "#f8efec", tint: "#f1e2dd", title: "#9b6b63", accent: "#c9846f", ink: "#4a3934", soft: "#b39a92", card: "#ffffff" }
68
+ ["sand" /* Sand */]: { background: "#f5f4f2", tint: "#ece8e3", title: "#958a80", accent: "#e9b47f", ink: "#5f564f", soft: "#b3a89e", card: "#ffffff", arch: "#ede8e2" },
69
+ ["night" /* Night */]: { background: "#1c1a17", tint: "#25221e", title: "#e8dccb", accent: "#e9b47f", ink: "#f4efe8", soft: "#9c9284", card: "#2c2824", arch: "#25221f" },
70
+ ["sea" /* Sea */]: { background: "#eef4f3", tint: "#e1ecea", title: "#4f7d7a", accent: "#e07a5f", ink: "#2f3e46", soft: "#8aa3a1", card: "#ffffff", arch: "#e4ecea" },
71
+ ["rose" /* Rose */]: { background: "#f8efec", tint: "#f1e2dd", title: "#9b6b63", accent: "#c9846f", ink: "#4a3934", soft: "#b39a92", card: "#ffffff", arch: "#f1e5e1" }
67
72
  };
68
73
 
69
74
  // src/fontSets.ts
@@ -314,11 +319,11 @@ function itemGroup(item, l, u) {
314
319
  }
315
320
  return { lines, gapAfter: 26 * u };
316
321
  }
317
- function eventGroups(doc, l, u) {
322
+ function eventGroups(doc, l, u, withPrices) {
318
323
  const b = doc.blocks;
319
324
  const groups = [];
320
325
  b.schedule?.forEach((row) => groups.push({ lines: [l.strong?.(row.label, 66), l.accent?.(row.time, 60)], gapAfter: 30 * u }));
321
- b.prices?.forEach((row) => groups.push({ lines: [l.strong?.(row.amount, 66), l.accent?.(row.label, 52)], gapAfter: 30 * u }));
326
+ (withPrices ? b.prices : void 0)?.forEach((row) => groups.push({ lines: [l.strong?.(row.amount, 66), l.accent?.(row.label, 52)], gapAfter: 30 * u }));
322
327
  return groups;
323
328
  }
324
329
  function listGroups(doc, l, u) {
@@ -329,7 +334,11 @@ function listGroups(doc, l, u) {
329
334
  }
330
335
  return groups;
331
336
  }
332
- function bodyGroups(doc, p, u) {
337
+ function flankPriceGroups(doc, p, u) {
338
+ const l = makers(p, u);
339
+ return (doc.blocks.prices ?? []).map((row) => ({ lines: [l.strong?.(row.amount, 110), l.accent?.(row.label, 48)], gapAfter: 30 * u }));
340
+ }
341
+ function bodyGroups(doc, p, u, withPrices = true) {
333
342
  const l = makers(p, u);
334
343
  const b = doc.blocks;
335
344
  const groups = [];
@@ -337,10 +346,10 @@ function bodyGroups(doc, p, u) {
337
346
  if (b.venue) {
338
347
  groups.push({ lines: b.venue.map((v) => l.venue?.(v, isList ? 48 : 58)), gapAfter: 40 * u, rule: { color: p.accent, height: 8 * u } });
339
348
  }
340
- groups.push(...isList ? listGroups(doc, l, u) : eventGroups(doc, l, u));
349
+ groups.push(...isList ? listGroups(doc, l, u) : eventGroups(doc, l, u, withPrices));
341
350
  if (b.includes) {
342
- const lines = [l.accent?.(b.includes.heading, 36), ...b.includes.items.map((i) => l.item?.(i, 40))];
343
- groups.push({ lines, gapAfter: 24 * u, card: { color: p.card, pad: 28 * u } });
351
+ const lines = [l.accent?.(b.includes.heading, 38), ...b.includes.items.map((i) => l.item?.(i, 38))];
352
+ groups.push({ lines, gapAfter: 24 * u, card: { color: p.card, pad: 28 * u }, uniform: true });
344
353
  }
345
354
  if (b.footer) {
346
355
  groups.push({ lines: [l.soft?.(b.footer, 34)], gapAfter: 0 });
@@ -348,6 +357,51 @@ function bodyGroups(doc, p, u) {
348
357
  return groups;
349
358
  }
350
359
 
360
+ // src/layout/layoutSpecs.ts
361
+ var flanksBeside = (pic, top, bottom2, m) => [
362
+ [m, top, pic[0] - 2 * m, bottom2 - top],
363
+ [pic[0] + pic[2] + m, top, 1 - pic[0] - pic[2] - 2 * m, bottom2 - top]
364
+ ];
365
+ var ARCH_PIC = [0.22, 0.42, 0.56, 0.58];
366
+ var PHONE_ARCH_PIC = [0.2, 0.6, 0.6, 0.4];
367
+ var DESK_ARCH_PIC = [0.355, 0.07, 0.32, 0.93];
368
+ var ARCH_LANDSCAPE = {
369
+ header: [0.04, 0.06, 0.3, 0.5],
370
+ body: [0.04, 0.58, 0.3, 0.36],
371
+ picture: [0.36, 0.08, 0.3, 0.92],
372
+ alignX: 0.5,
373
+ flanks: [[0.68, 0.08, 0.28, 0.42], [0.68, 0.52, 0.28, 0.42]],
374
+ arch: 0.06
375
+ };
376
+ var LAYOUT_SPECS = {
377
+ ["arch" /* Arch */]: {
378
+ portrait: { header: [0.045, 0.025, 0.91, 0.18], body: [0.045, 0.215, 0.91, 0.19], picture: ARCH_PIC, alignX: 0.5, flanks: flanksBeside(ARCH_PIC, 0.44, 0.97, 0.03), arch: 0.04 },
379
+ landscape: ARCH_LANDSCAPE
380
+ },
381
+ ["phone-clock-safe" /* PhoneClockSafe */]: {
382
+ portrait: { header: [0.045, 0.28, 0.91, 0.2], body: [0.045, 0.5, 0.42, 0.44], picture: [0.48, 0.5, 0.52, 0.5], alignX: 1 },
383
+ landscape: { header: [0.04, 0.2, 0.52, 0.3], body: [0.04, 0.52, 0.52, 0.42], picture: [0.6, 0.12, 0.4, 0.88], alignX: 1 }
384
+ },
385
+ ["phone-arch" /* PhoneArch */]: {
386
+ portrait: { header: [0.045, 0.3, 0.91, 0.13], body: [0.045, 0.44, 0.91, 0.14], picture: PHONE_ARCH_PIC, alignX: 0.5, flanks: flanksBeside(PHONE_ARCH_PIC, 0.63, 0.94, 0.03), arch: 0.08 },
387
+ landscape: { ...ARCH_LANDSCAPE, header: [0.04, 0.16, 0.3, 0.42], picture: [0.36, 0.16, 0.3, 0.84] }
388
+ },
389
+ ["desktop-safe" /* DesktopSafe */]: {
390
+ portrait: { header: [0.08, 0.06, 0.84, 0.24], body: [0.08, 0.31, 0.46, 0.58], picture: [0.56, 0.36, 0.44, 0.64], alignX: 1 },
391
+ landscape: { header: [0.0625, 0.05, 0.58, 0.44], body: [0.0625, 0.5, 0.58, 0.38], picture: [0.67, 0.0972, 0.29, 0.9028], alignX: 1 }
392
+ },
393
+ ["desktop-arch" /* DesktopArch */]: {
394
+ portrait: { header: [0.08, 0.06, 0.84, 0.2], body: [0.08, 0.27, 0.84, 0.2], picture: [0.14, 0.48, 0.72, 0.52], alignX: 0.5, arch: 0.05 },
395
+ landscape: { header: [0.07, 0.3, 0.26, 0.45], body: [0.7, 0.25, 0.27, 0.65], picture: DESK_ARCH_PIC, alignX: 0.5, logo: [0.88, 0.04, 0.09, 0.14], arch: 0.05 }
396
+ }
397
+ };
398
+ var r = Math.round;
399
+ var toRect = (f, w, h) => {
400
+ const x = r(f[0] * w);
401
+ const y = r(f[1] * h);
402
+ return { x, y, w: r((f[0] + f[2]) * w) - x, h: r((f[1] + f[3]) * h) - y };
403
+ };
404
+
351
405
  // src/layout/geometry.ts
352
406
  var MARGIN = 0.045;
353
407
  var HEADER_PORTRAIT = 0.3;
@@ -360,12 +414,12 @@ var PICTURE_SIDE = {
360
414
  ["list" /* List */]: [0.5, 0.36]
361
415
  };
362
416
  var ANCHOR_Y = { ["top" /* Top */]: 0, ["center" /* Center */]: 0.5, ["bottom" /* Bottom */]: 1 };
363
- var r = Math.round;
417
+ var r2 = Math.round;
364
418
  function side(w, h, fraction) {
365
- const m = r(Math.min(w, h) * MARGIN);
419
+ const m = r2(Math.min(w, h) * MARGIN);
366
420
  if (h >= w) {
367
- const split2 = r(w * (1 - fraction[0]));
368
- const top2 = r(h * HEADER_PORTRAIT);
421
+ const split2 = r2(w * (1 - fraction[0]));
422
+ const top2 = r2(h * HEADER_PORTRAIT);
369
423
  return {
370
424
  header: { x: m, y: m, w: w - 2 * m, h: top2 - 2 * m },
371
425
  picture: { x: split2, y: top2, w: w - split2, h: h - top2 },
@@ -373,19 +427,19 @@ function side(w, h, fraction) {
373
427
  alignX: 1
374
428
  };
375
429
  }
376
- const split = r(w * (1 - fraction[1]));
377
- const top = r(h * HEADER_LANDSCAPE);
430
+ const split = r2(w * (1 - fraction[1]));
431
+ const top = r2(h * HEADER_LANDSCAPE);
378
432
  return {
379
433
  header: { x: m, y: m, w: split - 2 * m, h: top - m },
380
434
  picture: { x: split, y: 0, w: w - split, h },
381
- body: { x: m, y: top + r(m / 2), w: split - 2 * m, h: h - top - r(m / 2) - m },
435
+ body: { x: m, y: top + r2(m / 2), w: split - 2 * m, h: h - top - r2(m / 2) - m },
382
436
  alignX: 1
383
437
  };
384
438
  }
385
439
  function bottom(w, h) {
386
- const m = r(Math.min(w, h) * MARGIN);
387
- const top = r(h * BOTTOM_HEADER);
388
- const pic = r(h * BOTTOM_PICTURE);
440
+ const m = r2(Math.min(w, h) * MARGIN);
441
+ const top = r2(h * BOTTOM_HEADER);
442
+ const pic = r2(h * BOTTOM_PICTURE);
389
443
  return {
390
444
  header: { x: m, y: m, w: w - 2 * m, h: top - 2 * m },
391
445
  body: { x: m, y: top, w: w - 2 * m, h: pic - top - m },
@@ -393,8 +447,23 @@ function bottom(w, h) {
393
447
  alignX: 0.5
394
448
  };
395
449
  }
450
+ function fromSpec(spec, w, h) {
451
+ return {
452
+ header: toRect(spec.header, w, h),
453
+ body: toRect(spec.body, w, h),
454
+ picture: toRect(spec.picture, w, h),
455
+ alignX: spec.alignX,
456
+ flanks: spec.flanks?.map((f) => toRect(f, w, h)),
457
+ logo: spec.logo ? toRect(spec.logo, w, h) : void 0,
458
+ arch: spec.arch
459
+ };
460
+ }
396
461
  var mirror = (rect, w) => ({ ...rect, x: w - rect.x - rect.w });
397
462
  function geometry(layout, w, h) {
463
+ const oriented = LAYOUT_SPECS[layout];
464
+ if (oriented) {
465
+ return fromSpec(h >= w ? oriented.portrait : oriented.landscape, w, h);
466
+ }
398
467
  if (layout === "picture-bottom" /* PictureBottom */) {
399
468
  return bottom(w, h);
400
469
  }
@@ -431,6 +500,12 @@ function lineSize(line, width, k, avail) {
431
500
  const indent = line.bullet ? line.size * k * BULLET_INDENT : 0;
432
501
  return Math.max(0, Math.min(line.size * k, line.size * (avail - indent) / Math.max(width, 1)));
433
502
  }
503
+ function groupRatio(m, k, avail) {
504
+ if (!m.group.uniform) {
505
+ return null;
506
+ }
507
+ return Math.min(...m.group.lines.map((line, i) => lineSize(line, m.widths[i] ?? 1, k, avail) / line.size));
508
+ }
434
509
  function placeGroup(m, k, col, y0, out) {
435
510
  const { group } = m;
436
511
  let y = y0;
@@ -441,11 +516,12 @@ function placeGroup(m, k, col, y0, out) {
441
516
  const pad = group.card ? group.card.pad * k : 0;
442
517
  const top = y;
443
518
  y += pad;
519
+ const ratio = groupRatio(m, k, col.w - 2 * pad);
444
520
  group.lines.forEach((line, i) => {
445
- const size = lineSize(line, m.widths[i] ?? 1, k, col.w - 2 * pad);
521
+ const size = ratio === null ? lineSize(line, m.widths[i] ?? 1, k, col.w - 2 * pad) : line.size * ratio;
446
522
  const indent = line.bullet ? line.size * k * BULLET_INDENT : 0;
447
- const x = col.x + pad + indent;
448
523
  const w = (m.widths[i] ?? 0) * size / line.size;
524
+ const x = col.right ? col.x + col.w - pad - w : col.x + pad + indent;
449
525
  out?.texts.push({ text: line.text, font: "", color: line.color, box: { x, y, w, h: size * LINE_HEIGHT } });
450
526
  if (line.bullet && out) {
451
527
  out.bullets.push({ x: col.x + pad + size * BULLET_RADIUS, y: y + size * LINE_HEIGHT / 2, r: size * BULLET_RADIUS, color: line.bullet });
@@ -524,21 +600,22 @@ function flow(ctx, groups, zone, fonts) {
524
600
  var BASE = 1080;
525
601
  var LOGO_SHARE = 0.26;
526
602
  var CARD_RADIUS = 0.035;
527
- function roundRect(ctx, r2, radius) {
528
- const rad = Math.min(radius, r2.w / 2, r2.h / 2);
603
+ var CAP_TOP = 0.15;
604
+ function roundRect(ctx, r3, radius) {
605
+ const rad = Math.min(radius, r3.w / 2, r3.h / 2);
529
606
  ctx.beginPath();
530
- ctx.moveTo(r2.x + rad, r2.y);
531
- ctx.arcTo(r2.x + r2.w, r2.y, r2.x + r2.w, r2.y + r2.h, rad);
532
- ctx.arcTo(r2.x + r2.w, r2.y + r2.h, r2.x, r2.y + r2.h, rad);
533
- ctx.arcTo(r2.x, r2.y + r2.h, r2.x, r2.y, rad);
534
- ctx.arcTo(r2.x, r2.y, r2.x + r2.w, r2.y, rad);
607
+ ctx.moveTo(r3.x + rad, r3.y);
608
+ ctx.arcTo(r3.x + r3.w, r3.y, r3.x + r3.w, r3.y + r3.h, rad);
609
+ ctx.arcTo(r3.x + r3.w, r3.y + r3.h, r3.x, r3.y + r3.h, rad);
610
+ ctx.arcTo(r3.x, r3.y + r3.h, r3.x, r3.y, rad);
611
+ ctx.arcTo(r3.x, r3.y, r3.x + r3.w, r3.y, rad);
535
612
  ctx.closePath();
536
613
  ctx.fill();
537
614
  }
538
615
  function drawFlow(ctx, f, radius) {
539
- f.rules.forEach((r2) => {
540
- ctx.fillStyle = r2.color;
541
- ctx.fillRect(r2.rect.x, r2.rect.y, r2.rect.w, r2.rect.h);
616
+ f.rules.forEach((r3) => {
617
+ ctx.fillStyle = r3.color;
618
+ ctx.fillRect(r3.rect.x, r3.rect.y, r3.rect.w, r3.rect.h);
542
619
  });
543
620
  f.cards.forEach((c) => {
544
621
  ctx.fillStyle = c.color;
@@ -569,6 +646,30 @@ function checked(input, assets) {
569
646
  }
570
647
  return result.doc;
571
648
  }
649
+ function archRect(geo) {
650
+ if (geo.arch === void 0) {
651
+ return null;
652
+ }
653
+ const top = geo.picture.y + Math.round(geo.picture.h * geo.arch);
654
+ return { x: geo.picture.x, y: top, w: geo.picture.w, h: geo.picture.y + geo.picture.h - top };
655
+ }
656
+ function drawArch(ctx, r3, color) {
657
+ const rad = r3.w / 2;
658
+ ctx.fillStyle = color;
659
+ ctx.fillRect(r3.x, r3.y + rad, r3.w, r3.h - rad);
660
+ ctx.beginPath();
661
+ ctx.arc(r3.x + rad, r3.y + rad, rad, Math.PI, Math.PI * 2);
662
+ ctx.fill();
663
+ }
664
+ function flankFlows(ctx, groups, flanks, fonts) {
665
+ const half = Math.ceil(groups.length / 2);
666
+ return flanks.map((zone, i) => i === 0 ? flow(ctx, groups.slice(0, half), zone, fonts) : flow(ctx, groups.slice(half), { ...zone, right: true }, fonts));
667
+ }
668
+ function capAligned(zone, head) {
669
+ const first = head.texts[0]?.box;
670
+ const shift = first ? Math.min(Math.max(0, Math.round(first.y + first.h * CAP_TOP) - zone.y), Math.round(zone.h / 2)) : 0;
671
+ return { ...zone, y: zone.y + shift, h: zone.h - shift };
672
+ }
572
673
  function splitHeader(header, hasLogo) {
573
674
  const logoW = hasLogo ? Math.round(header.w * LOGO_SHARE) : 0;
574
675
  return { text: { ...header, w: header.w - logoW * 1.1 }, logo: { ...header, x: header.x + header.w - logoW, w: logoW } };
@@ -591,20 +692,25 @@ function render(input, assets, canvas) {
591
692
  ctx.fillRect(0, 0, width, height);
592
693
  if (doc.background === "tint" /* Tint */) {
593
694
  ctx.fillStyle = palette.tint;
594
- [geo.header, geo.body].forEach((r2) => ctx.fillRect(r2.x, r2.y, r2.w, r2.h));
695
+ [geo.header, geo.body].forEach((r3) => ctx.fillRect(r3.x, r3.y, r3.w, r3.h));
595
696
  }
596
- const zones = splitHeader(geo.header, doc.logo !== void 0);
697
+ const zones = geo.logo ? { text: geo.header, logo: geo.logo } : splitHeader(geo.header, doc.logo !== void 0);
597
698
  const head = flow(ctx, headerGroups(doc, palette, u), zones.text, fonts);
598
- const body = flow(ctx, bodyGroups(doc, palette, u), geo.body, fonts);
699
+ const flanks = geo.flanks ?? [];
700
+ const body = flow(ctx, bodyGroups(doc, palette, u, flanks.length === 0), geo.body, fonts);
701
+ const sides = flanks.length > 0 ? flankFlows(ctx, flankPriceGroups(doc, palette, u), flanks, fonts) : [emptyFlow()];
599
702
  const radius = Math.min(width, height) * CARD_RADIUS;
600
- drawFlow(ctx, head, radius);
601
- drawFlow(ctx, body, radius);
703
+ [head, body, ...sides].forEach((f) => drawFlow(ctx, f, radius));
602
704
  const logoImage = doc.logo ? assets[doc.logo.imageId] : void 0;
603
705
  if (logoImage) {
604
- const r2 = placeContain(logoImage, zones.logo, "top" /* Top */, 1, 1);
605
- ctx.drawImage(logoImage, r2.x, r2.y, r2.w, r2.h);
706
+ const r3 = placeContain(logoImage, capAligned(zones.logo, head), "top" /* Top */, 1, 1);
707
+ ctx.drawImage(logoImage, r3.x, r3.y, r3.w, r3.h);
606
708
  }
607
709
  const image = doc.picture ? assets[doc.picture.imageId] : void 0;
710
+ const backdrop = image ? archRect(geo) : null;
711
+ if (backdrop) {
712
+ drawArch(ctx, backdrop, palette.arch);
713
+ }
608
714
  const picture = image && doc.picture ? placeContain(image, geo.picture, doc.picture.anchor, geo.alignX, doc.picture.scale) : null;
609
715
  if (image && picture) {
610
716
  ctx.drawImage(image, picture.x, picture.y, picture.w, picture.h);
@@ -614,8 +720,9 @@ function render(input, assets, canvas) {
614
720
  height,
615
721
  picture,
616
722
  pictureRegion: geo.picture,
617
- textBoxes: [...head.texts, ...body.texts].map((t) => t.box),
618
- cardBoxes: body.cards.map((c) => c.rect)
723
+ textBoxes: [head, body, ...sides].flatMap((f) => f.texts.map((t) => t.box)),
724
+ cardBoxes: body.cards.map((c) => c.rect),
725
+ backdrop
619
726
  };
620
727
  }
621
728
 
@@ -634,6 +741,30 @@ function exportPng(canvas) {
634
741
  return new Blob([bytes], { type: "image/png" });
635
742
  }
636
743
 
744
+ // src/layoutCatalogue.ts
745
+ var POSTERS = ["story" /* Story */, "post" /* Post */, "square" /* Square */];
746
+ var LAYOUT_CATALOGUE = [
747
+ { id: "picture-right" /* PictureRight */, designId: "E-A", label: "Picture right", description: "Titles across the top, details on the left, the picture on the right standing on the bottom edge.", formats: POSTERS },
748
+ { id: "picture-left" /* PictureLeft */, designId: "E-B", label: "Picture left", description: "Titles across the top, the picture on the left standing on the bottom edge, details on the right.", formats: POSTERS },
749
+ { id: "arch" /* Arch */, designId: "E-C", label: "Arch", description: "Titles and details on top, the picture centred in a soft arch at the bottom, prices either side.", formats: POSTERS },
750
+ { id: "picture-bottom" /* PictureBottom */, designId: "picture-bottom", label: "Picture bottom", description: "Titles and details on top, the picture across the bottom half.", formats: POSTERS },
751
+ { id: "list" /* List */, designId: "list", label: "Upcoming list", description: "Several dated events as a list beside the picture.", formats: POSTERS },
752
+ { id: "phone-clock-safe" /* PhoneClockSafe */, designId: "P-A", label: "Phone, clock clear", description: "Lock-screen wallpaper: top kept clear for the clock, details on the left, picture on the right.", formats: ["phone" /* Phone */] },
753
+ { id: "phone-arch" /* PhoneArch */, designId: "P-B", label: "Phone arch", description: "Lock-screen wallpaper: top kept clear for the clock, details in the middle, the picture in an arch at the bottom.", formats: ["phone" /* Phone */] },
754
+ { id: "desktop-safe" /* DesktopSafe */, designId: "D-A", label: "Desktop, icons clear", description: "Desktop wallpaper: text on the left clear of desktop icons and the taskbar, the picture on the right.", formats: ["desktop" /* Desktop */] },
755
+ { id: "desktop-arch" /* DesktopArch */, designId: "D-B", label: "Desktop arch", description: "Desktop wallpaper: titles left, the picture in a centred arch, details right.", formats: ["desktop" /* Desktop */] }
756
+ ];
757
+ var DEFAULTS = {
758
+ ["story" /* Story */]: "picture-right" /* PictureRight */,
759
+ ["post" /* Post */]: "picture-right" /* PictureRight */,
760
+ ["square" /* Square */]: "picture-right" /* PictureRight */,
761
+ ["phone" /* Phone */]: "phone-clock-safe" /* PhoneClockSafe */,
762
+ ["desktop" /* Desktop */]: "desktop-safe" /* DesktopSafe */
763
+ };
764
+ function defaultLayoutFor(format) {
765
+ return DEFAULTS[format];
766
+ }
767
+
637
768
  // src/examples/kizombaWorkshop.ts
638
769
  var WORKSHOPS = [
639
770
  { script: "Saturday 31 October", date: "Sat 31 Oct", first: "20:00 - 21:00", second: "21:00 - 22:00", party: "20\u20AC" },
@@ -685,6 +816,6 @@ var kizombaWorkshop = {
685
816
  };
686
817
  var kizombaWorkshopDocs = [...WORKSHOPS.map(workshopDoc), kizombaWorkshop];
687
818
 
688
- export { BackgroundStyle, FONT_SETS, FORMAT_SIZES, FlierDocError, FontSetId, FormatId, LayoutId, PALETTES, PaletteId, PictureAnchor, exportPng, flierDocSchema, kizombaWorkshop, kizombaWorkshopDocs, render, validateFlierDoc };
819
+ export { BackgroundStyle, FONT_SETS, FORMAT_SIZES, FlierDocError, FontSetId, FormatId, LAYOUT_CATALOGUE, LayoutId, PALETTES, PaletteId, PictureAnchor, defaultLayoutFor, exportPng, flierDocSchema, kizombaWorkshop, kizombaWorkshopDocs, render, validateFlierDoc };
689
820
  //# sourceMappingURL=index.mjs.map
690
821
  //# sourceMappingURL=index.mjs.map