@openpresentation/opf 0.20.4 → 0.21.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 (61) hide show
  1. package/dist/browser.js +16 -16
  2. package/dist/{chunk-Z75YB54S.js → chunk-2X4ZG2CN.js} +5 -5
  3. package/dist/{chunk-WD4W7KKK.js → chunk-6UBIR2U3.js} +54 -11
  4. package/dist/{chunk-DYGYMBBW.js → chunk-7YFMWEPQ.js} +2 -2
  5. package/dist/{chunk-7PQZDC2H.js → chunk-ARLOTG23.js} +1 -1
  6. package/dist/{chunk-VFMHM2IL.js → chunk-BWWGYOOG.js} +22 -0
  7. package/dist/{chunk-IDMQWS6O.js → chunk-D2XIDBUB.js} +6 -6
  8. package/dist/{chunk-5SQ6CIWR.js → chunk-D7WZVSNV.js} +5 -5
  9. package/dist/{chunk-OIGCC6VA.js → chunk-EFICNDGV.js} +2 -2
  10. package/dist/{chunk-YOLDSF7U.js → chunk-THEUCQZZ.js} +1 -1
  11. package/dist/{chunk-S4FR7ATF.js → chunk-U55BQQKU.js} +1 -1
  12. package/dist/{chunk-V66KJA3H.js → chunk-VLFDWV7L.js} +1 -1
  13. package/dist/{chunk-52GKVP3I.js → chunk-W62CX2WG.js} +22 -12
  14. package/dist/{chunk-URUNMZFO.js → chunk-WZPFIPOO.js} +2 -2
  15. package/dist/{chunk-XAYMPBNE.js → chunk-X6SB52RP.js} +333 -149
  16. package/dist/{chunk-2M7U4WL3.js → chunk-XQARTOZJ.js} +260 -104
  17. package/dist/{chunk-TZ5IZETE.js → chunk-YD44KIRA.js} +1 -1
  18. package/dist/{chunk-TCBEF5OY.js → chunk-YZ7RZ4MU.js} +1 -1
  19. package/dist/{composition-QtS1rnhv.d.ts → composition-DzAV0cfU.d.ts} +133 -3
  20. package/dist/composition.d.ts +1 -1
  21. package/dist/composition.js +1 -1
  22. package/dist/conversion-524P44NX.js +19 -0
  23. package/dist/{conversion-Cqwu0Ds9.d.ts → conversion-CtTg2ivR.d.ts} +6 -5
  24. package/dist/convert.d.ts +3 -3
  25. package/dist/convert.js +7 -7
  26. package/dist/data.d.ts +1 -1
  27. package/dist/data.js +2 -2
  28. package/dist/{deck-report-BdG5H3Qj.d.ts → deck-report-971nEzTY.d.ts} +2 -2
  29. package/dist/deck.d.ts +6 -6
  30. package/dist/deck.js +10 -10
  31. package/dist/diff.d.ts +1 -1
  32. package/dist/diff.js +5 -5
  33. package/dist/docs.js +16 -10
  34. package/dist/examples.d.ts +1 -1
  35. package/dist/{finding-DqgwzUmr.d.ts → finding-l9dlQ2NF.d.ts} +4 -0
  36. package/dist/format.js +2 -2
  37. package/dist/index.d.ts +21 -15
  38. package/dist/index.js +20 -20
  39. package/dist/markdown.d.ts +4 -4
  40. package/dist/markdown.js +7 -7
  41. package/dist/node-engine.d.ts +30 -9
  42. package/dist/node-engine.js +20 -20
  43. package/dist/{pagination-CAX6mHG6.d.ts → pagination-BTqRj7dM.d.ts} +2 -2
  44. package/dist/pagination.d.ts +2 -2
  45. package/dist/pagination.js +4 -4
  46. package/dist/patch.d.ts +1 -1
  47. package/dist/patch.js +4 -4
  48. package/dist/{presentation-BG4QCcdB.d.ts → presentation-ZNcXSpvm.d.ts} +50 -4
  49. package/dist/repo-readme.js +1 -1
  50. package/dist/schemas.js +1 -1
  51. package/dist/spec/schemas/finding.schema.json +6 -1
  52. package/dist/spec/schemas/opf.schema.json +8 -0
  53. package/dist/types.d.ts +2 -2
  54. package/dist/{validation-types-DRaNnieo.d.ts → validation-types-uLDSrJgM.d.ts} +3 -3
  55. package/dist/{validator-BJtXHJKh.d.ts → validator-DxAjRPmE.d.ts} +4 -10
  56. package/dist/validator.d.ts +5 -5
  57. package/dist/validator.js +3 -3
  58. package/dist/yaml.d.ts +4 -4
  59. package/dist/yaml.js +7 -7
  60. package/package.json +1 -1
  61. package/dist/conversion-DRCJIMWS.js +0 -19
