@koda-sl/baker-cli 0.395.0-dev.f8ecbaa42 → 0.395.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/README.md +243 -132
  2. package/canvas/static-ad-composition/index.html +3 -154
  3. package/canvas/static-ad-composition/meta.json +1 -1
  4. package/dist/{chunk-AOVFDDVW.js → chunk-BRIJ4OWT.js} +14 -2
  5. package/dist/{chunk-AOVFDDVW.js.map → chunk-BRIJ4OWT.js.map} +1 -1
  6. package/dist/{chunk-NEZ3NAJV.js → chunk-EEHNRAFA.js} +4 -4
  7. package/dist/{chunk-Q3LMLQAI.js → chunk-LHJ5IXBN.js} +3963 -2664
  8. package/dist/chunk-LHJ5IXBN.js.map +1 -0
  9. package/dist/{chunk-OKE2QJSJ.js → chunk-Q7RQ3H6Y.js} +3 -3
  10. package/dist/{chunk-T2UNK5BW.js → chunk-QP7637HG.js} +3 -3
  11. package/dist/{chunk-QIQ57EIA.js → chunk-ZWMATKNS.js} +2 -2
  12. package/dist/cli.js +11599 -11312
  13. package/dist/cli.js.map +1 -1
  14. package/dist/{client-EQOSDYJL.js → client-4P6U75EX.js} +4 -4
  15. package/dist/engine/index.d.ts +175 -120
  16. package/dist/engine/index.js +3 -3
  17. package/dist/{env-ANKM47IJ.js → env-LJHSZSNA.js} +2 -2
  18. package/dist/{output-NR4EJQDV.js → output-HVBFJX4I.js} +5 -5
  19. package/dist/{shared-SLCDVV45.js → shared-7ZEF4DIX.js} +6 -6
  20. package/package.json +2 -1
  21. package/dist/chunk-Q3LMLQAI.js.map +0 -1
  22. /package/dist/{chunk-NEZ3NAJV.js.map → chunk-EEHNRAFA.js.map} +0 -0
  23. /package/dist/{chunk-OKE2QJSJ.js.map → chunk-Q7RQ3H6Y.js.map} +0 -0
  24. /package/dist/{chunk-T2UNK5BW.js.map → chunk-QP7637HG.js.map} +0 -0
  25. /package/dist/{chunk-QIQ57EIA.js.map → chunk-ZWMATKNS.js.map} +0 -0
  26. /package/dist/{client-EQOSDYJL.js.map → client-4P6U75EX.js.map} +0 -0
  27. /package/dist/{env-ANKM47IJ.js.map → env-LJHSZSNA.js.map} +0 -0
  28. /package/dist/{output-NR4EJQDV.js.map → output-HVBFJX4I.js.map} +0 -0
  29. /package/dist/{shared-SLCDVV45.js.map → shared-7ZEF4DIX.js.map} +0 -0
@@ -20,18 +20,10 @@
20
20
  .block { font-family: 'AdBody', 'Helvetica Neue', Arial, sans-serif; overflow-wrap: break-word; text-wrap: pretty; }
21
21
  .block.headline, .block.subheadline, .block.cta { font-family: 'AdHeadline', 'AdBody', 'Helvetica Neue', Arial, sans-serif; }
22
22
  .block.headline { text-wrap: balance; letter-spacing: -0.01em; }
23
- .fill { display: inline-block; line-height: 1.1; padding: 0.5em 1.2em; white-space: nowrap; }
23
+ .fill { display: inline-block; line-height: 1.1; padding: 0.5em 1.2em; }
24
24
  .fill.highlight { padding: 0.12em 0.4em; box-decoration-break: clone; -webkit-box-decoration-break: clone; }
25
25
  .fill.sticker { transform: rotate(-3deg); }
26
- .fill.outline { background: transparent !important; border: 0.09em solid currentColor; }
27
26
  .logo { display: block; width: auto; object-fit: contain; }
