@dloizides/poster-render 0.1.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/README.md +2 -1
- package/dist/index.d.mts +22 -2
- package/dist/index.d.ts +22 -2
- package/dist/index.js +250 -48
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +249 -49
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.1
|
|
4
|
+
|
|
5
|
+
- Venue pin: an accent disc with a pin glyph beside the venue lines; `RenderReport.iconBoxes`.
|
|
6
|
+
- Includes block drawn as a heading plus bullets, with no card.
|
|
7
|
+
- Price groups stay in one column when a wide body splits into two (`FlowGroup.keepWithNext`).
|
|
8
|
+
- `desktop-safe` landscape gets an explicit logo rect beside the title; `desktop-arch` logo enlarged and no longer pushed down to the title cap; `RenderReport.logo`.
|
|
9
|
+
- List rows: date at 0.7x, 48 px between dated rows.
|
|
10
|
+
|
|
11
|
+
## 0.2.0
|
|
12
|
+
|
|
13
|
+
- Layouts `arch`, `phone-clock-safe`, `phone-arch`, `desktop-safe`, `desktop-arch` (FLIER-1 D4 "Keep all layouts"); `LAYOUT_CATALOGUE` + `defaultLayoutFor`.
|
|
14
|
+
- Critic r2 nits: arch prices moved up beside the arch top, lighter arch fill, phone arch top at 63% height, desktop arch 40 px right, logo top on the title cap top.
|
|
15
|
+
- Includes block uses one size for every line; `RenderReport.backdrop`; `Palette.arch`.
|
|
16
|
+
|
|
3
17
|
## 0.1.0
|
|
4
18
|
|
|
5
19
|
- FlierDoc schema + validator, render, exportPng, 4 layouts, 5 formats, palettes, font sets, Kizomba example.
|
package/README.md
CHANGED
|
@@ -7,6 +7,7 @@ One JSON document (`FlierDoc`) in, one poster out. Used by Flier Studio (FLIER-1
|
|
|
7
7
|
- `render(doc, assets, canvas)`: validates first (throws `FlierDocError` before touching the canvas), resizes the canvas to the format, draws, returns a `RenderReport` (picture rect, text and card boxes).
|
|
8
8
|
- `exportPng(canvas)`: PNG `Blob` of the canvas size.
|
|
9
9
|
- Formats: story 1080x1920, post 1080x1350, square 1080x1080, phone 1170x2532, desktop 2560x1440.
|
|
10
|
-
- Layouts: `picture-right
|
|
10
|
+
- Layouts: `picture-right` (E-A), `picture-left` (E-B), `arch` (E-C), `picture-bottom`, `list`, `phone-clock-safe` (P-A, top kept clear for the lock-screen clock), `phone-arch` (P-B), `desktop-safe` (D-A, text clear of desktop icons and the taskbar), `desktop-arch` (D-B). `LAYOUT_CATALOGUE` lists id, design id, label, description and designed formats (for the app picker and the LLM prompt); `defaultLayoutFor(format)` gives E-A / P-A / D-A.
|
|
11
|
+
- Arch layouts paint a soft arch (palette `arch`, about 4% off the ground) behind the picture only, inside the picture region; prices sit large on either side. The includes block is set at one size for every line. Palettes: `sand`, `night`, `sea`, `rose`. Font sets: `classic`, `modern`, `elegant` (the app loads the web fonts).
|
|
11
12
|
- The picture is placed contain + anchor in its own region: never cropped, never faded, drawn last, and no text or card is laid out in its region. Text shrinks to fit, never overflows.
|
|
12
13
|
- Example: `kizombaWorkshopDocs` (3 workshops + list flier), `kizombaWorkshop` (the list flier).
|
package/dist/index.d.mts
CHANGED
|
@@ -21,7 +21,12 @@ declare enum LayoutId {
|
|
|
21
21
|
PictureRight = "picture-right",
|
|
22
22
|
PictureLeft = "picture-left",
|
|
23
23
|
PictureBottom = "picture-bottom",
|
|
24
|
-
List = "list"
|
|
24
|
+
List = "list",
|
|
25
|
+
Arch = "arch",
|
|
26
|
+
PhoneClockSafe = "phone-clock-safe",
|
|
27
|
+
PhoneArch = "phone-arch",
|
|
28
|
+
DesktopSafe = "desktop-safe",
|
|
29
|
+
DesktopArch = "desktop-arch"
|
|
25
30
|
}
|
|
26
31
|
|
|
27
32
|
declare enum PaletteId {
|
|
@@ -135,6 +140,9 @@ interface RenderReport {
|
|
|
135
140
|
pictureRegion: Rect;
|
|
136
141
|
textBoxes: Rect[];
|
|
137
142
|
cardBoxes: Rect[];
|
|
143
|
+
iconBoxes: Rect[];
|
|
144
|
+
logo: Rect | null;
|
|
145
|
+
backdrop: Rect | null;
|
|
138
146
|
}
|
|
139
147
|
interface Palette {
|
|
140
148
|
background: string;
|
|
@@ -144,6 +152,7 @@ interface Palette {
|
|
|
144
152
|
ink: string;
|
|
145
153
|
soft: string;
|
|
146
154
|
card: string;
|
|
155
|
+
arch: string;
|
|
147
156
|
}
|
|
148
157
|
interface FontSet {
|
|
149
158
|
display: string;
|
|
@@ -200,7 +209,18 @@ interface DataUrlCanvas {
|
|
|
200
209
|
/** Encodes the canvas as a PNG Blob of the canvas's exact pixel size. */
|
|
201
210
|
declare function exportPng(canvas: DataUrlCanvas): Blob;
|
|
202
211
|
|
|
212
|
+
interface LayoutCatalogueEntry {
|
|
213
|
+
id: LayoutId;
|
|
214
|
+
designId: string;
|
|
215
|
+
label: string;
|
|
216
|
+
description: string;
|
|
217
|
+
formats: readonly FormatId[];
|
|
218
|
+
}
|
|
219
|
+
declare const LAYOUT_CATALOGUE: readonly LayoutCatalogueEntry[];
|
|
220
|
+
/** The default layout for a format (D4: E-A for posters, P-A for phone, D-A for desktop). */
|
|
221
|
+
declare function defaultLayoutFor(format: FormatId): LayoutId;
|
|
222
|
+
|
|
203
223
|
declare const kizombaWorkshop: FlierDoc;
|
|
204
224
|
declare const kizombaWorkshopDocs: FlierDoc[];
|
|
205
225
|
|
|
206
|
-
export { BackgroundStyle, type DataUrlCanvas, FONT_SETS, FORMAT_SIZES, type FlierBlocks, type FlierDoc, FlierDocError, type FlierDocResult, type FontSet, FontSetId, FormatId, type FormatSize, type IncludesBlock, type JsonSchema, LayoutId, type ListItem, type LogoSlot, PALETTES, type Palette, PaletteId, PictureAnchor, type PictureSlot, type PosterAssets, type PosterCanvas, type PosterContext, type PosterImage, type PriceRow, type Rect, type RenderReport, type ScheduleRow, type TextMetricsLike, exportPng, flierDocSchema, kizombaWorkshop, kizombaWorkshopDocs, render, validateFlierDoc };
|
|
226
|
+
export { BackgroundStyle, type DataUrlCanvas, FONT_SETS, FORMAT_SIZES, type FlierBlocks, type FlierDoc, FlierDocError, type FlierDocResult, type FontSet, FontSetId, FormatId, type FormatSize, type IncludesBlock, type JsonSchema, LAYOUT_CATALOGUE, type LayoutCatalogueEntry, LayoutId, type ListItem, type LogoSlot, PALETTES, type Palette, PaletteId, PictureAnchor, type PictureSlot, type PosterAssets, type PosterCanvas, type PosterContext, type PosterImage, type PriceRow, type Rect, type RenderReport, type ScheduleRow, type TextMetricsLike, defaultLayoutFor, exportPng, flierDocSchema, kizombaWorkshop, kizombaWorkshopDocs, render, validateFlierDoc };
|
package/dist/index.d.ts
CHANGED
|
@@ -21,7 +21,12 @@ declare enum LayoutId {
|
|
|
21
21
|
PictureRight = "picture-right",
|
|
22
22
|
PictureLeft = "picture-left",
|
|
23
23
|
PictureBottom = "picture-bottom",
|
|
24
|
-
List = "list"
|
|
24
|
+
List = "list",
|
|
25
|
+
Arch = "arch",
|
|
26
|
+
PhoneClockSafe = "phone-clock-safe",
|
|
27
|
+
PhoneArch = "phone-arch",
|
|
28
|
+
DesktopSafe = "desktop-safe",
|
|
29
|
+
DesktopArch = "desktop-arch"
|
|
25
30
|
}
|
|
26
31
|
|
|
27
32
|
declare enum PaletteId {
|
|
@@ -135,6 +140,9 @@ interface RenderReport {
|
|
|
135
140
|
pictureRegion: Rect;
|
|
136
141
|
textBoxes: Rect[];
|
|
137
142
|
cardBoxes: Rect[];
|
|
143
|
+
iconBoxes: Rect[];
|
|
144
|
+
logo: Rect | null;
|
|
145
|
+
backdrop: Rect | null;
|
|
138
146
|
}
|
|
139
147
|
interface Palette {
|
|
140
148
|
background: string;
|
|
@@ -144,6 +152,7 @@ interface Palette {
|
|
|
144
152
|
ink: string;
|
|
145
153
|
soft: string;
|
|
146
154
|
card: string;
|
|
155
|
+
arch: string;
|
|
147
156
|
}
|
|
148
157
|
interface FontSet {
|
|
149
158
|
display: string;
|
|
@@ -200,7 +209,18 @@ interface DataUrlCanvas {
|
|
|
200
209
|
/** Encodes the canvas as a PNG Blob of the canvas's exact pixel size. */
|
|
201
210
|
declare function exportPng(canvas: DataUrlCanvas): Blob;
|
|
202
211
|
|
|
212
|
+
interface LayoutCatalogueEntry {
|
|
213
|
+
id: LayoutId;
|
|
214
|
+
designId: string;
|
|
215
|
+
label: string;
|
|
216
|
+
description: string;
|
|
217
|
+
formats: readonly FormatId[];
|
|
218
|
+
}
|
|
219
|
+
declare const LAYOUT_CATALOGUE: readonly LayoutCatalogueEntry[];
|
|
220
|
+
/** The default layout for a format (D4: E-A for posters, P-A for phone, D-A for desktop). */
|
|
221
|
+
declare function defaultLayoutFor(format: FormatId): LayoutId;
|
|
222
|
+
|
|
203
223
|
declare const kizombaWorkshop: FlierDoc;
|
|
204
224
|
declare const kizombaWorkshopDocs: FlierDoc[];
|
|
205
225
|
|
|
206
|
-
export { BackgroundStyle, type DataUrlCanvas, FONT_SETS, FORMAT_SIZES, type FlierBlocks, type FlierDoc, FlierDocError, type FlierDocResult, type FontSet, FontSetId, FormatId, type FormatSize, type IncludesBlock, type JsonSchema, LayoutId, type ListItem, type LogoSlot, PALETTES, type Palette, PaletteId, PictureAnchor, type PictureSlot, type PosterAssets, type PosterCanvas, type PosterContext, type PosterImage, type PriceRow, type Rect, type RenderReport, type ScheduleRow, type TextMetricsLike, exportPng, flierDocSchema, kizombaWorkshop, kizombaWorkshopDocs, render, validateFlierDoc };
|
|
226
|
+
export { BackgroundStyle, type DataUrlCanvas, FONT_SETS, FORMAT_SIZES, type FlierBlocks, type FlierDoc, FlierDocError, type FlierDocResult, type FontSet, FontSetId, FormatId, type FormatSize, type IncludesBlock, type JsonSchema, LAYOUT_CATALOGUE, type LayoutCatalogueEntry, LayoutId, type ListItem, type LogoSlot, PALETTES, type Palette, PaletteId, PictureAnchor, type PictureSlot, type PosterAssets, type PosterCanvas, type PosterContext, type PosterImage, type PriceRow, type Rect, type RenderReport, type ScheduleRow, type TextMetricsLike, defaultLayoutFor, exportPng, flierDocSchema, kizombaWorkshop, kizombaWorkshopDocs, render, validateFlierDoc };
|
package/dist/index.js
CHANGED
|
@@ -31,6 +31,11 @@ var LayoutId = /* @__PURE__ */ ((LayoutId2) => {
|
|
|
31
31
|
LayoutId2["PictureLeft"] = "picture-left";
|
|
32
32
|
LayoutId2["PictureBottom"] = "picture-bottom";
|
|
33
33
|
LayoutId2["List"] = "list";
|
|
34
|
+
LayoutId2["Arch"] = "arch";
|
|
35
|
+
LayoutId2["PhoneClockSafe"] = "phone-clock-safe";
|
|
36
|
+
LayoutId2["PhoneArch"] = "phone-arch";
|
|
37
|
+
LayoutId2["DesktopSafe"] = "desktop-safe";
|
|
38
|
+
LayoutId2["DesktopArch"] = "desktop-arch";
|
|
34
39
|
return LayoutId2;
|
|
35
40
|
})(LayoutId || {});
|
|
36
41
|
|
|
@@ -62,10 +67,10 @@ var FORMAT_SIZES = {
|
|
|
62
67
|
|
|
63
68
|
// src/palettes.ts
|
|
64
69
|
var PALETTES = {
|
|
65
|
-
["sand" /* Sand */]: { background: "#f5f4f2", tint: "#ece8e3", title: "#958a80", accent: "#e9b47f", ink: "#5f564f", soft: "#b3a89e", card: "#ffffff" },
|
|
66
|
-
["night" /* Night */]: { background: "#1c1a17", tint: "#25221e", title: "#e8dccb", accent: "#e9b47f", ink: "#f4efe8", soft: "#9c9284", card: "#2c2824" },
|
|
67
|
-
["sea" /* Sea */]: { background: "#eef4f3", tint: "#e1ecea", title: "#4f7d7a", accent: "#e07a5f", ink: "#2f3e46", soft: "#8aa3a1", card: "#ffffff" },
|
|
68
|
-
["rose" /* Rose */]: { background: "#f8efec", tint: "#f1e2dd", title: "#9b6b63", accent: "#c9846f", ink: "#4a3934", soft: "#b39a92", card: "#ffffff" }
|
|
70
|
+
["sand" /* Sand */]: { background: "#f5f4f2", tint: "#ece8e3", title: "#958a80", accent: "#e9b47f", ink: "#5f564f", soft: "#b3a89e", card: "#ffffff", arch: "#ede8e2" },
|
|
71
|
+
["night" /* Night */]: { background: "#1c1a17", tint: "#25221e", title: "#e8dccb", accent: "#e9b47f", ink: "#f4efe8", soft: "#9c9284", card: "#2c2824", arch: "#25221f" },
|
|
72
|
+
["sea" /* Sea */]: { background: "#eef4f3", tint: "#e1ecea", title: "#4f7d7a", accent: "#e07a5f", ink: "#2f3e46", soft: "#8aa3a1", card: "#ffffff", arch: "#e4ecea" },
|
|
73
|
+
["rose" /* Rose */]: { background: "#f8efec", tint: "#f1e2dd", title: "#9b6b63", accent: "#c9846f", ink: "#4a3934", soft: "#b39a92", card: "#ffffff", arch: "#f1e5e1" }
|
|
69
74
|
};
|
|
70
75
|
|
|
71
76
|
// src/fontSets.ts
|
|
@@ -309,18 +314,19 @@ function headerGroups(doc, p, u) {
|
|
|
309
314
|
return [{ lines: lines.filter((x) => x !== void 0), gapAfter: 0 }];
|
|
310
315
|
}
|
|
311
316
|
function itemGroup(item, l, u) {
|
|
312
|
-
const lines = [l.script?.(item.date,
|
|
317
|
+
const lines = [l.script?.(item.date, 67)];
|
|
313
318
|
item.schedule.forEach((row) => lines.push(l.strong?.(`${row.label} ${row.time}`, 42)));
|
|
314
319
|
if (item.price) {
|
|
315
320
|
lines.push(l.accent?.(item.price, 42));
|
|
316
321
|
}
|
|
317
|
-
return { lines, gapAfter:
|
|
322
|
+
return { lines, gapAfter: 48 * u };
|
|
318
323
|
}
|
|
319
|
-
function eventGroups(doc, l, u) {
|
|
324
|
+
function eventGroups(doc, l, u, withPrices) {
|
|
320
325
|
const b = doc.blocks;
|
|
321
326
|
const groups = [];
|
|
322
327
|
b.schedule?.forEach((row) => groups.push({ lines: [l.strong?.(row.label, 66), l.accent?.(row.time, 60)], gapAfter: 30 * u }));
|
|
323
|
-
|
|
328
|
+
const prices = (withPrices ? b.prices : void 0) ?? [];
|
|
329
|
+
prices.forEach((row, i) => groups.push({ lines: [l.strong?.(row.amount, 66), l.accent?.(row.label, 52)], gapAfter: 30 * u, keepWithNext: i < prices.length - 1 }));
|
|
324
330
|
return groups;
|
|
325
331
|
}
|
|
326
332
|
function listGroups(doc, l, u) {
|
|
@@ -331,18 +337,22 @@ function listGroups(doc, l, u) {
|
|
|
331
337
|
}
|
|
332
338
|
return groups;
|
|
333
339
|
}
|
|
334
|
-
function
|
|
340
|
+
function flankPriceGroups(doc, p, u) {
|
|
341
|
+
const l = makers(p, u);
|
|
342
|
+
return (doc.blocks.prices ?? []).map((row) => ({ lines: [l.strong?.(row.amount, 110), l.accent?.(row.label, 48)], gapAfter: 30 * u }));
|
|
343
|
+
}
|
|
344
|
+
function bodyGroups(doc, p, u, withPrices = true) {
|
|
335
345
|
const l = makers(p, u);
|
|
336
346
|
const b = doc.blocks;
|
|
337
347
|
const groups = [];
|
|
338
348
|
const isList = doc.layout === "list" /* List */;
|
|
339
349
|
if (b.venue) {
|
|
340
|
-
groups.push({ lines: b.venue.map((v) => l.venue?.(v, isList ? 48 : 58)), gapAfter: 40 * u, rule: { color: p.accent, height: 8 * u } });
|
|
350
|
+
groups.push({ lines: b.venue.map((v) => l.venue?.(v, isList ? 48 : 58)), gapAfter: 40 * u, rule: { color: p.accent, height: 8 * u }, icon: { color: p.accent, glyph: p.background } });
|
|
341
351
|
}
|
|
342
|
-
groups.push(...isList ? listGroups(doc, l, u) : eventGroups(doc, l, u));
|
|
352
|
+
groups.push(...isList ? listGroups(doc, l, u) : eventGroups(doc, l, u, withPrices));
|
|
343
353
|
if (b.includes) {
|
|
344
|
-
const lines = [l.accent?.(b.includes.heading,
|
|
345
|
-
groups.push({ lines, gapAfter: 24 * u,
|
|
354
|
+
const lines = [l.accent?.(b.includes.heading, 38), ...b.includes.items.map((i) => l.item?.(i, 38))];
|
|
355
|
+
groups.push({ lines, gapAfter: 24 * u, uniform: true });
|
|
346
356
|
}
|
|
347
357
|
if (b.footer) {
|
|
348
358
|
groups.push({ lines: [l.soft?.(b.footer, 34)], gapAfter: 0 });
|
|
@@ -350,6 +360,51 @@ function bodyGroups(doc, p, u) {
|
|
|
350
360
|
return groups;
|
|
351
361
|
}
|
|
352
362
|
|
|
363
|
+
// src/layout/layoutSpecs.ts
|
|
364
|
+
var flanksBeside = (pic, top, bottom2, m) => [
|
|
365
|
+
[m, top, pic[0] - 2 * m, bottom2 - top],
|
|
366
|
+
[pic[0] + pic[2] + m, top, 1 - pic[0] - pic[2] - 2 * m, bottom2 - top]
|
|
367
|
+
];
|
|
368
|
+
var ARCH_PIC = [0.22, 0.42, 0.56, 0.58];
|
|
369
|
+
var PHONE_ARCH_PIC = [0.2, 0.6, 0.6, 0.4];
|
|
370
|
+
var DESK_ARCH_PIC = [0.355, 0.07, 0.32, 0.93];
|
|
371
|
+
var ARCH_LANDSCAPE = {
|
|
372
|
+
header: [0.04, 0.06, 0.3, 0.5],
|
|
373
|
+
body: [0.04, 0.58, 0.3, 0.36],
|
|
374
|
+
picture: [0.36, 0.08, 0.3, 0.92],
|
|
375
|
+
alignX: 0.5,
|
|
376
|
+
flanks: [[0.68, 0.08, 0.28, 0.42], [0.68, 0.52, 0.28, 0.42]],
|
|
377
|
+
arch: 0.06
|
|
378
|
+
};
|
|
379
|
+
var LAYOUT_SPECS = {
|
|
380
|
+
["arch" /* Arch */]: {
|
|
381
|
+
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 },
|
|
382
|
+
landscape: ARCH_LANDSCAPE
|
|
383
|
+
},
|
|
384
|
+
["phone-clock-safe" /* PhoneClockSafe */]: {
|
|
385
|
+
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 },
|
|
386
|
+
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 }
|
|
387
|
+
},
|
|
388
|
+
["phone-arch" /* PhoneArch */]: {
|
|
389
|
+
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 },
|
|
390
|
+
landscape: { ...ARCH_LANDSCAPE, header: [0.04, 0.16, 0.3, 0.42], picture: [0.36, 0.16, 0.3, 0.84] }
|
|
391
|
+
},
|
|
392
|
+
["desktop-safe" /* DesktopSafe */]: {
|
|
393
|
+
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 },
|
|
394
|
+
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, logo: [0.4, 0.045, 0.09, 0.17] }
|
|
395
|
+
},
|
|
396
|
+
["desktop-arch" /* DesktopArch */]: {
|
|
397
|
+
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 },
|
|
398
|
+
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.86, 0.03, 0.11, 0.18], arch: 0.05 }
|
|
399
|
+
}
|
|
400
|
+
};
|
|
401
|
+
var r = Math.round;
|
|
402
|
+
var toRect = (f, w, h) => {
|
|
403
|
+
const x = r(f[0] * w);
|
|
404
|
+
const y = r(f[1] * h);
|
|
405
|
+
return { x, y, w: r((f[0] + f[2]) * w) - x, h: r((f[1] + f[3]) * h) - y };
|
|
406
|
+
};
|
|
407
|
+
|
|
353
408
|
// src/layout/geometry.ts
|
|
354
409
|
var MARGIN = 0.045;
|
|
355
410
|
var HEADER_PORTRAIT = 0.3;
|
|
@@ -362,12 +417,12 @@ var PICTURE_SIDE = {
|
|
|
362
417
|
["list" /* List */]: [0.5, 0.36]
|
|
363
418
|
};
|
|
364
419
|
var ANCHOR_Y = { ["top" /* Top */]: 0, ["center" /* Center */]: 0.5, ["bottom" /* Bottom */]: 1 };
|
|
365
|
-
var
|
|
420
|
+
var r2 = Math.round;
|
|
366
421
|
function side(w, h, fraction) {
|
|
367
|
-
const m =
|
|
422
|
+
const m = r2(Math.min(w, h) * MARGIN);
|
|
368
423
|
if (h >= w) {
|
|
369
|
-
const split2 =
|
|
370
|
-
const top2 =
|
|
424
|
+
const split2 = r2(w * (1 - fraction[0]));
|
|
425
|
+
const top2 = r2(h * HEADER_PORTRAIT);
|
|
371
426
|
return {
|
|
372
427
|
header: { x: m, y: m, w: w - 2 * m, h: top2 - 2 * m },
|
|
373
428
|
picture: { x: split2, y: top2, w: w - split2, h: h - top2 },
|
|
@@ -375,19 +430,19 @@ function side(w, h, fraction) {
|
|
|
375
430
|
alignX: 1
|
|
376
431
|
};
|
|
377
432
|
}
|
|
378
|
-
const split =
|
|
379
|
-
const top =
|
|
433
|
+
const split = r2(w * (1 - fraction[1]));
|
|
434
|
+
const top = r2(h * HEADER_LANDSCAPE);
|
|
380
435
|
return {
|
|
381
436
|
header: { x: m, y: m, w: split - 2 * m, h: top - m },
|
|
382
437
|
picture: { x: split, y: 0, w: w - split, h },
|
|
383
|
-
body: { x: m, y: top +
|
|
438
|
+
body: { x: m, y: top + r2(m / 2), w: split - 2 * m, h: h - top - r2(m / 2) - m },
|
|
384
439
|
alignX: 1
|
|
385
440
|
};
|
|
386
441
|
}
|
|
387
442
|
function bottom(w, h) {
|
|
388
|
-
const m =
|
|
389
|
-
const top =
|
|
390
|
-
const pic =
|
|
443
|
+
const m = r2(Math.min(w, h) * MARGIN);
|
|
444
|
+
const top = r2(h * BOTTOM_HEADER);
|
|
445
|
+
const pic = r2(h * BOTTOM_PICTURE);
|
|
391
446
|
return {
|
|
392
447
|
header: { x: m, y: m, w: w - 2 * m, h: top - 2 * m },
|
|
393
448
|
body: { x: m, y: top, w: w - 2 * m, h: pic - top - m },
|
|
@@ -395,8 +450,23 @@ function bottom(w, h) {
|
|
|
395
450
|
alignX: 0.5
|
|
396
451
|
};
|
|
397
452
|
}
|
|
453
|
+
function fromSpec(spec, w, h) {
|
|
454
|
+
return {
|
|
455
|
+
header: toRect(spec.header, w, h),
|
|
456
|
+
body: toRect(spec.body, w, h),
|
|
457
|
+
picture: toRect(spec.picture, w, h),
|
|
458
|
+
alignX: spec.alignX,
|
|
459
|
+
flanks: spec.flanks?.map((f) => toRect(f, w, h)),
|
|
460
|
+
logo: spec.logo ? toRect(spec.logo, w, h) : void 0,
|
|
461
|
+
arch: spec.arch
|
|
462
|
+
};
|
|
463
|
+
}
|
|
398
464
|
var mirror = (rect, w) => ({ ...rect, x: w - rect.x - rect.w });
|
|
399
465
|
function geometry(layout, w, h) {
|
|
466
|
+
const oriented = LAYOUT_SPECS[layout];
|
|
467
|
+
if (oriented) {
|
|
468
|
+
return fromSpec(h >= w ? oriented.portrait : oriented.landscape, w, h);
|
|
469
|
+
}
|
|
400
470
|
if (layout === "picture-bottom" /* PictureBottom */) {
|
|
401
471
|
return bottom(w, h);
|
|
402
472
|
}
|
|
@@ -427,12 +497,32 @@ var RULE_WIDTH = 0.9;
|
|
|
427
497
|
var WIDE = 1.6;
|
|
428
498
|
var MIN_K = 0.02;
|
|
429
499
|
var STEPS = 22;
|
|
500
|
+
var ICON_SCALE = 1.6;
|
|
501
|
+
var ICON_GAP = 0.35;
|
|
430
502
|
var fontOf = (line, size, fonts) => `${line.weight} ${size}px ${fonts[line.role]}`;
|
|
431
|
-
var emptyFlow = () => ({ texts: [], cards: [], rules: [], bullets: [] });
|
|
503
|
+
var emptyFlow = () => ({ texts: [], cards: [], rules: [], bullets: [], icons: [] });
|
|
504
|
+
var iconSize = (group, k) => {
|
|
505
|
+
const first = group.lines[0];
|
|
506
|
+
return group.icon && first ? first.size * k * LINE_HEIGHT * ICON_SCALE : 0;
|
|
507
|
+
};
|
|
432
508
|
function lineSize(line, width, k, avail) {
|
|
433
509
|
const indent = line.bullet ? line.size * k * BULLET_INDENT : 0;
|
|
434
510
|
return Math.max(0, Math.min(line.size * k, line.size * (avail - indent) / Math.max(width, 1)));
|
|
435
511
|
}
|
|
512
|
+
function groupRatio(m, k, avail) {
|
|
513
|
+
if (!m.group.uniform) {
|
|
514
|
+
return null;
|
|
515
|
+
}
|
|
516
|
+
return Math.min(...m.group.lines.map((line, i) => lineSize(line, m.widths[i] ?? 1, k, avail) / line.size));
|
|
517
|
+
}
|
|
518
|
+
function placeIcon(group, d, x, textTop, textBottom, out) {
|
|
519
|
+
if (!group.icon || d <= 0) {
|
|
520
|
+
return textBottom;
|
|
521
|
+
}
|
|
522
|
+
const textH = textBottom - textTop;
|
|
523
|
+
out?.icons.push({ rect: { x, y: textTop + Math.max(0, (textH - d) / 2), w: d, h: d }, color: group.icon.color, glyph: group.icon.glyph });
|
|
524
|
+
return textTop + Math.max(textH, d);
|
|
525
|
+
}
|
|
436
526
|
function placeGroup(m, k, col, y0, out) {
|
|
437
527
|
const { group } = m;
|
|
438
528
|
let y = y0;
|
|
@@ -443,17 +533,22 @@ function placeGroup(m, k, col, y0, out) {
|
|
|
443
533
|
const pad = group.card ? group.card.pad * k : 0;
|
|
444
534
|
const top = y;
|
|
445
535
|
y += pad;
|
|
536
|
+
const d = iconSize(group, k);
|
|
537
|
+
const iconIndent = d > 0 ? d * (1 + ICON_GAP) : 0;
|
|
538
|
+
const avail = col.w - 2 * pad - iconIndent;
|
|
539
|
+
const ratio = groupRatio(m, k, avail);
|
|
446
540
|
group.lines.forEach((line, i) => {
|
|
447
|
-
const size = lineSize(line, m.widths[i] ?? 1, k,
|
|
448
|
-
const indent = line.bullet ? line.size * k * BULLET_INDENT : 0;
|
|
449
|
-
const x = col.x + pad + indent;
|
|
541
|
+
const size = ratio === null ? lineSize(line, m.widths[i] ?? 1, k, avail) : line.size * ratio;
|
|
542
|
+
const indent = (line.bullet ? line.size * k * BULLET_INDENT : 0) + iconIndent;
|
|
450
543
|
const w = (m.widths[i] ?? 0) * size / line.size;
|
|
544
|
+
const x = col.right ? col.x + col.w - pad - w : col.x + pad + indent;
|
|
451
545
|
out?.texts.push({ text: line.text, font: "", color: line.color, box: { x, y, w, h: size * LINE_HEIGHT } });
|
|
452
546
|
if (line.bullet && out) {
|
|
453
547
|
out.bullets.push({ x: col.x + pad + size * BULLET_RADIUS, y: y + size * LINE_HEIGHT / 2, r: size * BULLET_RADIUS, color: line.bullet });
|
|
454
548
|
}
|
|
455
549
|
y += size * LINE_HEIGHT;
|
|
456
550
|
});
|
|
551
|
+
y = placeIcon(group, d, col.x + pad, top + pad, y, out);
|
|
457
552
|
y += pad;
|
|
458
553
|
if (group.card) {
|
|
459
554
|
out?.cards.unshift({ rect: { x: col.x, y: top, w: col.w, h: y - top }, color: group.card.color });
|
|
@@ -467,6 +562,27 @@ function placeColumn(groups, k, col, out) {
|
|
|
467
562
|
}
|
|
468
563
|
return h;
|
|
469
564
|
}
|
|
565
|
+
var tallest = (heights, cut) => {
|
|
566
|
+
const left = heights.slice(0, cut).reduce((a, b) => a + b, 0);
|
|
567
|
+
const right = heights.slice(cut).reduce((a, b) => a + b, 0);
|
|
568
|
+
return Math.max(left, right);
|
|
569
|
+
};
|
|
570
|
+
function keepTogether(groups, heights, cut) {
|
|
571
|
+
const breaks = (c) => groups[c - 1]?.group.keepWithNext === true;
|
|
572
|
+
let back = cut;
|
|
573
|
+
while (back > 1 && breaks(back)) {
|
|
574
|
+
back--;
|
|
575
|
+
}
|
|
576
|
+
let fwd = cut;
|
|
577
|
+
while (fwd < groups.length - 1 && breaks(fwd)) {
|
|
578
|
+
fwd++;
|
|
579
|
+
}
|
|
580
|
+
const candidates = [back, fwd].filter((c) => !breaks(c));
|
|
581
|
+
if (candidates.length === 0) {
|
|
582
|
+
return cut;
|
|
583
|
+
}
|
|
584
|
+
return candidates.reduce((best, c) => tallest(heights, c) < tallest(heights, best) ? c : best);
|
|
585
|
+
}
|
|
470
586
|
function splitColumns(groups, zone) {
|
|
471
587
|
if (zone.w / Math.max(zone.h, 1) <= WIDE || groups.length < 2) {
|
|
472
588
|
return [{ col: zone, groups }];
|
|
@@ -481,7 +597,7 @@ function splitColumns(groups, zone) {
|
|
|
481
597
|
}
|
|
482
598
|
acc += h;
|
|
483
599
|
});
|
|
484
|
-
cut = Math.min(cut, groups.length - 1);
|
|
600
|
+
cut = keepTogether(groups, heights, Math.min(cut, groups.length - 1));
|
|
485
601
|
const gap = Math.round(zone.w * 0.04);
|
|
486
602
|
const w = (zone.w - gap) / 2;
|
|
487
603
|
return [
|
|
@@ -526,21 +642,48 @@ function flow(ctx, groups, zone, fonts) {
|
|
|
526
642
|
var BASE = 1080;
|
|
527
643
|
var LOGO_SHARE = 0.26;
|
|
528
644
|
var CARD_RADIUS = 0.035;
|
|
529
|
-
|
|
530
|
-
|
|
645
|
+
var CAP_TOP = 0.15;
|
|
646
|
+
var PIN_HEAD_Y = 0.08;
|
|
647
|
+
var PIN_HEAD_R = 0.19;
|
|
648
|
+
var PIN_TIP_Y = 0.28;
|
|
649
|
+
var PIN_HOLE = 0.42;
|
|
650
|
+
var ARC_START = 0.75;
|
|
651
|
+
var ARC_END = 2.25;
|
|
652
|
+
function drawPin(ctx, r3, color, glyph) {
|
|
653
|
+
const cx = r3.x + r3.w / 2;
|
|
654
|
+
const cy = r3.y + r3.h / 2;
|
|
655
|
+
const hy = cy - r3.w * PIN_HEAD_Y;
|
|
656
|
+
const rad = r3.w * PIN_HEAD_R;
|
|
657
|
+
ctx.fillStyle = color;
|
|
658
|
+
ctx.beginPath();
|
|
659
|
+
ctx.arc(cx, cy, r3.w / 2, 0, Math.PI * 2);
|
|
660
|
+
ctx.fill();
|
|
661
|
+
ctx.fillStyle = glyph;
|
|
662
|
+
ctx.beginPath();
|
|
663
|
+
ctx.moveTo(cx, cy + r3.w * PIN_TIP_Y);
|
|
664
|
+
ctx.arc(cx, hy, rad, Math.PI * ARC_START, Math.PI * ARC_END);
|
|
665
|
+
ctx.closePath();
|
|
666
|
+
ctx.fill();
|
|
667
|
+
ctx.fillStyle = color;
|
|
668
|
+
ctx.beginPath();
|
|
669
|
+
ctx.arc(cx, hy, rad * PIN_HOLE, 0, Math.PI * 2);
|
|
670
|
+
ctx.fill();
|
|
671
|
+
}
|
|
672
|
+
function roundRect(ctx, r3, radius) {
|
|
673
|
+
const rad = Math.min(radius, r3.w / 2, r3.h / 2);
|
|
531
674
|
ctx.beginPath();
|
|
532
|
-
ctx.moveTo(
|
|
533
|
-
ctx.arcTo(
|
|
534
|
-
ctx.arcTo(
|
|
535
|
-
ctx.arcTo(
|
|
536
|
-
ctx.arcTo(
|
|
675
|
+
ctx.moveTo(r3.x + rad, r3.y);
|
|
676
|
+
ctx.arcTo(r3.x + r3.w, r3.y, r3.x + r3.w, r3.y + r3.h, rad);
|
|
677
|
+
ctx.arcTo(r3.x + r3.w, r3.y + r3.h, r3.x, r3.y + r3.h, rad);
|
|
678
|
+
ctx.arcTo(r3.x, r3.y + r3.h, r3.x, r3.y, rad);
|
|
679
|
+
ctx.arcTo(r3.x, r3.y, r3.x + r3.w, r3.y, rad);
|
|
537
680
|
ctx.closePath();
|
|
538
681
|
ctx.fill();
|
|
539
682
|
}
|
|
540
683
|
function drawFlow(ctx, f, radius) {
|
|
541
|
-
f.rules.forEach((
|
|
542
|
-
ctx.fillStyle =
|
|
543
|
-
ctx.fillRect(
|
|
684
|
+
f.rules.forEach((r3) => {
|
|
685
|
+
ctx.fillStyle = r3.color;
|
|
686
|
+
ctx.fillRect(r3.rect.x, r3.rect.y, r3.rect.w, r3.rect.h);
|
|
544
687
|
});
|
|
545
688
|
f.cards.forEach((c) => {
|
|
546
689
|
ctx.fillStyle = c.color;
|
|
@@ -552,6 +695,7 @@ function drawFlow(ctx, f, radius) {
|
|
|
552
695
|
ctx.arc(b.x, b.y, b.r, 0, Math.PI * 2);
|
|
553
696
|
ctx.fill();
|
|
554
697
|
});
|
|
698
|
+
f.icons.forEach((i) => drawPin(ctx, i.rect, i.color, i.glyph));
|
|
555
699
|
ctx.textAlign = "left";
|
|
556
700
|
ctx.textBaseline = "top";
|
|
557
701
|
f.texts.forEach((t) => {
|
|
@@ -571,6 +715,30 @@ function checked(input, assets) {
|
|
|
571
715
|
}
|
|
572
716
|
return result.doc;
|
|
573
717
|
}
|
|
718
|
+
function archRect(geo) {
|
|
719
|
+
if (geo.arch === void 0) {
|
|
720
|
+
return null;
|
|
721
|
+
}
|
|
722
|
+
const top = geo.picture.y + Math.round(geo.picture.h * geo.arch);
|
|
723
|
+
return { x: geo.picture.x, y: top, w: geo.picture.w, h: geo.picture.y + geo.picture.h - top };
|
|
724
|
+
}
|
|
725
|
+
function drawArch(ctx, r3, color) {
|
|
726
|
+
const rad = r3.w / 2;
|
|
727
|
+
ctx.fillStyle = color;
|
|
728
|
+
ctx.fillRect(r3.x, r3.y + rad, r3.w, r3.h - rad);
|
|
729
|
+
ctx.beginPath();
|
|
730
|
+
ctx.arc(r3.x + rad, r3.y + rad, rad, Math.PI, Math.PI * 2);
|
|
731
|
+
ctx.fill();
|
|
732
|
+
}
|
|
733
|
+
function flankFlows(ctx, groups, flanks, fonts) {
|
|
734
|
+
const half = Math.ceil(groups.length / 2);
|
|
735
|
+
return flanks.map((zone, i) => i === 0 ? flow(ctx, groups.slice(0, half), zone, fonts) : flow(ctx, groups.slice(half), { ...zone, right: true }, fonts));
|
|
736
|
+
}
|
|
737
|
+
function capAligned(zone, head) {
|
|
738
|
+
const first = head.texts[0]?.box;
|
|
739
|
+
const shift = first ? Math.min(Math.max(0, Math.round(first.y + first.h * CAP_TOP) - zone.y), Math.round(zone.h / 2)) : 0;
|
|
740
|
+
return { ...zone, y: zone.y + shift, h: zone.h - shift };
|
|
741
|
+
}
|
|
574
742
|
function splitHeader(header, hasLogo) {
|
|
575
743
|
const logoW = hasLogo ? Math.round(header.w * LOGO_SHARE) : 0;
|
|
576
744
|
return { text: { ...header, w: header.w - logoW * 1.1 }, logo: { ...header, x: header.x + header.w - logoW, w: logoW } };
|
|
@@ -593,20 +761,25 @@ function render(input, assets, canvas) {
|
|
|
593
761
|
ctx.fillRect(0, 0, width, height);
|
|
594
762
|
if (doc.background === "tint" /* Tint */) {
|
|
595
763
|
ctx.fillStyle = palette.tint;
|
|
596
|
-
[geo.header, geo.body].forEach((
|
|
764
|
+
[geo.header, geo.body].forEach((r3) => ctx.fillRect(r3.x, r3.y, r3.w, r3.h));
|
|
597
765
|
}
|
|
598
|
-
const zones = splitHeader(geo.header, doc.logo !== void 0);
|
|
766
|
+
const zones = geo.logo ? { text: geo.header, logo: geo.logo } : splitHeader(geo.header, doc.logo !== void 0);
|
|
599
767
|
const head = flow(ctx, headerGroups(doc, palette, u), zones.text, fonts);
|
|
600
|
-
const
|
|
768
|
+
const flanks = geo.flanks ?? [];
|
|
769
|
+
const body = flow(ctx, bodyGroups(doc, palette, u, flanks.length === 0), geo.body, fonts);
|
|
770
|
+
const sides = flanks.length > 0 ? flankFlows(ctx, flankPriceGroups(doc, palette, u), flanks, fonts) : [emptyFlow()];
|
|
601
771
|
const radius = Math.min(width, height) * CARD_RADIUS;
|
|
602
|
-
drawFlow(ctx,
|
|
603
|
-
drawFlow(ctx, body, radius);
|
|
772
|
+
[head, body, ...sides].forEach((f) => drawFlow(ctx, f, radius));
|
|
604
773
|
const logoImage = doc.logo ? assets[doc.logo.imageId] : void 0;
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
ctx.drawImage(logoImage,
|
|
774
|
+
const logo = logoImage ? placeContain(logoImage, geo.logo ? zones.logo : capAligned(zones.logo, head), "top" /* Top */, 1, 1) : null;
|
|
775
|
+
if (logoImage && logo) {
|
|
776
|
+
ctx.drawImage(logoImage, logo.x, logo.y, logo.w, logo.h);
|
|
608
777
|
}
|
|
609
778
|
const image = doc.picture ? assets[doc.picture.imageId] : void 0;
|
|
779
|
+
const backdrop = image ? archRect(geo) : null;
|
|
780
|
+
if (backdrop) {
|
|
781
|
+
drawArch(ctx, backdrop, palette.arch);
|
|
782
|
+
}
|
|
610
783
|
const picture = image && doc.picture ? placeContain(image, geo.picture, doc.picture.anchor, geo.alignX, doc.picture.scale) : null;
|
|
611
784
|
if (image && picture) {
|
|
612
785
|
ctx.drawImage(image, picture.x, picture.y, picture.w, picture.h);
|
|
@@ -616,8 +789,11 @@ function render(input, assets, canvas) {
|
|
|
616
789
|
height,
|
|
617
790
|
picture,
|
|
618
791
|
pictureRegion: geo.picture,
|
|
619
|
-
textBoxes: [
|
|
620
|
-
cardBoxes: body.cards.map((c) => c.rect)
|
|
792
|
+
textBoxes: [head, body, ...sides].flatMap((f) => f.texts.map((t) => t.box)),
|
|
793
|
+
cardBoxes: body.cards.map((c) => c.rect),
|
|
794
|
+
iconBoxes: [head, body, ...sides].flatMap((f) => f.icons.map((i) => i.rect)),
|
|
795
|
+
logo,
|
|
796
|
+
backdrop
|
|
621
797
|
};
|
|
622
798
|
}
|
|
623
799
|
|
|
@@ -636,6 +812,30 @@ function exportPng(canvas) {
|
|
|
636
812
|
return new Blob([bytes], { type: "image/png" });
|
|
637
813
|
}
|
|
638
814
|
|
|
815
|
+
// src/layoutCatalogue.ts
|
|
816
|
+
var POSTERS = ["story" /* Story */, "post" /* Post */, "square" /* Square */];
|
|
817
|
+
var LAYOUT_CATALOGUE = [
|
|
818
|
+
{ 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 },
|
|
819
|
+
{ 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 },
|
|
820
|
+
{ 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 },
|
|
821
|
+
{ id: "picture-bottom" /* PictureBottom */, designId: "picture-bottom", label: "Picture bottom", description: "Titles and details on top, the picture across the bottom half.", formats: POSTERS },
|
|
822
|
+
{ id: "list" /* List */, designId: "list", label: "Upcoming list", description: "Several dated events as a list beside the picture.", formats: POSTERS },
|
|
823
|
+
{ 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 */] },
|
|
824
|
+
{ 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 */] },
|
|
825
|
+
{ 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 */] },
|
|
826
|
+
{ 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 */] }
|
|
827
|
+
];
|
|
828
|
+
var DEFAULTS = {
|
|
829
|
+
["story" /* Story */]: "picture-right" /* PictureRight */,
|
|
830
|
+
["post" /* Post */]: "picture-right" /* PictureRight */,
|
|
831
|
+
["square" /* Square */]: "picture-right" /* PictureRight */,
|
|
832
|
+
["phone" /* Phone */]: "phone-clock-safe" /* PhoneClockSafe */,
|
|
833
|
+
["desktop" /* Desktop */]: "desktop-safe" /* DesktopSafe */
|
|
834
|
+
};
|
|
835
|
+
function defaultLayoutFor(format) {
|
|
836
|
+
return DEFAULTS[format];
|
|
837
|
+
}
|
|
838
|
+
|
|
639
839
|
// src/examples/kizombaWorkshop.ts
|
|
640
840
|
var WORKSHOPS = [
|
|
641
841
|
{ script: "Saturday 31 October", date: "Sat 31 Oct", first: "20:00 - 21:00", second: "21:00 - 22:00", party: "20\u20AC" },
|
|
@@ -693,10 +893,12 @@ exports.FORMAT_SIZES = FORMAT_SIZES;
|
|
|
693
893
|
exports.FlierDocError = FlierDocError;
|
|
694
894
|
exports.FontSetId = FontSetId;
|
|
695
895
|
exports.FormatId = FormatId;
|
|
896
|
+
exports.LAYOUT_CATALOGUE = LAYOUT_CATALOGUE;
|
|
696
897
|
exports.LayoutId = LayoutId;
|
|
697
898
|
exports.PALETTES = PALETTES;
|
|
698
899
|
exports.PaletteId = PaletteId;
|
|
699
900
|
exports.PictureAnchor = PictureAnchor;
|
|
901
|
+
exports.defaultLayoutFor = defaultLayoutFor;
|
|
700
902
|
exports.exportPng = exportPng;
|
|
701
903
|
exports.flierDocSchema = flierDocSchema;
|
|
702
904
|
exports.kizombaWorkshop = kizombaWorkshop;
|