package/dist/browser.js CHANGED
@@ -1,20 +1,20 @@
1
- import { OPFApiError } from './chunk-52GKVP3I.js';
2
- export { OPFApiError, OPFExportError, OPFImportError, OPFMoveToCustomError, copySlides, edit, embed, fill, fillRecords, moveToCustom, parseSlideSelection, sameRecord, stats, updateFromCatalog } from './chunk-52GKVP3I.js';
1
+ import { OPFApiError } from './chunk-W62CX2WG.js';
2
+ export { OPFApiError, OPFExportError, OPFImportError, OPFMoveToCustomError, copySlides, edit, embed, fill, fillRecords, localAssetSources, moveToCustom, parseSlideSelection, sameRecord, stats, updateFromCatalog } from './chunk-W62CX2WG.js';
3
3
  export { specFileEntries, specFileKinds, specFilePaths } from './chunk-UJSAR6GF.js';
4
- export { OPFDataImportError, ingest, parseTabularData } from './chunk-TZ5IZETE.js';
5
- export { DECK_FORMATS, deckFormatOf, parse, stringify } from './chunk-5SQ6CIWR.js';
6
- export { fromMarkdown, toMarkdown } from './chunk-Z75YB54S.js';
7
- import './chunk-IDMQWS6O.js';
8
- export { OPFMarkdownError } from './chunk-7PQZDC2H.js';
9
- export { diff, merge } from './chunk-URUNMZFO.js';
10
- export { OPFPatchError, OPFPatchValidationError, applyPatch } from './chunk-YOLDSF7U.js';
11
- export { OPFFormatError, format } from './chunk-S4FR7ATF.js';
12
- export { OPFPaginationError, paginate, paginateSlide } from './chunk-DYGYMBBW.js';
13
- import './chunk-V66KJA3H.js';
14
- import './chunk-TCBEF5OY.js';
15
- export { CATALOG_SCHEMA, DEFAULT_CHART_PALETTE, DEFAULT_VALIDATION_THRESHOLDS, OPFValidationError, assertValid, assertValidCatalogRecord, catalogDisplayKinds, catalogSchemaNames, findValidationRule, resolveSlideContext, validate, validateCatalogRecord, validationCategories, validationRules } from './chunk-2M7U4WL3.js';
16
- export { CATALOG_GROUP_PATTERN, CATALOG_REFERENCE_PATTERN, CHART_TYPES, DEFAULT_VARIABLE_DATE_FORMAT, ENGINE_DEFAULT_CHART_TYPES, ENGINE_DEFAULT_COLOR_SCHEME, ENGINE_DEFAULT_FONT_SCHEME, ENGINE_DEFAULT_THEME, LANGUAGES, LOGO_SHAPES, OPFCatalogsOptionError, OPFUnresolvedReferenceError, OPFVariableError, SLIDE_SCOPED_BUILTINS, SOCIAL_PLATFORMS, VARIABLE_KINDS, catalogGroupSource, catalogKinds, catalogRecords, catalogReferenceSites, chartNumber, coerceVariableValue, datasetDiagnostics, formatDataNumber, formatVariableNumber, fromExcelNumberFormat, hasContentVariables, inlineChartData, inlineDatasets, inlineTableData, isDatasetRef, isTemplate, isXYChartType, listBuiltinVariables, listVariables, normalizeLanguageFamily, numberFormatError, parseReference, resolveChartData, resolveDesignRecords, resolveFontScheme, resolveReference, resolveSlideVariables, resolveTableData, resolveVariables, suggestChartNumberFix, tableCellDisplayValue, toExcelNumberFormat, unresolvedReference, unusedDatasets, variableDeclarations } from './chunk-XAYMPBNE.js';
17
- export { audience, chartType, colorScheme, fontScheme, language, layout, narrative, presentation, purpose, schemaEntries, schemaNames, schemas, socialPlatform, theme, tone } from './chunk-VFMHM2IL.js';
4
+ export { OPFDataImportError, ingest, parseTabularData } from './chunk-YD44KIRA.js';
5
+ export { DECK_FORMATS, deckFormatOf, parse, stringify } from './chunk-D7WZVSNV.js';
6
+ export { fromMarkdown, toMarkdown } from './chunk-2X4ZG2CN.js';
7
+ import './chunk-D2XIDBUB.js';
8
+ export { OPFMarkdownError } from './chunk-ARLOTG23.js';
9
+ export { diff, merge } from './chunk-WZPFIPOO.js';
10
+ export { OPFPatchError, OPFPatchValidationError, applyPatch } from './chunk-THEUCQZZ.js';
11
+ export { OPFFormatError, format } from './chunk-U55BQQKU.js';
12
+ export { OPFPaginationError, paginate, paginateSlide } from './chunk-7YFMWEPQ.js';
13
+ import './chunk-VLFDWV7L.js';
14
+ import './chunk-YZ7RZ4MU.js';
15
+ export { CATALOG_SCHEMA, DEFAULT_VALIDATION_THRESHOLDS, OPFValidationError, assertValid, assertValidCatalogRecord, catalogDisplayKinds, catalogSchemaNames, findValidationRule, resolveSlideContext, validate, validateCatalogRecord, validationCategories, validationRules } from './chunk-XQARTOZJ.js';
16
+ export { CATALOG_GROUP_PATTERN, CATALOG_REFERENCE_PATTERN, CHART_TYPES, DEFAULT_VARIABLE_DATE_FORMAT, ENGINE_DEFAULT_CHART_TYPES, ENGINE_DEFAULT_COLOR_SCHEME, ENGINE_DEFAULT_FONT_SCHEME, ENGINE_DEFAULT_THEME, LANGUAGES, LOGO_SHAPES, OPFCatalogsOptionError, OPFUnresolvedReferenceError, OPFVariableError, SLIDE_SCOPED_BUILTINS, SOCIAL_PLATFORMS, VARIABLE_KINDS, catalogGroupSource, catalogKinds, catalogRecords, catalogReferenceSites, chartNumber, coerceVariableValue, datasetDiagnostics, formatDataNumber, formatVariableNumber, fromExcelNumberFormat, hasContentVariables, inlineChartData, inlineDatasets, inlineTableData, isDatasetRef, isTemplate, isXYChartType, listBuiltinVariables, listVariables, normalizeLanguageFamily, numberFormatError, parseReference, resolveChartData, resolveDesignRecords, resolveFontScheme, resolveReference, resolveSlideVariables, resolveTableData, resolveVariables, suggestChartNumberFix, tableCellDisplayValue, toExcelNumberFormat, unresolvedReference, unusedDatasets, variableDeclarations } from './chunk-X6SB52RP.js';
17
+ export { audience, chartType, colorScheme, fontScheme, language, layout, narrative, presentation, purpose, schemaEntries, schemaNames, schemas, socialPlatform, theme, tone } from './chunk-BWWGYOOG.js';
18
18
  export { FONT_POLICY, applyFontPolicyDecisions, fontAvailabilityDiagnostics, fontPolicyFor } from './chunk-F7PLNWHQ.js';