28
- .shape { position: absolute; pointer-events: none; }
29
- .shape svg { display: block; height: 100%; width: auto; }
30
- .shape.chrome { display: flex; align-items: center; justify-content: space-between; }
31
- .chrome-back { display: flex; align-items: center; gap: 0.2em; font-family: 'AdBody', 'Helvetica Neue', Arial, sans-serif; }
32
- .chrome-more { display: flex; align-items: center; justify-content: center; border-radius: 999px; }
33
- .block.mark { display: flex; align-items: flex-start; gap: 0.45em; }
34
- .block.mark svg { flex: none; width: 1.05em; height: 1.05em; margin-top: 0.1em; }
35
27
  </style>
36
28
  </head>
37
29
  <body>
@@ -130,8 +122,6 @@
130
122
  el.style.minHeight = ((at.y[1] - at.y[0]) / 100) * H + "px";
131
123
  el.style.justifyContent = "center";
132
124
  el.style.gap = 1.2 * U + "px";
133
- // A card's lines keep off its edges.
134
- if (g.inset) el.style.padding = 2.6 * U + "px " + 3.2 * U + "px";
135
125
  // Copy rewritten for our brand runs longer than the source's: allow some growth
136
126
  // past the region before the type shrinks.
137
127
  el.dataset.max = String(((at.y[1] - at.y[0]) / 100) * H * 1.35);
@@ -156,91 +146,6 @@
156
146
  else el.insertBefore(img, el.firstChild);
157
147
  }
158
148
 
