@formfeed/mcp 0.3.11 → 0.3.13

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 (2) hide show
  1. package/bin/formfeed-mcp.mjs +980 -339
  2. package/package.json +1 -1
@@ -914,7 +914,7 @@ var require_version_check = __commonJS({
914
914
  var require_regex = __commonJS({
915
915
  "node_modules/.pnpm/qrcode@1.5.4/node_modules/qrcode/lib/core/regex.js"(exports) {
916
916
  "use strict";
917
- var numeric = "[0-9]+";
917
+ var numeric2 = "[0-9]+";
918
918
  var alphanumeric = "[A-Z $%*+\\-./:]+";
919
919
  var kanji = "(?:[u3000-u303F]|[u3040-u309F]|[u30A0-u30FF]|[uFF00-uFFEF]|[u4E00-u9FAF]|[u2605-u2606]|[u2190-u2195]|u203B|[u2010u2015u2018u2019u2025u2026u201Cu201Du2225u2260]|[u0391-u0451]|[u00A7u00A8u00B1u00B4u00D7u00F7])+";
920
920
  kanji = kanji.replace(/u/g, "\\u");
@@ -922,10 +922,10 @@ var require_regex = __commonJS({
922
922
  exports.KANJI = new RegExp(kanji, "g");
923
923
  exports.BYTE_KANJI = new RegExp("[^A-Z0-9 $%*+\\-./:]+", "g");
924
924
  exports.BYTE = new RegExp(byte, "g");
925
- exports.NUMERIC = new RegExp(numeric, "g");
925
+ exports.NUMERIC = new RegExp(numeric2, "g");
926
926
  exports.ALPHANUMERIC = new RegExp(alphanumeric, "g");
927
927
  var TEST_KANJI = new RegExp("^" + kanji + "$");
928
- var TEST_NUMERIC = new RegExp("^" + numeric + "$");
928
+ var TEST_NUMERIC = new RegExp("^" + numeric2 + "$");
929
929
  var TEST_ALPHANUMERIC = new RegExp("^[A-Z0-9 $%*+\\-./:]+$");
930
930
  exports.testKanji = function testKanji(str2) {
931
931
  return TEST_KANJI.test(str2);
@@ -4409,7 +4409,7 @@ var require_browser = __commonJS({
4409
4409
  var QRCode = require_qrcode();
4410
4410
  var CanvasRenderer = require_canvas();
4411
4411
  var SvgRenderer = require_svg_tag();
4412
- function renderCanvas(renderFunc, canvas, text3, opts, cb) {
4412
+ function renderCanvas(renderFunc, canvas, text4, opts, cb) {
4413
4413
  const args2 = [].slice.call(arguments, 1);
4414
4414
  const argsNum = args2.length;
4415
4415
  const isLastArgCb = typeof args2[argsNum - 1] === "function";
@@ -4421,8 +4421,8 @@ var require_browser = __commonJS({
4421
4421
  throw new Error("Too few arguments provided");
4422
4422
  }
4423
4423
  if (argsNum === 2) {
4424
- cb = text3;
4425
- text3 = canvas;
4424
+ cb = text4;
4425
+ text4 = canvas;
4426
4426
  canvas = opts = void 0;
4427
4427
  } else if (argsNum === 3) {
4428
4428
  if (canvas.getContext && typeof cb === "undefined") {
@@ -4430,8 +4430,8 @@ var require_browser = __commonJS({
4430
4430
  opts = void 0;
4431
4431
  } else {
4432
4432
  cb = opts;
4433
- opts = text3;
4434
- text3 = canvas;
4433
+ opts = text4;
4434
+ text4 = canvas;
4435
4435
  canvas = void 0;
4436
4436
  }
4437
4437
  }
@@ -4440,16 +4440,16 @@ var require_browser = __commonJS({
4440
4440
  throw new Error("Too few arguments provided");
4441
4441
  }
4442
4442
  if (argsNum === 1) {
4443
- text3 = canvas;
4443
+ text4 = canvas;
4444
4444
  canvas = opts = void 0;
4445
4445
  } else if (argsNum === 2 && !canvas.getContext) {
4446
- opts = text3;
4447
- text3 = canvas;
4446
+ opts = text4;
4447
+ text4 = canvas;
4448
4448
  canvas = void 0;
4449
4449
  }
4450
4450
  return new Promise(function(resolve2, reject) {
4451
4451
  try {
4452
- const data = QRCode.create(text3, opts);
4452
+ const data = QRCode.create(text4, opts);
4453
4453
  resolve2(renderFunc(data, canvas, opts));
4454
4454
  } catch (e) {
4455
4455
  reject(e);
@@ -4457,7 +4457,7 @@ var require_browser = __commonJS({
4457
4457
  });
4458
4458
  }
4459
4459
  try {
4460
- const data = QRCode.create(text3, opts);
4460
+ const data = QRCode.create(text4, opts);
4461
4461
  cb(null, renderFunc(data, canvas, opts));
4462
4462
  } catch (e) {
4463
4463
  cb(e);
@@ -4482,8 +4482,8 @@ var require_server = __commonJS({
4482
4482
  var Utf8Renderer = require_utf8();
4483
4483
  var TerminalRenderer = require_terminal2();
4484
4484
  var SvgRenderer = require_svg();
4485
- function checkParams(text3, opts, cb) {
4486
- if (typeof text3 === "undefined") {
4485
+ function checkParams(text4, opts, cb) {
4486
+ if (typeof text4 === "undefined") {
4487
4487
  throw new Error("String required as first argument");
4488
4488
  }
4489
4489
  if (typeof cb === "undefined") {
@@ -4530,11 +4530,11 @@ var require_server = __commonJS({
4530
4530
  return Utf8Renderer;
4531
4531
  }
4532
4532
  }
4533
- function render(renderFunc, text3, params) {
4533
+ function render(renderFunc, text4, params) {
4534
4534
  if (!params.cb) {
4535
4535
  return new Promise(function(resolve2, reject) {
4536
4536
  try {
4537
- const data = QRCode.create(text3, params.opts);
4537
+ const data = QRCode.create(text4, params.opts);
4538
4538
  return renderFunc(data, params.opts, function(err, data2) {
4539
4539
  return err ? reject(err) : resolve2(data2);
4540
4540
  });
@@ -4544,7 +4544,7 @@ var require_server = __commonJS({
4544
4544
  });
4545
4545
  }
4546
4546
  try {
4547
- const data = QRCode.create(text3, params.opts);
4547
+ const data = QRCode.create(text4, params.opts);
4548
4548
  return renderFunc(data, params.opts, params.cb);
4549
4549
  } catch (e) {
4550
4550
  params.cb(e);
@@ -4552,43 +4552,43 @@ var require_server = __commonJS({
4552
4552
  }
4553
4553
  exports.create = QRCode.create;
4554
4554
  exports.toCanvas = require_browser().toCanvas;
4555
- exports.toString = function toString2(text3, opts, cb) {
4556
- const params = checkParams(text3, opts, cb);
4555
+ exports.toString = function toString2(text4, opts, cb) {
4556
+ const params = checkParams(text4, opts, cb);
4557
4557
  const type = params.opts ? params.opts.type : void 0;
4558
4558
  const renderer = getStringRendererFromType(type);
4559
- return render(renderer.render, text3, params);
4559
+ return render(renderer.render, text4, params);
4560
4560
  };
4561
- exports.toDataURL = function toDataURL(text3, opts, cb) {
4562
- const params = checkParams(text3, opts, cb);
4561
+ exports.toDataURL = function toDataURL(text4, opts, cb) {
4562
+ const params = checkParams(text4, opts, cb);
4563
4563
  const renderer = getRendererFromType(params.opts.type);
4564
- return render(renderer.renderToDataURL, text3, params);
4564
+ return render(renderer.renderToDataURL, text4, params);
4565
4565
  };
4566
- exports.toBuffer = function toBuffer(text3, opts, cb) {
4567
- const params = checkParams(text3, opts, cb);
4566
+ exports.toBuffer = function toBuffer(text4, opts, cb) {
4567
+ const params = checkParams(text4, opts, cb);
4568
4568
  const renderer = getRendererFromType(params.opts.type);
4569
- return render(renderer.renderToBuffer, text3, params);
4569
+ return render(renderer.renderToBuffer, text4, params);
4570
4570
  };
4571
- exports.toFile = function toFile(path, text3, opts, cb) {
4572
- if (typeof path !== "string" || !(typeof text3 === "string" || typeof text3 === "object")) {
4571
+ exports.toFile = function toFile(path, text4, opts, cb) {
4572
+ if (typeof path !== "string" || !(typeof text4 === "string" || typeof text4 === "object")) {
4573
4573
  throw new Error("Invalid argument");
4574
4574
  }
4575
4575
  if (arguments.length < 3 && !canPromise()) {
4576
4576
  throw new Error("Too few arguments provided");
4577
4577
  }
4578
- const params = checkParams(text3, opts, cb);
4578
+ const params = checkParams(text4, opts, cb);
4579
4579
  const type = params.opts.type || getTypeFromFilename(path);
4580
4580
  const renderer = getRendererFromType(type);
4581
4581
  const renderToFile = renderer.renderToFile.bind(null, path);
4582
- return render(renderToFile, text3, params);
4582
+ return render(renderToFile, text4, params);
4583
4583
  };
4584
- exports.toFileStream = function toFileStream(stream, text3, opts) {
4584
+ exports.toFileStream = function toFileStream(stream, text4, opts) {
4585
4585
  if (arguments.length < 2) {
4586
4586
  throw new Error("Too few arguments provided");
4587
4587
  }
4588
- const params = checkParams(text3, opts, stream.emit.bind(stream, "error"));
4588
+ const params = checkParams(text4, opts, stream.emit.bind(stream, "error"));
4589
4589
  const renderer = getRendererFromType("png");
4590
4590
  const renderToFileStream = renderer.renderToFileStream.bind(null, stream);
4591
- render(renderToFileStream, text3, params);
4591
+ render(renderToFileStream, text4, params);
4592
4592
  };
4593
4593
  }
4594
4594
  });
@@ -4707,13 +4707,13 @@ var require_exception = __commonJS({
4707
4707
  exports.__esModule = true;
4708
4708
  var errorProps = ["description", "fileName", "lineNumber", "endLineNumber", "message", "name", "number", "stack"];
4709
4709
  function Exception(message2, node) {
4710
- var loc = node && node.loc, line = void 0, endLineNumber = void 0, column = void 0, endColumn = void 0;
4710
+ var loc = node && node.loc, line2 = void 0, endLineNumber = void 0, column = void 0, endColumn = void 0;
4711
4711
  if (loc) {
4712
- line = loc.start.line;
4712
+ line2 = loc.start.line;
4713
4713
  endLineNumber = loc.end.line;
4714
4714
  column = loc.start.column;
4715
4715
  endColumn = loc.end.column;
4716
- message2 += " - " + line + ":" + column;
4716
+ message2 += " - " + line2 + ":" + column;
4717
4717
  }
4718
4718
  var tmp = Error.prototype.constructor.call(this, message2);
4719
4719
  for (var idx = 0; idx < errorProps.length; idx++) {
@@ -4724,7 +4724,7 @@ var require_exception = __commonJS({
4724
4724
  }
4725
4725
  try {
4726
4726
  if (loc) {
4727
- this.lineNumber = line;
4727
+ this.lineNumber = line2;
4728
4728
  this.endLineNumber = endLineNumber;
4729
4729
  if (Object.defineProperty) {
4730
4730
  Object.defineProperty(this, "column", {
@@ -8428,10 +8428,10 @@ var require_source_map_consumer = __commonJS({
8428
8428
  }, this).forEach(aCallback, context);
8429
8429
  };
8430
8430
  SourceMapConsumer.prototype.allGeneratedPositionsFor = function SourceMapConsumer_allGeneratedPositionsFor(aArgs) {
8431
- var line = util.getArg(aArgs, "line");
8431
+ var line2 = util.getArg(aArgs, "line");
8432
8432
  var needle = {
8433
8433
  source: util.getArg(aArgs, "source"),
8434
- originalLine: line,
8434
+ originalLine: line2,
8435
8435
  originalColumn: util.getArg(aArgs, "column", 0)
8436
8436
  };
8437
8437
  needle.source = this._findSourceIndex(needle.source);
@@ -8461,7 +8461,7 @@ var require_source_map_consumer = __commonJS({
8461
8461
  }
8462
8462
  } else {
8463
8463
  var originalColumn = mapping.originalColumn;
8464
- while (mapping && mapping.originalLine === line && mapping.originalColumn == originalColumn) {
8464
+ while (mapping && mapping.originalLine === line2 && mapping.originalColumn == originalColumn) {
8465
8465
  mappings.push({
8466
8466
  line: util.getArg(mapping, "generatedLine", null),
8467
8467
  column: util.getArg(mapping, "generatedColumn", null),
@@ -9240,7 +9240,7 @@ var require_code_gen = __commonJS({
9240
9240
  }
9241
9241
  var SourceMap;
9242
9242
  if (!SourceNode) {
9243
- SourceNode = function(line, column, srcFile, chunks) {
9243
+ SourceNode = function(line2, column, srcFile, chunks) {
9244
9244
  this.src = "";
9245
9245
  if (chunks) {
9246
9246
  this.add(chunks);
@@ -9295,8 +9295,8 @@ var require_code_gen = __commonJS({
9295
9295
  },
9296
9296
  merge: function merge2() {
9297
9297
  var source = this.empty();
9298
- this.each(function(line) {
9299
- source.add([" ", line, "\n"]);
9298
+ this.each(function(line2) {
9299
+ source.add([" ", line2, "\n"]);
9300
9300
  });
9301
9301
  return source;
9302
9302
  },
@@ -9559,14 +9559,14 @@ var require_javascript_compiler = __commonJS({
9559
9559
  },
9560
9560
  mergeSource: function mergeSource(varDeclarations) {
9561
9561
  var isSimple = this.environment.isSimple, appendOnly = !this.forceBuffer, appendFirst = void 0, sourceSeen = void 0, bufferStart = void 0, bufferEnd = void 0;
9562
- this.source.each(function(line) {
9563
- if (line.appendToBuffer) {
9562
+ this.source.each(function(line2) {
9563
+ if (line2.appendToBuffer) {
9564
9564
  if (bufferStart) {
9565
- line.prepend(" + ");
9565
+ line2.prepend(" + ");
9566
9566
  } else {
9567
- bufferStart = line;
9567
+ bufferStart = line2;
9568
9568
  }
9569
- bufferEnd = line;
9569
+ bufferEnd = line2;
9570
9570
  } else {
9571
9571
  if (bufferStart) {
9572
9572
  if (!sourceSeen) {
@@ -11590,12 +11590,12 @@ var require_nunjucks = __commonJS({
11590
11590
  var CallExtensionAsync = CallExtension.extend("CallExtensionAsync");
11591
11591
  function print(str2, indent, inline) {
11592
11592
  var lines = str2.split("\n");
11593
- lines.forEach(function(line, i) {
11594
- if (line && (inline && i > 0 || !inline)) {
11593
+ lines.forEach(function(line2, i) {
11594
+ if (line2 && (inline && i > 0 || !inline)) {
11595
11595
  process.stdout.write(" ".repeat(indent));
11596
11596
  }
11597
11597
  var nl3 = i === lines.length - 1 ? "" : "\n";
11598
- process.stdout.write("" + line + nl3);
11598
+ process.stdout.write("" + line2 + nl3);
11599
11599
  });
11600
11600
  }
11601
11601
  function printNodes(node, indent) {
@@ -11780,8 +11780,8 @@ var require_nunjucks = __commonJS({
11780
11780
  for (var _len = arguments.length, lines = new Array(_len), _key = 0; _key < _len; _key++) {
11781
11781
  lines[_key] = arguments[_key];
11782
11782
  }
11783
- lines.forEach(function(line) {
11784
- return _this._emitLine(line);
11783
+ lines.forEach(function(line2) {
11784
+ return _this._emitLine(line2);
11785
11785
  });
11786
11786
  };
11787
11787
  _proto._emitFuncBegin = function _emitFuncBegin(node, name) {
@@ -15081,27 +15081,27 @@ var require_nunjucks = __commonJS({
15081
15081
  return this;
15082
15082
  };
15083
15083
  EventEmitter.prototype.removeListener = function removeListener(type, listener) {
15084
- var list2, events, position, i, originalListener;
15084
+ var list3, events, position, i, originalListener;
15085
15085
  checkListener(listener);
15086
15086
  events = this._events;
15087
15087
  if (events === void 0)
15088
15088
  return this;
15089
- list2 = events[type];
15090
- if (list2 === void 0)
15089
+ list3 = events[type];
15090
+ if (list3 === void 0)
15091
15091
  return this;
15092
- if (list2 === listener || list2.listener === listener) {
15092
+ if (list3 === listener || list3.listener === listener) {
15093
15093
  if (--this._eventsCount === 0)
15094
15094
  this._events = /* @__PURE__ */ Object.create(null);
15095
15095
  else {
15096
15096
  delete events[type];
15097
15097
  if (events.removeListener)
15098
- this.emit("removeListener", type, list2.listener || listener);
15098
+ this.emit("removeListener", type, list3.listener || listener);
15099
15099
  }
15100
- } else if (typeof list2 !== "function") {
15100
+ } else if (typeof list3 !== "function") {
15101
15101
  position = -1;
15102
- for (i = list2.length - 1; i >= 0; i--) {
15103
- if (list2[i] === listener || list2[i].listener === listener) {
15104
- originalListener = list2[i].listener;
15102
+ for (i = list3.length - 1; i >= 0; i--) {
15103
+ if (list3[i] === listener || list3[i].listener === listener) {
15104
+ originalListener = list3[i].listener;
15105
15105
  position = i;
15106
15106
  break;
15107
15107
  }
@@ -15109,12 +15109,12 @@ var require_nunjucks = __commonJS({
15109
15109
  if (position < 0)
15110
15110
  return this;
15111
15111
  if (position === 0)
15112
- list2.shift();
15112
+ list3.shift();
15113
15113
  else {
15114
- spliceOne(list2, position);
15114
+ spliceOne(list3, position);
15115
15115
  }
15116
- if (list2.length === 1)
15117
- events[type] = list2[0];
15116
+ if (list3.length === 1)
15117
+ events[type] = list3[0];
15118
15118
  if (events.removeListener !== void 0)
15119
15119
  this.emit("removeListener", type, originalListener || listener);
15120
15120
  }
@@ -15207,10 +15207,10 @@ var require_nunjucks = __commonJS({
15207
15207
  copy[i] = arr[i];
15208
15208
  return copy;
15209
15209
  }
15210
- function spliceOne(list2, index) {
15211
- for (; index + 1 < list2.length; index++)
15212
- list2[index] = list2[index + 1];
15213
- list2.pop();
15210
+ function spliceOne(list3, index) {
15211
+ for (; index + 1 < list3.length; index++)
15212
+ list3[index] = list3[index + 1];
15213
+ list3.pop();
15214
15214
  }
15215
15215
  function unwrapListeners(arr) {
15216
15216
  var ret = new Array(arr.length);
@@ -15593,7 +15593,7 @@ var require_nunjucks = __commonJS({
15593
15593
  return 0;
15594
15594
  }
15595
15595
  exports2.length = lengthFilter;
15596
- function list2(val2) {
15596
+ function list3(val2) {
15597
15597
  if (lib.isString(val2)) {
15598
15598
  return val2.split("");
15599
15599
  } else if (lib.isObject(val2)) {
@@ -15610,7 +15610,7 @@ var require_nunjucks = __commonJS({
15610
15610
  throw new lib.TemplateError("list filter: type not iterable");
15611
15611
  }
15612
15612
  }
15613
- exports2.list = list2;
15613
+ exports2.list = list3;
15614
15614
  function lower(str2) {
15615
15615
  str2 = normalize(str2, "");
15616
15616
  return str2.toLowerCase();
@@ -15699,7 +15699,7 @@ var require_nunjucks = __commonJS({
15699
15699
  function reverse(val2) {
15700
15700
  var arr;
15701
15701
  if (lib.isString(val2)) {
15702
- arr = list2(val2);
15702
+ arr = list3(val2);
15703
15703
  } else {
15704
15704
  arr = lib.map(val2, function(v2) {
15705
15705
  return v2;
@@ -16850,26 +16850,26 @@ var require_liquid_node = __commonJS({
16850
16850
  }
16851
16851
  };
16852
16852
  function mkContext(token) {
16853
- const [line, col] = token.getPosition();
16853
+ const [line2, col] = token.getPosition();
16854
16854
  const lines = token.input.split("\n");
16855
- const begin = Math.max(line - 2, 1);
16856
- const end = Math.min(line + 3, lines.length);
16855
+ const begin = Math.max(line2 - 2, 1);
16856
+ const end = Math.min(line2 + 3, lines.length);
16857
16857
  const context = range2(begin, end + 1).map((lineNumber) => {
16858
- const rowIndicator = lineNumber === line ? ">> " : " ";
16858
+ const rowIndicator = lineNumber === line2 ? ">> " : " ";
16859
16859
  const num = padStart(String(lineNumber), String(end).length);
16860
- let text3 = `${rowIndicator}${num}| `;
16861
- const colIndicator = lineNumber === line ? "\n" + padStart("^", col + text3.length) : "";
16862
- text3 += lines[lineNumber - 1];
16863
- text3 += colIndicator;
16864
- return text3;
16860
+ let text4 = `${rowIndicator}${num}| `;
16861
+ const colIndicator = lineNumber === line2 ? "\n" + padStart("^", col + text4.length) : "";
16862
+ text4 += lines[lineNumber - 1];
16863
+ text4 += colIndicator;
16864
+ return text4;
16865
16865
  }).join("\n");
16866
16866
  return context;
16867
16867
  }
16868
16868
  function mkMessage(msg, token) {
16869
16869
  if (token.file)
16870
16870
  msg += `, file:${token.file}`;
16871
- const [line, col] = token.getPosition();
16872
- msg += `, line:${line}, col:${col}`;
16871
+ const [line2, col] = token.getPosition();
16872
+ msg += `, line:${line2}, col:${col}`;
16873
16873
  return msg;
16874
16874
  }
16875
16875
  var TYPES = [0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 4, 4, 4, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 2, 8, 0, 0, 0, 0, 8, 0, 0, 0, 64, 0, 65, 0, 0, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 0, 0, 2, 2, 2, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0];
@@ -18291,12 +18291,12 @@ var require_liquid_node = __commonJS({
18291
18291
  return nameOrFunction;
18292
18292
  }
18293
18293
  function normalizeDirectoryList(value) {
18294
- let list2 = [];
18294
+ let list3 = [];
18295
18295
  if (isArray(value))
18296
- list2 = value;
18296
+ list3 = value;
18297
18297
  if (isString(value))
18298
- list2 = [value];
18299
- return list2;
18298
+ list3 = [value];
18299
+ return list3;
18300
18300
  }
18301
18301
  function whiteSpaceCtrl(tokens, options) {
18302
18302
  let inRaw = false;
@@ -19597,7 +19597,7 @@ var require_liquid_node = __commonJS({
19597
19597
  BlockMode2[BlockMode2["OUTPUT"] = 0] = "OUTPUT";
19598
19598
  BlockMode2[BlockMode2["STORE"] = 1] = "STORE";
19599
19599
  })(BlockMode || (BlockMode = {}));
19600
- var abs = argumentsToNumber(Math.abs);
19600
+ var abs2 = argumentsToNumber(Math.abs);
19601
19601
  var at_least = argumentsToNumber(Math.max);
19602
19602
  var at_most = argumentsToNumber(Math.min);
19603
19603
  var ceil = argumentsToNumber(Math.ceil);
@@ -19616,7 +19616,7 @@ var require_liquid_node = __commonJS({
19616
19616
  }
19617
19617
  var mathFilters = /* @__PURE__ */ Object.freeze({
19618
19618
  __proto__: null,
19619
- abs,
19619
+ abs: abs2,
19620
19620
  at_least,
19621
19621
  at_most,
19622
19622
  ceil,
@@ -21416,10 +21416,10 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
21416
21416
 
21417
21417
  // packages/engine/src/lib/errors.ts
21418
21418
  var EngineSyntaxError = class extends Error {
21419
- constructor(engine, message2, line, column) {
21419
+ constructor(engine, message2, line2, column) {
21420
21420
  super(message2);
21421
21421
  this.engine = engine;
21422
- this.line = line;
21422
+ this.line = line2;
21423
21423
  this.column = column;
21424
21424
  }
21425
21425
  name = "EngineSyntaxError";
@@ -21435,10 +21435,10 @@ var RenderLimitError = class extends Error {
21435
21435
  name = "RenderLimitError";
21436
21436
  };
21437
21437
  var RenderError = class extends Error {
21438
- constructor(engine, message2, line, column) {
21438
+ constructor(engine, message2, line2, column) {
21439
21439
  super(message2);
21440
21440
  this.engine = engine;
21441
- this.line = line;
21441
+ this.line = line2;
21442
21442
  this.column = column;
21443
21443
  }
21444
21444
  name = "RenderError";
@@ -67329,9 +67329,9 @@ function bwipp_validatetext() {
67329
67329
  }
67330
67330
  $_ = $__;
67331
67331
  }
67332
- function bwipp_encode(bwipjs, encoder3, text3, opts, dontdraw) {
67333
- if (typeof text3 !== "string") {
67334
- throw new Error("bwipp.typeError: barcode text not a string (" + text3 + ")");
67332
+ function bwipp_encode(bwipjs, encoder3, text4, opts, dontdraw) {
67333
+ if (typeof text4 !== "string") {
67334
+ throw new Error("bwipp.typeError: barcode text not a string (" + text4 + ")");
67335
67335
  }
67336
67336
  opts = opts || {};
67337
67337
  if (typeof opts === "string") {
@@ -67356,11 +67356,11 @@ function bwipp_encode(bwipjs, encoder3, text3, opts, dontdraw) {
67356
67356
  throw new Error("bwipp.typeError: options not an object");
67357
67357
  }
67358
67358
  if (opts.binarytext) {
67359
- if (/[\u0100-\uffff]/.test(text3)) {
67359
+ if (/[\u0100-\uffff]/.test(text4)) {
67360
67360
  throw new Error("bwip-js: 16-bit chars not allowed with binarytext");
67361
67361
  }
67362
- } else if (/[\u0080-\uffff]/.test(text3)) {
67363
- text3 = unescape(encodeURIComponent(text3));
67362
+ } else if (/[\u0080-\uffff]/.test(text4)) {
67363
+ text4 = unescape(encodeURIComponent(text4));
67364
67364
  }
67365
67365
  if (opts.dontdraw) {
67366
67366
  dontdraw = true;
@@ -67372,7 +67372,7 @@ function bwipp_encode(bwipjs, encoder3, text3, opts, dontdraw) {
67372
67372
  }
67373
67373
  }
67374
67374
  $$ = bwipjs;
67375
- $k = [text3, map];
67375
+ $k = [text4, map];
67376
67376
  $j = 2;
67377
67377
  $_ = {
67378
67378
  bwipjs_rawstack: dontdraw ? [] : false
@@ -67683,8 +67683,8 @@ var BWIPJS_OPTIONS = {
67683
67683
  backgroundcolor: 1
67684
67684
  };
67685
67685
  function _Render(encoder3, options, drawing) {
67686
- var text3 = options.text;
67687
- if (!text3) {
67686
+ var text4 = options.text;
67687
+ if (!text4) {
67688
67688
  throw new ReferenceError("bwip-js: bar code text not specified.");
67689
67689
  }
67690
67690
  FixupOptions(options);
@@ -67709,7 +67709,7 @@ function _Render(encoder3, options, drawing) {
67709
67709
  bwippopts.width = bwippopts.width / 25.4 || 0;
67710
67710
  }
67711
67711
  bw.scale(scaleX, scaleY);
67712
- bwipp_encode(bw, encoder3, text3, bwippopts);
67712
+ bwipp_encode(bw, encoder3, text4, bwippopts);
67713
67713
  return bw.render();
67714
67714
  }
67715
67715
  var BWIPJS = (function() {
@@ -67831,8 +67831,8 @@ var BWIPJS = (function() {
67831
67831
  BWIPJS2.prototype.setlinewidth = function(w) {
67832
67832
  this.g_penw = w;
67833
67833
  };
67834
- BWIPJS2.prototype.selectfont = function(f2, z3) {
67835
- this.g_font = { FontName: this.jsstring(f2), FontSize: +z3 };
67834
+ BWIPJS2.prototype.selectfont = function(f2, z4) {
67835
+ this.g_font = { FontName: this.jsstring(f2), FontSize: +z4 };
67836
67836
  };
67837
67837
  BWIPJS2.prototype.getfont = function() {
67838
67838
  return this.g_font.FontName;
@@ -68937,7 +68937,7 @@ var STBTT = /* @__PURE__ */ (function() {
68937
68937
  var floor = Math.floor;
68938
68938
  var ceil = Math.ceil;
68939
68939
  var sqrt = Math.sqrt;
68940
- var abs = Math.abs;
68940
+ var abs2 = Math.abs;
68941
68941
  function oalloc(n) {
68942
68942
  var o = [];
68943
68943
  for (var i = 0; i < n; i++) {
@@ -69948,7 +69948,7 @@ var STBTT = /* @__PURE__ */ (function() {
69948
69948
  dx6 = dy6 = s[10];
69949
69949
  dx = dx1 + dx2 + dx3 + dx4 + dx5;
69950
69950
  dy = dy1 + dy2 + dy3 + dy4 + dy5;
69951
- if (abs(dx) > abs(dy)) {
69951
+ if (abs2(dx) > abs2(dy)) {
69952
69952
  dy6 = -dy;
69953
69953
  } else {
69954
69954
  dx6 = -dx;
@@ -70201,7 +70201,7 @@ var STBTT = /* @__PURE__ */ (function() {
70201
70201
  }
70202
70202
  function stbtt__rasterize_sorted_edges(result, edges, nedges, vsubsample, off_x, off_y) {
70203
70203
  vsubsample |= 0, off_x |= 0, off_y |= 0;
70204
- var active = null, z3;
70204
+ var active = null, z4;
70205
70205
  var y2 = off_y, j2 = 0, i;
70206
70206
  var scanline = new Float32Array(result.w * 2 + 1);
70207
70207
  var scanline2 = scanline.subarray(result.w);
@@ -70215,18 +70215,18 @@ var STBTT = /* @__PURE__ */ (function() {
70215
70215
  for (var $i = 0, $l = scanline.length; $i < $l; $i++) scanline[$i] = 0;
70216
70216
  }
70217
70217
  while (step) {
70218
- z3 = step;
70219
- step = z3.next;
70220
- if (z3.ey <= scan_y_top) {
70221
- z3.direction = 0;
70218
+ z4 = step;
70219
+ step = z4.next;
70220
+ if (z4.ey <= scan_y_top) {
70221
+ z4.direction = 0;
70222
70222
  } else {
70223
70223
  }
70224
70224
  }
70225
70225
  while (edges[eoff].y0 <= scan_y_bottom) {
70226
70226
  if (edges[eoff].y0 != edges[eoff].y1) {
70227
- z3 = stbtt__new_active(edges[eoff], off_x, scan_y_top);
70228
- z3.next = active;
70229
- active = z3;
70227
+ z4 = stbtt__new_active(edges[eoff], off_x, scan_y_top);
70228
+ z4.next = active;
70229
+ active = z4;
70230
70230
  }
70231
70231
  ++eoff;
70232
70232
  }
@@ -70237,7 +70237,7 @@ var STBTT = /* @__PURE__ */ (function() {
70237
70237
  var k2, m2;
70238
70238
  sum += scanline2[i];
70239
70239
  k2 = scanline[i] + sum;
70240
- k2 = abs(k2) * 255 + 0.5;
70240
+ k2 = abs2(k2) * 255 + 0.5;
70241
70241
  m2 = k2 >>> 0;
70242
70242
  if (m2 > 255) {
70243
70243
  m2 = 255;
@@ -70246,9 +70246,9 @@ var STBTT = /* @__PURE__ */ (function() {
70246
70246
  }
70247
70247
  step = active;
70248
70248
  while (step) {
70249
- z3 = step;
70250
- z3.fx += z3.fdx;
70251
- step = z3.next;
70249
+ z4 = step;
70250
+ z4.fx += z4.fdx;
70251
+ step = z4.next;
70252
70252
  }
70253
70253
  ++y2;
70254
70254
  ++j2;
@@ -70268,12 +70268,12 @@ var STBTT = /* @__PURE__ */ (function() {
70268
70268
  }
70269
70269
  function stbtt__sort_edges_quicksort(p, o, n) {
70270
70270
  while (n > 12) {
70271
- var t, c, i, j2, z3, m2 = n >> 1, c01 = p[o].y0 < p[o + m2].y0, c12 = p[o + m2].y0 < p[o + n - 1].y0;
70271
+ var t, c, i, j2, z4, m2 = n >> 1, c01 = p[o].y0 < p[o + m2].y0, c12 = p[o + m2].y0 < p[o + n - 1].y0;
70272
70272
  if (c01 != c12) {
70273
70273
  c = p[o].y0 < p[o + n - 11].y0;
70274
- z3 = c == c12 ? 0 : n - 1;
70275
- t = p[o + z3];
70276
- p[o + z3] = p[o + m2];
70274
+ z4 = c == c12 ? 0 : n - 1;
70275
+ t = p[o + z4];
70276
+ p[o + z4] = p[o + m2];
70277
70277
  p[o + m2] = t;
70278
70278
  }
70279
70279
  t = p[o];
@@ -70688,9 +70688,12 @@ var barcodeTypes = {
70688
70688
  };
70689
70689
  var ownTextLayout = /* @__PURE__ */ new Set(["ean13", "ean8", "upca"]);
70690
70690
  function codeText(helper, value) {
70691
- const text3 = value === void 0 || value === null ? "" : String(value);
70692
- if (text3 === "") throw new Error(`${helper}: nothing to encode, the value is empty or missing from the data`);
70693
- return text3;
70691
+ const text4 = value === void 0 || value === null ? "" : String(value);
70692
+ if (text4 === "")
70693
+ throw new Error(
70694
+ `${helper}: nothing to encode, the value is empty or missing from the data`
70695
+ );
70696
+ return text4;
70694
70697
  }
70695
70698
  var codeHelpers = [
70696
70699
  {
@@ -70698,18 +70701,25 @@ var codeHelpers = [
70698
70701
  aliases: ["qr"],
70699
70702
  doc: {
70700
70703
  signature: "qrcode(value, { size = 160, ecc = 'M', margin = 1, color, background })",
70701
- description: "QR code as an SVG data URI for an <img> src.",
70704
+ description: "QR code as an SVG data URI for an <img> src. Give the image an `alt` that says where the code leads: a screen reader cannot scan it.",
70702
70705
  examples: {
70703
- jinja2: '<img src="{{ qrcode(order.url, { size: 120 }) }}">',
70704
- liquid: '<img src="{{ order.url | qrcode: size: 120 }}">',
70705
- handlebars: '<img src="{{qrcode order.url size=120}}">'
70706
+ jinja2: '<img src="{{ qrcode(order.url, { size: 120 }) }}" alt="QR code: {{ order.url }}">',
70707
+ liquid: '<img src="{{ order.url | qrcode: size: 120 }}" alt="QR code: {{ order.url }}">',
70708
+ handlebars: '<img src="{{qrcode order.url size=120}}" alt="QR code: {{order.url}}">'
70706
70709
  },
70707
70710
  category: "code"
70708
70711
  },
70709
70712
  fn: (ctx, value, options) => {
70710
70713
  const o = options ?? {};
70711
70714
  const svg = qrSvg(codeText("qrcode", value), o);
70712
- if (ctx.drawing) return ctx.drawing({ kind: "svg", svg, width: o.size, height: o.size, alt: "QR code" });
70715
+ if (ctx.drawing)
70716
+ return ctx.drawing({
70717
+ kind: "svg",
70718
+ svg,
70719
+ width: o.size,
70720
+ height: o.size,
70721
+ alt: "QR code"
70722
+ });
70713
70723
  return svgDataUri(svg);
70714
70724
  }
70715
70725
  },
@@ -70717,28 +70727,29 @@ var codeHelpers = [
70717
70727
  name: "barcode",
70718
70728
  doc: {
70719
70729
  signature: "barcode(value, { type = 'code128', height = 12, width, text = true, scale = 2 })",
70720
- description: "Barcode (code128, ean13, ean8, upc, itf14, code39, datamatrix, pdf417) as an SVG data URI.",
70730
+ description: "Barcode (code128, ean13, ean8, upc, itf14, code39, datamatrix, pdf417) as an SVG data URI. Give the image an `alt` with the value it encodes.",
70721
70731
  examples: {
70722
- jinja2: `<img src="{{ barcode(item.sku, { type: 'code128' }) }}">`,
70723
- liquid: `<img src="{{ item.sku | barcode: type: 'code128' }}">`,
70724
- handlebars: `<img src="{{barcode item.sku type='code128'}}">`
70732
+ jinja2: `<img src="{{ barcode(item.sku, { type: 'code128' }) }}" alt="Barcode {{ item.sku }}">`,
70733
+ liquid: `<img src="{{ item.sku | barcode: type: 'code128' }}" alt="Barcode {{ item.sku }}">`,
70734
+ handlebars: `<img src="{{barcode item.sku type='code128'}}" alt="Barcode {{item.sku}}">`
70725
70735
  },
70726
70736
  category: "code"
70727
70737
  },
70728
70738
  fn: (ctx, value, options) => {
70729
70739
  const o = options ?? {};
70730
70740
  const bcid = barcodeTypes[String(o.type ?? "code128").toLowerCase()] ?? "code128";
70731
- const text3 = codeText("barcode", value);
70741
+ const text4 = codeText("barcode", value);
70732
70742
  const svg = ToSVG({
70733
70743
  bcid,
70734
- text: text3,
70744
+ text: text4,
70735
70745
  height: o.height ?? 12,
70736
70746
  ...o.width === void 0 ? {} : { width: o.width },
70737
70747
  scale: o.scale ?? 2,
70738
70748
  includetext: o.text !== false,
70739
70749
  ...ownTextLayout.has(bcid) ? {} : { textxalign: "center" }
70740
70750
  });
70741
- if (ctx.drawing) return ctx.drawing({ kind: "svg", svg, alt: `Barcode ${text3}` });
70751
+ if (ctx.drawing)
70752
+ return ctx.drawing({ kind: "svg", svg, alt: `Barcode ${text4}` });
70742
70753
  return svgDataUri(svg);
70743
70754
  }
70744
70755
  },
@@ -70747,11 +70758,11 @@ var codeHelpers = [
70747
70758
  aliases: ["epc_qr", "girocode"],
70748
70759
  doc: {
70749
70760
  signature: "epcQr({ name, iban, bic?, amount?, reference?, text? }, { size })",
70750
- description: "SEPA credit transfer QR code (EPC069-12 / GiroCode) that banking apps scan to prefill a payment.",
70761
+ description: "SEPA credit transfer QR code (EPC069-12 / GiroCode) that banking apps scan to prefill a payment. Give the image an `alt`, and print the bank details as text as well: the code is a picture.",
70751
70762
  examples: {
70752
- jinja2: '<img src="{{ epcQr({ name: company.name, iban: company.iban, amount: invoice.total, reference: invoice.number }) }}">',
70753
- liquid: '<img src="{{ company.iban | epcQr: name: company.name, amount: invoice.total, reference: invoice.number }}">',
70754
- handlebars: '<img src="{{epcQr name=company.name iban=company.iban amount=invoice.total reference=invoice.number}}">'
70763
+ jinja2: '<img src="{{ epcQr({ name: company.name, iban: company.iban, amount: invoice.total, reference: invoice.number }) }}" alt="QR code to pay invoice {{ invoice.number }}">',
70764
+ liquid: '<img src="{{ company.iban | epcQr: name: company.name, amount: invoice.total, reference: invoice.number }}" alt="QR code to pay invoice {{ invoice.number }}">',
70765
+ handlebars: '<img src="{{epcQr name=company.name iban=company.iban amount=invoice.total reference=invoice.number}}" alt="QR code to pay invoice {{invoice.number}}">'
70755
70766
  },
70756
70767
  category: "code"
70757
70768
  },
@@ -70764,18 +70775,33 @@ var codeHelpers = [
70764
70775
  ...input && typeof input === "object" ? input : typeof input === "string" && input ? { iban: input } : {},
70765
70776
  ...options ?? {}
70766
70777
  };
70767
- const payment = {};
70778
+ const payment2 = {};
70768
70779
  const qr = {};
70769
70780
  for (const [key, value] of Object.entries(fields))
70770
- (EPC_FIELDS.has(key) ? payment : qr)[key] = value;
70781
+ (EPC_FIELDS.has(key) ? payment2 : qr)[key] = value;
70771
70782
  const o = { ecc: "M", ...qr };
70772
- const svg = qrSvg(epcPayload(payment), o);
70773
- if (ctx.drawing) return ctx.drawing({ kind: "svg", svg, width: o.size, height: o.size, alt: "GiroCode" });
70783
+ const svg = qrSvg(epcPayload(payment2), o);
70784
+ if (ctx.drawing)
70785
+ return ctx.drawing({
70786
+ kind: "svg",
70787
+ svg,
70788
+ width: o.size,
70789
+ height: o.size,
70790
+ alt: "GiroCode"
70791
+ });
70774
70792
  return svgDataUri(svg);
70775
70793
  }
70776
70794
  }
70777
70795
  ];
70778
- var EPC_FIELDS = /* @__PURE__ */ new Set(["name", "iban", "bic", "amount", "reference", "text", "purpose"]);
70796
+ var EPC_FIELDS = /* @__PURE__ */ new Set([
70797
+ "name",
70798
+ "iban",
70799
+ "bic",
70800
+ "amount",
70801
+ "reference",
70802
+ "text",
70803
+ "purpose"
70804
+ ]);
70779
70805
 
70780
70806
  // node_modules/.pnpm/@date-fns+tz@1.5.0/node_modules/@date-fns/tz/constants/index.js
70781
70807
  var constructFromSymbol = Symbol.for("constructDateFrom");
@@ -77605,8 +77631,8 @@ var currencyValues6 = { currency: (
77605
77631
  function resolveTranslation(dictionaries, locale, key) {
77606
77632
  const lang = locale.split("-")[0] ?? locale;
77607
77633
  for (const candidate of [locale, lang, "en"]) {
77608
- const text3 = dictionaries?.[candidate]?.[key];
77609
- if (typeof text3 === "string") return { text: text3, from: candidate };
77634
+ const text4 = dictionaries?.[candidate]?.[key];
77635
+ if (typeof text4 === "string") return { text: text4, from: candidate };
77610
77636
  }
77611
77637
  return { text: key, from: null };
77612
77638
  }
@@ -78079,9 +78105,9 @@ var formatHelpers = [
78079
78105
  category: "text"
78080
78106
  },
78081
78107
  fn: (ctx, key, params) => {
78082
- const { text: text3 } = resolveTranslation(ctx.i18n, ctx.locale, str(key));
78108
+ const { text: text4 } = resolveTranslation(ctx.i18n, ctx.locale, str(key));
78083
78109
  const p = params ?? {};
78084
- return text3.replace(/\{(\w+)\}/g, (_2, name) => str(p[name]));
78110
+ return text4.replace(/\{(\w+)\}/g, (_2, name) => str(p[name]));
78085
78111
  }
78086
78112
  },
78087
78113
  {
@@ -78352,7 +78378,16 @@ var collectionHelpers = [
78352
78378
  ];
78353
78379
 
78354
78380
  // packages/engine/src/lib/helpers/document.ts
78355
- var CHART_PALETTE = ["#3E63DD", "#12A594", "#E5484D", "#F76B15", "#8E4EC6", "#FFC53D", "#0090FF", "#978365"];
78381
+ var CHART_PALETTE = [
78382
+ "#3E63DD",
78383
+ "#12A594",
78384
+ "#E5484D",
78385
+ "#F76B15",
78386
+ "#8E4EC6",
78387
+ "#FFC53D",
78388
+ "#0090FF",
78389
+ "#978365"
78390
+ ];
78356
78391
  var SLICED = /* @__PURE__ */ new Set(["pie", "doughnut", "polarArea"]);
78357
78392
  var colour = (value) => typeof value === "string" && value ? value : Array.isArray(value) && value.length ? value.map(String) : void 0;
78358
78393
  function chartDataFromPlain(spec) {
@@ -78366,8 +78401,13 @@ function chartDataFromPlain(spec) {
78366
78401
  });
78367
78402
  const own = colour(s.color);
78368
78403
  const fill = SLICED.has(type) ? own ?? labels.map((_2, i) => CHART_PALETTE[i % CHART_PALETTE.length]) : own ?? CHART_PALETTE[index % CHART_PALETTE.length];
78369
- const dataset = { data, backgroundColor: fill, borderColor: fill };
78370
- if (s.label !== void 0 && s.label !== null && s.label !== "") dataset["label"] = String(s.label);
78404
+ const dataset = {
78405
+ data,
78406
+ backgroundColor: fill,
78407
+ borderColor: fill
78408
+ };
78409
+ if (s.label !== void 0 && s.label !== null && s.label !== "")
78410
+ dataset["label"] = String(s.label);
78371
78411
  if (type === "line") dataset["fill"] = false;
78372
78412
  return dataset;
78373
78413
  });
@@ -78384,7 +78424,8 @@ function chartPayload(spec) {
78384
78424
  const options = { ...spec.options ?? {} };
78385
78425
  options["animation"] = false;
78386
78426
  options["responsive"] = false;
78387
- if (!isPlain(spec)) return { type: spec.type ?? "bar", data: spec.data ?? {}, options };
78427
+ if (!isPlain(spec))
78428
+ return { type: spec.type ?? "bar", data: spec.data ?? {}, options };
78388
78429
  const data = chartDataFromPlain(spec);
78389
78430
  const unnamed = data.datasets.length === 1 && data.datasets[0]?.["label"] === void 0;
78390
78431
  const plugins = asObject(options["plugins"]);
@@ -78397,7 +78438,8 @@ function chartMarkup(spec, id) {
78397
78438
  const height = toNumber(spec.height ?? 240) || 240;
78398
78439
  const payload = escapeHtml(JSON.stringify(chartPayload(spec)));
78399
78440
  const idAttr = id ? ` id="${escapeHtml(id)}"` : "";
78400
- return `<canvas class="ff-chart"${idAttr} width="${width}" height="${height}" style="width:${width}px;height:${height}px" data-ff-chart="${payload}"></canvas>`;
78441
+ const alt = typeof spec.alt === "string" && spec.alt.trim() ? ` role="img" aria-label="${escapeHtml(spec.alt.trim())}"` : "";
78442
+ return `<canvas class="ff-chart"${idAttr}${alt} width="${width}" height="${height}" style="width:${width}px;height:${height}px" data-ff-chart="${payload}"></canvas>`;
78401
78443
  }
78402
78444
  function imageMarkup(url, options = {}) {
78403
78445
  const styles = [
@@ -78418,18 +78460,21 @@ var documentHelpers = [
78418
78460
  name: "chart",
78419
78461
  html: true,
78420
78462
  doc: {
78421
- signature: "chart({ type, labels, values, label, color } | { type, labels, series } | { type, data, options }, { width, height })",
78422
- description: "Draws a Chart.js chart (bar, line, pie, doughnut, radar, \u2026) from plain data, `labels` with `values` or several `series` of `{ label, values, color }`, or from a full Chart.js `data` and `options`; animations are disabled so PDF and preview match.",
78463
+ signature: "chart({ type, labels, values, label, color } | { type, labels, series } | { type, data, options }, { width, height, alt })",
78464
+ description: "Draws a Chart.js chart (bar, line, pie, doughnut, radar, \u2026) from plain data, `labels` with `values` or several `series` of `{ label, values, color }`, or from a full Chart.js `data` and `options`; animations are disabled so PDF and preview match. `alt` says in words what the chart shows: a screen reader reads it in place of the picture, and a tagged PDF needs it.",
78423
78465
  examples: {
78424
- jinja2: "{{ chart({ type: 'line', labels: sales.labels, values: sales.quarters, width: 480 }) }}",
78425
- liquid: "{{ '' | chart: type: 'line', labels: sales.labels, values: sales.quarters, width: 480 }}",
78426
- handlebars: "{{chart type='line' labels=sales.labels values=sales.quarters width=480}}"
78466
+ jinja2: "{{ chart({ type: 'line', labels: sales.labels, values: sales.quarters, width: 480, alt: 'Sales by quarter' }) }}",
78467
+ liquid: "{{ '' | chart: type: 'line', labels: sales.labels, values: sales.quarters, width: 480, alt: 'Sales by quarter' }}",
78468
+ handlebars: "{{chart type='line' labels=sales.labels values=sales.quarters width=480 alt='Sales by quarter'}}"
78427
78469
  },
78428
78470
  category: "document"
78429
78471
  },
78430
78472
  fn: (ctx, spec, extra) => {
78431
78473
  if (ctx.mode === "office") throw new Error(officeUnsupported("chart"));
78432
- return chartMarkup({ ...asObject(spec), ...asObject(extra) });
78474
+ return chartMarkup({
78475
+ ...asObject(spec),
78476
+ ...asObject(extra)
78477
+ });
78433
78478
  }
78434
78479
  },
78435
78480
  {
@@ -78437,18 +78482,24 @@ var documentHelpers = [
78437
78482
  html: true,
78438
78483
  doc: {
78439
78484
  signature: "image(url, { width, height, fit, alt })",
78440
- description: "Places an image with fixed size and crop mode (`cover`, `contain`, `fill`); the render-worker fetches it through its cache and blocks private hosts.",
78485
+ description: "Places an image with fixed size and crop mode (`cover`, `contain`, `fill`); the render-worker fetches it through its cache and blocks private hosts. `alt` says what it shows; without one the image counts as decoration and a screen reader passes over it.",
78441
78486
  examples: {
78442
- jinja2: "{{ image(product.photo, { width: 120, height: 80, fit: 'cover' }) }}",
78443
- liquid: "{{ product.photo | image: width: 120, height: 80, fit: 'cover' }}",
78444
- handlebars: "{{image product.photo width=120 height=80 fit='cover'}}"
78487
+ jinja2: "{{ image(product.photo, { width: 120, height: 80, fit: 'cover', alt: product.name }) }}",
78488
+ liquid: "{{ product.photo | image: width: 120, height: 80, fit: 'cover', alt: product.name }}",
78489
+ handlebars: "{{image product.photo width=120 height=80 fit='cover' alt=product.name}}"
78445
78490
  },
78446
78491
  category: "document"
78447
78492
  },
78448
78493
  fn: (ctx, url, options) => {
78449
78494
  const o = asObject(options);
78450
78495
  if (ctx.drawing)
78451
- return ctx.drawing({ kind: "url", url: resolveAsset(ctx.assetBaseUrl, String(url ?? "")), width: o.width, height: o.height, alt: o.alt });
78496
+ return ctx.drawing({
78497
+ kind: "url",
78498
+ url: resolveAsset(ctx.assetBaseUrl, String(url ?? "")),
78499
+ width: o.width,
78500
+ height: o.height,
78501
+ alt: o.alt
78502
+ });
78452
78503
  return imageMarkup(String(url ?? ""), o);
78453
78504
  }
78454
78505
  }
@@ -78603,22 +78654,22 @@ function unavailableHelper(name) {
78603
78654
  }
78604
78655
 
78605
78656
  // packages/engine/src/lib/analysis/tags.ts
78606
- function rangeAt(line, column, length) {
78657
+ function rangeAt(line2, column, length) {
78607
78658
  return {
78608
- start: { line, column },
78609
- end: { line, column: column + Math.max(1, length) }
78659
+ start: { line: line2, column },
78660
+ end: { line: line2, column: column + Math.max(1, length) }
78610
78661
  };
78611
78662
  }
78612
78663
  function positionOf(source, offset) {
78613
- let line = 1;
78664
+ let line2 = 1;
78614
78665
  let last = -1;
78615
78666
  for (let i = 0; i < offset && i < source.length; i++) {
78616
78667
  if (source.charCodeAt(i) === 10) {
78617
- line++;
78668
+ line2++;
78618
78669
  last = i;
78619
78670
  }
78620
78671
  }
78621
- return { line, column: offset - last };
78672
+ return { line: line2, column: offset - last };
78622
78673
  }
78623
78674
  function rangeOf(source, start, end) {
78624
78675
  return { start: positionOf(source, start), end: positionOf(source, end) };
@@ -78864,12 +78915,12 @@ function toSyntaxError(e) {
78864
78915
  const err = e;
78865
78916
  const message2 = String(err.message ?? e);
78866
78917
  const m2 = /Parse error on line (\d+)/.exec(message2);
78867
- const line = err.lineNumber ?? (m2 ? Number(m2[1]) : 1);
78918
+ const line2 = err.lineNumber ?? (m2 ? Number(m2[1]) : 1);
78868
78919
  const column = typeof err.column === "number" ? err.column + 1 : 1;
78869
78920
  return new EngineSyntaxError(
78870
78921
  "handlebars",
78871
78922
  message2.split("\n")[0] ?? message2,
78872
- line,
78923
+ line2,
78873
78924
  column
78874
78925
  );
78875
78926
  }
@@ -79179,48 +79230,48 @@ var SPEC = /^(?:([\s\S])?([<>=^]))?([+\- ])?(#)?(0)?(\d+)?([,_])?(?:\.(\d+))?([b
79179
79230
  function group(digits, separator) {
79180
79231
  return digits.replace(/\B(?=(\d{3})+(?!\d))/g, separator);
79181
79232
  }
79182
- function pythonExponent(text3) {
79183
- return text3.replace(/e([+-])(\d)$/i, (m2, sign, digit) => `${m2[0]}${sign}0${digit}`);
79233
+ function pythonExponent(text4) {
79234
+ return text4.replace(/e([+-])(\d)$/i, (m2, sign, digit) => `${m2[0]}${sign}0${digit}`);
79184
79235
  }
79185
79236
  function formatNumber(value, type, precision, alternate) {
79186
79237
  if (!Number.isFinite(value)) return Number.isNaN(value) ? "nan" : "inf";
79187
- const abs = Math.abs(value);
79238
+ const abs2 = Math.abs(value);
79188
79239
  switch (type) {
79189
79240
  case "f":
79190
79241
  case "F":
79191
- return abs.toFixed(precision ?? 6);
79242
+ return abs2.toFixed(precision ?? 6);
79192
79243
  case "%":
79193
- return `${(abs * 100).toFixed(precision ?? 6)}%`;
79244
+ return `${(abs2 * 100).toFixed(precision ?? 6)}%`;
79194
79245
  case "e":
79195
79246
  case "E": {
79196
- const text3 = pythonExponent(abs.toExponential(precision ?? 6));
79197
- return type === "E" ? text3.toUpperCase() : text3;
79247
+ const text4 = pythonExponent(abs2.toExponential(precision ?? 6));
79248
+ return type === "E" ? text4.toUpperCase() : text4;
79198
79249
  }
79199
79250
  case "g":
79200
79251
  case "G": {
79201
79252
  const p = precision === 0 ? 1 : precision ?? 6;
79202
- const exp = abs === 0 ? 0 : Math.floor(Math.log10(abs));
79203
- let text3 = exp < -4 || exp >= p ? pythonExponent(abs.toExponential(p - 1)) : abs.toFixed(Math.max(0, p - 1 - exp));
79253
+ const exp = abs2 === 0 ? 0 : Math.floor(Math.log10(abs2));
79254
+ let text4 = exp < -4 || exp >= p ? pythonExponent(abs2.toExponential(p - 1)) : abs2.toFixed(Math.max(0, p - 1 - exp));
79204
79255
  if (!alternate) {
79205
- const [mantissa = "", exponent] = text3.split("e");
79256
+ const [mantissa = "", exponent] = text4.split("e");
79206
79257
  const trimmed = mantissa.includes(".") ? mantissa.replace(/0+$/, "").replace(/\.$/, "") : mantissa;
79207
- text3 = exponent === void 0 ? trimmed : `${trimmed}e${exponent}`;
79258
+ text4 = exponent === void 0 ? trimmed : `${trimmed}e${exponent}`;
79208
79259
  }
79209
- return type === "G" ? text3.toUpperCase() : text3;
79260
+ return type === "G" ? text4.toUpperCase() : text4;
79210
79261
  }
79211
79262
  case "d":
79212
79263
  case "n":
79213
- return String(Math.trunc(abs));
79264
+ return String(Math.trunc(abs2));
79214
79265
  case "b":
79215
- return (alternate ? "0b" : "") + Math.trunc(abs).toString(2);
79266
+ return (alternate ? "0b" : "") + Math.trunc(abs2).toString(2);
79216
79267
  case "o":
79217
- return (alternate ? "0o" : "") + Math.trunc(abs).toString(8);
79268
+ return (alternate ? "0o" : "") + Math.trunc(abs2).toString(8);
79218
79269
  case "x":
79219
- return (alternate ? "0x" : "") + Math.trunc(abs).toString(16);
79270
+ return (alternate ? "0x" : "") + Math.trunc(abs2).toString(16);
79220
79271
  case "X":
79221
- return (alternate ? "0X" : "") + Math.trunc(abs).toString(16).toUpperCase();
79272
+ return (alternate ? "0X" : "") + Math.trunc(abs2).toString(16).toUpperCase();
79222
79273
  default:
79223
- return precision === void 0 ? String(abs) : formatNumber(abs, "g", precision, alternate);
79274
+ return precision === void 0 ? String(abs2) : formatNumber(abs2, "g", precision, alternate);
79224
79275
  }
79225
79276
  }
79226
79277
  function formatValue(value, spec) {
@@ -79275,35 +79326,35 @@ function lookupField(name, positional, named, next) {
79275
79326
  function pythonFormat(template, positional, named = {}) {
79276
79327
  let auto = 0;
79277
79328
  const next = () => auto++;
79278
- const render = (text3) => {
79329
+ const render = (text4) => {
79279
79330
  let out = "";
79280
- for (let i = 0; i < text3.length; i++) {
79281
- const ch = text3[i];
79331
+ for (let i = 0; i < text4.length; i++) {
79332
+ const ch = text4[i];
79282
79333
  if (ch === "}") {
79283
79334
  out += "}";
79284
- if (text3[i + 1] === "}") i++;
79335
+ if (text4[i + 1] === "}") i++;
79285
79336
  continue;
79286
79337
  }
79287
79338
  if (ch !== "{") {
79288
79339
  out += ch;
79289
79340
  continue;
79290
79341
  }
79291
- if (text3[i + 1] === "{") {
79342
+ if (text4[i + 1] === "{") {
79292
79343
  out += "{";
79293
79344
  i++;
79294
79345
  continue;
79295
79346
  }
79296
79347
  let depth = 1;
79297
79348
  let j2 = i + 1;
79298
- for (; j2 < text3.length && depth > 0; j2++) {
79299
- if (text3[j2] === "{") depth++;
79300
- else if (text3[j2] === "}") depth--;
79349
+ for (; j2 < text4.length && depth > 0; j2++) {
79350
+ if (text4[j2] === "{") depth++;
79351
+ else if (text4[j2] === "}") depth--;
79301
79352
  }
79302
79353
  if (depth > 0) {
79303
- out += text3.slice(i);
79354
+ out += text4.slice(i);
79304
79355
  break;
79305
79356
  }
79306
- const field = text3.slice(i + 1, j2 - 1);
79357
+ const field = text4.slice(i + 1, j2 - 1);
79307
79358
  const colon = field.indexOf(":");
79308
79359
  const head = colon < 0 ? field : field.slice(0, colon);
79309
79360
  const name = head.replace(/![rsa]$/, "");
@@ -79407,7 +79458,7 @@ var stringMethods = {
79407
79458
  return out;
79408
79459
  },
79409
79460
  split: (s, sep, max) => sep === void 0 || sep === null ? s.trim().split(/\s+/) : s.split(String(sep), max === void 0 ? void 0 : Number(max) + 1),
79410
- join: (s, list2) => Array.isArray(list2) ? list2.join(s) : String(list2),
79461
+ join: (s, list3) => Array.isArray(list3) ? list3.join(s) : String(list3),
79411
79462
  format: (s, ...args2) => {
79412
79463
  const named = keywordArgs(args2);
79413
79464
  return pythonFormat(s, named ? args2.slice(0, -1) : args2, named ?? {});
@@ -79641,9 +79692,9 @@ function toSyntaxError2(e, fallbackLine = 1) {
79641
79692
  const fromMessage = /\[Line (\d+), Column (\d+)\]/.exec(
79642
79693
  String(err.message ?? "")
79643
79694
  );
79644
- const line = typeof err.lineno === "number" ? err.lineno + 1 : fromMessage ? Number(fromMessage[1]) : fallbackLine;
79695
+ const line2 = typeof err.lineno === "number" ? err.lineno + 1 : fromMessage ? Number(fromMessage[1]) : fallbackLine;
79645
79696
  const column = typeof err.colno === "number" ? err.colno + 1 : fromMessage ? Number(fromMessage[2]) : 1;
79646
- return new EngineSyntaxError("jinja2", message2, line, column);
79697
+ return new EngineSyntaxError("jinja2", message2, line2, column);
79647
79698
  }
79648
79699
  function nodeRange(node, length = 1) {
79649
79700
  return rangeAt(node.lineno + 1, node.colno + 1, length);
@@ -80138,12 +80189,12 @@ var validationContext3 = {
80138
80189
  };
80139
80190
  function toSyntaxError3(e) {
80140
80191
  const err = e;
80141
- let line = err.line ?? 1;
80192
+ let line2 = err.line ?? 1;
80142
80193
  let column = err.col ?? 1;
80143
80194
  const pos = err.token?.getPosition?.();
80144
- if (pos) [line, column] = pos;
80195
+ if (pos) [line2, column] = pos;
80145
80196
  const message2 = String(err.message ?? e).replace(/,\s*line:\d+,\s*col:\d+/, "").trim();
80146
- return new EngineSyntaxError("liquid", message2, line, column);
80197
+ return new EngineSyntaxError("liquid", message2, line2, column);
80147
80198
  }
80148
80199
  var identifier = /(?<![\w."'])([A-Za-z_][\w]*)((?:\.[A-Za-z_]\w*|\[\d+\])*)/g;
80149
80200
  function pathsIn(expression, base, source, out, scopes) {
@@ -80432,8 +80483,8 @@ function unionTypes(a, b2) {
80432
80483
  ...Array.isArray(b2) ? b2 : b2 ? [b2] : []
80433
80484
  ]);
80434
80485
  if (set.has("number")) set.delete("integer");
80435
- const list2 = [...set];
80436
- return list2.length === 1 ? list2[0] : list2;
80486
+ const list3 = [...set];
80487
+ return list3.length === 1 ? list3[0] : list3;
80437
80488
  }
80438
80489
  function merge(a, b2) {
80439
80490
  if (!a) return b2;
@@ -80501,9 +80552,9 @@ function inferSchema(sample) {
80501
80552
  var outputFormats = ["pdf", "png", "jpg", "webp", "docx", "pptx"];
80502
80553
 
80503
80554
  // packages/engine/src/lib/dialect.ts
80504
- var loop = (engine, item, list2, body) => engine === "handlebars" ? `{{#each ${list2}}}
80555
+ var loop = (engine, item, list3, body) => engine === "handlebars" ? `{{#each ${list3}}}
80505
80556
  ${body.replace(new RegExp(`(?<![\\w.])${item}\\.`, "g"), "")}
80506
- {{/each}}` : `{% for ${item} in ${list2} %}
80557
+ {{/each}}` : `{% for ${item} in ${list3} %}
80507
80558
  ${body}
80508
80559
  {% endfor %}`;
80509
80560
  var val = (engine, expr, filter) => {
@@ -81040,7 +81091,7 @@ var ASSET_NAME_PATTERN = new RegExp(`^${SEGMENT}(?:/${SEGMENT})*$`);
81040
81091
  var ASSET_MAX_BYTES = 10 * 1024 * 1024;
81041
81092
 
81042
81093
  // packages/engine/src/lib/generated/frames.ts
81043
- var textEditRuntime = '"use strict";(()=>{var H=`\nhtml.ff-edit-mode [data-ff-edit] { cursor: text; }\nhtml.ff-edit-mode [data-ff-edit]:hover { outline: 1px dashed rgba(37,99,235,.85); outline-offset: 2px; }\nhtml.ff-edit-mode [data-ff-edit="t"]:hover { outline-color: rgba(147,51,234,.9); }\n.ff-editing { outline: 2px solid #2563eb !important; outline-offset: 2px; cursor: text; }\n.ff-editing .ff-chip { background: rgba(37,99,235,.14) !important; box-shadow: inset 0 0 0 1px rgba(37,99,235,.45) !important; border-radius: 3px !important; padding: 0 1px !important; cursor: default; }\n.ff-edit-badge { position: absolute; z-index: 2147483647; font: 500 11px/1.4 system-ui, sans-serif !important; color: #fff !important; background: #2563eb !important; padding: 1px 6px !important; border-radius: 4px !important; pointer-events: none; white-space: nowrap; }\n`;function R(s,l={}){let g=l.clicks!==!1,p=l.live===!0,o=s.document,i=null,a=null,c=e=>{try{s.parent.postMessage(e,"*")}catch{}},b=o.createElement("style");b.setAttribute("data-formfeed","edit"),b.setAttribute("data-pagedjs-ignore",""),b.textContent=H,(o.head??o.documentElement).appendChild(b),g&&o.documentElement.classList.add("ff-edit-mode");let D=e=>(e&&typeof e.closest=="function"?e:null)?.closest("[data-ff-edit]")??null;o.addEventListener("click",e=>{if(!g)return;if(i&&!i.done&&i.element.contains(e.target)){e.stopImmediatePropagation();return}let t=D(e.target);if(!t)return;e.preventDefault(),e.stopImmediatePropagation(),i&&!i.done&&y();let n=t.getAttribute("data-ff-src")??"",r=t.getBoundingClientRect();a={src:n,element:t,x:e.clientX,y:e.clientY},c({type:"formfeed:edit-request",src:n,edit:t.getAttribute("data-ff-edit"),text:t.textContent??"",count:o.querySelectorAll(`[data-ff-src="${n.replace(/"/g,"")}"]`).length,split:t.hasAttribute("data-split-from")||t.hasAttribute("data-split-to"),rect:{left:r.left,top:r.top,width:r.width,height:r.height}})},!0),o.addEventListener("keydown",e=>{if(!g||i&&!i.done||!(e.ctrlKey||e.metaKey)||e.altKey)return;let t=e.key.toLowerCase();(t==="z"||t==="y")&&(e.preventDefault(),c({type:t==="y"||e.shiftKey?"formfeed:redo":"formfeed:undo"}))}),s.addEventListener("message",e=>{if(e.source!==s.parent)return;let t=e.data;!t||typeof t.type!="string"||(t.type==="formfeed:edit-begin"?F(t):(t.type==="formfeed:edit-refuse"||t.type==="formfeed:edit-end")&&(a=null,i&&!i.done&&h(!1)))});function F(e){i&&!i.done&&h(!1);let t=e.layer?o.querySelector(`[data-ff-layer="${String(e.layer).replace(/"/g,"")}"] > .ff-text`):a&&a.src===e.src?a.element:o.querySelector(`[data-ff-src="${String(e.src).replace(/"/g,"")}"]`),n=e.at,r=e.layer?n&&Number.isFinite(n.x)&&Number.isFinite(n.y)?{x:Number(n.x),y:Number(n.y)}:null:a&&a.src===e.src?a:null;if(a=null,!t||!Array.isArray(e.items)){c({type:"formfeed:edit-cancel",token:String(e.token)});return}let m=Array.from(t.childNodes),f=o.createDocumentFragment();for(let u of e.items)if(u.kind==="text")f.appendChild(o.createTextNode(String(u.text)));else if(u.kind==="break")f.appendChild(o.createElement("br"));else if(u.kind==="chip"){let d=o.createElement("span");d.className="ff-chip",d.setAttribute("data-ff-chip",String(u.index)),d.setAttribute("contenteditable","false"),u.title&&(d.title=String(u.title)),d.textContent=String(u.text),f.appendChild(d)}for(let u of m)t.removeChild(u);t.appendChild(f),t.contentEditable="true",t.classList.add("ff-editing"),t.setAttribute("role","textbox"),e.label&&t.setAttribute("aria-label",String(e.label)),t.spellcheck=!0,i={token:String(e.token),element:t,saved:m,allowBreaks:e.allowBreaks===!0,badge:e.note?B(t,String(e.note)):null,done:!1},t.addEventListener("keydown",E),t.addEventListener("beforeinput",v),t.addEventListener("paste",C),t.addEventListener("drop",L),t.addEventListener("focusout",A),p&&t.addEventListener("input",x),t.focus(),e.select==="all"?w(t):P(t,r),c({type:"formfeed:edit-started",token:i.token}),typeof e.insert=="string"&&e.insert&&k(e.insert.replace(/\\r\\n?|\\n/g," "))}function k(e){if(typeof o.execCommand=="function"&&o.execCommand("insertText",!1,e))return;let t=s.getSelection(),n=t&&t.rangeCount?t.getRangeAt(0):null;n&&(n.deleteContents(),n.insertNode(o.createTextNode(e)),n.collapse(!1),p&&x())}function x(){i&&!i.done&&c({type:"formfeed:edit-input",token:i.token,items:S(i.element)})}function B(e,t){let n=o.createElement("div");n.className="ff-edit-badge",n.textContent=t;let r=e.getBoundingClientRect();return n.style.left=`${r.left+s.scrollX}px`,n.style.top=`${Math.max(0,r.top+s.scrollY-22)}px`,o.body.appendChild(n),n}function w(e){let t=s.getSelection();if(!t)return;let n=o.createRange();n.selectNodeContents(e),t.removeAllRanges(),t.addRange(n)}function P(e,t){let n=s.getSelection();if(!n)return;let r=null,m=o;if(t){if(m.caretRangeFromPoint)r=m.caretRangeFromPoint(t.x,t.y);else if(m.caretPositionFromPoint){let f=m.caretPositionFromPoint(t.x,t.y);f&&(r=o.createRange(),r.setStart(f.offsetNode,f.offset))}}if(!r||!e.contains(r.startContainer))r=o.createRange(),r.selectNodeContents(e),r.collapse(!1);else if(t){let f=r.startContainer,d=(f.nodeType===1?f:f.parentElement)?.closest("[data-ff-chip]")??null;if(d&&d!==e&&e.contains(d)){let N=d.getBoundingClientRect();r=o.createRange(),t.x<N.left+N.width/2?r.setStartBefore(d):r.setStartAfter(d),r.collapse(!0)}}n.removeAllRanges(),n.addRange(r)}function E(e){let t=e.key;t==="Escape"?(e.preventDefault(),h(!0)):t==="Enter"&&!e.shiftKey?(e.preventDefault(),y()):t==="Enter"?(e.preventDefault(),i?.allowBreaks&&M()):t==="Tab"?(e.preventDefault(),y()):(e.ctrlKey||e.metaKey)&&["b","i","u"].includes(t.toLowerCase())&&(e.preventDefault(),p&&i&&!e.altKey&&c({type:"formfeed:edit-style",token:i.token,key:t.toLowerCase()}))}function v(e){let t=e.inputType??"";(t.startsWith("format")||t==="insertFromDrop"||t==="insertParagraph"||t==="insertLineBreak")&&e.preventDefault()}function C(e){e.preventDefault(),k((e.clipboardData?.getData("text/plain")??"").replace(/\\r\\n?|\\n/g," "))}function L(e){e.preventDefault()}function A(){s.setTimeout(()=>{i&&!i.done&&(!o.hasFocus()||!i.element.contains(o.activeElement))&&y()},0)}function M(){let e=s.getSelection();if(!e||!e.rangeCount)return;let t=e.getRangeAt(0);t.deleteContents();let n=o.createElement("br");t.insertNode(n),n.nextSibling||n.parentNode?.appendChild(o.createElement("br"));let r=o.createRange();r.setStartAfter(n),r.collapse(!0),e.removeAllRanges(),e.addRange(r)}function T(e){e.done=!0;let t=e.element;t.removeEventListener("keydown",E),t.removeEventListener("beforeinput",v),t.removeEventListener("paste",C),t.removeEventListener("drop",L),t.removeEventListener("focusout",A),t.removeEventListener("input",x),t.removeAttribute("contenteditable"),t.removeAttribute("role"),t.removeAttribute("aria-label"),t.classList.remove("ff-editing"),e.badge?.remove(),i===e&&(i=null)}function y(){let e=i;if(!e||e.done)return;let t=S(e.element);T(e),c({type:"formfeed:edit-commit",token:e.token,items:t})}function h(e){let t=i;if(!t||t.done)return;let n=t.element;for(;n.firstChild;)n.removeChild(n.firstChild);for(let r of t.saved)n.appendChild(r);T(t),e&&c({type:"formfeed:edit-cancel",token:t.token})}}function S(s){let l=[],g=o=>{let i=l[l.length-1];i?.kind==="text"?i.text+=o:o&&l.push({kind:"text",text:o})},p=o=>{for(let i of Array.from(o.childNodes))if(i.nodeType===3)g(i.data);else if(i.nodeType===1){let a=i,c=a.getAttribute("data-ff-chip");c!==null?l.push({kind:"chip",index:Number(c)}):a.tagName==="BR"?l.push({kind:"break"}):((a.tagName==="DIV"||a.tagName==="P")&&l.length&&l.push({kind:"break"}),p(a))}};for(p(s);l[l.length-1]?.kind==="break";)l.pop();return l}R(window);})();';
81094
+ var textEditRuntime = '"use strict";(()=>{var O=`\nhtml.ff-edit-mode [data-ff-edit] { cursor: text; }\nhtml.ff-edit-mode [data-ff-edit]:hover { outline: 1px dashed rgba(37,99,235,.85); outline-offset: 2px; }\nhtml.ff-edit-mode [data-ff-edit="t"]:hover { outline-color: rgba(147,51,234,.9); }\n.ff-editing { outline: 2px solid #2563eb !important; outline-offset: 2px; cursor: text; }\n.ff-editing .ff-chip { background: rgba(37,99,235,.14) !important; box-shadow: inset 0 0 0 1px rgba(37,99,235,.45) !important; border-radius: 3px !important; padding: 0 1px !important; cursor: default; }\n.ff-edit-badge { position: absolute; z-index: 2147483647; font: 500 11px/1.4 system-ui, sans-serif !important; color: #fff !important; background: #2563eb !important; padding: 1px 6px !important; border-radius: 4px !important; pointer-events: none; white-space: nowrap; }\n`;function F(l,d={}){let m=d.clicks!==!1,g=d.live===!0,o=l.document,i=null,s=null,f=e=>{try{l.parent.postMessage(e,"*")}catch{}},v=m?o.querySelector(\'meta[name="formfeed:document"]\')?.getAttribute("content")??null:null,h=!1;l.addEventListener("blur",()=>{h=!0}),l.addEventListener("focus",()=>{h=!1});let y=o.createElement("style");y.setAttribute("data-formfeed","edit"),y.setAttribute("data-pagedjs-ignore",""),y.textContent=O,(o.head??o.documentElement).appendChild(y),m&&o.documentElement.classList.add("ff-edit-mode");let M=e=>(e&&typeof e.closest=="function"?e:null)?.closest("[data-ff-edit]")??null;o.addEventListener("click",e=>{if(!m)return;if(i&&!i.done&&i.element.contains(e.target)){e.stopImmediatePropagation();return}let t=M(e.target);t&&(e.preventDefault(),e.stopImmediatePropagation(),C(t,{x:e.clientX,y:e.clientY}))},!0);function C(e,t){i&&!i.done&&x();let n=e.getAttribute("data-ff-src")??"",r=e.getBoundingClientRect(),u=Array.from(o.querySelectorAll(`[data-ff-src="${n.replace(/"/g,"")}"]`));s={src:n,element:e,point:t},f({type:"formfeed:edit-request",src:n,doc:v,edit:e.getAttribute("data-ff-edit"),text:e.textContent??"",elements:e.childElementCount,count:u.length,index:Math.max(0,u.indexOf(e)),split:e.hasAttribute("data-split-from")||e.hasAttribute("data-split-to"),rect:{left:r.left,top:r.top,width:r.width,height:r.height}})}o.addEventListener("keydown",e=>{if(!m||i&&!i.done||!(e.ctrlKey||e.metaKey)||e.altKey)return;let t=e.key.toLowerCase();(t==="z"||t==="y")&&(e.preventDefault(),f({type:t==="y"||e.shiftKey?"formfeed:redo":"formfeed:undo"}))}),l.addEventListener("message",e=>{if(e.source!==l.parent)return;let t=e.data;!t||typeof t.type!="string"||(t.type==="formfeed:edit-begin"?P(t):t.type==="formfeed:edit-refuse"||t.type==="formfeed:edit-end"?(s=null,i&&!i.done&&E(!1)):t.type==="formfeed:edit-open"&&B(t))});function B(e){if(!m||typeof e.src!="string"||i&&!i.done)return;let t=Array.from(o.querySelectorAll(`[data-ff-src="${e.src.replace(/"/g,"")}"][data-ff-edit]`)),n=Number.isInteger(e.index)?Number(e.index):0,r=t[n]??t[0];r&&C(r,null)}if(m){let e=()=>f({type:"formfeed:edit-ready",doc:v}),t=l;t.PagedConfig?t.formfeedEditReady=e:o.readyState==="loading"?o.addEventListener("DOMContentLoaded",e):e()}function P(e){i&&!i.done&&E(!1);let t=e.layer?o.querySelector(`[data-ff-layer="${String(e.layer).replace(/"/g,"")}"] > .ff-text`):s&&s.src===e.src?s.element:o.querySelector(`[data-ff-src="${String(e.src).replace(/"/g,"")}"]`),n=e.at,r=e.layer?n&&Number.isFinite(n.x)&&Number.isFinite(n.y)?{x:Number(n.x),y:Number(n.y)}:null:s&&s.src===e.src?s.point:null;s=null;let u=h&&!o.hasFocus();if(!t||!Array.isArray(e.items)||u){f({type:"formfeed:edit-cancel",token:String(e.token)});return}let c=Array.from(t.childNodes),b=o.createDocumentFragment();for(let a of e.items)if(a.kind==="text")b.appendChild(o.createTextNode(String(a.text)));else if(a.kind==="break")b.appendChild(o.createElement("br"));else if(a.kind==="chip"){let p=o.createElement("span");p.className="ff-chip",p.setAttribute("data-ff-chip",String(a.index)),p.setAttribute("contenteditable","false"),a.title&&(p.title=String(a.title)),p.textContent=String(a.text),b.appendChild(p)}for(let a of c)t.removeChild(a);t.appendChild(b),t.contentEditable="true",t.classList.add("ff-editing"),t.setAttribute("role","textbox"),e.label&&t.setAttribute("aria-label",String(e.label)),t.spellcheck=!0,i={token:String(e.token),element:t,saved:c,allowBreaks:e.allowBreaks===!0,badge:e.note?H(t,String(e.note)):null,done:!1},t.addEventListener("keydown",A),t.addEventListener("beforeinput",T),t.addEventListener("paste",S),t.addEventListener("drop",N),t.addEventListener("focusout",R),g&&t.addEventListener("input",k),t.focus(),e.select==="all"?I(t):K(t,r),f({type:"formfeed:edit-started",token:i.token}),typeof e.insert=="string"&&e.insert&&L(e.insert.replace(/\\r\\n?|\\n/g," "))}function L(e){if(typeof o.execCommand=="function"&&o.execCommand("insertText",!1,e))return;let t=l.getSelection(),n=t&&t.rangeCount?t.getRangeAt(0):null;n&&(n.deleteContents(),n.insertNode(o.createTextNode(e)),n.collapse(!1),g&&k())}function k(){i&&!i.done&&f({type:"formfeed:edit-input",token:i.token,items:D(i.element)})}function H(e,t){let n=o.createElement("div");n.className="ff-edit-badge",n.textContent=t;let r=e.getBoundingClientRect();return n.style.left=`${r.left+l.scrollX}px`,n.style.top=`${Math.max(0,r.top+l.scrollY-22)}px`,o.body.appendChild(n),n}function I(e){let t=l.getSelection();if(!t)return;let n=o.createRange();n.selectNodeContents(e),t.removeAllRanges(),t.addRange(n)}function K(e,t){let n=l.getSelection();if(!n)return;let r=null,u=o;if(t){if(u.caretRangeFromPoint)r=u.caretRangeFromPoint(t.x,t.y);else if(u.caretPositionFromPoint){let c=u.caretPositionFromPoint(t.x,t.y);c&&(r=o.createRange(),r.setStart(c.offsetNode,c.offset))}}if(!r||!e.contains(r.startContainer))r=o.createRange(),r.selectNodeContents(e),r.collapse(!1);else if(t){let c=r.startContainer,a=(c.nodeType===1?c:c.parentElement)?.closest("[data-ff-chip]")??null;if(a&&a!==e&&e.contains(a)){let p=a.getBoundingClientRect();r=o.createRange(),t.x<p.left+p.width/2?r.setStartBefore(a):r.setStartAfter(a),r.collapse(!0)}}n.removeAllRanges(),n.addRange(r)}function A(e){let t=e.key;t==="Escape"?(e.preventDefault(),E(!0)):t==="Enter"&&!e.shiftKey?(e.preventDefault(),x()):t==="Enter"?(e.preventDefault(),i?.allowBreaks&&q()):t==="Tab"?(e.preventDefault(),x()):(e.ctrlKey||e.metaKey)&&["b","i","u"].includes(t.toLowerCase())&&(e.preventDefault(),g&&i&&!e.altKey&&f({type:"formfeed:edit-style",token:i.token,key:t.toLowerCase()}))}function T(e){let t=e.inputType??"";(t.startsWith("format")||t==="insertFromDrop"||t==="insertParagraph"||t==="insertLineBreak")&&e.preventDefault()}function S(e){e.preventDefault(),L((e.clipboardData?.getData("text/plain")??"").replace(/\\r\\n?|\\n/g," "))}function N(e){e.preventDefault()}function R(){l.setTimeout(()=>{i&&!i.done&&(!o.hasFocus()||!i.element.contains(o.activeElement))&&x()},0)}function q(){let e=l.getSelection();if(!e||!e.rangeCount)return;let t=e.getRangeAt(0);t.deleteContents();let n=o.createElement("br");t.insertNode(n),n.nextSibling||n.parentNode?.appendChild(o.createElement("br"));let r=o.createRange();r.setStartAfter(n),r.collapse(!0),e.removeAllRanges(),e.addRange(r)}function w(e){e.done=!0;let t=e.element;t.removeEventListener("keydown",A),t.removeEventListener("beforeinput",T),t.removeEventListener("paste",S),t.removeEventListener("drop",N),t.removeEventListener("focusout",R),t.removeEventListener("input",k),t.removeAttribute("contenteditable"),t.removeAttribute("role"),t.removeAttribute("aria-label"),t.classList.remove("ff-editing"),e.badge?.remove(),i===e&&(i=null)}function x(){let e=i;if(!e||e.done)return;let t=D(e.element);w(e),f({type:"formfeed:edit-commit",token:e.token,items:t})}function E(e){let t=i;if(!t||t.done)return;let n=t.element;for(;n.firstChild;)n.removeChild(n.firstChild);for(let r of t.saved)n.appendChild(r);w(t),e&&f({type:"formfeed:edit-cancel",token:t.token})}}function D(l){let d=[],m=o=>{let i=d[d.length-1];i?.kind==="text"?i.text+=o:o&&d.push({kind:"text",text:o})},g=o=>{for(let i of Array.from(o.childNodes))if(i.nodeType===3)m(i.data);else if(i.nodeType===1){let s=i,f=s.getAttribute("data-ff-chip");f!==null?d.push({kind:"chip",index:Number(f)}):s.tagName==="BR"?d.push({kind:"break"}):((s.tagName==="DIV"||s.tagName==="P")&&d.length&&d.push({kind:"break"}),g(s))}};for(g(l);d[d.length-1]?.kind==="break";)d.pop();return d}F(window);})();';
81044
81095
 
81045
81096
  // packages/engine/src/lib/preview.ts
81046
81097
  var textEditScript = `<script>${textEditRuntime.replace(/<\/script/gi, "<\\/script")}</script>`;
@@ -81585,6 +81636,199 @@ var designStarters = [
81585
81636
  }
81586
81637
  ];
81587
81638
 
81639
+ // packages/engine/src/lib/einvoice/codes.generated.ts
81640
+ var list2 = (codes) => new Set(codes.split(" "));
81641
+ var documentTypeCodes = list2(
81642
+ "71 80 81 82 83 84 102 130 202 203 204 211 218 219 261 262 295 296 308 325 326 331 380 381 382 383 384 385 386 387 388 389 390 393 394 395 396 420 456 457 458 471 472 473 500 501 502 503 527 532 553 575 623 633 751 780 817 870 875 876 877 935"
81643
+ );
81644
+ var countryCodes = list2(
81645
+ "1A AD AE AF AG AI AL AM AO AQ AR AS AT AU AW AX AZ BA BB BD BE BF BG BH BI BJ BL BM BN BO BQ BR BS BT BV BW BY BZ CA CC CD CF CG CH CI CK CL CM CN CO CR CU CV CW CX CY CZ DE DJ DK DM DO DZ EC EE EG EH ER ES ET FI FJ FK FM FO FR GA GB GD GE GF GG GH GI GL GM GN GP GQ GR GS GT GU GW GY HK HM HN HR HT HU ID IE IL IM IN IO IQ IR IS IT JE JM JO JP KE KG KH KI KM KN KP KR KW KY KZ LA LB LC LI LK LR LS LT LU LV LY MA MC MD ME MF MG MH MK ML MM MN MO MP MQ MR MS MT MU MV MW MX MY MZ NA NC NE NF NG NI NL NO NP NR NU NZ OM PA PE PF PG PH PK PL PM PN PR PS PT PW PY QA RE RO RS RU RW SA SB SC SD SE SG SH SI SJ SK SL SM SN SO SR SS ST SV SX SY SZ TC TD TF TG TH TJ TK TL TM TN TO TR TT TV TW TZ UA UG UM US UY UZ VA VC VE VG VI VN VU WF WS XI YE YT ZA ZM ZW 1A XI"
81646
+ );
81647
+ var unitCodes = list2(
81648
+ "10 11 13 14 15 20 21 22 23 24 25 27 28 33 34 35 37 38 40 41 56 57 58 59 60 61 74 77 80 81 85 87 89 91 1I 2A 2B 2C 2G 2H 2I 2J 2K 2L 2M 2N 2P 2Q 2R 2U 2X 2Y 2Z 3B 3C 4C 4G 4H 4K 4L 4M 4N 4O 4P 4Q 4R 4T 4U 4W 4X 5A 5B 5E 5J A10 A11 A12 A13 A14 A15 A16 A17 A18 A19 A2 A20 A21 A22 A23 A24 A26 A27 A28 A29 A3 A30 A31 A32 A33 A34 A35 A36 A37 A38 A39 A4 A40 A41 A42 A43 A44 A45 A47 A48 A49 A5 A53 A54 A55 A56 A59 A6 A68 A69 A7 A70 A71 A73 A74 A75 A76 A8 A84 A85 A86 A87 A88 A89 A9 A90 A91 A93 A94 A95 A96 A97 A98 A99 AA AB ACR ACT AD AE AH AI AK AL AMH AMP ANN APZ AQ AS ASM ASU ATM AWG AY AZ B1 B10 B11 B12 B13 B14 B15 B16 B17 B18 B19 B20 B21 B22 B23 B24 B25 B26 B27 B28 B29 B3 B30 B31 B32 B33 B34 B35 B4 B41 B42 B43 B44 B45 B46 B47 B48 B49 B50 B52 B53 B54 B55 B56 B57 B58 B59 B60 B61 B62 B63 B64 B66 B67 B68 B69 B7 B70 B71 B72 B73 B74 B75 B76 B77 B78 B79 B8 B80 B81 B82 B83 B84 B85 B86 B87 B88 B89 B90 B91 B92 B93 B94 B95 B96 B97 B98 B99 BAR BB BFT BHP BIL BLD BLL BP BPM BQL BTU BUA BUI C0 C10 C11 C12 C13 C14 C15 C16 C17 C18 C19 C20 C21 C22 C23 C24 C25 C26 C27 C28 C29 C3 C30 C31 C32 C33 C34 C35 C36 C37 C38 C39 C40 C41 C42 C43 C44 C45 C46 C47 C48 C49 C50 C51 C52 C53 C54 C55 C56 C57 C58 C59 C60 C61 C62 C63 C64 C65 C66 C67 C68 C69 C7 C70 C71 C72 C73 C74 C75 C76 C78 C79 C8 C80 C81 C82 C83 C84 C85 C86 C87 C88 C89 C9 C90 C91 C92 C93 C94 C95 C96 C97 C99 CCT CDL CEL CEN CG CGM CKG CLF CLT CMK CMQ CMT CNP CNT COU CTG CTM CTN CUR CWA CWI D03 D04 D1 D10 D11 D12 D13 D15 D16 D17 D18 D19 D2 D20 D21 D22 D23 D24 D25 D26 D27 D29 D30 D31 D32 D33 D34 D36 D41 D42 D43 D44 D45 D46 D47 D48 D49 D5 D50 D51 D52 D53 D54 D55 D56 D57 D58 D59 D6 D60 D61 D62 D63 D65 D68 D69 D73 D74 D77 D78 D80 D81 D82 D83 D85 D86 D87 D88 D89 D91 D93 D94 D95 DAA DAD DAY DB DBM DBW DD DEC DG DJ DLT DMA DMK DMO DMQ DMT DN DPC DPR DPT DRA DRI DRL DT DTN DWT DZN DZP E01 E07 E08 E09 E10 E12 E14 E15 E16 E17 E18 E19 E20 E21 E22 E23 E25 E27 E28 E30 E31 E32 E33 E34 E35 E36 E37 E38 E39 E4 E40 E41 E42 E43 E44 E45 E46 E47 E48 E49 E50 E51 E52 E53 E54 E55 E56 E57 E58 E59 E60 E61 E62 E63 E64 E65 E66 E67 E68 E69 E70 E71 E72 E73 E74 E75 E76 E77 E78 E79 E80 E81 E82 E83 E84 E85 E86 E87 E88 E89 E90 E91 E92 E93 E94 E95 E96 E97 E98 E99 EA EB EQ F01 F02 F03 F04 F05 F06 F07 F08 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 F32 F33 F34 F35 F36 F37 F38 F39 F40 F41 F42 F43 F44 F45 F46 F47 F48 F49 F50 F51 F52 F53 F54 F55 F56 F57 F58 F59 F60 F61 F62 F63 F64 F65 F66 F67 F68 F69 F70 F71 F72 F73 F74 F75 F76 F77 F78 F79 F80 F81 F82 F83 F84 F85 F86 F87 F88 F89 F90 F91 F92 F93 F94 F95 F96 F97 F98 F99 FAH FAR FBM FC FF FH FIT FL FNU FOT FP FR FS FTK FTQ G01 G04 G05 G06 G08 G09 G10 G11 G12 G13 G14 G15 G16 G17 G18 G19 G2 G20 G21 G23 G24 G25 G26 G27 G28 G29 G3 G30 G31 G32 G33 G34 G35 G36 G37 G38 G39 G40 G41 G42 G43 G44 G45 G46 G47 G48 G49 G50 G51 G52 G53 G54 G55 G56 G57 G58 G59 G60 G61 G62 G63 G64 G65 G66 G67 G68 G69 G70 G71 G72 G73 G74 G75 G76 G77 G78 G79 G80 G81 G82 G83 G84 G85 G86 G87 G88 G89 G90 G91 G92 G93 G94 G95 G96 G97 G98 G99 GB GBQ GDW GE GF GFI GGR GIA GIC GII GIP GJ GL GLD GLI GLL GM GO GP GQ GRM GRN GRO GV GWH H03 H04 H05 H06 H07 H08 H09 H10 H11 H12 H13 H14 H15 H16 H18 H19 H20 H21 H22 H23 H24 H25 H26 H27 H28 H29 H30 H31 H32 H33 H34 H35 H36 H37 H38 H39 H40 H41 H42 H43 H44 H45 H46 H47 H48 H49 H50 H51 H52 H53 H54 H55 H56 H57 H58 H59 H60 H61 H62 H63 H64 H65 H66 H67 H68 H69 H70 H71 H72 H73 H74 H75 H76 H77 H79 H80 H81 H82 H83 H84 H85 H87 H88 H89 H90 H91 H92 H93 H94 H95 H96 H98 H99 HA HAD HBA HBX HC HDW HEA HGM HH HIU HKM HLT HM HMO HMQ HMT HPA HTZ HUR HWE IA IE INH INK INQ ISD IU IUG IV J10 J12 J13 J14 J15 J16 J17 J18 J19 J2 J20 J21 J22 J23 J24 J25 J26 J27 J28 J29 J30 J31 J32 J33 J34 J35 J36 J38 J39 J40 J41 J42 J43 J44 J45 J46 J47 J48 J49 J50 J51 J52 J53 J54 J55 J56 J57 J58 J59 J60 J61 J62 J63 J64 J65 J66 J67 J68 J69 J70 J71 J72 J73 J74 J75 J76 J78 J79 J81 J82 J83 J84 J85 J87 J90 J91 J92 J93 J95 J96 J97 J98 J99 JE JK JM JNT JOU JPS JWL K1 K10 K11 K12 K13 K14 K15 K16 K17 K18 K19 K2 K20 K21 K22 K23 K26 K27 K28 K3 K30 K31 K32 K33 K34 K35 K36 K37 K38 K39 K40 K41 K42 K43 K45 K46 K47 K48 K49 K50 K51 K52 K53 K54 K55 K58 K59 K6 K60 K61 K62 K63 K64 K65 K66 K67 K68 K69 K70 K71 K73 K74 K75 K76 K77 K78 K79 K80 K81 K82 K83 K84 K85 K86 K87 K88 K89 K90 K91 K92 K93 K94 K95 K96 K97 K98 K99 KA KAT KB KBA KCC KDW KEL KGM KGS KHY KHZ KI KIC KIP KJ KJO KL KLK KLX KMA KMH KMK KMQ KMT KNI KNM KNS KNT KO KPA KPH KPO KPP KR KSD KSH KT KTN KUR KVA KVR KVT KW KWH KWN KWO KWS KWT KWY KX L10 L11 L12 L13 L14 L15 L16 L17 L18 L19 L2 L20 L21 L23 L24 L25 L26 L27 L28 L29 L30 L31 L32 L33 L34 L35 L36 L37 L38 L39 L40 L41 L42 L43 L44 L45 L46 L47 L48 L49 L50 L51 L52 L53 L54 L55 L56 L57 L58 L59 L60 L63 L64 L65 L66 L67 L68 L69 L70 L71 L72 L73 L74 L75 L76 L77 L78 L79 L80 L81 L82 L83 L84 L85 L86 L87 L88 L89 L90 L91 L92 L93 L94 L95 L96 L98 L99 LA LAC LBR LBT LD LEF LF LH LK LM LN LO LP LPA LR LS LTN LTR LUB LUM LUX LY M1 M10 M11 M12 M13 M14 M15 M16 M17 M18 M19 M20 M21 M22 M23 M24 M25 M26 M27 M29 M30 M31 M32 M33 M34 M35 M36 M37 M38 M39 M4 M40 M41 M42 M43 M44 M45 M46 M47 M48 M49 M5 M50 M51 M52 M53 M55 M56 M57 M58 M59 M60 M61 M62 M63 M64 M65 M66 M67 M68 M69 M7 M70 M71 M72 M73 M74 M75 M76 M77 M78 M79 M80 M81 M82 M83 M84 M85 M86 M87 M88 M89 M9 M90 M91 M92 M93 M94 M95 M96 M97 M98 M99 MAH MAL MAM MAR MAW MBE MBF MBR MC MCU MD MGM MHZ MIK MIL MIN MIO MIU MKD MKM MKW MLD MLT MMK MMQ MMT MND MNJ MON MPA MQD MQH MQM MQS MQW MRD MRM MRW MSK MTK MTQ MTR MTS MTZ MVA MWH N1 N10 N11 N12 N13 N14 N15 N16 N17 N18 N19 N20 N21 N22 N23 N24 N25 N26 N27 N28 N29 N3 N30 N31 N32 N33 N34 N35 N36 N37 N38 N39 N40 N41 N42 N43 N44 N45 N46 N47 N48 N49 N50 N51 N52 N53 N54 N55 N56 N57 N58 N59 N60 N61 N62 N63 N64 N65 N66 N67 N68 N69 N70 N71 N72 N73 N74 N75 N76 N77 N78 N79 N80 N81 N82 N83 N84 N85 N86 N87 N88 N89 N90 N91 N92 N93 N94 N95 N96 N97 N98 N99 NA NAR NCL NEW NF NIL NIU NL NM3 NMI NMP NPT NT NTU NU NX OA ODE ODG ODK ODM OHM ON ONZ OPM OT OZA OZI P1 P10 P11 P12 P13 P14 P15 P16 P17 P18 P19 P2 P20 P21 P22 P23 P24 P25 P26 P27 P28 P29 P30 P31 P32 P33 P34 P35 P36 P37 P38 P39 P40 P41 P42 P43 P44 P45 P46 P47 P48 P49 P5 P50 P51 P52 P53 P54 P55 P56 P57 P58 P59 P60 P61 P62 P63 P64 P65 P66 P67 P68 P69 P70 P71 P72 P73 P74 P75 P76 P77 P78 P79 P80 P81 P82 P83 P84 P85 P86 P87 P88 P89 P90 P91 P92 P93 P94 P95 P96 P97 P98 P99 PAL PD PFL PGL PI PLA PO PQ PR PS PTD PTI PTL PTN Q10 Q11 Q12 Q13 Q14 Q15 Q16 Q17 Q18 Q19 Q20 Q21 Q22 Q23 Q24 Q25 Q26 Q27 Q28 Q29 Q3 Q30 Q31 Q32 Q33 Q34 Q35 Q36 Q37 Q38 Q39 Q40 Q41 Q42 QA QAN QB QR QTD QTI QTL QTR R1 R9 RH RM ROM RP RPM RPS RT S3 S4 SAN SCO SCR SEC SET SG SIE SM3 SMI SQ SQR SR STC STI STK STL STN STW SW SX SYR T0 T3 TAH TAN TI TIC TIP TKM TMS TNE TP TPI TPR TQD TRL TST TTS U1 U2 UB UC VA VLT VP W2 WA WB WCD WE WEB WEE WG WHR WM WSD WTT X1 X1A X1B X1D X1F X1G X1W X2C X3A X3H X43 X44 X4A X4B X4C X4D X4F X4G X4H X5H X5L X5M X6H X6P X7A X7B X8A X8B X8C XAA XAB XAC XAD XAE XAF XAG XAH XAI XAJ XAL XAM XAP XAT XAV XB4 XBA XBB XBC XBD XBE XBF XBG XBH XBI XBJ XBK XBL XBM XBN XBO XBP XBQ XBR XBS XBT XBU XBV XBW XBX XBY XBZ XCA XCB XCC XCD XCE XCF XCG XCH XCI XCJ XCK XCL XCM XCN XCO XCP XCQ XCR XCS XCT XCU XCV XCW XCX XCY XCZ XDA XDB XDC XDG XDH XDI XDJ XDK XDL XDM XDN XDP XDR XDS XDT XDU XDV XDW XDX XDY XEC XED XEE XEF XEG XEH XEI XEN XFB XFC XFD XFE XFI XFL XFO XFP XFR XFT XFW XFX XGB XGI XGL XGR XGU XGY XGZ XHA XHB XHC XHG XHN XHR XIA XIB XIC XID XIE XIF XIG XIH XIK XIL XIN XIZ XJB XJC XJG XJR XJT XJY XKG XKI XLE XLG XLT XLU XLV XLZ XMA XMB XMC XME XMR XMS XMT XMW XMX XNA XNE XNF XNG XNS XNT XNU XNV XO1 XO2 XO3 XO4 XO5 XO6 XO7 XO8 XO9 XOA XOB XOC XOD XOE XOF XOG XOH XOI XOJ XOK XOL XOM XON XOP XOQ XOR XOS XOT XOU XOV XOW XOX XOY XOZ XP1 XP2 XP3 XP4 XPA XPB XPC XPD XPE XPF XPG XPH XPI XPJ XPK XPL XPN XPO XPP XPR XPT XPU XPV XPX XPY XPZ XQA XQB XQC XQD XQF XQG XQH XQJ XQK XQL XQM XQN XQP XQQ XQR XQS XRD XRG XRJ XRK XRL XRO XRT XRZ XSA XSB XSC XSD XSE XSH XSI XSK XSL XSM XSO XSP XSS XST XSU XSV XSW XSX XSY XSZ XT1 XTB XTC XTD XTE XTG XTI XTK XTL XTN XTO XTR XTS XTT XTU XTV XTW XTY XTZ XUC XUN XVA XVG XVI XVK XVL XVN XVO XVP XVQ XVR XVS XVY XWA XWB XWC XWD XWF XWG XWH XWJ XWK XWL XWM XWN XWP XWQ XWR XWS XWT XWU XWV XWW XWX XWY XWZ XXA XXB XXC XXD XXF XXG XXH XXJ XXK XYA XYB XYC XYD XYF XYG XYH XYJ XYK XYL XYM XYN XYP XYQ XYR XYS XYT XYV XYW XYX XYY XYZ XZA XZB XZC XZD XZF XZG XZH XZJ XZK XZL XZM XZN XZP XZQ XZR XZS XZT XZU XZV XZW XZX XZY XZZ YDK YDQ YRD Z11 Z9 ZP ZZ"
81649
+ );
81650
+ var electronicAddressSchemes = list2(
81651
+ "0002 0007 0009 0037 0060 0088 0096 0097 0106 0130 0135 0142 0147 0151 0154 0158 0170 0177 0183 0184 0188 0190 0191 0192 0193 0194 0195 0196 0198 0199 0200 0201 0202 0203 0204 0205 0208 0209 0210 0211 0212 0213 0215 0216 0217 0218 0221 0225 0230 0235 0240 0242 0244 0245 0246 0248 9910 9913 9914 9915 9918 9919 9920 9922 9923 9924 9925 9926 9927 9928 9929 9930 9931 9932 9933 9934 9935 9936 9937 9938 9939 9940 9941 9942 9943 9944 9945 9946 9947 9948 9949 9950 9951 9952 9953 9957 9959 AN AQ AS AU EM"
81652
+ );
81653
+ var currencyCodes = list2(
81654
+ "AED AFN ALL AMD AOA ARS AUD AWG AZN BAM BBD BDT BHD BIF BMD BND BOB BOV BRL BSD BTN BWP BYN BZD CAD CDF CHE CHF CHW CLF CLP CNH CNY COP COU CRC CUP CVE CZK DJF DKK DOP DZD EGP ERN ETB EUR FJD FKP GBP GEL GHS GIP GMD GNF GTQ GYD HKD HNL HTG HUF IDR ILS INR IQD IRR ISK JMD JOD JPY KES KGS KHR KMF KPW KRW KWD KYD KZT LAK LBP LKR LRD LSL LYD MAD MDL MGA MKD MMK MNT MOP MRU MUR MVR MWK MXN MXV MYR MZN NAD NGN NIO NOK NPR NZD OMR PAB PEN PGK PHP PKR PLN PYG QAR RON RSD RUB RWF SAR SBD SCR SDG SEK SGD SHP SLE SOS SRD SSP STN SVC SYP SZL THB TJS TMT TND TOP TRY TTD TWD TZS UAH UGX USD USN UYI UYU UYW UZS VED VES VND VUV WST XAF XAG XAU XBA XBB XBC XBD XCD XCG XDR XOF XPD XPF XPT XSU XTS XUA XXX YER ZAR ZMW ZWG"
81655
+ );
81656
+ var paymentMeansCodes = list2(
81657
+ "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 74 75 76 77 78 91 92 93 94 95 96 97 98 ZZZ"
81658
+ );
81659
+
81660
+ // packages/engine/src/lib/einvoice/schema.ts
81661
+ import { z as z2 } from "zod";
81662
+ var numeric = z2.union([z2.number(), z2.string()]);
81663
+ var text2 = z2.string().trim().min(1);
81664
+ var isoDate2 = z2.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Expected a date as YYYY-MM-DD");
81665
+ var identifier2 = z2.union([
81666
+ text2,
81667
+ z2.object({ value: text2, scheme: text2.optional() })
81668
+ ]);
81669
+ var address = z2.object({
81670
+ street: text2.optional(),
81671
+ street2: text2.optional(),
81672
+ street3: text2.optional(),
81673
+ postcode: text2.optional(),
81674
+ city: text2.optional(),
81675
+ /** ISO 3166-1 alpha-2 (BT-40, BT-55, BT-80). */
81676
+ country: text2,
81677
+ /** Region or province (BT-39, BT-54, BT-79). */
81678
+ subdivision: text2.optional()
81679
+ });
81680
+ var contact = z2.object({
81681
+ name: text2.optional(),
81682
+ phone: text2.optional(),
81683
+ email: text2.optional()
81684
+ });
81685
+ var party = z2.object({
81686
+ name: text2,
81687
+ /** The name the business trades under, where it differs (BT-28, BT-45). */
81688
+ trading_name: text2.optional(),
81689
+ /** An identifier of the party (BT-29, BT-46). */
81690
+ id: identifier2.optional(),
81691
+ /** The register entry (BT-30, BT-47): a SIREN, a company number. */
81692
+ legal_registration: identifier2.optional(),
81693
+ vat_id: text2.optional(),
81694
+ address,
81695
+ contact: contact.optional(),
81696
+ /** Where the party receives electronic invoices (BT-34, BT-49); a bare e-mail address is scheme EM. */
81697
+ electronic_address: identifier2.optional()
81698
+ });
81699
+ var period = z2.object({ start: isoDate2.optional(), end: isoDate2.optional() });
81700
+ var VAT_CATEGORIES = ["S", "Z", "E", "AE", "K", "G", "O"];
81701
+ var vatCategory = z2.enum(VAT_CATEGORIES);
81702
+ var lineTax = z2.object({
81703
+ category: vatCategory,
81704
+ /** Percent, `19` for 19 %. Left out for category O only. */
81705
+ rate: numeric.optional()
81706
+ });
81707
+ var allowanceOrCharge = z2.object({
81708
+ amount: numeric,
81709
+ reason: text2.optional(),
81710
+ /** UNTDID 5189 for an allowance, UNTDID 7161 for a charge. */
81711
+ reason_code: text2.optional(),
81712
+ base_amount: numeric.optional(),
81713
+ percent: numeric.optional()
81714
+ });
81715
+ var line = z2.object({
81716
+ id: z2.union([text2, z2.number()]),
81717
+ name: text2,
81718
+ description: text2.optional(),
81719
+ quantity: numeric,
81720
+ /** UN/ECE Recommendation 20: C62 a piece, HUR an hour, DAY a day, KGM a kilogram. */
81721
+ unit_code: text2.default("C62"),
81722
+ net_price: numeric,
81723
+ /** The quantity the price is for, where it is not one unit (BT-149). */
81724
+ price_base_quantity: numeric.optional(),
81725
+ net_amount: numeric,
81726
+ tax: lineTax,
81727
+ period: period.optional(),
81728
+ allowances: z2.array(allowanceOrCharge).optional(),
81729
+ charges: z2.array(allowanceOrCharge).optional(),
81730
+ buyer_accounting_reference: text2.optional(),
81731
+ note: text2.optional(),
81732
+ /** The seller's and the buyer's article numbers (BT-155, BT-156), a GTIN and the like (BT-157). */
81733
+ seller_item_id: text2.optional(),
81734
+ buyer_item_id: text2.optional(),
81735
+ standard_item_id: identifier2.optional(),
81736
+ /** The line of the buyer's order this one answers (BT-132). */
81737
+ order_line_reference: text2.optional()
81738
+ });
81739
+ var breakdown = z2.object({
81740
+ category: vatCategory,
81741
+ rate: numeric.optional(),
81742
+ basis: numeric,
81743
+ amount: numeric,
81744
+ exemption_reason: text2.optional(),
81745
+ /** A VATEX code (BT-121), for example VATEX-EU-AE for reverse charge. */
81746
+ exemption_reason_code: text2.optional()
81747
+ });
81748
+ var totals = z2.object({
81749
+ line_net: numeric,
81750
+ allowances: numeric.optional(),
81751
+ charges: numeric.optional(),
81752
+ tax_basis: numeric,
81753
+ tax_total: numeric,
81754
+ /** The VAT total in the accounting currency (BT-111). */
81755
+ tax_total_accounting: numeric.optional(),
81756
+ grand: numeric,
81757
+ prepaid: numeric.optional(),
81758
+ rounding: numeric.optional(),
81759
+ due: numeric
81760
+ });
81761
+ var payment = z2.object({
81762
+ /** UNTDID 4461: 58 SEPA credit transfer, 59 SEPA direct debit, 30 credit transfer, 48 card. */
81763
+ means_code: z2.union([text2, z2.number()]).optional(),
81764
+ iban: text2.optional(),
81765
+ bic: text2.optional(),
81766
+ account_name: text2.optional(),
81767
+ /** What the payer quotes with the payment (BT-83). */
81768
+ reference: text2.optional(),
81769
+ terms: text2.optional(),
81770
+ due_date: isoDate2.optional(),
81771
+ /** Direct debit: the mandate (BT-89), the creditor's identifier (BT-90), the account debited (BT-91). */
81772
+ mandate_id: text2.optional(),
81773
+ creditor_id: text2.optional(),
81774
+ debited_iban: text2.optional()
81775
+ });
81776
+ var note = z2.object({
81777
+ text: text2,
81778
+ /** UNTDID 4451, which French invoices use for their statutory mentions (PMT, PMD, AAB). */
81779
+ subject_code: text2.optional()
81780
+ });
81781
+ var invoiceSchema = z2.object({
81782
+ number: text2,
81783
+ issue_date: isoDate2,
81784
+ /** UNTDID 1001: 380 invoice, 381 credit note, 384 corrected invoice, 389 self-billed. */
81785
+ type_code: z2.union([text2, z2.number()]).default("380"),
81786
+ currency: text2,
81787
+ /** The currency the VAT is accounted in, where the invoice is in another (BT-6); goes with `totals.tax_total_accounting`. */
81788
+ accounting_currency: text2.optional(),
81789
+ /** The buyer's routing reference (BT-10); a German authority's Leitweg-ID goes here. */
81790
+ buyer_reference: text2.optional(),
81791
+ order_reference: text2.optional(),
81792
+ contract_reference: text2.optional(),
81793
+ note: text2.optional(),
81794
+ notes: z2.array(note).optional(),
81795
+ period: period.optional(),
81796
+ /** The invoices a credit note or a correction refers to (BG-3). */
81797
+ preceding_invoices: z2.array(z2.object({ number: text2, issue_date: isoDate2.optional() })).optional(),
81798
+ /** France (spec 17 §4.4): what was sold, and the billing framework's code where the plain case does not fit. */
81799
+ operation: z2.enum(["goods", "services", "mixed"]).optional(),
81800
+ operation_code: text2.optional(),
81801
+ seller: party.extend({
81802
+ tax_number: text2.optional(),
81803
+ /** Further legal information the invoice must state (BT-33): register court, capital. */
81804
+ legal_info: text2.optional(),
81805
+ /** France: VAT is owed when the invoice is issued, not when it is paid. */
81806
+ vat_on_debits: z2.boolean().optional()
81807
+ }),
81808
+ buyer: party.extend({
81809
+ /** France: the buyer's SIREN, nine digits. */
81810
+ siren: text2.optional()
81811
+ }),
81812
+ delivery: z2.object({
81813
+ name: text2.optional(),
81814
+ date: isoDate2.optional(),
81815
+ address: address.optional()
81816
+ }).optional(),
81817
+ lines: z2.array(line).min(1),
81818
+ /** Allowances and charges on the whole document (BG-20, BG-21), each with the VAT it falls under. */
81819
+ allowances: z2.array(allowanceOrCharge.extend({ tax: lineTax })).optional(),
81820
+ charges: z2.array(allowanceOrCharge.extend({ tax: lineTax })).optional(),
81821
+ tax: z2.object({ breakdown: z2.array(breakdown).min(1) }),
81822
+ totals,
81823
+ payment: payment.optional()
81824
+ });
81825
+ var einvoiceOptionsSchema = z2.object({
81826
+ profile: z2.string().optional(),
81827
+ flavour: z2.string().optional(),
81828
+ xml: z2.enum(["embedded", "both"]).optional(),
81829
+ display_check: z2.enum(["warn", "strict"]).optional()
81830
+ }).strict();
81831
+
81588
81832
  // packages/engine/src/lib/office/errors.ts
81589
81833
  var officeLimits = {
81590
81834
  /** Entries in one container. */
@@ -81625,7 +81869,10 @@ function multipart(fields, file) {
81625
81869
  form.set("file", blob, name);
81626
81870
  for (const [key, value] of Object.entries(fields)) {
81627
81871
  if (value === void 0) continue;
81628
- form.set(key, typeof value === "string" ? value : typeof value === "object" ? JSON.stringify(value) : String(value));
81872
+ form.set(
81873
+ key,
81874
+ typeof value === "string" ? value : typeof value === "object" ? JSON.stringify(value) : String(value)
81875
+ );
81629
81876
  }
81630
81877
  return form;
81631
81878
  }
@@ -81655,7 +81902,10 @@ function randomKey() {
81655
81902
  if (c?.randomUUID) return c.randomUUID();
81656
81903
  return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
81657
81904
  }
81658
- var withKey = (options) => ({ ...options, idempotencyKey: options.idempotencyKey ?? randomKey() });
81905
+ var withKey = (options) => ({
81906
+ ...options,
81907
+ idempotencyKey: options.idempotencyKey ?? randomKey()
81908
+ });
81659
81909
  var idOf = (source) => typeof source === "string" ? source : source.id;
81660
81910
  var Formfeed = class {
81661
81911
  baseUrl;
@@ -81665,14 +81915,28 @@ var Formfeed = class {
81665
81915
  timeoutMs;
81666
81916
  extraHeaders;
81667
81917
  constructor(options) {
81668
- if (!options.apiKey) throw new FormfeedError("invalid_request", "apiKey is required", 0);
81918
+ if (!options.apiKey)
81919
+ throw new FormfeedError("invalid_request", "apiKey is required", 0);
81669
81920
  this.apiKey = options.apiKey;
81670
- this.baseUrl = (options.baseUrl ?? hosts[options.region ?? "eu"]).replace(/\/$/, "");
81921
+ this.baseUrl = (options.baseUrl ?? hosts[options.region ?? "eu"]).replace(
81922
+ /\/$/,
81923
+ ""
81924
+ );
81671
81925
  this.fetchImpl = options.fetch ?? globalThis.fetch;
81672
81926
  this.maxRetries = options.maxRetries ?? 3;
81673
81927
  this.timeoutMs = options.timeoutMs ?? 12e4;
81674
- this.extraHeaders = Object.fromEntries(Object.entries(options.headers ?? {}).map(([name, value]) => [name.toLowerCase(), value]));
81675
- if (!this.fetchImpl) throw new FormfeedError("invalid_request", "fetch is not available; pass options.fetch", 0);
81928
+ this.extraHeaders = Object.fromEntries(
81929
+ Object.entries(options.headers ?? {}).map(([name, value]) => [
81930
+ name.toLowerCase(),
81931
+ value
81932
+ ])
81933
+ );
81934
+ if (!this.fetchImpl)
81935
+ throw new FormfeedError(
81936
+ "invalid_request",
81937
+ "fetch is not available; pass options.fetch",
81938
+ 0
81939
+ );
81676
81940
  }
81677
81941
  renders = {
81678
81942
  /** Renders a template, HTML or URL. Sync by default; `mode: 'async'` returns a queued render. */
@@ -81680,16 +81944,26 @@ var Formfeed = class {
81680
81944
  ...options,
81681
81945
  idempotencyKey: options.idempotencyKey ?? randomKey()
81682
81946
  }),
81683
- get: (id, options = {}) => this.request("GET", `/renders/${encodeURIComponent(id)}`, void 0, options),
81947
+ get: (id, options = {}) => this.request(
81948
+ "GET",
81949
+ `/renders/${encodeURIComponent(id)}`,
81950
+ void 0,
81951
+ options
81952
+ ),
81684
81953
  /** Polls until the render succeeded or failed (async renders). */
81685
81954
  waitFor: async (id, options = {}) => {
81686
81955
  const deadline = Date.now() + (options.timeoutMs ?? 12e4);
81687
81956
  const interval = options.intervalMs ?? 1e3;
81688
81957
  for (; ; ) {
81689
81958
  const render = await this.renders.get(id, { signal: options.signal });
81690
- if (render.status === "succeeded" || render.status === "failed") return render;
81959
+ if (render.status === "succeeded" || render.status === "failed")
81960
+ return render;
81691
81961
  if (Date.now() + interval > deadline)
81692
- throw new FormfeedError("timeout", `render ${id} did not finish within the wait time`, 0);
81962
+ throw new FormfeedError(
81963
+ "timeout",
81964
+ `render ${id} did not finish within the wait time`,
81965
+ 0
81966
+ );
81693
81967
  await sleep(interval, options.signal);
81694
81968
  }
81695
81969
  },
@@ -81697,17 +81971,34 @@ var Formfeed = class {
81697
81971
  download: async (render, options = {}) => {
81698
81972
  const target = typeof render === "string" ? await this.renders.get(render, options) : render;
81699
81973
  if (!target.download_url)
81700
- throw new FormfeedError("not_ready", `render ${target.id} has no output (${target.status})`, 0);
81701
- const res = await this.fetchImpl(target.download_url, { signal: options.signal });
81702
- if (!res.ok) throw new FormfeedError("download_failed", `download answered HTTP ${res.status}`, res.status);
81974
+ throw new FormfeedError(
81975
+ "not_ready",
81976
+ `render ${target.id} has no output (${target.status})`,
81977
+ 0
81978
+ );
81979
+ const res = await this.fetchImpl(target.download_url, {
81980
+ signal: options.signal
81981
+ });
81982
+ if (!res.ok)
81983
+ throw new FormfeedError(
81984
+ "download_failed",
81985
+ `download answered HTTP ${res.status}`,
81986
+ res.status
81987
+ );
81703
81988
  return new Uint8Array(await res.arrayBuffer());
81704
81989
  },
81705
81990
  /** Page of renders, newest first. */
81706
81991
  list: (query = {}, options = {}) => {
81707
81992
  const params = new URLSearchParams();
81708
- for (const [k2, v2] of Object.entries(query)) if (v2 !== void 0 && v2 !== null && v2 !== "") params.set(k2, String(v2));
81993
+ for (const [k2, v2] of Object.entries(query))
81994
+ if (v2 !== void 0 && v2 !== null && v2 !== "") params.set(k2, String(v2));
81709
81995
  const qs = params.toString();
81710
- return this.request("GET", `/renders${qs ? `?${qs}` : ""}`, void 0, options);
81996
+ return this.request(
81997
+ "GET",
81998
+ `/renders${qs ? `?${qs}` : ""}`,
81999
+ void 0,
82000
+ options
82001
+ );
81711
82002
  },
81712
82003
  /** Every render matching the query, following the cursor. */
81713
82004
  all: async (query = {}, options = {}) => {
@@ -81721,12 +82012,22 @@ var Formfeed = class {
81721
82012
  return out;
81722
82013
  },
81723
82014
  /** Removes the stored files of a render before they expire. Needs the `file:delete` scope. */
81724
- deleteOutputs: (id, options = {}) => this.request("DELETE", `/renders/${encodeURIComponent(id)}/outputs`, void 0, options),
82015
+ deleteOutputs: (id, options = {}) => this.request(
82016
+ "DELETE",
82017
+ `/renders/${encodeURIComponent(id)}/outputs`,
82018
+ void 0,
82019
+ options
82020
+ ),
81725
82021
  /**
81726
82022
  * The stored request of a render, to render it again. Needs `render:input`; throws
81727
82023
  * `render_input_expired` (410) when the workspace keeps no requests or the period ended.
81728
82024
  */
81729
- input: (id, options = {}) => this.request("GET", `/renders/${encodeURIComponent(id)}/input`, void 0, options),
82025
+ input: (id, options = {}) => this.request(
82026
+ "GET",
82027
+ `/renders/${encodeURIComponent(id)}/input`,
82028
+ void 0,
82029
+ options
82030
+ ),
81730
82031
  batch: (request, options = {}) => this.request("POST", "/renders/batch", request, {
81731
82032
  ...options,
81732
82033
  idempotencyKey: options.idempotencyKey ?? randomKey()
@@ -81738,10 +82039,30 @@ var Formfeed = class {
81738
82039
  * 0.5 units each on live keys; info is free.
81739
82040
  */
81740
82041
  pdf = {
81741
- merge: (sources, output = {}, options = {}) => this.request("POST", "/pdf/merge", { ...output, sources: sources.map(idOf) }, withKey(options)),
81742
- protect: (source, protect, options = {}) => this.request("POST", "/pdf/protect", { ...protect, source: idOf(source) }, withKey(options)),
81743
- watermark: (source, watermark, options = {}) => this.request("POST", "/pdf/watermark", { ...watermark, source: idOf(source) }, withKey(options)),
81744
- info: (source, options = {}) => this.request("POST", "/pdf/info", { source: idOf(source) }, options),
82042
+ merge: (sources, output = {}, options = {}) => this.request(
82043
+ "POST",
82044
+ "/pdf/merge",
82045
+ { ...output, sources: sources.map(idOf) },
82046
+ withKey(options)
82047
+ ),
82048
+ protect: (source, protect, options = {}) => this.request(
82049
+ "POST",
82050
+ "/pdf/protect",
82051
+ { ...protect, source: idOf(source) },
82052
+ withKey(options)
82053
+ ),
82054
+ watermark: (source, watermark, options = {}) => this.request(
82055
+ "POST",
82056
+ "/pdf/watermark",
82057
+ { ...watermark, source: idOf(source) },
82058
+ withKey(options)
82059
+ ),
82060
+ info: (source, options = {}) => this.request(
82061
+ "POST",
82062
+ "/pdf/info",
82063
+ { source: idOf(source) },
82064
+ options
82065
+ ),
81745
82066
  /**
81746
82067
  * Converts an office document to a PDF render (Starter plan and above): an uploaded file (Word,
81747
82068
  * Excel, PowerPoint, OpenDocument, RTF or HTML, up to 20 MB, not kept), or the output of a Word or
@@ -81750,8 +82071,18 @@ var Formfeed = class {
81750
82071
  */
81751
82072
  convert: (source, convert = {}, options = {}) => {
81752
82073
  if (typeof source === "object" && "file" in source)
81753
- return this.request("POST", "/pdf/convert", multipart({ ...convert }, source.file), withKey(options));
81754
- return this.request("POST", "/pdf/convert", { ...convert, source: idOf(source) }, withKey(options));
82074
+ return this.request(
82075
+ "POST",
82076
+ "/pdf/convert",
82077
+ multipart({ ...convert }, source.file),
82078
+ withKey(options)
82079
+ );
82080
+ return this.request(
82081
+ "POST",
82082
+ "/pdf/convert",
82083
+ { ...convert, source: idOf(source) },
82084
+ withKey(options)
82085
+ );
81755
82086
  }
81756
82087
  };
81757
82088
  /**
@@ -81763,7 +82094,10 @@ var Formfeed = class {
81763
82094
  files = {
81764
82095
  /** Uploads a file; the same name replaces the existing file in place and keeps its URL. */
81765
82096
  upload: (file, options = {}) => {
81766
- const blob = file.data instanceof Blob ? file.data : new Blob([file.data], file.contentType ? { type: file.contentType } : {});
82097
+ const blob = file.data instanceof Blob ? file.data : new Blob(
82098
+ [file.data],
82099
+ file.contentType ? { type: file.contentType } : {}
82100
+ );
81767
82101
  const form = new FormData();
81768
82102
  form.set("file", blob, file.name);
81769
82103
  form.set("name", file.name);
@@ -81772,9 +82106,15 @@ var Formfeed = class {
81772
82106
  /** Page of files, newest first. */
81773
82107
  list: (query = {}, options = {}) => {
81774
82108
  const params = new URLSearchParams();
81775
- for (const [k2, v2] of Object.entries(query)) if (v2 !== void 0 && v2 !== null && v2 !== "") params.set(k2, String(v2));
82109
+ for (const [k2, v2] of Object.entries(query))
82110
+ if (v2 !== void 0 && v2 !== null && v2 !== "") params.set(k2, String(v2));
81776
82111
  const qs = params.toString();
81777
- return this.request("GET", `/files${qs ? `?${qs}` : ""}`, void 0, options);
82112
+ return this.request(
82113
+ "GET",
82114
+ `/files${qs ? `?${qs}` : ""}`,
82115
+ void 0,
82116
+ options
82117
+ );
81778
82118
  },
81779
82119
  /** Every file matching the query, following the cursor. */
81780
82120
  all: async (query = {}, options = {}) => {
@@ -81787,9 +82127,19 @@ var Formfeed = class {
81787
82127
  } while (cursor);
81788
82128
  return out;
81789
82129
  },
81790
- get: (id, options = {}) => this.request("GET", `/files/${encodeURIComponent(id)}`, void 0, options),
82130
+ get: (id, options = {}) => this.request(
82131
+ "GET",
82132
+ `/files/${encodeURIComponent(id)}`,
82133
+ void 0,
82134
+ options
82135
+ ),
81791
82136
  /** Removes the file and its bytes; templates that name it render a missing image afterwards. */
81792
- delete: (file, options = {}) => this.request("DELETE", `/files/${encodeURIComponent(idOf(file))}`, void 0, options)
82137
+ delete: (file, options = {}) => this.request(
82138
+ "DELETE",
82139
+ `/files/${encodeURIComponent(idOf(file))}`,
82140
+ void 0,
82141
+ options
82142
+ )
81793
82143
  };
81794
82144
  /** The organisation's brand kit, read-only through the API (it is edited in the app). Needs `template:read`. */
81795
82145
  brand = {
@@ -81801,19 +82151,44 @@ var Formfeed = class {
81801
82151
  */
81802
82152
  partials = {
81803
82153
  /** Every shared partial, without its source. */
81804
- list: async (options = {}) => (await this.request("GET", "/partials", void 0, options)).data,
82154
+ list: async (options = {}) => (await this.request(
82155
+ "GET",
82156
+ "/partials",
82157
+ void 0,
82158
+ options
82159
+ )).data,
81805
82160
  /** One partial with its source. */
81806
- get: (name, options = {}) => this.request("GET", `/partials/${encodeURIComponent(name)}`, void 0, options),
82161
+ get: (name, options = {}) => this.request(
82162
+ "GET",
82163
+ `/partials/${encodeURIComponent(name)}`,
82164
+ void 0,
82165
+ options
82166
+ ),
81807
82167
  /** Creates or replaces a partial; pass `base_version` to fail with 409 when it changed since you read it. */
81808
82168
  put: async (name, input, options = {}) => {
81809
- const { status, body } = await this.send("PUT", `/partials/${encodeURIComponent(name)}`, input, options);
82169
+ const { status, body } = await this.send(
82170
+ "PUT",
82171
+ `/partials/${encodeURIComponent(name)}`,
82172
+ input,
82173
+ options
82174
+ );
81810
82175
  return { partial: body, created: status === 201 };
81811
82176
  },
81812
82177
  /** Removes a partial; templates that still include it fail to render afterwards. */
81813
- delete: (name, options = {}) => this.request("DELETE", `/partials/${encodeURIComponent(name)}`, void 0, options)
82178
+ delete: (name, options = {}) => this.request(
82179
+ "DELETE",
82180
+ `/partials/${encodeURIComponent(name)}`,
82181
+ void 0,
82182
+ options
82183
+ )
81814
82184
  };
81815
82185
  jobs = {
81816
- get: (id, options = {}) => this.request("GET", `/jobs/${encodeURIComponent(id)}`, void 0, options),
82186
+ get: (id, options = {}) => this.request(
82187
+ "GET",
82188
+ `/jobs/${encodeURIComponent(id)}`,
82189
+ void 0,
82190
+ options
82191
+ ),
81817
82192
  waitFor: async (id, options = {}) => {
81818
82193
  const deadline = Date.now() + (options.timeoutMs ?? 6e5);
81819
82194
  const interval = options.intervalMs ?? 2e3;
@@ -81821,37 +82196,77 @@ var Formfeed = class {
81821
82196
  const job = await this.jobs.get(id, { signal: options.signal });
81822
82197
  if (job.status !== "queued" && job.status !== "processing") return job;
81823
82198
  if (Date.now() + interval > deadline)
81824
- throw new FormfeedError("timeout", `job ${id} did not finish within the wait time`, 0);
82199
+ throw new FormfeedError(
82200
+ "timeout",
82201
+ `job ${id} did not finish within the wait time`,
82202
+ 0
82203
+ );
81825
82204
  await sleep(interval, options.signal);
81826
82205
  }
81827
82206
  }
81828
82207
  };
81829
82208
  webhooks = {
81830
- list: async (options = {}) => (await this.request("GET", "/webhooks", void 0, options)).data,
82209
+ list: async (options = {}) => (await this.request(
82210
+ "GET",
82211
+ "/webhooks",
82212
+ void 0,
82213
+ options
82214
+ )).data,
81831
82215
  create: (input, options = {}) => this.request("POST", "/webhooks", input, options),
81832
- update: (id, patch, options = {}) => this.request("PUT", `/webhooks/${encodeURIComponent(id)}`, patch, options),
81833
- delete: (id, options = {}) => this.request("DELETE", `/webhooks/${encodeURIComponent(id)}`, void 0, options),
81834
- test: (id, options = {}) => this.request("POST", `/webhooks/${encodeURIComponent(id)}/test`, void 0, options),
82216
+ update: (id, patch, options = {}) => this.request(
82217
+ "PUT",
82218
+ `/webhooks/${encodeURIComponent(id)}`,
82219
+ patch,
82220
+ options
82221
+ ),
82222
+ delete: (id, options = {}) => this.request(
82223
+ "DELETE",
82224
+ `/webhooks/${encodeURIComponent(id)}`,
82225
+ void 0,
82226
+ options
82227
+ ),
82228
+ test: (id, options = {}) => this.request(
82229
+ "POST",
82230
+ `/webhooks/${encodeURIComponent(id)}/test`,
82231
+ void 0,
82232
+ options
82233
+ ),
81835
82234
  /**
81836
82235
  * Sends a stored event (`evt_…`) again as a new delivery to a registered endpoint (`webhook:manage`)
81837
82236
  * or a running listen session (`webhook:listen`).
81838
82237
  */
81839
- resend: (eventId, endpointId, options = {}) => this.request("POST", `/webhooks/events/${encodeURIComponent(eventId)}/resend`, { endpoint_id: endpointId }, options),
82238
+ resend: (eventId, endpointId, options = {}) => this.request(
82239
+ "POST",
82240
+ `/webhooks/events/${encodeURIComponent(eventId)}/resend`,
82241
+ { endpoint_id: endpointId },
82242
+ options
82243
+ ),
81840
82244
  /**
81841
82245
  * Listen sessions, what `formfeed listen` uses. Needs `webhook:listen`. Starting a session ends the
81842
82246
  * previous one of the same key; the WebSocket itself is up to the caller.
81843
82247
  */
81844
82248
  listen: {
81845
82249
  start: (input = {}, options = {}) => this.request("POST", "/webhooks/listen", input, options),
81846
- end: (id, options = {}) => this.request("DELETE", `/webhooks/listen/${encodeURIComponent(id)}`, void 0, options)
82250
+ end: (id, options = {}) => this.request(
82251
+ "DELETE",
82252
+ `/webhooks/listen/${encodeURIComponent(id)}`,
82253
+ void 0,
82254
+ options
82255
+ )
81847
82256
  }
81848
82257
  };
81849
82258
  templates = {
81850
82259
  list: (query = {}, options = {}) => {
81851
82260
  const params = new URLSearchParams();
81852
- for (const [k2, v2] of Object.entries(query)) if (v2 !== void 0 && v2 !== null && v2 !== "") params.set(k2, String(v2));
82261
+ for (const [k2, v2] of Object.entries(query))
82262
+ if (v2 !== void 0 && v2 !== null && v2 !== "") params.set(k2, String(v2));
81853
82263
  const qs = params.toString();
81854
- return this.request("GET", `/templates${qs ? `?${qs}` : ""}`, void 0, options);
82264
+ return this.request(
82265
+ "GET",
82266
+ `/templates${qs ? `?${qs}` : ""}`,
82267
+ void 0,
82268
+ options
82269
+ );
81855
82270
  },
81856
82271
  /** Every template of the workspace, following the cursor. */
81857
82272
  all: async (query = {}, options = {}) => {
@@ -81864,27 +82279,63 @@ var Formfeed = class {
81864
82279
  } while (cursor);
81865
82280
  return out;
81866
82281
  },
81867
- get: (idOrSlug, options = {}) => this.request("GET", `/templates/${encodeURIComponent(idOrSlug)}`, void 0, options),
82282
+ get: (idOrSlug, options = {}) => this.request(
82283
+ "GET",
82284
+ `/templates/${encodeURIComponent(idOrSlug)}`,
82285
+ void 0,
82286
+ options
82287
+ ),
81868
82288
  /** A Word or PowerPoint template (`kind` `docx` or `pptx`) is created from its `file`, sent as multipart. */
81869
82289
  create: (input, options = {}) => {
81870
82290
  if (isOfficeInput(input) && input.file) {
81871
82291
  const { file, ...fields } = input;
81872
- return this.request("POST", "/templates", multipart(fields, file), options);
82292
+ return this.request(
82293
+ "POST",
82294
+ "/templates",
82295
+ multipart(fields, file),
82296
+ options
82297
+ );
81873
82298
  }
81874
82299
  return this.request("POST", "/templates", input, options);
81875
82300
  },
81876
- update: (idOrSlug, patch, options = {}) => this.request("PUT", `/templates/${encodeURIComponent(idOrSlug)}`, patch, options),
81877
- archive: (idOrSlug, options = {}) => this.request("DELETE", `/templates/${encodeURIComponent(idOrSlug)}`, void 0, options),
82301
+ update: (idOrSlug, patch, options = {}) => this.request(
82302
+ "PUT",
82303
+ `/templates/${encodeURIComponent(idOrSlug)}`,
82304
+ patch,
82305
+ options
82306
+ ),
82307
+ archive: (idOrSlug, options = {}) => this.request(
82308
+ "DELETE",
82309
+ `/templates/${encodeURIComponent(idOrSlug)}`,
82310
+ void 0,
82311
+ options
82312
+ ),
81878
82313
  versions: {
81879
- list: async (idOrSlug, options = {}) => (await this.request("GET", `/templates/${encodeURIComponent(idOrSlug)}/versions`, void 0, options)).data,
82314
+ list: async (idOrSlug, options = {}) => (await this.request(
82315
+ "GET",
82316
+ `/templates/${encodeURIComponent(idOrSlug)}/versions`,
82317
+ void 0,
82318
+ options
82319
+ )).data,
81880
82320
  /** `which`: 'published', 'latest', a version number or a channel name (its main version). Carries the files. */
81881
- get: (idOrSlug, which = "published", options = {}) => this.request("GET", `/templates/${encodeURIComponent(idOrSlug)}/versions/${encodeURIComponent(String(which))}`, void 0, options),
82321
+ get: (idOrSlug, which = "published", options = {}) => this.request(
82322
+ "GET",
82323
+ `/templates/${encodeURIComponent(idOrSlug)}/versions/${encodeURIComponent(String(which))}`,
82324
+ void 0,
82325
+ options
82326
+ ),
81882
82327
  /** For a Word or PowerPoint template, pass `file` to replace the document; without it the latest file is kept. */
81883
82328
  create: (idOrSlug, input, options = {}) => {
81884
82329
  const path = `/templates/${encodeURIComponent(idOrSlug)}/versions`;
81885
82330
  if (isOfficeInput(input)) {
81886
82331
  const { file, ...fields } = input;
81887
- if (file) return this.request("POST", path, multipart(fields, file), options);
82332
+ if (file)
82333
+ return this.request(
82334
+ "POST",
82335
+ path,
82336
+ multipart(fields, file),
82337
+ options
82338
+ );
81888
82339
  return this.request("POST", path, fields, options);
81889
82340
  }
81890
82341
  return this.request("POST", path, input, options);
@@ -81913,7 +82364,12 @@ var Formfeed = class {
81913
82364
  * uses the version the channel points at. Moves reach renders within a minute.
81914
82365
  */
81915
82366
  channels: {
81916
- list: (idOrSlug, options = {}) => this.request("GET", `/templates/${encodeURIComponent(idOrSlug)}/channels`, void 0, options),
82367
+ list: (idOrSlug, options = {}) => this.request(
82368
+ "GET",
82369
+ `/templates/${encodeURIComponent(idOrSlug)}/channels`,
82370
+ void 0,
82371
+ options
82372
+ ),
81917
82373
  /** Creates or moves a channel; on `published` this publishes. */
81918
82374
  set: (idOrSlug, name, move, options = {}) => {
81919
82375
  const { allowBreaking, ...rest } = options;
@@ -81947,19 +82403,39 @@ var Formfeed = class {
81947
82403
  schema: (idOrSlug, options = {}) => {
81948
82404
  const { version, ...rest } = options;
81949
82405
  const query = version === void 0 ? "" : `?version=${encodeURIComponent(String(version))}`;
81950
- return this.request("GET", `/templates/${encodeURIComponent(idOrSlug)}/schema${query}`, void 0, rest);
82406
+ return this.request(
82407
+ "GET",
82408
+ `/templates/${encodeURIComponent(idOrSlug)}/schema${query}`,
82409
+ void 0,
82410
+ rest
82411
+ );
81951
82412
  },
81952
82413
  /**
81953
82414
  * Checks a version with data without rendering: syntax, header and footer, missing partials,
81954
82415
  * runtime errors and the data against the stored schema. Free. Without `data`, the version's
81955
82416
  * sample data is checked. `version` takes a channel name too.
81956
82417
  */
81957
- validate: (idOrSlug, input = {}, options = {}) => this.request("POST", `/templates/${encodeURIComponent(idOrSlug)}/validate`, input, options)
82418
+ validate: (idOrSlug, input = {}, options = {}) => this.request(
82419
+ "POST",
82420
+ `/templates/${encodeURIComponent(idOrSlug)}/validate`,
82421
+ input,
82422
+ options
82423
+ )
81958
82424
  };
81959
82425
  account = {
81960
- get: (options = {}) => this.request("GET", "/account", void 0, options),
82426
+ get: (options = {}) => this.request(
82427
+ "GET",
82428
+ "/account",
82429
+ void 0,
82430
+ options
82431
+ ),
81961
82432
  /** Units of the current period, or of `YYYY-MM`, with a daily series and a breakdown per template. */
81962
- usage: (period = "current", options = {}) => this.request("GET", `/usage?period=${encodeURIComponent(period)}`, void 0, options)
82433
+ usage: (period2 = "current", options = {}) => this.request(
82434
+ "GET",
82435
+ `/usage?period=${encodeURIComponent(period2)}`,
82436
+ void 0,
82437
+ options
82438
+ )
81963
82439
  };
81964
82440
  /** Workspaces of the key's organisation. Needs `workspace:delete`, which no key has by default. */
81965
82441
  workspaces = {
@@ -81967,7 +82443,12 @@ var Formfeed = class {
81967
82443
  * Deletes a workspace: it leaves the app and the API at once, its keys are revoked and its content
81968
82444
  * is removed after 30 days. The organisation's last workspace is refused with `last_workspace`.
81969
82445
  */
81970
- delete: (id, options = {}) => this.request("DELETE", `/workspaces/${encodeURIComponent(id)}`, void 0, options)
82446
+ delete: (id, options = {}) => this.request(
82447
+ "DELETE",
82448
+ `/workspaces/${encodeURIComponent(id)}`,
82449
+ void 0,
82450
+ options
82451
+ )
81971
82452
  };
81972
82453
  channelAction(idOrSlug, name, action, options) {
81973
82454
  const { allowBreaking, ...rest } = options;
@@ -81995,13 +82476,21 @@ var Formfeed = class {
81995
82476
  ...this.extraHeaders
81996
82477
  };
81997
82478
  const isForm = typeof FormData !== "undefined" && body instanceof FormData;
81998
- if (body !== void 0 && !isForm) headers["content-type"] = "application/json";
81999
- if (options.idempotencyKey) headers["idempotency-key"] = options.idempotencyKey;
82479
+ if (body !== void 0 && !isForm)
82480
+ headers["content-type"] = "application/json";
82481
+ if (options.idempotencyKey)
82482
+ headers["idempotency-key"] = options.idempotencyKey;
82000
82483
  let attempt = 0;
82001
82484
  for (; ; ) {
82002
82485
  const controller = new AbortController();
82003
- const timer = setTimeout(() => controller.abort(new Error("request timed out")), this.timeoutMs);
82004
- options.signal?.addEventListener("abort", () => controller.abort(options.signal?.reason));
82486
+ const timer = setTimeout(
82487
+ () => controller.abort(new Error("request timed out")),
82488
+ this.timeoutMs
82489
+ );
82490
+ options.signal?.addEventListener(
82491
+ "abort",
82492
+ () => controller.abort(options.signal?.reason)
82493
+ );
82005
82494
  let res;
82006
82495
  try {
82007
82496
  res = await this.fetchImpl(url, {
@@ -82017,22 +82506,38 @@ var Formfeed = class {
82017
82506
  await sleep(this.backoff(attempt, null), options.signal);
82018
82507
  continue;
82019
82508
  }
82020
- throw new FormfeedError("network_error", e instanceof Error ? e.message : String(e), 0);
82509
+ throw new FormfeedError(
82510
+ "network_error",
82511
+ e instanceof Error ? e.message : String(e),
82512
+ 0
82513
+ );
82021
82514
  }
82022
82515
  clearTimeout(timer);
82023
82516
  if ((res.status === 429 || res.status === 503) && attempt < this.maxRetries) {
82024
82517
  attempt++;
82025
- await sleep(this.backoff(attempt, res.headers.get("retry-after")), options.signal);
82518
+ await sleep(
82519
+ this.backoff(attempt, res.headers.get("retry-after")),
82520
+ options.signal
82521
+ );
82026
82522
  continue;
82027
82523
  }
82028
82524
  if (res.status === 204) return { status: 204, body: void 0 };
82029
- if (as === "bytes" && res.ok) return { status: res.status, body: new Uint8Array(await res.arrayBuffer()) };
82030
- const text3 = await res.text();
82525
+ if (as === "bytes" && res.ok)
82526
+ return {
82527
+ status: res.status,
82528
+ body: new Uint8Array(await res.arrayBuffer())
82529
+ };
82530
+ const text4 = await res.text();
82031
82531
  let json2 = null;
82032
82532
  try {
82033
- json2 = text3 ? JSON.parse(text3) : null;
82533
+ json2 = text4 ? JSON.parse(text4) : null;
82034
82534
  } catch {
82035
- if (res.ok) throw new FormfeedError("invalid_response", `the API answered HTTP ${res.status} with a body that is not JSON`, res.status);
82535
+ if (res.ok)
82536
+ throw new FormfeedError(
82537
+ "invalid_response",
82538
+ `the API answered HTTP ${res.status} with a body that is not JSON`,
82539
+ res.status
82540
+ );
82036
82541
  }
82037
82542
  if (!res.ok) {
82038
82543
  const problem = json2 ?? {};
@@ -82058,14 +82563,23 @@ var Formfeed = class {
82058
82563
  var encoder2 = new TextEncoder();
82059
82564
 
82060
82565
  // packages/mcp/src/lib/server.ts
82061
- import { z as z2 } from "zod";
82566
+ import { z as z3 } from "zod";
82062
82567
  var CONVERT_LIMIT_BYTES = 20 * 1024 * 1024;
82063
- var SERVER_INFO = { name: "formfeed", version: "0.3.11" };
82064
- var READS = { readOnlyHint: true, destructiveHint: false, openWorldHint: false };
82065
- var CREATES = { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false };
82066
- var engineSchema = z2.enum(["jinja2", "liquid", "handlebars"]);
82067
- var outputSchema = z2.enum(outputFormats);
82068
- var kindSchema = z2.enum(["pdf", "image", "docx", "pptx"]);
82568
+ var SERVER_INFO = { name: "formfeed", version: "0.3.13" };
82569
+ var READS = {
82570
+ readOnlyHint: true,
82571
+ destructiveHint: false,
82572
+ openWorldHint: false
82573
+ };
82574
+ var CREATES = {
82575
+ readOnlyHint: false,
82576
+ destructiveHint: false,
82577
+ idempotentHint: false,
82578
+ openWorldHint: false
82579
+ };
82580
+ var engineSchema = z3.enum(["jinja2", "liquid", "handlebars"]);
82581
+ var outputSchema = z3.enum(outputFormats);
82582
+ var kindSchema = z3.enum(["pdf", "image", "docx", "pptx"]);
82069
82583
  var templateSummary = (t) => ({
82070
82584
  id: t.id,
82071
82585
  slug: t.slug,
@@ -82086,19 +82600,38 @@ var renderSummary = (r) => ({
82086
82600
  units: r.units,
82087
82601
  environment: r.environment,
82088
82602
  template: r.template,
82089
- error: r.error
82603
+ error: r.error,
82604
+ // the validator's verdict of a render whose template declares PDF/UA-1 (plan 21): whether the
82605
+ // file passed, and for each failed rule what to change and in which elements
82606
+ ...r.accessibility ? { accessibility: r.accessibility } : {}
82090
82607
  });
82091
- function text2(data) {
82092
- return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }], structuredContent: data };
82608
+ function text3(data) {
82609
+ return {
82610
+ content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
82611
+ structuredContent: data
82612
+ };
82093
82613
  }
82094
82614
  function failure(e) {
82095
82615
  const message2 = e instanceof FormfeedError ? `${e.code}: ${e.message}` : e instanceof Error ? e.message : String(e);
82096
- return { content: [{ type: "text", text: message2 }], isError: true };
82616
+ const verdict = e instanceof FormfeedError && e.code === "pdfua_validation_failed" ? e.problem?.["accessibility"] : void 0;
82617
+ return {
82618
+ content: [
82619
+ {
82620
+ type: "text",
82621
+ text: verdict ? `${message2}
82622
+ ${JSON.stringify({ accessibility: verdict }, null, 2)}` : message2
82623
+ }
82624
+ ],
82625
+ isError: true
82626
+ };
82097
82627
  }
82098
82628
  function createFormfeedServer(options) {
82099
82629
  const client = new Formfeed({
82100
82630
  apiKey: options.apiKey,
82101
- headers: { "user-agent": `formfeed-mcp/${SERVER_INFO.version}`, ...options.workspaceId ? { "x-formfeed-workspace": options.workspaceId } : {} },
82631
+ headers: {
82632
+ "user-agent": `formfeed-mcp/${SERVER_INFO.version}`,
82633
+ ...options.workspaceId ? { "x-formfeed-workspace": options.workspaceId } : {}
82634
+ },
82102
82635
  ...options.region ? { region: options.region } : {},
82103
82636
  ...options.baseUrl ? { baseUrl: options.baseUrl } : {},
82104
82637
  ...options.fetch ? { fetch: options.fetch } : {}
@@ -82114,15 +82647,19 @@ function createFormfeedServer(options) {
82114
82647
  inputSchema: {
82115
82648
  kind: kindSchema.optional().describe("Only templates that produce this kind of document"),
82116
82649
  engine: engineSchema.optional().describe("Only templates written in this template language"),
82117
- tag: z2.string().optional().describe("Only templates with this tag; exact match, tags are lowercase with dashes (e.g. billing)"),
82118
- q: z2.string().optional().describe("Text to find in the name or slug, case-insensitive (e.g. invoice)")
82650
+ tag: z3.string().optional().describe(
82651
+ "Only templates with this tag; exact match, tags are lowercase with dashes (e.g. billing)"
82652
+ ),
82653
+ q: z3.string().optional().describe(
82654
+ "Text to find in the name or slug, case-insensitive (e.g. invoice)"
82655
+ )
82119
82656
  },
82120
82657
  annotations: READS
82121
82658
  },
82122
82659
  async (args2) => {
82123
82660
  try {
82124
82661
  const templates = await client.templates.all(args2);
82125
- return text2({ templates: templates.map(templateSummary) });
82662
+ return text3({ templates: templates.map(templateSummary) });
82126
82663
  } catch (e) {
82127
82664
  return failure(e);
82128
82665
  }
@@ -82133,17 +82670,28 @@ function createFormfeedServer(options) {
82133
82670
  {
82134
82671
  title: "Get the data schema of a template",
82135
82672
  description: "Returns the JSON Schema of the `data` object a template expects and the sample data it was designed with, from its published version, else its latest draft. Call it after list_templates and before render or validate_template, to build data that fits; ad-hoc html has no stored schema to read. When the template stores no schema, one is inferred from the sample data: treat that as a guide, not a contract. Read-only and free; an unknown slug returns an error.",
82136
- inputSchema: { template: z2.string().describe("Slug (e.g. invoice) or tpl_ id, as list_templates returns them") },
82673
+ inputSchema: {
82674
+ template: z3.string().describe(
82675
+ "Slug (e.g. invoice) or tpl_ id, as list_templates returns them"
82676
+ )
82677
+ },
82137
82678
  annotations: READS
82138
82679
  },
82139
82680
  async ({ template }) => {
82140
82681
  try {
82141
82682
  const version = await client.templates.versions.get(template, "published").catch(async (e) => {
82142
- if (e.status === 404) return client.templates.versions.get(template, "latest");
82683
+ if (e.status === 404)
82684
+ return client.templates.versions.get(template, "latest");
82143
82685
  throw e;
82144
82686
  });
82145
82687
  const schema = version.data_schema ?? inferSchema(version.sample_data ?? {});
82146
- return text2({ template, version: version.number, status: version.status, schema, sample_data: version.sample_data ?? {} });
82688
+ return text3({
82689
+ template,
82690
+ version: version.number,
82691
+ status: version.status,
82692
+ schema,
82693
+ sample_data: version.sample_data ?? {}
82694
+ });
82147
82695
  } catch (e) {
82148
82696
  return failure(e);
82149
82697
  }
@@ -82155,22 +82703,29 @@ function createFormfeedServer(options) {
82155
82703
  title: "Validate a template with data",
82156
82704
  description: "Checks a template and its data without rendering: free, no units, nothing stored, no document produced. Call it before render when you assembled the data yourself, or after writing ad-hoc html. With template, the API checks the published version (else the latest) as a render would: syntax, header and footer, errors only this data triggers, and the data against the stored JSON Schema (a wrong type or a missing required field is an error). With html and engine it compiles offline and reports syntax errors, unknown filters and variables missing from data. Returns ok and diagnostics (severity, code, message, plus path, line and column, or part and paragraph for Word and PowerPoint). Warnings leave ok true: settle each before rendering.",
82157
82705
  inputSchema: {
82158
- template: z2.string().optional().describe("Slug or tpl_ id of a stored template; pass this or html"),
82159
- html: z2.string().optional().describe("Template source to check offline, when there is no stored template; pass this or template"),
82706
+ template: z3.string().optional().describe("Slug or tpl_ id of a stored template; pass this or html"),
82707
+ html: z3.string().optional().describe(
82708
+ "Template source to check offline, when there is no stored template; pass this or template"
82709
+ ),
82160
82710
  engine: engineSchema.optional().describe("Template language of html; required with html"),
82161
- data: z2.record(z2.string(), z2.unknown()).optional().describe("The data the document will be rendered with, shaped as get_template_schema describes. Left out, a stored template is checked with its sample data")
82711
+ data: z3.record(z3.string(), z3.unknown()).optional().describe(
82712
+ "The data the document will be rendered with, shaped as get_template_schema describes. Left out, a stored template is checked with its sample data"
82713
+ )
82162
82714
  },
82163
82715
  annotations: READS
82164
82716
  },
82165
82717
  async ({ template, html, engine, data }) => {
82166
82718
  try {
82167
82719
  if (template) {
82168
- const check = (version) => client.templates.validate(template, { version, ...data ? { data } : {} });
82720
+ const check = (version) => client.templates.validate(template, {
82721
+ version,
82722
+ ...data ? { data } : {}
82723
+ });
82169
82724
  const result = await check("published").catch((e) => {
82170
82725
  if (e.status === 404) return check("latest");
82171
82726
  throw e;
82172
82727
  });
82173
- return text2({
82728
+ return text3({
82174
82729
  ok: result.ok,
82175
82730
  template: result.template,
82176
82731
  diagnostics: result.diagnostics.map((d) => ({
@@ -82183,18 +82738,35 @@ function createFormfeedServer(options) {
82183
82738
  }))
82184
82739
  });
82185
82740
  }
82186
- if (!html || !engine) return failure(new Error("Pass a template slug, or html and engine"));
82741
+ if (!html || !engine)
82742
+ return failure(new Error("Pass a template slug, or html and engine"));
82187
82743
  const eng = getEngine(engine);
82188
82744
  const diagnostics = [];
82189
82745
  try {
82190
82746
  eng.compile(html, { name: "ad-hoc" });
82191
82747
  } catch (e) {
82192
- diagnostics.push({ severity: "error", code: "syntax-error", message: e instanceof Error ? e.message : String(e), range: { start: { line: 1, column: 1 }, end: { line: 1, column: 2 } } });
82748
+ diagnostics.push({
82749
+ severity: "error",
82750
+ code: "syntax-error",
82751
+ message: e instanceof Error ? e.message : String(e),
82752
+ range: {
82753
+ start: { line: 1, column: 1 },
82754
+ end: { line: 1, column: 2 }
82755
+ }
82756
+ });
82193
82757
  }
82194
- diagnostics.push(...eng.analyze(html, { sampleData: data ?? {} }).diagnostics);
82195
- return text2({
82758
+ diagnostics.push(
82759
+ ...eng.analyze(html, { sampleData: data ?? {} }).diagnostics
82760
+ );
82761
+ return text3({
82196
82762
  ok: !diagnostics.some((d) => d.severity === "error"),
82197
- diagnostics: diagnostics.map((d) => ({ severity: d.severity, code: d.code, message: d.message, line: d.range.start.line, column: d.range.start.column }))
82763
+ diagnostics: diagnostics.map((d) => ({
82764
+ severity: d.severity,
82765
+ code: d.code,
82766
+ message: d.message,
82767
+ line: d.range.start.line,
82768
+ column: d.range.start.column
82769
+ }))
82198
82770
  });
82199
82771
  } catch (e) {
82200
82772
  return failure(e);
@@ -82207,22 +82779,42 @@ function createFormfeedServer(options) {
82207
82779
  title: "Render a document",
82208
82780
  description: "Creates a document by filling a stored template, or ad-hoc html, with data: a PDF or image, or DOCX, PPTX or PDF from Word and PowerPoint templates. Returns the render with status and download_url. Use it to make a document from data; to turn an existing office file into a PDF, use convert_to_pdf. Stored templates render their published version, so one whose published_version is null fails with template_not_found. Every call is a new render: a live key consumes units, a test key is free (watermarked on the Free plan). A render that fails returns status failed and an error with code and message; validate_template finds most causes beforehand. The link expires at expires_at; get_render issues a fresh one.",
82209
82781
  inputSchema: {
82210
- template: z2.string().optional().describe("Slug or tpl_ id of a stored template; pass this or html"),
82211
- html: z2.string().optional().describe("A complete HTML document to render instead of a stored template, up to 5 MB"),
82212
- engine: engineSchema.optional().describe("Template language of html, when it contains expressions to fill from data"),
82213
- data: z2.record(z2.string(), z2.unknown()).optional().describe("Values for the template, shaped as get_template_schema describes; leave out when it needs none"),
82782
+ template: z3.string().optional().describe("Slug or tpl_ id of a stored template; pass this or html"),
82783
+ html: z3.string().optional().describe(
82784
+ "A complete HTML document to render instead of a stored template, up to 5 MB"
82785
+ ),
82786
+ engine: engineSchema.optional().describe(
82787
+ "Template language of html, when it contains expressions to fill from data"
82788
+ ),
82789
+ data: z3.record(z3.string(), z3.unknown()).optional().describe(
82790
+ "Values for the template, shaped as get_template_schema describes; leave out when it needs none"
82791
+ ),
82214
82792
  output: outputSchema.optional().describe(
82215
82793
  "Left out, the template decides: PDF for PDF templates and html, its image format for image templates, its default output for Word and PowerPoint templates. Word templates render docx or pdf, PowerPoint templates pptx or pdf"
82216
82794
  ),
82217
- filename: z2.string().optional().describe("Name of the file behind download_url, e.g. invoice-2026-0042.pdf"),
82218
- locale: z2.string().optional().describe("BCP 47 tag for helpers and translations, e.g. de-DE"),
82219
- wait: z2.boolean().default(true).describe("Most renders are finished when the call returns; true also waits for one that continues in the background, false returns it as it is (queued or rendering) to check later with get_render")
82795
+ filename: z3.string().optional().describe(
82796
+ "Name of the file behind download_url, e.g. invoice-2026-0042.pdf"
82797
+ ),
82798
+ locale: z3.string().optional().describe("BCP 47 tag for helpers and translations, e.g. de-DE"),
82799
+ wait: z3.boolean().default(true).describe(
82800
+ "Most renders are finished when the call returns; true also waits for one that continues in the background, false returns it as it is (queued or rendering) to check later with get_render"
82801
+ )
82220
82802
  },
82221
82803
  annotations: CREATES
82222
82804
  },
82223
- async ({ template, html, engine, data, output, filename, locale, wait }) => {
82805
+ async ({
82806
+ template,
82807
+ html,
82808
+ engine,
82809
+ data,
82810
+ output,
82811
+ filename,
82812
+ locale,
82813
+ wait
82814
+ }) => {
82224
82815
  try {
82225
- if (!template && !html) return failure(new Error("Pass template or html"));
82816
+ if (!template && !html)
82817
+ return failure(new Error("Pass template or html"));
82226
82818
  let render = await client.renders.create({
82227
82819
  ...template ? { template } : {},
82228
82820
  ...html ? { html } : {},
@@ -82233,8 +82825,9 @@ function createFormfeedServer(options) {
82233
82825
  ...locale ? { locale } : {},
82234
82826
  meta: { source: "mcp" }
82235
82827
  });
82236
- if (wait && render.status !== "succeeded" && render.status !== "failed") render = await client.renders.waitFor(render.id);
82237
- return text2(renderSummary(render));
82828
+ if (wait && render.status !== "succeeded" && render.status !== "failed")
82829
+ render = await client.renders.waitFor(render.id);
82830
+ return text3(renderSummary(render));
82238
82831
  } catch (e) {
82239
82832
  return failure(e);
82240
82833
  }
@@ -82252,23 +82845,46 @@ function createFormfeedServer(options) {
82252
82845
  "Every call is a new render that counts units like a PDF; the Free plan cannot convert (Starter and above). The document is converted and not kept."
82253
82846
  ].join(" "),
82254
82847
  inputSchema: {
82255
- render_id: z2.string().optional().describe("rnd_ id of a render whose output is docx or pptx, to get that document as a PDF"),
82256
- ...options.localFiles ? { path: z2.string().optional().describe("Absolute path of the document on this machine") } : {},
82257
- file_base64: z2.string().optional().describe("The document to convert, base64 encoded; needs file_name"),
82258
- file_name: z2.string().optional().describe("Name of the document, e.g. report.xlsx; the type is read from the content"),
82259
- page_ranges: z2.string().regex(/^\d+(-\d+)?(,\d+(-\d+)?)*$/).optional().describe("Pages to convert, e.g. 1-3,5; all pages when left out"),
82260
- landscape: z2.boolean().optional().describe("Landscape for spreadsheets and documents without their own page setup"),
82261
- single_page_sheets: z2.boolean().optional().describe("Each spreadsheet sheet on one page"),
82262
- filename: z2.string().optional().describe("Name of the PDF behind download_url, e.g. report.pdf")
82848
+ render_id: z3.string().optional().describe(
82849
+ "rnd_ id of a render whose output is docx or pptx, to get that document as a PDF"
82850
+ ),
82851
+ ...options.localFiles ? {
82852
+ path: z3.string().optional().describe("Absolute path of the document on this machine")
82853
+ } : {},
82854
+ file_base64: z3.string().optional().describe("The document to convert, base64 encoded; needs file_name"),
82855
+ file_name: z3.string().optional().describe(
82856
+ "Name of the document, e.g. report.xlsx; the type is read from the content"
82857
+ ),
82858
+ page_ranges: z3.string().regex(/^\d+(-\d+)?(,\d+(-\d+)?)*$/).optional().describe("Pages to convert, e.g. 1-3,5; all pages when left out"),
82859
+ landscape: z3.boolean().optional().describe(
82860
+ "Landscape for spreadsheets and documents without their own page setup"
82861
+ ),
82862
+ single_page_sheets: z3.boolean().optional().describe("Each spreadsheet sheet on one page"),
82863
+ filename: z3.string().optional().describe("Name of the PDF behind download_url, e.g. report.pdf")
82263
82864
  },
82264
82865
  annotations: CREATES
82265
82866
  },
82266
82867
  async (args2) => {
82267
82868
  try {
82268
- const { render_id, file_base64, file_name, page_ranges, landscape, single_page_sheets, filename } = args2;
82869
+ const {
82870
+ render_id,
82871
+ file_base64,
82872
+ file_name,
82873
+ page_ranges,
82874
+ landscape,
82875
+ single_page_sheets,
82876
+ filename
82877
+ } = args2;
82269
82878
  const path = args2.path;
82270
- const sources = [render_id, file_base64, path].filter((s) => s !== void 0 && s !== "");
82271
- if (sources.length !== 1) return failure(new Error("Pass exactly one of render_id, file_base64" + (options.localFiles ? " or path" : "")));
82879
+ const sources = [render_id, file_base64, path].filter(
82880
+ (s) => s !== void 0 && s !== ""
82881
+ );
82882
+ if (sources.length !== 1)
82883
+ return failure(
82884
+ new Error(
82885
+ "Pass exactly one of render_id, file_base64" + (options.localFiles ? " or path" : "")
82886
+ )
82887
+ );
82272
82888
  const convert = {
82273
82889
  meta: { source: "mcp" },
82274
82890
  ...page_ranges ? { page_ranges } : {},
@@ -82285,20 +82901,41 @@ function createFormfeedServer(options) {
82285
82901
  if (path) {
82286
82902
  const { readFile, stat } = await import("node:fs/promises");
82287
82903
  const { basename } = await import("node:path");
82288
- if ((await stat(path)).size > CONVERT_LIMIT_BYTES) return failure(new Error(`${path} is larger than 20 MB, the limit for conversions`));
82904
+ if ((await stat(path)).size > CONVERT_LIMIT_BYTES)
82905
+ return failure(
82906
+ new Error(
82907
+ `${path} is larger than 20 MB, the limit for conversions`
82908
+ )
82909
+ );
82289
82910
  data = new Uint8Array(await readFile(path));
82290
82911
  name = file_name ?? basename(path);
82291
82912
  } else {
82292
- if (!file_name) return failure(new Error("file_name is required with file_base64"));
82913
+ if (!file_name)
82914
+ return failure(
82915
+ new Error("file_name is required with file_base64")
82916
+ );
82293
82917
  data = Uint8Array.from(Buffer.from(file_base64, "base64"));
82294
- if (data.length === 0) return failure(new Error("file_base64 is empty or not base64"));
82295
- if (data.length > CONVERT_LIMIT_BYTES) return failure(new Error("The document is larger than 20 MB, the limit for conversions"));
82918
+ if (data.length === 0)
82919
+ return failure(new Error("file_base64 is empty or not base64"));
82920
+ if (data.length > CONVERT_LIMIT_BYTES)
82921
+ return failure(
82922
+ new Error(
82923
+ "The document is larger than 20 MB, the limit for conversions"
82924
+ )
82925
+ );
82296
82926
  name = file_name;
82297
82927
  }
82298
- render = await client.pdf.convert({ file: { data, name } }, { ...convert, ...filename ? {} : { filename: `${name.replace(/\.[^.]+$/, "")}.pdf` } });
82928
+ render = await client.pdf.convert(
82929
+ { file: { data, name } },
82930
+ {
82931
+ ...convert,
82932
+ ...filename ? {} : { filename: `${name.replace(/\.[^.]+$/, "")}.pdf` }
82933
+ }
82934
+ );
82299
82935
  }
82300
- if (render.status !== "succeeded" && render.status !== "failed") render = await client.renders.waitFor(render.id);
82301
- return text2(renderSummary(render));
82936
+ if (render.status !== "succeeded" && render.status !== "failed")
82937
+ render = await client.renders.waitFor(render.id);
82938
+ return text3(renderSummary(render));
82302
82939
  } catch (e) {
82303
82940
  return failure(e);
82304
82941
  }
@@ -82309,12 +82946,16 @@ function createFormfeedServer(options) {
82309
82946
  {
82310
82947
  title: "Get a render",
82311
82948
  description: "Returns the current state of a render: status (queued, rendering, succeeded or failed), download_url with expires_at, page_count, units and error. Use it to follow a render started with wait false, or to get a fresh link once the old one has expired; render and convert_to_pdf already return this for the render they just made. Read-only and free; an unknown id returns an error.",
82312
- inputSchema: { id: z2.string().describe("rnd_ id of the render, as render or convert_to_pdf returned it") },
82949
+ inputSchema: {
82950
+ id: z3.string().describe(
82951
+ "rnd_ id of the render, as render or convert_to_pdf returned it"
82952
+ )
82953
+ },
82313
82954
  annotations: READS
82314
82955
  },
82315
82956
  async ({ id }) => {
82316
82957
  try {
82317
- return text2(renderSummary(await client.renders.get(id)));
82958
+ return text3(renderSummary(await client.renders.get(id)));
82318
82959
  } catch (e) {
82319
82960
  return failure(e);
82320
82961
  }