19
19
 
20
20
  // src/browser.ts
@@ -1,8 +1,8 @@
1
- import { Ctx, splitLines, lineRange, readYamlMapping, NOT_CHECKED, OPFMarkdownError, writeYaml, readCsv, DECIMAL, csvField, scalarText } from './chunk-7PQZDC2H.js';
2
- import { parseQuoteLines, levelsFromIndents, parseCodeFence, splitWhen, fenceCode } from './chunk-V66KJA3H.js';
3
- import { same, isRecord, runText, isPlainRun, FORMATTING } from './chunk-TCBEF5OY.js';
4
- import { validate } from './chunk-2M7U4WL3.js';
5
- import { checkCatalogsOption, PROMOTED_REGION_KEY } from './chunk-XAYMPBNE.js';
1
+ import { Ctx, splitLines, lineRange, readYamlMapping, NOT_CHECKED, OPFMarkdownError, writeYaml, readCsv, DECIMAL, csvField, scalarText } from './chunk-ARLOTG23.js';
2
+ import { parseQuoteLines, levelsFromIndents, parseCodeFence, splitWhen, fenceCode } from './chunk-VLFDWV7L.js';
3
+ import { same, isRecord, runText, isPlainRun, FORMATTING } from './chunk-YZ7RZ4MU.js';
4
+ import { validate } from './chunk-XQARTOZJ.js';
5
+ import { checkCatalogsOption, PROMOTED_REGION_KEY } from './chunk-X6SB52RP.js';
6
6
 
7
7
  // src/markdown/canon.ts
8
8
  var FORMAT_KEYS = FORMATTING;