159
- // The structures of a text-only ad, each at its layout region's box on this format:
160
- // cards and panels, dividers, icons and an app's chrome. Drawn before the copy, under it.
161
- var ICON_PATHS = {
162
- check: '<path d="M5 12.5l4.5 4.5L19 7.5" fill="none" stroke="C" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>',
163
- cross: '<path d="M6.5 6.5l11 11M17.5 6.5l-11 11" fill="none" stroke="C" stroke-width="3" stroke-linecap="round"/>',
164
- dots: '<circle cx="5" cy="12" r="2" fill="C"/><circle cx="12" cy="12" r="2" fill="C"/><circle cx="19" cy="12" r="2" fill="C"/>',
165
- chevron_left: '<path d="M15 4.5L7.5 12 15 19.5" fill="none" stroke="C" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"/>',
166
- arrow_right: '<path d="M4 12h15M13 6l6 6-6 6" fill="none" stroke="C" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"/>',
167
- star: '<path d="M12 3l2.7 5.6 6.1.9-4.4 4.3 1 6.1L12 17l-5.4 2.9 1-6.1-4.4-4.3 6.1-.9z" fill="C"/>',
168
- heart: '<path d="M12 20s-7-4.4-7-10a4 4 0 017-2.6A4 4 0 0119 10c0 5.6-7 10-7 10z" fill="C"/>',
169
- };
170
- function icon(name, color) {
171
- var path = ICON_PATHS[name] || "";
172
- return '<svg viewBox="0 0 24 24" aria-hidden="true">' + path.split('"C"').join('"' + color + '"') + "</svg>";
173
- }
174
- var SHAPE_RADIUS = { pill: "999px", rounded: 2.4 * U + "px", square: "0" };
175
- function addShape(s) {
176
- var at = s.at && s.at[FRAME.format];
177
- if (!at) return;
178
- var left = (at.x[0] / 100) * W;
179
- var top = (at.y[0] / 100) * H;
180
- var width = ((at.x[1] - at.x[0]) / 100) * W;
181
- var height = ((at.y[1] - at.y[0]) / 100) * H;
182
- var el = document.createElement("div");
183
- el.className = "shape " + s.kind;
184
- el.setAttribute("data-layout-ignore", "");
185
- el.style.left = left + "px";
186
- el.style.top = top + "px";
187
- el.style.width = width + "px";
188
- el.style.height = height + "px";
189
- if (s.kind === "box") {
190
- el.style.background = s.fill || "transparent";
191
- if (s.border) el.style.border = Math.max(2, 0.28 * U) + "px solid " + s.border;
192
- el.style.borderRadius = SHAPE_RADIUS[s.radius] || SHAPE_RADIUS.rounded;
193
- if (s.shadow) el.style.boxShadow = "0 " + 0.8 * U + "px " + 2.6 * U + "px rgba(0,0,0,0.18)";
194
- } else if (s.kind === "rule") {
195
- var thick = Math.max(2, 0.32 * U);
196
- el.style.background = s.color;
197
- if (width >= height) {
198
- el.style.top = top + height / 2 - thick / 2 + "px";
199
- el.style.height = thick + "px";
200
- } else {
201
- el.style.left = left + width / 2 - thick / 2 + "px";
202
- el.style.width = thick + "px";
203
- }
204
- } else if (s.kind === "icon") {
205
- el.style.display = "flex";
206
- el.style.justifyContent = "center";
207
- el.style.alignItems = "center";
208
- if (s.ring) {
209
- // A circled icon (a note's "more" button): the ring is as tall as the region.
210
- var ring = Math.min(width, height);
211
- var circle = document.createElement("div");
212
- circle.className = "chrome-more";
213
- circle.style.width = ring + "px";
214
- circle.style.height = ring + "px";
215
- circle.style.border = Math.max(2, ring * 0.07) + "px solid " + s.color;
216
- circle.innerHTML = '<span style="display:block;height:' + ring * 0.6 + 'px">' + icon(s.icon, s.color) + "</span>";
217
- el.appendChild(circle);
218
- } else {
219
- el.innerHTML = icon(s.icon, s.color);
220
- }
221
- } else if (s.kind === "chrome") {
222
- var size = Math.min(height * 0.62, 5 * U);
223
- var back = document.createElement("div");
224
- back.className = "chrome-back";
225
- if (!facesStaged) back.style.fontFamily = FALLBACK_FACE;
226
- back.style.color = s.color;
227
- back.style.fontSize = size + "px";
228
- back.innerHTML = '<span style="display:block;height:1.1em">' + icon("chevron_left", s.color) + "</span>";
229
- var label = document.createElement("span");
230
- label.textContent = s.label;
231
- back.appendChild(label);
232
- var more = document.createElement("div");
233
- more.className = "chrome-more";
234
- more.style.width = size * 1.35 + "px";
235
- more.style.height = size * 1.35 + "px";
236
- more.style.border = Math.max(2, size * 0.09) + "px solid " + s.color;
237
- more.innerHTML = '<span style="display:block;height:' + size * 0.8 + 'px">' + icon("dots", s.color) + "</span>";
238
- el.appendChild(back);
239
- if (s.more) el.appendChild(more);
240
- }
241
- root.appendChild(el);
242
- }
243
-
244
149
  function addBlock(b) {
245
150
  var el = document.createElement("div");
246
151
  el.className = "block " + b.role;
@@ -249,11 +154,6 @@
249
154
  el.dataset.base = String(size);
250
155
  el.style.fontSize = size * U + "px";
251
156
  el.style.fontWeight = String(WEIGHT[b.weight] || (b.role === "cta" ? 700 : 400));
252
- // A staged face is one weight, so a line prompt.json sets bold (a bold paragraph, a
253
- // sign-off) is drawn in the heavy face whatever its role.
254
- if (facesStaged && WEIGHT[b.weight] >= 600) {
255
- el.style.fontFamily = "'AdHeadline', 'AdBody', 'Helvetica Neue', Arial, sans-serif";
256
- }
257
157
  el.style.lineHeight = b.role === "headline" ? "1.04" : "1.22";
258
158
  el.style.textTransform = CASE[b.case] || "none";
259
159
  el.style.textAlign = b.align || "center";
@@ -269,29 +169,15 @@
269
169
  fill.style.background = t.background || (AD.cta && AD.cta.background) || "#111111";
270
170
  fill.style.color = t.color || (AD.cta && AD.cta.color) || "#ffffff";
271
171
  fill.style.borderRadius = RADIUS[t.shape] || RADIUS.rounded;
272
- if (t.outline) fill.classList.add("outline");
273
172
  el.appendChild(fill);
274
173
  } else {
275
- if (t.kind === "mark") {
276
- // A tick or cross list item: the mark in its own colour, then the line.
277
- el.classList.add("mark");
278
- el.innerHTML = icon(t.mark, t.color);
279
- var words = document.createElement("span");
280
- words.textContent = text;
281
- el.appendChild(words);
282
- } else {
283
- el.textContent = text;
284
- }
174
+ el.textContent = text;
285
175
  el.style.color = ink;
286
176
  if (t.kind === "underline") {
287
177
  el.style.textDecoration = "underline";
288
178
  el.style.textDecorationThickness = "0.08em";
289
179
  el.style.textUnderlineOffset = "0.18em";
290
180
  }
291
- if (t.kind === "strike") {
292
- el.style.textDecoration = "line-through";
293
- el.style.textDecorationThickness = "0.08em";
294
- }
295
181
  var dark = (luma(ink) || 255) < 110;
296
182
  el.dataset.dark = dark ? "1" : "0";
297
183
  if (hasPlate) el.style.textShadow = dark ? "0 1px 10px rgba(255,255,255,0.35)" : "0 2px 14px rgba(0,0,0,0.45)";
@@ -300,7 +186,6 @@
300
186
  }
