@bendyline/squisq 2.11.7 → 2.11.9

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 (40) hide show
  1. package/dist/{Doc-BkxT7G80.d.ts → Doc-DmElSKmg.d.ts} +219 -1
  2. package/dist/{ImageEditDoc-C8ZB54Vv.d.ts → ImageEditDoc-Dm_BETxC.d.ts} +1 -1
  3. package/dist/{chunk-EF353KGH.js → chunk-2PGC4JDT.js} +1 -1
  4. package/dist/{chunk-YGGYYBJS.js → chunk-B5STNW6C.js} +2 -2
  5. package/dist/{chunk-IYZTF4VO.js → chunk-CCRBHFNO.js} +3 -3
  6. package/dist/{chunk-VU4T74LI.js → chunk-DTM4FG7S.js} +1 -1
  7. package/dist/chunk-JSGIWW35.js +70 -0
  8. package/dist/chunk-L7QZORLB.js +230 -0
  9. package/dist/chunk-NEWNNLWN.js +64 -0
  10. package/dist/{chunk-6ECMNUIP.js → chunk-OU5FYBOB.js} +170 -4
  11. package/dist/{chunk-Y4D6TDZT.js → chunk-PCCQLD3G.js} +2 -0
  12. package/dist/{chunk-SKKBRLLM.js → chunk-QDA7NXDO.js} +7 -42
  13. package/dist/{chunk-3YNFMFNK.js → chunk-QOVINAB2.js} +18 -9
  14. package/dist/{chunk-SOIV7KDO.js → chunk-VRTXPGP7.js} +256 -26
  15. package/dist/{chunk-XJXBI3N5.js → chunk-XZVBR5BP.js} +1 -1
  16. package/dist/{chunk-GAZKTT4R.js → chunk-YNO6JV36.js} +96 -33
  17. package/dist/doc/index.d.ts +10 -6
  18. package/dist/doc/index.js +23 -21
  19. package/dist/fence/index.d.ts +1 -1
  20. package/dist/generate/index.d.ts +1 -1
  21. package/dist/imageEdit/index.d.ts +47 -4
  22. package/dist/imageEdit/index.js +5 -1
  23. package/dist/index.d.ts +5 -5
  24. package/dist/index.js +52 -41
  25. package/dist/jsonForm/index.d.ts +1 -1
  26. package/dist/jsonForm/index.js +6 -4
  27. package/dist/markdown/index.js +3 -3
  28. package/dist/{materializePageSection-Dp2aHFbc.d.ts → materializePageSection-BfttC9Zj.d.ts} +6 -3
  29. package/dist/mediaEdit/index.d.ts +467 -0
  30. package/dist/mediaEdit/index.js +990 -0
  31. package/dist/narration/index.d.ts +20 -12
  32. package/dist/narration/index.js +7 -5
  33. package/dist/schemas/index.d.ts +4 -4
  34. package/dist/schemas/index.js +10 -4
  35. package/dist/{themeLibrary-BbSjnGmd.d.ts → themeLibrary-ChnTImby.d.ts} +1 -1
  36. package/dist/timing/index.d.ts +1 -1
  37. package/dist/transform/index.d.ts +2 -2
  38. package/dist/transform/index.js +7 -6
  39. package/package.json +6 -1
  40. package/dist/{chunk-CW24CH7I.js → chunk-HUXK7EOT.js} +3 -3