@@ -1,11 +1,11 @@
1
- import { defaultCatalogs } from './chunk-OIGCC6VA.js';
2
- import { OPFApiError, parseSlideSelection, OPFExportError, asApiError, OPFImportError } from './chunk-52GKVP3I.js';
3
- import { deckFormatOf, readDeckReport, stringify } from './chunk-5SQ6CIWR.js';
4
- import { paginate } from './chunk-DYGYMBBW.js';
5
- import { validate, OPFValidationError } from './chunk-2M7U4WL3.js';
6
- import { stat, readdir, lstat, mkdir, open, rename, link, unlink, readFile } from 'fs/promises';
1
+ import { defaultCatalogs } from './chunk-EFICNDGV.js';
2
+ import { localAssetSources, OPFApiError, parseSlideSelection, OPFExportError, asApiError, OPFImportError } from './chunk-W62CX2WG.js';
3
+ import { deckFormatOf, readDeckReport, stringify } from './chunk-D7WZVSNV.js';
4
+ import { paginate } from './chunk-7YFMWEPQ.js';
5
+ import { validate, OPFValidationError } from './chunk-XQARTOZJ.js';
6
+ import { link, stat, readdir, lstat, readFile, open, unlink, mkdir, rename } from 'fs/promises';
7
7
  import path6 from 'path';
8
- import { readFileSync, realpathSync, statSync } from 'fs';
8
+ import { readFileSync, statSync, realpathSync } from 'fs';
9
9
  import { pathToFileURL, fileURLToPath } from 'url';
10
10
  import { createRequire } from 'module';
11
11
  import { randomUUID } from 'crypto';
@@ -74,6 +74,11 @@ function createImageResolver(root, reporter, passDirectory = "pass --asset-dir")
74
74
  return outcome;
75
75
  }
76
76
  return {
77
+ /** The reason a local source cannot be read (`missing`: no such file; `blocked`: outside the folder, not an image, too large), or undefined when it can, or is not a local file. */
78
+ check: (source) => {
79
+ const outcome = read(source);
80
+ return "problem" in outcome ? outcome : void 0;
81
+ },
77
82
  /** opf-render: a data URI string, or null for the placeholder (a missing file is reported by the renderer as unresolved-asset). */
78
83
  forSvg: (source, context) => {
79
84
  if (!source) return null;
@@ -91,6 +96,25 @@ function createImageResolver(root, reporter, passDirectory = "pass --asset-dir")
91
96
  }
92
97
  };
93
98
  }
99
+ function pointerToString(value, source, pointer = "") {
100
+ if (value === source) return pointer;
101
+ if (value === null || typeof value !== "object") return void 0;
102
+ for (const [key, child] of Object.entries(value)) {
103
+ const found = pointerToString(child, source, `${pointer}/${key.replaceAll("~", "~0").replaceAll("/", "~1")}`);
104
+ if (found !== void 0) return found;
105
+ }
106
+ return void 0;
107
+ }
108
+ function localAssetProblems(deck, root) {
109
+ const resolver = createImageResolver(root, { add() {
110
+ } });
111
+ const problems = [];
112
+ for (const source of localAssetSources(deck)) {
113
+ const found = resolver.check(source);
114
+ if (found) problems.push({ path: pointerToString(deck, source) ?? "", source, ...found });
115
+ }
116
+ return problems;
117
+ }
94
118
  var RENDER_PACKAGE = "@openpresentation/opf-render";
95
119
  var PPTX_PACKAGE = "@openpresentation/opf-pptx";
96
120
  var PEER_RANGES = { [RENDER_PACKAGE]: "^0.20.0", [PPTX_PACKAGE]: "^0.20.0" };
@@ -348,6 +372,25 @@ async function checkDestinations(files, overwrite, flags = true) {
348
372
  }
349
373
  }
350
374
  }