301
187
 
302
188
  var drawCopy = FRAME.draw_copy !== false;
303
- (hasPlate ? [] : AD.shapes || []).forEach(addShape);
304
189
  (drawCopy ? AD.copy || [] : []).forEach(addBlock);
305
190
  if (AD.logo) addLogo(AD.logo);
306
191
 
@@ -313,9 +198,7 @@
313
198
  // layout is written.
314
199
  function fit(el) {
315
200
  var max = Number(el.dataset.max);
316
- // The room inside a card's padding, not the card's outer width.
317
- var pad = getComputedStyle(el);
318
- var width = el.getBoundingClientRect().width - parseFloat(pad.paddingLeft) - parseFloat(pad.paddingRight);
201
+ var width = el.getBoundingClientRect().width;
319
202
  var scale = 1;
320
203
  for (var i = 0; i < 40; i++) {
321
204
  var tooTall = el.scrollHeight > max;
@@ -326,42 +209,10 @@
326
209
  scale *= 0.94;
327
210
  Array.prototype.forEach.call(el.querySelectorAll(".block"), function (c) {
328
211
  c.style.fontSize = Number(c.dataset.base) * U * scale + "px";
329
- c.dataset.scale = String(scale);
330
212
  });
331
213
  }
332
214
  }
333
215
 
334
- // A region's copy may run past its box, but never into the next region down the same
335
- // column: the room it has ends where that one starts.
336
- function keepClearOfNext(el) {
337
- var r = el.getBoundingClientRect();
338
- var room = Infinity;
339
- Array.prototype.forEach.call(root.querySelectorAll(".group.placed"), function (other) {
340
- if (other === el) return;
341
- var q = other.getBoundingClientRect();
342
- var sameColumn = Math.min(r.right, q.right) - Math.max(r.left, q.left) > 0;
343
- if (sameColumn && q.top > r.top + 1) room = Math.min(room, q.top - r.top - 0.8 * U);
344
- });
345
- // Two regions the format already stacks on each other are left as they are: holding
346
- // one to less than its own box would only shrink its type to nothing.
347
- if (room === Infinity || room < parseFloat(el.style.minHeight)) return;
348
- el.dataset.max = String(Math.min(Number(el.dataset.max), room));
349
- }
350
-
351
- // Lines set at one size in prompt.json stay one size in the ad: every one is drawn at
352
- // the smallest scale any of them needed to fit.
353
- function evenSizes() {
354
- var least = {};
355
- var blocks = Array.prototype.slice.call(root.querySelectorAll(".block"));
356
- blocks.forEach(function (b) {
357
- var s = Number(b.dataset.scale || 1);
358
- least[b.dataset.base] = Math.min(least[b.dataset.base] || 1, s);
359
- });
360
- blocks.forEach(function (b) {
361
- b.style.fontSize = Number(b.dataset.base) * U * least[b.dataset.base] + "px";
362
- });
363
- }
364
-
365
216
  // A soft scrim behind a band of light type over the picture (or a light one behind