@@ -0,0 +1,64 @@
1
+ // src/mediaEdit/dsp/biquad.ts
2
+ var BUTTERWORTH_Q = Math.SQRT1_2;
3
+ function createBiquadState() {
4
+ return { x1: 0, x2: 0, y1: 0, y2: 0 };
5
+ }
6
+ function omega(sampleRate, freqHz) {
7
+ const w0 = 2 * Math.PI * freqHz / sampleRate;
8
+ return { cosW0: Math.cos(w0), sinW0: Math.sin(w0) };
9
+ }
10
+ function highpassCoeffs(sampleRate, freqHz, q = BUTTERWORTH_Q) {
11
+ const { cosW0, sinW0 } = omega(sampleRate, freqHz);
12
+ const alpha = sinW0 / (2 * q);
13
+ const a0 = 1 + alpha;
14
+ return {
15
+ b0: (1 + cosW0) / 2 / a0,
16
+ b1: -(1 + cosW0) / a0,
17
+ b2: (1 + cosW0) / 2 / a0,
18
+ a1: -2 * cosW0 / a0,
19
+ a2: (1 - alpha) / a0
20
+ };
21
+ }
22
+ function lowpassCoeffs(sampleRate, freqHz, q = BUTTERWORTH_Q) {
23
+ const { cosW0, sinW0 } = omega(sampleRate, freqHz);
24
+ const alpha = sinW0 / (2 * q);
25
+ const a0 = 1 + alpha;
26
+ return {
27
+ b0: (1 - cosW0) / 2 / a0,
28
+ b1: (1 - cosW0) / a0,
29
+ b2: (1 - cosW0) / 2 / a0,
30
+ a1: -2 * cosW0 / a0,
31
+ a2: (1 - alpha) / a0
32
+ };
33
+ }
34
+ function biquadRun(coeffs, state, input, output) {
35
+ let { x1, x2, y1, y2 } = state;
36
+ const { b0, b1, b2, a1, a2 } = coeffs;
37
+ for (let i = 0; i < input.length; i++) {
38
+ const x0 = input[i];
39
+ const y0 = b0 * x0 + b1 * x1 + b2 * x2 - a1 * y1 - a2 * y2;
40
+ output[i] = y0;
41
+ x2 = x1;
42
+ x1 = x0;
43
+ y2 = y1;
44
+ y1 = y0;
45
+ }
46
+ return { x1, x2, y1, y2 };
47
+ }
48
+ function createBiquadCascade(stages) {
49
+ const states = stages.map(() => createBiquadState());
50
+ return {
51
+ process(block) {
52
+ for (let s = 0; s < stages.length; s++) {
53
+ states[s] = biquadRun(stages[s], states[s], block, block);
54
+ }
55
+ }
56
+ };
57
+ }
58
+
59
+ export {
60
+ highpassCoeffs,
61
+ lowpassCoeffs,
62
+ biquadRun,
63
+ createBiquadCascade
64
+ };
@@ -216,11 +216,11 @@ async function revertToImageEditVersion(container, version, options = {}) {
216
216
  if (options.snapshotCurrent !== false) {
217
217
  const saveOptions = { stateFilename: options.stateFilename };
218
218
  if (options.doc !== void 0) saveOptions.doc = options.doc;
219
- const result = await saveImageEditVersion(container, saveOptions);
220
- if (!result.saved && result.reason !== "unchanged") {
219
+ const result2 = await saveImageEditVersion(container, saveOptions);
220
+ if (!result2.saved && result2.reason !== "unchanged") {
221
221
  return { reverted: false, snapshotted: null, reason: "snapshot-failed" };
222
222
  }
223
- snapshotted = result.version;
223
+ snapshotted = result2.version;
224
224
  }
225
225
  await writeImageEditDoc(container, doc, options.stateFilename);
226
226
  return { reverted: true, snapshotted };
@@ -482,6 +482,170 @@ function escapeText(s) {
482
482
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
483
483
  }
484
484
 
485
+ // src/imageEdit/animatedImage.ts
486
+ var MIN_FRAME_DELAY_MS = 10;
487
+ var CLAMPED_DELAY_MS = 100;
488
+ function inspectAnimatedImage(input) {
489
+ const bytes = input instanceof Uint8Array ? input : new Uint8Array(input);
490
+ return inspectGif(bytes) ?? inspectPng(bytes) ?? inspectWebp(bytes);
491
+ }
492
+ var ANIMATABLE_EXTENSIONS = /* @__PURE__ */ new Set(["gif", "webp", "apng"]);
493
+ var ANIMATABLE_MIME = /^image\/(?:gif|webp|apng)(?=$|[;,\s])/i;
494
+ function mayBeAnimatedImage(srcOrMime) {
495
+ const value = srcOrMime.trim();
496
+ if (!value) return false;
497
+ if (/^data:/i.test(value)) return ANIMATABLE_MIME.test(value.slice(5));
498
+ if (ANIMATABLE_MIME.test(value)) return true;
499
+ const path = value.split(/[?#]/, 1)[0] ?? "";
500
+ const dot = path.lastIndexOf(".");
501
+ if (dot < 0 || dot < path.lastIndexOf("/")) return false;
502
+ return ANIMATABLE_EXTENSIONS.has(path.slice(dot + 1).toLowerCase());
503
+ }
504
+ function inspectGif(b) {
505
+ if (b.length < 13) return null;
506
+ if (b[0] !== 71 || b[1] !== 73 || b[2] !== 70 || b[3] !== 56) return null;
507
+ if (b[4] !== 55 && b[4] !== 57 || b[5] !== 97) return null;
508
+ let pos = 13 + colorTableSize(b[10]);
509
+ let frames = 0;
510
+ let duration = 0;
511
+ let pendingDelayMs = 0;
512
+ let playCount = 1;
513
+ while (pos < b.length) {
514
+ const marker = b[pos++];
515
+ if (marker === 59) break;
516
+ if (marker === 33) {
517
+ if (pos >= b.length) break;
518
+ const label = b[pos++];
519
+ if (label === 249 && pos + 3 < b.length && b[pos] >= 4) {
520
+ pendingDelayMs = (b[pos + 2] | b[pos + 3] << 8) * 10;
521
+ } else if (label === 255 && b[pos] === 11 && pos + 12 <= b.length) {
522
+ const id = ascii(b, pos + 1, 11);
523
+ const sub = pos + 12;
524
+ if ((id === "NETSCAPE2.0" || id === "ANIMEXTS1.0") && sub + 3 < b.length && b[sub] >= 3 && b[sub + 1] === 1) {
525
+ const loops = b[sub + 2] | b[sub + 3] << 8;
526
+ playCount = loops === 0 ? 0 : loops + 1;
527
+ }
528
+ }
529
+ pos = skipSubBlocks(b, pos);
530
+ if (pos < 0) break;
531
+ continue;
532
+ }
533
+ if (marker === 44) {
534
+ if (pos + 9 > b.length) break;
535
+ const packed = b[pos + 8];
536
+ pos += 9 + colorTableSize(packed);
537
+ pos += 1;
538
+ frames++;
539
+ duration += playedDelay(pendingDelayMs);
540
+ pendingDelayMs = 0;
541
+ pos = skipSubBlocks(b, pos);
542
+ if (pos < 0) break;
543
+ continue;
544
+ }
545
+ break;
546
+ }
547
+ return result("gif", frames, duration, playCount);
548
+ }
549
+ function colorTableSize(packed) {
550
+ return packed & 128 ? 3 * (1 << (packed & 7) + 1) : 0;
551
+ }
552
+ function skipSubBlocks(b, start) {
553
+ let pos = start;
554
+ while (pos < b.length) {
555
+ const size = b[pos];
556
+ pos += 1;
557
+ if (size === 0) return pos;
558
+ pos += size;
559
+ }
560
+ return -1;
561
+ }
562
+ var PNG_SIGNATURE = [137, 80, 78, 71, 13, 10, 26, 10];
563
+ function inspectPng(b) {
564
+ if (b.length < PNG_SIGNATURE.length) return null;
565
+ for (let i = 0; i < PNG_SIGNATURE.length; i++) {
566
+ if (b[i] !== PNG_SIGNATURE[i]) return null;
567
+ }
568
+ let pos = PNG_SIGNATURE.length;
569
+ let hasAnimationControl = false;
570
+ let frames = 1;
571
+ let playCount = 1;
572
+ let duration = 0;
573
+ while (pos + 8 <= b.length) {
574
+ const length = readU32BE(b, pos);
575
+ const type = ascii(b, pos + 4, 4);
576
+ const data = pos + 8;
577
+ if (type === "acTL" && length >= 8 && data + 8 <= b.length) {
578
+ hasAnimationControl = true;
579
+ frames = readU32BE(b, data);
580
+ playCount = readU32BE(b, data + 4);
581
+ } else if (type === "fcTL" && length >= 26 && data + 26 <= b.length) {
582
+ const num = readU16BE(b, data + 20);
583
+ const den = readU16BE(b, data + 22) || 100;
584
+ duration += playedDelay(num * 1e3 / den);
585
+ } else if (type === "IDAT" && !hasAnimationControl) {
586
+ break;
587
+ } else if (type === "IEND") {
588
+ break;
589
+ }
590
+ pos = data + length + 4;
591
+ }
592
+ return result("png", hasAnimationControl ? frames : 1, duration, playCount);
593
+ }
594
+ function inspectWebp(b) {
595
+ if (b.length < 12 || ascii(b, 0, 4) !== "RIFF" || ascii(b, 8, 4) !== "WEBP") return null;
596
+ let pos = 12;
597
+ let animationFlag = false;
598
+ let frames = 0;
599
+ let duration = 0;
600
+ let loopCount = null;
601
+ while (pos + 8 <= b.length) {
602
+ const type = ascii(b, pos, 4);
603
+ const size = readU32LE(b, pos + 4);
604
+ const data = pos + 8;
605
+ if (type === "VP8X" && size >= 10 && data < b.length) {
606
+ animationFlag = (b[data] & 2) !== 0;
607
+ if (!animationFlag) break;
608
+ } else if (type === "ANIM" && size >= 6 && data + 6 <= b.length) {
609
+ loopCount = b[data + 4] | b[data + 5] << 8;
610
+ } else if (type === "ANMF" && size >= 16 && data + 15 <= b.length) {
611
+ frames++;
612
+ duration += playedDelay(b[data + 12] | b[data + 13] << 8 | b[data + 14] << 16);
613
+ } else if ((type === "VP8 " || type === "VP8L") && !animationFlag) {
614
+ break;
615
+ }
616
+ pos = data + size + (size & 1);
617
+ }
618
+ const frameCount = animationFlag ? frames : 1;
619
+ return result("webp", frameCount, duration, loopCount ?? 0);
620
+ }
621
+ function result(format, frameCount, durationMs, playCount) {
622
+ const animated = frameCount > 1;
623
+ return {
624
+ format,
625
+ animated,
626
+ frameCount: Math.max(frameCount, 1),
627
+ durationMs: animated ? Math.round(durationMs) : 0,
628
+ playCount: animated ? playCount : 1
629
+ };
630
+ }
631
+ function playedDelay(ms) {
632
+ return ms <= MIN_FRAME_DELAY_MS ? CLAMPED_DELAY_MS : ms;
633
+ }
634
+ function ascii(b, start, length) {
635
+ let out = "";
636
+ for (let i = start; i < start + length && i < b.length; i++) out += String.fromCharCode(b[i]);
637
+ return out;
638
+ }
639
+ function readU16BE(b, pos) {
640
+ return b[pos] << 8 | b[pos + 1];
641
+ }
642
+ function readU32BE(b, pos) {
643
+ return (b[pos] << 24 | b[pos + 1] << 16 | b[pos + 2] << 8 | b[pos + 3]) >>> 0;
644
+ }
645
+ function readU32LE(b, pos) {
646
+ return (b[pos] | b[pos + 1] << 8 | b[pos + 2] << 16 | b[pos + 3] << 24) >>> 0;
647
+ }
648
+
485
649
  export {
486
650
  IMAGE_EDIT_STATE_FILENAME,
487
651
  IMAGE_EDIT_ASSETS_PREFIX,
@@ -507,5 +671,7 @@ export {
507
671
  coalesceImageEditVersions,
508
672
  ImageEditVersionManager,
509
673
  exportImageEditDoc,
510
- buildSvgString
674
+ buildSvgString,
675
+ inspectAnimatedImage,
676
+ mayBeAnimatedImage
511
677
  };
@@ -725,6 +725,7 @@ var PAGE_SECTION_KINDS = [
725
725
  "prose",
726
726
  "footer"
727
727
  ];
728
+ var PAGE_VARIANTS = ["page", "document"];
728
729
  var PAGE_DESIGN_FAMILIES = [
729
730
  "clean",
730
731
  "editorial",
@@ -2994,6 +2995,7 @@ export {
2994
2995
  pickContrastingText,
2995
2996
  deriveScale,
2996
2997
  PAGE_SECTION_KINDS,
2998
+ PAGE_VARIANTS,
2997
2999
  PAGE_DESIGN_FAMILIES,
2998
3000
  PAGE_SECTION_SPACINGS,
2999
3001
  PAGE_DIVIDERS,
@@ -1,11 +1,16 @@
1
+ import {
2
+ biquadRun,
3
+ highpassCoeffs,
4
+ lowpassCoeffs
5
+ } from "./chunk-NEWNNLWN.js";
1
6
  import {
2
7
  buildNarrationScript,
3
8
  expectedSyllablesAt,
4
9
  wordPosAtExpectedSyllables
5
- } from "./chunk-EF353KGH.js";
10
+ } from "./chunk-2PGC4JDT.js";
6
11
  import {
7
12
  flattenRenderableBlocks
8
- } from "./chunk-3YNFMFNK.js";
13
+ } from "./chunk-QOVINAB2.js";
9
14
 
10
15
  // src/narration/types.ts
11
16
  var DEFAULT_FEATURE_CONFIG = Object.freeze({
@@ -71,32 +76,6 @@ var DEFAULT_ALIGN_CONFIG = Object.freeze({
71
76
  });
72
77
 
73
78
  // src/narration/features.ts
74
- function highpassCoeffs(sampleRate, freqHz) {
75
- const w0 = 2 * Math.PI * freqHz / sampleRate;
76
- const cosW0 = Math.cos(w0);
77
- const alpha = Math.sin(w0) / (2 * Math.SQRT1_2);
78
- const a0 = 1 + alpha;
79
- return {
80
- b0: (1 + cosW0) / 2 / a0,
81
- b1: -(1 + cosW0) / a0,
82
- b2: (1 + cosW0) / 2 / a0,
83
- a1: -2 * cosW0 / a0,
84
- a2: (1 - alpha) / a0
85
- };
86
- }
87
- function lowpassCoeffs(sampleRate, freqHz) {
88
- const w0 = 2 * Math.PI * freqHz / sampleRate;
89
- const cosW0 = Math.cos(w0);
90
- const alpha = Math.sin(w0) / (2 * Math.SQRT1_2);
91
- const a0 = 1 + alpha;
92
- return {
93
- b0: (1 - cosW0) / 2 / a0,
94
- b1: (1 - cosW0) / a0,
95
- b2: (1 - cosW0) / 2 / a0,
96
- a1: -2 * cosW0 / a0,
97
- a2: (1 - alpha) / a0
98
- };
99
- }
100
79
  function createBandpass(sampleRate, lowHz = DEFAULT_FEATURE_CONFIG.bandLowHz, highHz = DEFAULT_FEATURE_CONFIG.bandHighHz) {
101
80
  return {
102
81
  coeffs: { hp: highpassCoeffs(sampleRate, lowHz), lp: lowpassCoeffs(sampleRate, highHz) },
@@ -104,20 +83,6 @@ function createBandpass(sampleRate, lowHz = DEFAULT_FEATURE_CONFIG.bandLowHz, hi
104
83
  lp: { x1: 0, x2: 0, y1: 0, y2: 0 }
105
84
  };
106
85
  }
107
- function biquadRun(coeffs, state, input, output) {
108
- let { x1, x2, y1, y2 } = state;
109
- const { b0, b1, b2, a1, a2 } = coeffs;
110
- for (let i = 0; i < input.length; i++) {
111
- const x0 = input[i];
112
- const y0 = b0 * x0 + b1 * x1 + b2 * x2 - a1 * y1 - a2 * y2;
113
- output[i] = y0;
114
- x2 = x1;
115
- x1 = x0;
116
- y2 = y1;
117
- y1 = y0;
118
- }
119
- return { x1, x2, y1, y2 };
120
- }
121
86
  function bandpassRun(state, input, output) {
122
87
  const hp = biquadRun(state.coeffs.hp, state.hp, input, output);
123
88
  const lp = biquadRun(state.coeffs.lp, state.lp, output, output);
@@ -1,11 +1,3 @@
1
- import {
2
- anchorPoint,
3
- base64ToUtf8,
4
- connectorPath,
5
- lineStyleDasharray,
6
- shapePath,
7
- snapEndpoints
8
- } from "./chunk-PUS54YU6.js";
9
1
  import {
10
2
  detectAsciiDiagram,
11
3
  detectAsciiTimeline,
@@ -22,6 +14,14 @@ import {
22
14
  pickAutoTemplate,
23
15
  profileBlockContents
24
16
  } from "./chunk-C3NAY5YP.js";
17
+ import {
18
+ anchorPoint,
19
+ base64ToUtf8,
20
+ connectorPath,
21
+ lineStyleDasharray,
22
+ shapePath,
23
+ snapEndpoints
24
+ } from "./chunk-PUS54YU6.js";
25
25
  import {
26
26
  DEFAULT_THEME,
27
27
  FRONTMATTER_CUSTOM_TEMPLATES_KEY,
@@ -41,7 +41,12 @@ import {
41
41
  validateCustomTemplateDefinition,
42
42
  validateTheme,
43
43
  withAlpha
44
- } from "./chunk-Y4D6TDZT.js";
44
+ } from "./chunk-PCCQLD3G.js";
45
+ import {
46
+ mediaEditValuesFromAttributes,
47
+ mediaEditValuesFromParams,
48
+ parseMediaEdits
49
+ } from "./chunk-L7QZORLB.js";
45
50
  import {
46
51
  KNOWN_BLOCK_META_KEYS,
47
52
  TABLE_FED_TEMPLATES,
@@ -11133,6 +11138,8 @@ function toMediaClip(parsed, id) {
11133
11138
  if (clipEnd != null) clip.clipEnd = clipEnd;
11134
11139
  if (clip.lockToBlock === true) delete clip.clipEnd;
11135
11140
  if (params.spillover === "true" || params.spillover === "") clip.spillover = true;
11141
+ const edits = parseMediaEdits(mediaEditValuesFromParams(params));
11142
+ if (edits) clip.edits = edits;
11136
11143
  return clip;
11137
11144
  }
11138
11145
  function firstVideoElement(children) {
@@ -11195,6 +11202,8 @@ function htmlVideoClip(node, id) {
11195
11202
  const clipEnd = time(element.attributes["data-squisq-video-clip-end"]);
11196
11203
  if (clipStart != null) clip.clipStart = clipStart;
11197
11204
  if (!locked && clipEnd != null) clip.clipEnd = clipEnd;
11205
+ const edits = parseMediaEdits(mediaEditValuesFromAttributes("video", element.attributes));
11206
+ if (edits) clip.edits = edits;
11198
11207
  return clip;
11199
11208
  }
11200
11209
  function extractMediaFromContents(contents, makeId, blockId) {