miriad-viz 0.9.2 → 0.9.4

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.
@@ -144,12 +144,15 @@ var STEP_FILE_MAP = {
144
144
  // render output is the final video — too large for board
145
145
  };
146
146
  var ALWAYS_SYNC = [".miriad-viz.json"];
147
- async function syncStepOutputs(config, step, dataDir) {
147
+ var OUTPUT_DIR_STEPS = /* @__PURE__ */ new Set(["transform"]);
148
+ async function syncStepOutputs(config, step, dataDir, outputDir) {
149
+ const stepDir = OUTPUT_DIR_STEPS.has(step) && outputDir ? outputDir : dataDir;
148
150
  const files = STEP_FILE_MAP[step] ?? [];
149
151
  const allFiles = [.../* @__PURE__ */ new Set([...files, ...ALWAYS_SYNC])];
150
152
  let synced = 0;
151
153
  for (const file of allFiles) {
152
- const localPath = resolve(dataDir, file);
154
+ const dir = ALWAYS_SYNC.includes(file) ? dataDir : stepDir;
155
+ const localPath = resolve(dir, file);
153
156
  if (!existsSync(localPath)) continue;
154
157
  await syncTextFile(config, localPath, file);
155
158
  synced++;
@@ -169,7 +172,7 @@ async function syncStepOutputs(config, step, dataDir) {
169
172
  console.log(` \u2601 Synced ${synced} file${synced > 1 ? "s" : ""} to board`);
170
173
  }
171
174
  }
172
- async function pullFromBoard(config, dataDir) {
175
+ async function pullFromBoard(config, dataDir, outputDir) {
173
176
  const warnings = [];
174
177
  let pulled = 0;
175
178
  try {
@@ -226,7 +229,7 @@ async function pullFromBoard(config, dataDir) {
226
229
  if (existsSync(progressPath)) {
227
230
  try {
228
231
  const progress = JSON.parse(readFileSync(progressPath, "utf-8"));
229
- const validationWarnings = validateProgressConsistency(progress, dataDir);
232
+ const validationWarnings = validateProgressConsistency(progress, dataDir, outputDir);
230
233
  warnings.push(...validationWarnings);
231
234
  } catch {
232
235
  warnings.push("Failed to parse .miriad-viz.json for consistency check");
@@ -248,7 +251,7 @@ var STEP_REQUIRED_FILES = {
248
251
  "sound-design": ["audio-manifest.json"],
249
252
  transform: ["viz-data.json"]
250
253
  };
251
- function validateProgressConsistency(progress, dataDir) {
254
+ function validateProgressConsistency(progress, dataDir, outputDir) {
252
255
  const warnings = [];
253
256
  const steps = progress.steps;
254
257
  if (!steps) return warnings;
@@ -268,7 +271,8 @@ function validateProgressConsistency(progress, dataDir) {
268
271
  continue;
269
272
  }
270
273
  for (const file of requiredFiles) {
271
- if (!existsSync(resolve(dataDir, file))) {
274
+ const checkDir = OUTPUT_DIR_STEPS.has(step) && outputDir ? outputDir : dataDir;
275
+ if (!existsSync(resolve(checkDir, file))) {
272
276
  warnings.push(`Step '${step}' marked complete but ${file} missing \u2014 resetting to pending`);
273
277
  state.status = "pending";
274
278
  break;
@@ -12,7 +12,7 @@ import {
12
12
  canSync,
13
13
  getBoardSyncConfig,
14
14
  syncStepOutputs
15
- } from "./chunk-UTFBENVA.js";
15
+ } from "./chunk-7BH6QQNB.js";
16
16
  import {
17
17
  markComplete,
18
18
  markError,
package/dist-cli/index.js CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  pullFromBoard,
5
5
  syncStepOutputs,
6
6
  syncTextFile
7
- } from "./chunk-UTFBENVA.js";
7
+ } from "./chunk-7BH6QQNB.js";
8
8
  import {
9
9
  PROGRESS_FILENAME,
10
10
  STEPS,
@@ -525,6 +525,7 @@ function computeNext(progress, existingFiles, logTails, flags = {}, dataSummary,
525
525
  return {
526
526
  ...chainResult,
527
527
  action: "completed_and_chained",
528
+ completedSteps: ["script", ...chainResult.completedSteps ?? []],
528
529
  output: [...output, ...chainResult.output]
529
530
  };
530
531
  }
@@ -550,7 +551,7 @@ function computeNext(progress, existingFiles, logTails, flags = {}, dataSummary,
550
551
  output.push(" \u2502 \u2502");
551
552
  output.push(" \u2502 When approved: npx miriad-viz next --script-approved \u2502");
552
553
  output.push(" \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F");
553
- return { action: "creative_stop", step, progress, output };
554
+ return { action: "creative_stop", step, progress, output, completedSteps: [step] };
554
555
  }
555
556
  output.push("", "\u270F\uFE0F Script writing in progress.");
556
557
  output.push("", " Write your script to: data/script.json");
@@ -648,6 +649,7 @@ function computeNext(progress, existingFiles, logTails, flags = {}, dataSummary,
648
649
  return {
649
650
  ...chainResult,
650
651
  action: "completed_and_chained",
652
+ completedSteps: ["curate", ...chainResult.completedSteps ?? []],
651
653
  output: [...output, ...chainResult.output]
652
654
  };
653
655
  }
@@ -673,7 +675,7 @@ function computeNext(progress, existingFiles, logTails, flags = {}, dataSummary,
673
675
  output.push(" \u2502 \u2502");
674
676
  output.push(" \u2502 When approved: npx miriad-viz next --curate-approved \u2502");
675
677
  output.push(" \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F");
676
- return { action: "creative_stop", step, progress, output };
678
+ return { action: "creative_stop", step, progress, output, completedSteps: [step] };
677
679
  }
678
680
  const existing = CURATE_OUTPUT_FILES.filter((f) => fileSet.has(f));
679
681
  const missing = CURATE_OUTPUT_FILES.filter((f) => !fileSet.has(f));
@@ -738,6 +740,66 @@ function computeNext(progress, existingFiles, logTails, flags = {}, dataSummary,
738
740
  output.push(" - Add standout quotes with speaker, text, and timestamp");
739
741
  output.push(" 5. Present to human and iterate");
740
742
  output.push("");
743
+ output.push(" \u2501\u2501\u2501 SCHEMA EXAMPLES (copy these as starting templates) \u2501\u2501\u2501");
744
+ output.push("");
745
+ output.push(" \u{1F4C4} timeline-events.json:");
746
+ output.push(" ```json");
747
+ output.push(" [");
748
+ output.push(' { "type": "message", "t": "2026-02-20T14:30:00Z", "from": "bob",');
749
+ output.push(' "to": "snorre", "content": "Chat pill label shown on screen" },');
750
+ output.push(' { "type": "beam", "t": "2026-02-20T15:00:00Z", "from": "lead",');
751
+ output.push(' "to": "bob", "content": "Task assignment beam" },');
752
+ output.push(' { "type": "milestone", "t": "2026-02-20T16:00:00Z",');
753
+ output.push(' "label": "PR #42 merged", "agent": "bob", "style": "achievement" }');
754
+ output.push(" ]");
755
+ output.push(" ```");
756
+ output.push(
757
+ ' \u26A0\uFE0F type MUST be "message" or "beam" for chat pills. "milestone" renders differently.'
758
+ );
759
+ output.push("");
760
+ output.push(" \u{1F4C4} retro-page-data.json:");
761
+ output.push(" ```json");
762
+ output.push(" {");
763
+ output.push(' "meta": {');
764
+ output.push(' "title": "Project Name",');
765
+ output.push(' "subtitle": "A story of building something",');
766
+ output.push(' "startDate": "2026-02-20T00:00:00Z",');
767
+ output.push(' "endDate": "2026-02-21T00:00:00Z"');
768
+ output.push(" },");
769
+ output.push(' "teamAssembly": [');
770
+ output.push(' { "agent": "bob", "role": "Builder", "time": "2026-02-20T01:00:00Z" }');
771
+ output.push(" ],");
772
+ output.push(' "phases": [');
773
+ output.push(' { "id": "discovery", "label": "Discovery",');
774
+ output.push(' "startTime": "2026-02-20T00:00:00Z", "endTime": "2026-02-20T12:00:00Z" }');
775
+ output.push(" ],");
776
+ output.push(' "milestones": [');
777
+ output.push(
778
+ ' { "label": "First commit", "time": "2026-02-20T02:00:00Z", "phase": "discovery" }'
779
+ );
780
+ output.push(" ],");
781
+ output.push(' "narration": []');
782
+ output.push(" }");
783
+ output.push(" ```");
784
+ output.push(
785
+ " \u26A0\uFE0F meta.startDate and meta.endDate are REQUIRED. phases need startTime/endTime."
786
+ );
787
+ output.push(' \u26A0\uFE0F teamAssembly uses "agent" (not "name") and must have "time".');
788
+ output.push("");
789
+ output.push(" \u{1F4C4} retro-page-quotes.json:");
790
+ output.push(" ```json");
791
+ output.push(" {");
792
+ output.push(' "good": [');
793
+ output.push(
794
+ ' { "text": "Quote text here", "author": "bob", "timestamp": "2026-02-20T14:30:00Z" }'
795
+ );
796
+ output.push(" ],");
797
+ output.push(' "bad": [],');
798
+ output.push(' "funny": []');
799
+ output.push(" }");
800
+ output.push(" ```");
801
+ output.push(" \u2501\u2501\u2501 END SCHEMA EXAMPLES \u2501\u2501\u2501");
802
+ output.push("");
741
803
  output.push(" \u2705 Curation checklist:");
742
804
  output.push(" \u25A1 Every narration line has at least one labeled event in its time range");
743
805
  output.push(" \u25A1 Milestone labels are short (< 60 chars) and make sense as chat pills");
@@ -770,6 +832,7 @@ function computeNext(progress, existingFiles, logTails, flags = {}, dataSummary,
770
832
  return {
771
833
  ...chainResult,
772
834
  action: "completed_and_chained",
835
+ completedSteps: ["voices", ...chainResult.completedSteps ?? []],
773
836
  output: [...output, ...chainResult.output]
774
837
  };
775
838
  }
@@ -799,6 +862,7 @@ function computeNext(progress, existingFiles, logTails, flags = {}, dataSummary,
799
862
  return {
800
863
  ...chainResult,
801
864
  action: "completed_and_chained",
865
+ completedSteps: ["voices", ...chainResult.completedSteps ?? []],
802
866
  output: [...output, ...chainResult.output]
803
867
  };
804
868
  }
@@ -906,6 +970,7 @@ function computeNext(progress, existingFiles, logTails, flags = {}, dataSummary,
906
970
  return {
907
971
  ...chainResult,
908
972
  action: "completed_and_chained",
973
+ completedSteps: ["viz-timing", ...chainResult.completedSteps ?? []],
909
974
  output: [...output, ...chainResult.output]
910
975
  };
911
976
  }
@@ -938,6 +1003,7 @@ function computeNext(progress, existingFiles, logTails, flags = {}, dataSummary,
938
1003
  return {
939
1004
  ...chainResult,
940
1005
  action: "completed_and_chained",
1006
+ completedSteps: ["sound-design", ...chainResult.completedSteps ?? []],
941
1007
  output: [...output, ...chainResult.output]
942
1008
  };
943
1009
  }
@@ -977,7 +1043,7 @@ function computeNext(progress, existingFiles, logTails, flags = {}, dataSummary,
977
1043
  output.push("");
978
1044
  output.push(" \u26D4 CREATIVE STOP \u2014 Present results to the human and wait for approval.");
979
1045
  output.push(" Only run `npx miriad-viz next` after human approves.");
980
- return { action: "creative_stop", step, progress, output };
1046
+ return { action: "creative_stop", step, progress, output, completedSteps: [step] };
981
1047
  }
982
1048
  output.push(
983
1049
  "",
@@ -987,6 +1053,7 @@ function computeNext(progress, existingFiles, logTails, flags = {}, dataSummary,
987
1053
  return {
988
1054
  ...chainResult,
989
1055
  action: "completed_and_chained",
1056
+ completedSteps: [step, ...chainResult.completedSteps ?? []],
990
1057
  output: [...output, ...chainResult.output]
991
1058
  };
992
1059
  }
@@ -1544,7 +1611,11 @@ async function runNext(flags) {
1544
1611
  const syncConfig = getBoardSyncConfig(progress.project.dataDir);
1545
1612
  if (syncConfig) {
1546
1613
  console.log("\n\u2601 Checking board for existing pipeline state...");
1547
- const { pulled, warnings } = await pullFromBoard(syncConfig, dataDir);
1614
+ const { pulled, warnings } = await pullFromBoard(
1615
+ syncConfig,
1616
+ dataDir,
1617
+ resolve3(projectDir, progress.project.outputDir)
1618
+ );
1548
1619
  if (pulled > 0) {
1549
1620
  console.log(` \u2713 Pulled ${pulled} file${pulled > 1 ? "s" : ""} from board`);
1550
1621
  if (existsSync3(progressPath)) {
@@ -1643,8 +1714,12 @@ async function runNext(flags) {
1643
1714
  const syncConfig = getBoardSyncConfig(result.progress.project.dataDir);
1644
1715
  if (syncConfig) {
1645
1716
  const dataDir2 = resolve3(projectDir, result.progress.project.dataDir);
1717
+ const outputDir = resolve3(projectDir, result.progress.project.outputDir);
1646
1718
  if (result.step && (result.action === "completed_and_chained" || result.action === "creative_stop")) {
1647
- await syncStepOutputs(syncConfig, result.step, dataDir2);
1719
+ const stepsToSync = result.completedSteps?.length ? result.completedSteps : [result.step];
1720
+ for (const syncStep of new Set(stepsToSync)) {
1721
+ await syncStepOutputs(syncConfig, syncStep, dataDir2, outputDir);
1722
+ }
1648
1723
  } else {
1649
1724
  const progressPath = resolve3(projectDir, ".miriad-viz.json");
1650
1725
  if (existsSync3(progressPath)) {
@@ -1690,7 +1765,7 @@ async function main() {
1690
1765
  }
1691
1766
  case "extract": {
1692
1767
  const { projectDir, progress } = requireProject();
1693
- const { runExtract } = await import("./extract-5JGICL3V.js");
1768
+ const { runExtract } = await import("./extract-6XRQDMNC.js");
1694
1769
  await runExtract({
1695
1770
  projectDir,
1696
1771
  progress,
@@ -1711,7 +1786,7 @@ async function main() {
1711
1786
  case "transform": {
1712
1787
  const { projectDir, progress } = requireProject();
1713
1788
  const { parseDuration } = await import("./parse-duration-NVLCEFAF.js");
1714
- const { runTransform } = await import("./transform-Z4LA7G44.js");
1789
+ const { runTransform } = await import("./transform-3YUJZORK.js");
1715
1790
  const padding = {};
1716
1791
  if (typeof flags["pad-start"] === "string") {
1717
1792
  padding.padStartMs = parseDuration(flags["pad-start"]);
@@ -1739,19 +1814,19 @@ async function main() {
1739
1814
  console.log("");
1740
1815
  console.log(chainResult.previewTable);
1741
1816
  }
1742
- const { runTransform } = await import("./transform-Z4LA7G44.js");
1817
+ const { runTransform } = await import("./transform-3YUJZORK.js");
1743
1818
  await runTransform({ projectDir, progress });
1744
- const { runPreview: runPreview2 } = await import("./preview-UUWVOX5Y.js");
1819
+ const { runPreview: runPreview2 } = await import("./preview-7AGBBMPI.js");
1745
1820
  await runPreview2({ projectDir, progress, port, noOpen: flags["no-open"] === true });
1746
1821
  break;
1747
1822
  }
1748
- const { runPreview } = await import("./preview-UUWVOX5Y.js");
1823
+ const { runPreview } = await import("./preview-7AGBBMPI.js");
1749
1824
  await runPreview({ projectDir, progress, port, noOpen: flags["no-open"] === true });
1750
1825
  break;
1751
1826
  }
1752
1827
  case "render": {
1753
1828
  const { projectDir, progress } = requireProject();
1754
- const { runRender } = await import("./render-T2UXDN25.js");
1829
+ const { runRender } = await import("./render-LBIBW45Z.js");
1755
1830
  await runRender({ projectDir, progress, draft: flags.draft === true });
1756
1831
  break;
1757
1832
  }
@@ -8,11 +8,10 @@ import {
8
8
  } from "./chunk-GLABTDMO.js";
9
9
 
10
10
  // src/cli/guided/steps/preview.ts
11
- import { execSync } from "child_process";
12
11
  import { copyFileSync, existsSync, mkdirSync, readdirSync } from "fs";
13
12
  import { resolve } from "path";
14
13
  function copyPreviewAssets(options) {
15
- const { outputDir, audioDir, viewerDir } = options;
14
+ const { outputDir, dataDir, audioDir, viewerDir } = options;
16
15
  const viewerDataDir = resolve(viewerDir, "public", "data");
17
16
  const viewerAudioDir = resolve(viewerDir, "public", "audio");
18
17
  const result = {
@@ -26,10 +25,12 @@ function copyPreviewAssets(options) {
26
25
  copyFileSync(vizDataPath, resolve(viewerDataDir, "viz-data.json"));
27
26
  result.copiedVizData = true;
28
27
  }
29
- const timingPath = resolve(outputDir, "timing.json");
30
- if (existsSync(timingPath)) {
28
+ const timingOutputPath = resolve(outputDir, "timing.json");
29
+ const timingDataPath = resolve(dataDir, "timing.json");
30
+ const timingSource = existsSync(timingOutputPath) ? timingOutputPath : existsSync(timingDataPath) ? timingDataPath : null;
31
+ if (timingSource) {
31
32
  mkdirSync(viewerDataDir, { recursive: true });
32
- copyFileSync(timingPath, resolve(viewerDataDir, "timing.json"));
33
+ copyFileSync(timingSource, resolve(viewerDataDir, "timing.json"));
33
34
  result.copiedTiming = true;
34
35
  }
35
36
  if (existsSync(audioDir)) {
@@ -74,7 +75,8 @@ async function runPreview(options) {
74
75
  }
75
76
  }
76
77
  const audioDir = resolve(projectDir, "audio");
77
- const copyResult = copyPreviewAssets({ outputDir: outDir, audioDir, viewerDir });
78
+ const dataDir = resolve(projectDir, progress.project.dataDir);
79
+ const copyResult = copyPreviewAssets({ outputDir: outDir, dataDir, audioDir, viewerDir });
78
80
  if (copyResult.copiedVizData) {
79
81
  console.log(" \u2713 Copied viz-data.json to viewer/public/data/");
80
82
  }
@@ -84,26 +86,13 @@ async function runPreview(options) {
84
86
  if (copyResult.audioFileCount > 0) {
85
87
  console.log(` \u2713 Copied ${copyResult.audioFileCount} audio file(s) to viewer/public/audio/`);
86
88
  }
87
- const nodeModules = resolve(viewerDir, "node_modules");
88
- if (!existsSync(nodeModules)) {
89
- console.log(" Installing viewer dependencies...");
90
- execSync("pnpm install", { cwd: viewerDir, stdio: "inherit" });
91
- console.log(" \u2713 Dependencies installed");
92
- }
93
- const port = options.port || 5174;
94
89
  markComplete(progress, "preview");
95
90
  writeProgress(projectDir, progress);
96
- console.log(`
97
- Starting preview server on port ${port}...`);
98
- console.log(` Viewer: http://localhost:${port}`);
99
- console.log("\n Press Ctrl+C to stop.\n");
100
- try {
101
- execSync(`npx vite --port ${port}${options.noOpen ? "" : " --open"}`, {
102
- cwd: viewerDir,
103
- stdio: "inherit"
104
- });
105
- } catch {
106
- }
91
+ console.log("\n To start the preview server:");
92
+ console.log(
93
+ " cd viewer && pnpm install && nohup npx vite --host 0.0.0.0 --port 5174 > /tmp/vite.log 2>&1 &"
94
+ );
95
+ console.log("\n Then get a tunnel URL to share with the human.");
107
96
  }
108
97
  export {
109
98
  copyPreviewAssets,
@@ -2,7 +2,7 @@ import {
2
2
  canSync,
3
3
  getBoardSyncConfig,
4
4
  syncStepOutputs
5
- } from "./chunk-UTFBENVA.js";
5
+ } from "./chunk-7BH6QQNB.js";
6
6
  import {
7
7
  markComplete,
8
8
  markError,
@@ -11,7 +11,7 @@ import {
11
11
  canSync,
12
12
  getBoardSyncConfig,
13
13
  syncStepOutputs
14
- } from "./chunk-UTFBENVA.js";
14
+ } from "./chunk-7BH6QQNB.js";
15
15
  import {
16
16
  transformToRawData
17
17
  } from "./chunk-WP7ZSXBZ.js";
@@ -52,12 +52,6 @@ function deriveTimeRange(rawData, curationData, options) {
52
52
  }
53
53
  for (const m of rawData.messages) timestamps.push(m.timestamp);
54
54
  for (const a of rawData.agents) timestamps.push(a.joinedAt);
55
- for (const p of curationData.phases) {
56
- timestamps.push(p.startTime);
57
- timestamps.push(p.endTime);
58
- }
59
- for (const m of curationData.milestones) timestamps.push(m.timestamp);
60
- for (const q of curationData.quotes) timestamps.push(q.timestamp);
61
55
  if (timestamps.length === 0) {
62
56
  throw new Error("processData: no timestamps found in data \u2014 cannot derive time range");
63
57
  }
@@ -477,11 +471,25 @@ function parseInformalTimestamp(timeStr, referenceYear) {
477
471
  return date.getTime();
478
472
  }
479
473
  function findPhaseForTimestamp(timestamp, phases) {
480
- return phases.find((p) => {
474
+ if (phases.length === 0) return void 0;
475
+ const exact = phases.find((p) => {
481
476
  const start = new Date(p.start).getTime();
482
477
  const end = new Date(p.end).getTime();
483
478
  return timestamp >= start && timestamp <= end;
484
479
  });
480
+ if (exact) return exact;
481
+ let nearest;
482
+ let minDistance = Number.POSITIVE_INFINITY;
483
+ for (const p of phases) {
484
+ const start = new Date(p.start).getTime();
485
+ const end = new Date(p.end).getTime();
486
+ const distance = Math.min(Math.abs(timestamp - start), Math.abs(timestamp - end));
487
+ if (distance < minDistance) {
488
+ minDistance = distance;
489
+ nearest = p;
490
+ }
491
+ }
492
+ return nearest;
485
493
  }
486
494
 
487
495
  // src/cli/pipeline.ts
@@ -766,7 +774,7 @@ Output written to ${progress.project.outputDir}/:`);
766
774
  if (canSync()) {
767
775
  const syncConfig = getBoardSyncConfig(progress.project.dataDir);
768
776
  if (syncConfig) {
769
- await syncStepOutputs(syncConfig, "transform", outDir);
777
+ await syncStepOutputs(syncConfig, "transform", dataDir, outDir);
770
778
  }
771
779
  }
772
780
  console.log("\n\u2713 Transform complete. Proceed to the preview step.");
@@ -859,12 +859,6 @@ function deriveTimeRange(rawData, curationData, options) {
859
859
  }
860
860
  for (const m of rawData.messages) timestamps.push(m.timestamp);
861
861
  for (const a of rawData.agents) timestamps.push(a.joinedAt);
862
- for (const p of curationData.phases) {
863
- timestamps.push(p.startTime);
864
- timestamps.push(p.endTime);
865
- }
866
- for (const m of curationData.milestones) timestamps.push(m.timestamp);
867
- for (const q of curationData.quotes) timestamps.push(q.timestamp);
868
862
  if (timestamps.length === 0) {
869
863
  throw new Error("processData: no timestamps found in data \u2014 cannot derive time range");
870
864
  }
@@ -1498,5 +1492,5 @@ exports.computePRPeakRows = computePRPeakRows;
1498
1492
  exports.enrichVizData = enrichVizData;
1499
1493
  exports.getFrameState = getFrameState;
1500
1494
  exports.processData = processData;
1501
- //# sourceMappingURL=chunk-AQ5ZU7P2.cjs.map
1502
- //# sourceMappingURL=chunk-AQ5ZU7P2.cjs.map
1495
+ //# sourceMappingURL=chunk-DZYFC24M.cjs.map
1496
+ //# sourceMappingURL=chunk-DZYFC24M.cjs.map