366
217
  // dark type), so copy with no position of its own reads on any plate. Copy placed
367
218
  // by the layout sits on the calm area the plate kept for it.
@@ -392,9 +243,7 @@
392
243
 
393
244
  var ready = document.fonts && document.fonts.ready ? document.fonts.ready : Promise.resolve();
394
245
  ready.then(function () {
395
- Array.prototype.forEach.call(root.querySelectorAll(".group.placed"), keepClearOfNext);
396
246
  containers().forEach(fit);
397
- evenSizes();
398
247
  ["top", "bottom"].forEach(scrim);
399
248
  root.setAttribute("data-ready", "1");
400
249
  });
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "static-ad",
3
- "title": "Static ad: the picture (or, text-only, the layout drawn from prompt.json) with what the concept holds drawn on top",
3
+ "title": "Static ad: the picture (or the brand colours) with what the concept holds drawn on top",
4
4
  "description": "Written by `baker canvas scaffold-static-ad`, one copy per delivered format. Draws only what prompt.compose.json (derived from prompt.json) holds: each line of copy where the source layout placed it, set the way the reference set it (plain, underlined, with an arrow, as a button or sticker), in the staged fonts, and the logo file only when the concept shows one. The plate is the image model's clean picture; a text-only ad has none and sits on the brand colour. Width and height are this format's delivered size.",
5
5
  "width": 1080,
6
6
  "height": 1350,
@@ -947,6 +947,12 @@ function round2(value) {
947
947
  function asRecord(value) {
948
948
  return value && typeof value === "object" ? value : {};
949
949
  }
950
+ function bakerUses(value) {
951
+ const uses = asRecord(value);
952
+ const companies = typeof uses.companies === "number" ? uses.companies : 0;
953
+ if (companies === 0) return {};
954
+ return { baker_uses: companies, ...uses.ours === true ? { already_adapted: true } : {} };
955
+ }
950
956
  function compactWinningAd(record) {
951
957
  const dna = asRecord(record.dna);
952
958
  return {
@@ -958,7 +964,12 @@ function compactWinningAd(record) {
958
964
  summary: String(dna.creative_concept ?? ""),
959
965
  advertiser_id: String(record.advertiser_id ?? ""),
960
966
  ad_id: String(record.ad_id ?? ""),
961
- media_url: String(record.media_url ?? "")
967
+ media_url: String(record.media_url ?? ""),
968
+ ...typeof dna.visual === "string" && dna.visual ? { visual: dna.visual } : {},
969
+ ...typeof dna.container === "string" && dna.container ? { container: dna.container } : {},
970
+ ...typeof dna.mechanism === "string" && dna.mechanism ? { mechanism: dna.mechanism } : {},
971
+ ...bakerUses(record.baker_uses),
972
+ ...record.source === "followed" || record.source === "library" ? { source: record.source } : {}
962
973
  };
963
974
  }
964
975
  function fullWinningAd(record) {
@@ -975,6 +986,7 @@ function fullWinningAd(record) {
975
986
  awareness_stage: dna.awareness_stage ?? null,
976
987
  target_persona: dna.target_persona ?? null,
977
988
  hook_archetype: dna.hook_archetype ?? null,
989
+ mechanism: dna.mechanism ?? null,
978
990
  industry: dna.industry ?? null
979
991
  };
980
992
  }
@@ -1299,4 +1311,4 @@ export {
1299
1311
  captureVimeoCookie,
1300
1312
  childEnvWith
1301
1313
  };
1302
- //# sourceMappingURL=chunk-AOVFDDVW.js.map
1314
+ //# sourceMappingURL=chunk-BRIJ4OWT.js.map