375
+ var NO_HARD_LINKS = /* @__PURE__ */ new Set(["EPERM", "ENOTSUP", "EOPNOTSUPP", "ENOSYS", "EXDEV"]);
376
+ async function publishNew(temporary, output, publish = link) {
377
+ try {
378
+ await publish(temporary, output);
379
+ return;
380
+ } catch (error) {
381
+ if (!NO_HARD_LINKS.has(error.code ?? "")) throw error;
382
+ }
383
+ const bytes = await readFile(temporary);
384
+ const handle = await open(output, "wx");
385
+ try {
386
+ await handle.writeFile(bytes);
387
+ await handle.close();
388
+ } catch (error) {
389
+ await handle.close().catch(() => void 0);
390
+ await unlink(output).catch(() => void 0);
391
+ throw error;
392
+ }
393
+ }
351
394
  async function writeFiles(files, overwrite, flags = true) {
352
395
  const unique = new Set(files.map((entry) => path6.resolve(entry.file)));
353
396
  if (unique.size !== files.length) throw new OPFApiError("Two outputs would write the same file.", "invalid-option");
@@ -372,7 +415,7 @@ async function writeFiles(files, overwrite, flags = true) {
372
415
  item.temporary = "";
373
416
  } else {
374
417
  try {
375
- await link(item.temporary, item.output);
418
+ await publishNew(item.temporary, item.output);
376
419
  } catch (error) {
377
420
  if (error.code === "EEXIST") throw outputExists(item.output, flags);
378
421
  throw error;
@@ -438,14 +481,14 @@ var Reporter = class {
438
481
  help: HELP[code] ?? "",
439
482
  ...Object.fromEntries(Object.entries(details).filter(([, value]) => value !== void 0))
440
483
  };
441
- const key = JSON.stringify([entry.ruleId, entry.path, entry.message]);
484
+ const key = JSON.stringify([entry.ruleId, entry.path, entry.message, details]);
442
485
  if (this.seen.has(key)) return;
443
486
  this.seen.add(key);
444
487
  this.findings.push(entry);
445
488
  }
446
489
  /** Add a finding as the library made it (the `findings` of a thrown OPFRenderError, OPFPptxError or core validation error). Identical entries are kept once. */
447
490
  addFinding(finding) {
448
- const key = JSON.stringify([finding.ruleId, finding.path, finding.message]);
491
+ const key = JSON.stringify(finding);
449
492
  if (this.seen.has(key)) return;
450
493
  this.seen.add(key);
451
494
  this.findings.push(finding);
@@ -1035,4 +1078,4 @@ async function saveDeck(presentation, file, options = {}) {
1035
1078
  return { path: file, format };
1036
1079
  }
1037
1080
 
1038
- export { EXPORT_FORMATS, EXPORT_TEXT, PEER_RANGES, PPTX_PACKAGE, RENDER_EXTRAS, RENDER_PACKAGE, Reporter, VERSIONS, checkDate, checkDestinations, checkOptions, checkOutputPattern, checkRenamedOptions, checkScale, convertFiles, createZip, deckFileFormat, deckStem, embeddedFor, exportFormatOf, finishReport, importPresentation, leaseSharedFonts, listFontDirectories, loadPptx, loadRenderer, locatePackage, missingPeerFrom, openDeck, padNumber, planConversion, pointerOf, prepareExport, prepareFonts, reaches, readInput, reportThrown, resolveExportOptions, runExport, runImport, runPreparedExport, saveDeck, stemOf, writeFiles, writePlanned };
1081
+ export { EXPORT_FORMATS, EXPORT_TEXT, PEER_RANGES, PPTX_PACKAGE, RENDER_EXTRAS, RENDER_PACKAGE, Reporter, VERSIONS, assetRoot, checkDate, checkDestinations, checkOptions, checkOutputPattern, checkRenamedOptions, checkScale, convertFiles, createZip, deckFileFormat, deckStem, embeddedFor, exportFormatOf, finishReport, importPresentation, leaseSharedFonts, listFontDirectories, loadPptx, loadRenderer, localAssetProblems, locatePackage, missingPeerFrom, openDeck, padNumber, planConversion, pointerOf, prepareExport, prepareFonts, publishNew, reaches, readInput, reportThrown, resolveExportOptions, runExport, runImport, runPreparedExport, saveDeck, stemOf, writeFiles, writePlanned };
@@ -1,5 +1,5 @@
1
- import { assertValid, resolveSlideScriptMeasurement, resolveSlideContext } from './chunk-2M7U4WL3.js';
2
- import { resolveSlideVariables, checkCatalogsOption, usesSlideBuiltin, composeSlide, codeHighlightSlice, tableRowBoundaries, visitContentPayloads, regionAccepts, slideTokenSpans, sliceNumberedItems } from './chunk-XAYMPBNE.js';
1
+ import { assertValid, resolveSlideScriptMeasurement, resolveSlideContext } from './chunk-XQARTOZJ.js';
2
+ import { resolveSlideVariables, checkCatalogsOption, usesSlideBuiltin, composeSlide, codeHighlightSlice, tableRowBoundaries, visitContentPayloads, regionAccepts, slideTokenSpans, sliceNumberedItems } from './chunk-X6SB52RP.js';
3
3
 
4
4
  // src/pagination.ts
5
5
  var OPFPaginationError = class extends Error {
@@ -1,4 +1,4 @@
1
- import { isRecord, same } from './chunk-TCBEF5OY.js';
1
+ import { isRecord, same } from './chunk-YZ7RZ4MU.js';
2
2
  import { parseDocument, YAMLMap, Scalar, stringify } from 'yaml';
3
3
 
4
4
  // src/not-checked.ts
@@ -4653,6 +4653,21 @@ var presentation = {
4653
4653
  "Revenue grew from $12M in Q1 to $18M in Q2, with the steepest rise in the West region."
4654
4654
  ]
4655
4655
  },
4656
+ "colors": {
4657
+ "type": "array",
4658
+ "items": {
4659
+ "$ref": "#/$defs/ColorRef"
4660
+ },
4661
+ "minItems": 1,
4662
+ "maxItems": 24,
4663
+ "description": "Optional series colors, by position: entry i replaces palette color i, the color of series i (the i-th plotted value column), of slice or category i on a pie, doughnut, treemap or funnel chart, and of the i-th color a histogram, pareto, waterfall or box-and-whisker chart draws with. An entry is any ColorRef: a hex color, a color-scheme slot or role ('accent3', 'secondary') or a 'var:<id>' color variable; a scheme name keeps following the deck if its scheme changes, and is written to PowerPoint as a theme color. Positions past the last entry keep the deck palette (accent1 to accent6, then their tints). A color is kept at 3:1 contrast against the chart panel (a lighter or darker shade is used when it falls short) and 'chart.highlight' wins over it: highlighted marks take the primary color and the rest the muted neutral. A color that cannot be resolved falls back to the palette color for its position. Absent keeps the deck palette exactly.",
4664
+ "examples": [
4665
+ [
4666
+ "accent3",
4667
+ "#7B241C"
4668
+ ]
4669
+ ]
4670
+ },
4656
4671
  "highlight": {
4657
4672
  "$ref": "#/$defs/ChartHighlight",
4658
4673
  "description": "Optional emphasis: the series and/or categories that carry the message. The engines draw the highlighted marks in the deck's primary (accent) color and every other mark in a muted neutral derived from the theme (a light grey on a light chart panel, a dim grey on a dark one); there is no color field. A mark is highlighted when its series OR its category is named. Absent keeps today's colors exactly. Supported on column, bar and line charts (series and categories; on a line a category highlight marks that category's points), pie and doughnut charts (categories, one per slice), and area, scatter and radar charts (series); the histogram, pareto, waterfall, funnel, treemap, box-and-whisker, map and combo constructs drop the option with a 'chart-option-adapted' diagnostic, as does a part the type cannot highlight. A name that matches no column or row label is a 'chart-highlight-unknown-name' error."
@@ -8551,6 +8566,13 @@ var finding = {
8551
8566
  "params": {
8552
8567
  "type": "object",
8553
8568
  "additionalProperties": true
8569
+ },
8570
+ "alternatives": {
8571
+ "type": "array",
8572
+ "items": {
8573
+ "type": "string"
8574
+ },
8575
+ "description": "Present when the issue is the best match of a oneOf or anyOf: one line per other form the value was checked against and did not fit, such as `string: must be string`."
8554
8576
  }
8555
8577
  }
8556
8578
  },
@@ -1,9 +1,9 @@
1
- import { NOT_CHECKED, Ctx } from './chunk-7PQZDC2H.js';
2
- import { sortPresentationKeys } from './chunk-S4FR7ATF.js';
3
- import { same } from './chunk-TCBEF5OY.js';
4
- import { validate } from './chunk-2M7U4WL3.js';
5
- import { checkCatalogsOption } from './chunk-XAYMPBNE.js';
6
- import { presentation } from './chunk-VFMHM2IL.js';
1
+ import { NOT_CHECKED, Ctx } from './chunk-ARLOTG23.js';
2
+ import { sortPresentationKeys } from './chunk-U55BQQKU.js';
3
+ import { same } from './chunk-YZ7RZ4MU.js';
4
+ import { validate } from './chunk-XQARTOZJ.js';
5
+ import { checkCatalogsOption } from './chunk-X6SB52RP.js';
6
+ import { presentation } from './chunk-BWWGYOOG.js';
7
7
  import { Parser, parseDocument, isMap, Document, visit, isScalar, isAlias, isSeq } from 'yaml';
8
8
 
9
9
  var MAX_ALIAS_COUNT = 100;
@@ -1,8 +1,8 @@
1
- import { fromMarkdown, toMarkdown } from './chunk-Z75YB54S.js';
2
- import { fromYaml, toYaml } from './chunk-IDMQWS6O.js';
3
- import { NOT_CHECKED } from './chunk-7PQZDC2H.js';
4
- import { parseSource, validate, OPFValidationError } from './chunk-2M7U4WL3.js';
5
- import { checkCatalogsOption } from './chunk-XAYMPBNE.js';
1
+ import { fromMarkdown, toMarkdown } from './chunk-2X4ZG2CN.js';
2
+ import { fromYaml, toYaml } from './chunk-D2XIDBUB.js';
3
+ import { NOT_CHECKED } from './chunk-ARLOTG23.js';
4
+ import { parseSource, validate, OPFValidationError } from './chunk-XQARTOZJ.js';
5
+ import { checkCatalogsOption } from './chunk-X6SB52RP.js';
6
6
 
7
7
  // src/deck-report.ts
8
8
  var DECK_FORMATS = ["json", "yaml", "markdown"];
@@ -1,5 +1,5 @@
1
- import { OPFApiError } from './chunk-52GKVP3I.js';
2
- import { CATALOG_SCHEMA } from './chunk-2M7U4WL3.js';
1
+ import { OPFApiError } from './chunk-W62CX2WG.js';
2
+ import { CATALOG_SCHEMA } from './chunk-XQARTOZJ.js';
3
3
  import { CATALOG_SCHEMA as CATALOG_SCHEMA$1, gallery } from '@openpresentation/gallery';
4
4
 
5
5
  function galleryMismatch(declared, reads = CATALOG_SCHEMA) {
@@ -1,4 +1,4 @@
1
- import { validate } from './chunk-2M7U4WL3.js';
1
+ import { validate } from './chunk-XQARTOZJ.js';
2
2
 
3
3
  // src/patch.ts
4
4
  var OPFPatchError = class extends Error {
@@ -1,4 +1,4 @@
1
- import { presentation } from './chunk-VFMHM2IL.js';
1
+ import { presentation } from './chunk-BWWGYOOG.js';
2
2
 
3
3
  // src/format.ts
4
4
  var OPFFormatError = class extends Error {
@@ -1,4 +1,4 @@
1
- import { runText } from './chunk-TCBEF5OY.js';
1
+ import { runText } from './chunk-YZ7RZ4MU.js';
2
2
 
3
3
  // src/convert/text-lines.ts
4
4
  var LIST_PREFIX = /^([ \t]*)(?:([-*•+]|\d{1,3}[.)])[ \t]+)?/;
@@ -1,7 +1,7 @@
1
- import { OPFDataImportError, parseTabularData } from './chunk-TZ5IZETE.js';
2
- import { applyPatchWithInverse } from './chunk-YOLDSF7U.js';
3
- import { validate, OPFValidationError } from './chunk-2M7U4WL3.js';
4
- import { embeddedCopy, checkCatalogsOption, catalogReferenceSites, parseReference, catalogGroupDeclared, resolveReference, dottedPath, unresolvedReference, recordReferenceSites, catalogGroupSource, registeredCatalog, catalogKinds, CATALOG_GROUP_PATTERN, isRecord, visitContentPayloads, annotationText, listVariables, resolveVariables, LOGO_SHAPES, resolveDesignRecords, resolveFontFamilies, resolveCanvasDimensions, imageBackground } from './chunk-XAYMPBNE.js';
1
+ import { OPFDataImportError, parseTabularData } from './chunk-YD44KIRA.js';
2
+ import { applyPatchWithInverse } from './chunk-THEUCQZZ.js';
3
+ import { validate, OPFValidationError } from './chunk-XQARTOZJ.js';
4
+ import { embeddedCopy, checkCatalogsOption, catalogReferenceSites, parseReference, catalogGroupDeclared, resolveReference, dottedPath, unresolvedReference, recordReferenceSites, catalogGroupSource, registeredCatalog, catalogKinds, CATALOG_GROUP_PATTERN, isRecord, visitContentPayloads, annotationText, listVariables, resolveVariables, LOGO_SHAPES, resolveDesignRecords, resolveFontFamilies, resolveCanvasDimensions, imageBackground } from './chunk-X6SB52RP.js';
5
5
 
6
6
  // src/api-errors.ts
7
7
  var OPFApiError = class extends Error {
@@ -429,6 +429,14 @@ function visitRuns(value, visit) {
429
429
  }
430
430
  }
431
431
  function stats(presentation2, options = {}) {
432
+ return compute(presentation2, options);
433
+ }
434
+ function localAssetSources(presentation2) {
435
+ const found = /* @__PURE__ */ new Set();
436
+ compute(presentation2, {}, (src) => found.add(src));
437
+ return [...found];
438
+ }
439
+ function compute(presentation2, options, onFile) {
432
440
  const catalogs = { catalogs: checkCatalogsOption(options.catalogs, "stats") };
433
441
  if (!isRecord(presentation2)) throw new TypeError("stats needs a presentation object.");
434
442
  const deck = presentation2;
@@ -439,9 +447,14 @@ function stats(presentation2, options = {}) {
439
447
  const registry = isRecord(deck.assets) ? deck.assets : {};
440
448
  const uses = { total: 0, references: 0, embedded: 0, files: 0, remote: 0 };
441
449
  let embeddedTotal = 0;
442
- const useAsset = (asset) => {
450
+ const useAsset = (asset, video = false) => {
443
451
  const src = srcOf(asset);
444
452
  if (src === void 0) return;
453
+ if (onFile && !video) {
454
+ let source = src;
455
+ for (let hop = 0; source !== void 0 && assetForm(source) === "reference" && hop < 8; hop++) source = srcOf(registry[source.slice("asset:".length)]);
456
+ if (source !== void 0 && assetForm(source) === "file" && !source.includes("{{")) onFile(source);
457
+ }
445
458
  const form = assetForm(src);
446
459
  uses.total++;
447
460
  uses[form === "reference" ? "references" : form === "embedded" ? "embedded" : form === "remote" ? "remote" : "files"]++;
@@ -562,7 +575,7 @@ function stats(presentation2, options = {}) {
562
575
  const datasetUse = /* @__PURE__ */ new Map();
563
576
  const payloadCounts = { text: 0, items: 0, bullets: 0, quote: 0, metric: 0, code: 0, timeline: 0, chart: 0, table: 0, image: 0, video: 0, blocks: 0, regions: 0, groups: 0, maxDepth: 0 };
564
577
  const layouts = /* @__PURE__ */ new Map(), chartTypes = /* @__PURE__ */ new Map(), extensions = /* @__PURE__ */ new Set();
565
- const chartData = { inline: 0, dataset: 0, source: 0 };
578
+ const chartData = { inline: 0, dataset: 0, withSource: 0 };
566
579
  const tableItems = [];
567
580
  let tableRows = 0, tableColumns = 0, datasetBackedTables = 0, chartTotal = 0, captions = 0;
568
581
  const hidden = [], withoutNotes = [], sections = [];
@@ -641,7 +654,7 @@ function stats(presentation2, options = {}) {
641
654
  }
642
655
  if (node.image !== void 0) slideImages += contentImage(node.image);
643
656
  if (node.video !== void 0) {
644
- useAsset(node.video);
657
+ useAsset(node.video, true);
645
658
  images.videos++;
646
659
  }
647
660
  if (isRecord(node.chart)) {
@@ -654,10 +667,7 @@ function stats(presentation2, options = {}) {
654
667
  chartData.dataset++;
655
668
  bump(datasetUse, data.dataset);
656
669
  } else if (Array.isArray(data.columns) || Array.isArray(data.rows)) chartData.inline++;
657
- else if (typeof data.src === "string") {
658
- chartData.source++;
659
- useAsset(data.src);
660
- }
670
+ if (isRecord(data.source)) chartData.withSource++;
661
671
  }
662
672
  }
663
673
  if (isRecord(node.table)) {
@@ -920,4 +930,4 @@ function summarize(decks) {
920
930
  return [...merged.values()];
921
931
  }
922
932
 
923
- export { OPFApiError, OPFExportError, OPFImportError, OPFMoveToCustomError, asApiError, copySlides, edit, embed, fill, fillRecords, moveToCustom, parseSlideSelection, sameRecord, stats, updateFromCatalog };
933
+ export { OPFApiError, OPFExportError, OPFImportError, OPFMoveToCustomError, asApiError, copySlides, edit, embed, fill, fillRecords, localAssetSources, moveToCustom, parseSlideSelection, sameRecord, stats, updateFromCatalog };
@@ -1,5 +1,5 @@
1
- import { jsonEqual, formatPointer } from './chunk-YOLDSF7U.js';
2
- import { annotationText } from './chunk-XAYMPBNE.js';
1
+ import { jsonEqual, formatPointer } from './chunk-THEUCQZZ.js';
2
+ import { annotationText } from './chunk-X6SB52RP.js';
3
3
 
4
4
  // src/diff-match.ts
5
5
  var DEFAULT_MATCH_THRESHOLD = 0.5;