@fenfill/mcp 0.2.2 → 0.2.3

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.
package/dist/index.js CHANGED
@@ -113,7 +113,7 @@ var require_code = __commonJS({
113
113
  }
114
114
  exports._ = _;
115
115
  var plus = new _Code("+");
116
- function str(strs, ...args) {
116
+ function str2(strs, ...args) {
117
117
  const expr = [safeStringify(strs[0])];
118
118
  let i2 = 0;
119
119
  while (i2 < args.length) {
@@ -124,7 +124,7 @@ var require_code = __commonJS({
124
124
  optimize(expr);
125
125
  return new _Code(expr);
126
126
  }
127
- exports.str = str;
127
+ exports.str = str2;
128
128
  function addCodeArg(code, arg) {
129
129
  if (arg instanceof _Code)
130
130
  code.push(...arg._items);
@@ -167,7 +167,7 @@ var require_code = __commonJS({
167
167
  return;
168
168
  }
169
169
  function strConcat(c1, c2) {
170
- return c2.emptyStr() ? c1 : c1.emptyStr() ? c2 : str`${c1}${c2}`;
170
+ return c2.emptyStr() ? c1 : c1.emptyStr() ? c2 : str2`${c1}${c2}`;
171
171
  }
172
172
  exports.strConcat = strConcat;
173
173
  function interpolate2(x2) {
@@ -1129,22 +1129,22 @@ var require_util = __commonJS({
1129
1129
  return (0, codegen_1._)`${topSchemaRef}${schemaPath}${(0, codegen_1.getProperty)(keyword)}`;
1130
1130
  }
1131
1131
  exports.schemaRefOrVal = schemaRefOrVal;
1132
- function unescapeFragment(str) {
1133
- return unescapeJsonPointer(decodeURIComponent(str));
1132
+ function unescapeFragment(str2) {
1133
+ return unescapeJsonPointer(decodeURIComponent(str2));
1134
1134
  }
1135
1135
  exports.unescapeFragment = unescapeFragment;
1136
- function escapeFragment(str) {
1137
- return encodeURIComponent(escapeJsonPointer(str));
1136
+ function escapeFragment(str2) {
1137
+ return encodeURIComponent(escapeJsonPointer(str2));
1138
1138
  }
1139
1139
  exports.escapeFragment = escapeFragment;
1140
- function escapeJsonPointer(str) {
1141
- if (typeof str == "number")
1142
- return `${str}`;
1143
- return str.replace(/~/g, "~0").replace(/\//g, "~1");
1140
+ function escapeJsonPointer(str2) {
1141
+ if (typeof str2 == "number")
1142
+ return `${str2}`;
1143
+ return str2.replace(/~/g, "~0").replace(/\//g, "~1");
1144
1144
  }
1145
1145
  exports.escapeJsonPointer = escapeJsonPointer;
1146
- function unescapeJsonPointer(str) {
1147
- return str.replace(/~1/g, "/").replace(/~0/g, "~");
1146
+ function unescapeJsonPointer(str2) {
1147
+ return str2.replace(/~1/g, "/").replace(/~0/g, "~");
1148
1148
  }
1149
1149
  exports.unescapeJsonPointer = unescapeJsonPointer;
1150
1150
  function eachItem(xs, f3) {
@@ -2169,8 +2169,8 @@ var require_json_schema_traverse = __commonJS({
2169
2169
  post(schema, jsonPtr, rootSchema, parentJsonPtr, parentKeyword, parentSchema, keyIndex);
2170
2170
  }
2171
2171
  }
2172
- function escapeJsonPtr(str) {
2173
- return str.replace(/~/g, "~0").replace(/\//g, "~1");
2172
+ function escapeJsonPtr(str2) {
2173
+ return str2.replace(/~/g, "~0").replace(/\//g, "~1");
2174
2174
  }
2175
2175
  }
2176
2176
  });
@@ -3267,10 +3267,10 @@ var require_utils = __commonJS({
3267
3267
  isIPV6: true
3268
3268
  };
3269
3269
  }
3270
- function findToken(str, token) {
3270
+ function findToken(str2, token) {
3271
3271
  let ind = 0;
3272
- for (let i2 = 0; i2 < str.length; i2++) {
3273
- if (str[i2] === token) ind++;
3272
+ for (let i2 = 0; i2 < str2.length; i2++) {
3273
+ if (str2[i2] === token) ind++;
3274
3274
  }
3275
3275
  return ind;
3276
3276
  }
@@ -4284,7 +4284,7 @@ var require_core = __commonJS({
4284
4284
  var util_1 = require_util();
4285
4285
  var $dataRefSchema = require_data();
4286
4286
  var uri_1 = require_uri();
4287
- var defaultRegExp = (str, flags) => new RegExp(str, flags);
4287
+ var defaultRegExp = (str2, flags) => new RegExp(str2, flags);
4288
4288
  defaultRegExp.code = "new RegExp";
4289
4289
  var META_IGNORE_OPTIONS = ["removeAdditional", "useDefaults", "coerceTypes"];
4290
4290
  var EXT_SCOPE_NAMES = /* @__PURE__ */ new Set([
@@ -5079,16 +5079,16 @@ var require_ucs2length = __commonJS({
5079
5079
  "node_modules/ajv/dist/runtime/ucs2length.js"(exports) {
5080
5080
  "use strict";
5081
5081
  Object.defineProperty(exports, "__esModule", { value: true });
5082
- function ucs2length(str) {
5083
- const len = str.length;
5082
+ function ucs2length(str2) {
5083
+ const len = str2.length;
5084
5084
  let length = 0;
5085
5085
  let pos = 0;
5086
5086
  let value;
5087
5087
  while (pos < len) {
5088
5088
  length++;
5089
- value = str.charCodeAt(pos++);
5089
+ value = str2.charCodeAt(pos++);
5090
5090
  if (value >= 55296 && value <= 56319 && pos < len) {
5091
- value = str.charCodeAt(pos);
5091
+ value = str2.charCodeAt(pos);
5092
5092
  if ((value & 64512) === 56320)
5093
5093
  pos++;
5094
5094
  }
@@ -6971,8 +6971,8 @@ var require_formats = __commonJS({
6971
6971
  }
6972
6972
  var DATE = /^(\d\d\d\d)-(\d\d)-(\d\d)$/;
6973
6973
  var DAYS = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
6974
- function date5(str) {
6975
- const matches = DATE.exec(str);
6974
+ function date5(str2) {
6975
+ const matches = DATE.exec(str2);
6976
6976
  if (!matches)
6977
6977
  return false;
6978
6978
  const year = +matches[1];
@@ -6991,8 +6991,8 @@ var require_formats = __commonJS({
6991
6991
  }
6992
6992
  var TIME = /^(\d\d):(\d\d):(\d\d(?:\.\d+)?)(z|([+-])(\d\d)(?::?(\d\d))?)?$/i;
6993
6993
  function getTime(strictTimeZone) {
6994
- return function time3(str) {
6995
- const matches = TIME.exec(str);
6994
+ return function time3(str2) {
6995
+ const matches = TIME.exec(str2);
6996
6996
  if (!matches)
6997
6997
  return false;
6998
6998
  const hr = +matches[1];
@@ -7038,8 +7038,8 @@ var require_formats = __commonJS({
7038
7038
  var DATE_TIME_SEPARATOR = /t|\s/i;
7039
7039
  function getDateTime(strictTimeZone) {
7040
7040
  const time3 = getTime(strictTimeZone);
7041
- return function date_time(str) {
7042
- const dateTime = str.split(DATE_TIME_SEPARATOR);
7041
+ return function date_time(str2) {
7042
+ const dateTime = str2.split(DATE_TIME_SEPARATOR);
7043
7043
  return dateTime.length === 2 && date5(dateTime[0]) && time3(dateTime[1]);
7044
7044
  };
7045
7045
  }
@@ -7064,13 +7064,13 @@ var require_formats = __commonJS({
7064
7064
  }
7065
7065
  var NOT_URI_FRAGMENT = /\/|:/;
7066
7066
  var URI = /^(?:[a-z][a-z0-9+\-.]*:)(?:\/?\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:]|%[0-9a-f]{2})*@)?(?:\[(?:(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|[Vv][0-9a-f]+\.[a-z0-9\-._~!$&'()*+,;=:]+)\]|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)|(?:[a-z0-9\-._~!$&'()*+,;=]|%[0-9a-f]{2})*)(?::\d*)?(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*|\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)?|(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)(?:\?(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?(?:#(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?$/i;
7067
- function uri(str) {
7068
- return NOT_URI_FRAGMENT.test(str) && URI.test(str);
7067
+ function uri(str2) {
7068
+ return NOT_URI_FRAGMENT.test(str2) && URI.test(str2);
7069
7069
  }
7070
7070
  var BYTE = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/gm;
7071
- function byte(str) {
7071
+ function byte(str2) {
7072
7072
  BYTE.lastIndex = 0;
7073
- return BYTE.test(str);
7073
+ return BYTE.test(str2);
7074
7074
  }
7075
7075
  var MIN_INT32 = -(2 ** 31);
7076
7076
  var MAX_INT32 = 2 ** 31 - 1;
@@ -7084,11 +7084,11 @@ var require_formats = __commonJS({
7084
7084
  return true;
7085
7085
  }
7086
7086
  var Z_ANCHOR = /[^\\]\\Z/;
7087
- function regex(str) {
7088
- if (Z_ANCHOR.test(str))
7087
+ function regex(str2) {
7088
+ if (Z_ANCHOR.test(str2))
7089
7089
  return false;
7090
7090
  try {
7091
- new RegExp(str);
7091
+ new RegExp(str2);
7092
7092
  return true;
7093
7093
  } catch (e4) {
7094
7094
  return false;
@@ -7639,10 +7639,10 @@ var require_strings = __commonJS({
7639
7639
  }
7640
7640
  return padding + value;
7641
7641
  };
7642
- exports.copyStringIntoBuffer = function(str, buffer, offset) {
7643
- var length = str.length;
7642
+ exports.copyStringIntoBuffer = function(str2, buffer, offset) {
7643
+ var length = str2.length;
7644
7644
  for (var idx = 0; idx < length; idx++) {
7645
- buffer[offset++] = str.charCodeAt(idx);
7645
+ buffer[offset++] = str2.charCodeAt(idx);
7646
7646
  }
7647
7647
  return length;
7648
7648
  };
@@ -7652,8 +7652,8 @@ var require_strings = __commonJS({
7652
7652
  }
7653
7653
  return prefix + "-" + Math.floor(Math.random() * Math.pow(10, suffixLength));
7654
7654
  };
7655
- exports.escapeRegExp = function(str) {
7656
- return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
7655
+ exports.escapeRegExp = function(str2) {
7656
+ return str2.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
7657
7657
  };
7658
7658
  exports.cleanText = function(text) {
7659
7659
  return text.replace(/\t|\u0085|\u2028|\u2029/g, " ").replace(/[\b\v]/g, "");
@@ -7821,11 +7821,11 @@ var require_arrays = __commonJS({
7821
7821
  return mergedBuffer;
7822
7822
  };
7823
7823
  exports.arrayAsString = function(array2) {
7824
- var str = "";
7824
+ var str2 = "";
7825
7825
  for (var idx = 0, len = array2.length; idx < len; idx++) {
7826
- str += strings_1.charFromCode(array2[idx]);
7826
+ str2 += strings_1.charFromCode(array2[idx]);
7827
7827
  }
7828
- return str;
7828
+ return str2;
7829
7829
  };
7830
7830
  exports.byAscendingId = function(a, b) {
7831
7831
  return a.id - b.id;
@@ -9076,7 +9076,7 @@ var require_deflate = __commonJS({
9076
9076
  }
9077
9077
  function fill_window(s) {
9078
9078
  var _w_size = s.w_size;
9079
- var p4, n, m, more, str;
9079
+ var p4, n, m, more, str2;
9080
9080
  do {
9081
9081
  more = s.window_size - s.lookahead - s.strstart;
9082
9082
  if (s.strstart >= _w_size + (_w_size - MIN_LOOKAHEAD)) {
@@ -9104,14 +9104,14 @@ var require_deflate = __commonJS({
9104
9104
  n = read_buf(s.strm, s.window, s.strstart + s.lookahead, more);
9105
9105
  s.lookahead += n;
9106
9106
  if (s.lookahead + s.insert >= MIN_MATCH) {
9107
- str = s.strstart - s.insert;
9108
- s.ins_h = s.window[str];
9109
- s.ins_h = (s.ins_h << s.hash_shift ^ s.window[str + 1]) & s.hash_mask;
9107
+ str2 = s.strstart - s.insert;
9108
+ s.ins_h = s.window[str2];
9109
+ s.ins_h = (s.ins_h << s.hash_shift ^ s.window[str2 + 1]) & s.hash_mask;
9110
9110
  while (s.insert) {
9111
- s.ins_h = (s.ins_h << s.hash_shift ^ s.window[str + MIN_MATCH - 1]) & s.hash_mask;
9112
- s.prev[str & s.w_mask] = s.head[s.ins_h];
9113
- s.head[s.ins_h] = str;
9114
- str++;
9111
+ s.ins_h = (s.ins_h << s.hash_shift ^ s.window[str2 + MIN_MATCH - 1]) & s.hash_mask;
9112
+ s.prev[str2 & s.w_mask] = s.head[s.ins_h];
9113
+ s.head[s.ins_h] = str2;
9114
+ str2++;
9115
9115
  s.insert--;
9116
9116
  if (s.lookahead + s.insert < MIN_MATCH) {
9117
9117
  break;
@@ -9887,7 +9887,7 @@ var require_deflate = __commonJS({
9887
9887
  function deflateSetDictionary(strm, dictionary) {
9888
9888
  var dictLength = dictionary.length;
9889
9889
  var s;
9890
- var str, n;
9890
+ var str2, n;
9891
9891
  var wrap;
9892
9892
  var avail;
9893
9893
  var next;
@@ -9925,15 +9925,15 @@ var require_deflate = __commonJS({
9925
9925
  strm.input = dictionary;
9926
9926
  fill_window(s);
9927
9927
  while (s.lookahead >= MIN_MATCH) {
9928
- str = s.strstart;
9928
+ str2 = s.strstart;
9929
9929
  n = s.lookahead - (MIN_MATCH - 1);
9930
9930
  do {
9931
- s.ins_h = (s.ins_h << s.hash_shift ^ s.window[str + MIN_MATCH - 1]) & s.hash_mask;
9932
- s.prev[str & s.w_mask] = s.head[s.ins_h];
9933
- s.head[s.ins_h] = str;
9934
- str++;
9931
+ s.ins_h = (s.ins_h << s.hash_shift ^ s.window[str2 + MIN_MATCH - 1]) & s.hash_mask;
9932
+ s.prev[str2 & s.w_mask] = s.head[s.ins_h];
9933
+ s.head[s.ins_h] = str2;
9934
+ str2++;
9935
9935
  } while (--n);
9936
- s.strstart = str;
9936
+ s.strstart = str2;
9937
9937
  s.lookahead = MIN_MATCH - 1;
9938
9938
  fill_window(s);
9939
9939
  }
@@ -9984,12 +9984,12 @@ var require_strings2 = __commonJS({
9984
9984
  }
9985
9985
  var q;
9986
9986
  _utf8len[254] = _utf8len[254] = 1;
9987
- exports.string2buf = function(str) {
9988
- var buf, c2, c22, m_pos, i2, str_len = str.length, buf_len = 0;
9987
+ exports.string2buf = function(str2) {
9988
+ var buf, c2, c22, m_pos, i2, str_len = str2.length, buf_len = 0;
9989
9989
  for (m_pos = 0; m_pos < str_len; m_pos++) {
9990
- c2 = str.charCodeAt(m_pos);
9990
+ c2 = str2.charCodeAt(m_pos);
9991
9991
  if ((c2 & 64512) === 55296 && m_pos + 1 < str_len) {
9992
- c22 = str.charCodeAt(m_pos + 1);
9992
+ c22 = str2.charCodeAt(m_pos + 1);
9993
9993
  if ((c22 & 64512) === 56320) {
9994
9994
  c2 = 65536 + (c2 - 55296 << 10) + (c22 - 56320);
9995
9995
  m_pos++;
@@ -9999,9 +9999,9 @@ var require_strings2 = __commonJS({
9999
9999
  }
10000
10000
  buf = new utils.Buf8(buf_len);
10001
10001
  for (i2 = 0, m_pos = 0; i2 < buf_len; m_pos++) {
10002
- c2 = str.charCodeAt(m_pos);
10002
+ c2 = str2.charCodeAt(m_pos);
10003
10003
  if ((c2 & 64512) === 55296 && m_pos + 1 < str_len) {
10004
- c22 = str.charCodeAt(m_pos + 1);
10004
+ c22 = str2.charCodeAt(m_pos + 1);
10005
10005
  if ((c22 & 64512) === 56320) {
10006
10006
  c2 = 65536 + (c2 - 55296 << 10) + (c22 - 56320);
10007
10007
  m_pos++;
@@ -10040,10 +10040,10 @@ var require_strings2 = __commonJS({
10040
10040
  exports.buf2binstring = function(buf) {
10041
10041
  return buf2binstring(buf, buf.length);
10042
10042
  };
10043
- exports.binstring2buf = function(str) {
10044
- var buf = new utils.Buf8(str.length);
10043
+ exports.binstring2buf = function(str2) {
10044
+ var buf = new utils.Buf8(str2.length);
10045
10045
  for (var i2 = 0, len = buf.length; i2 < len; i2++) {
10046
- buf[i2] = str.charCodeAt(i2);
10046
+ buf[i2] = str2.charCodeAt(i2);
10047
10047
  }
10048
10048
  return buf;
10049
10049
  };
@@ -12368,11 +12368,11 @@ var require_utils2 = __commonJS({
12368
12368
  return bytes;
12369
12369
  };
12370
12370
  var arrayToString2 = function(array2) {
12371
- var str = "";
12371
+ var str2 = "";
12372
12372
  for (var i3 = 0; i3 < array2.length; i3++) {
12373
- str += String.fromCharCode(array2[i3]);
12373
+ str2 += String.fromCharCode(array2[i3]);
12374
12374
  }
12375
- return str;
12375
+ return str2;
12376
12376
  };
12377
12377
  exports.decompressJson = function(compressedJson) {
12378
12378
  return arrayToString2(pako_1.default.inflate(exports.decodeFromBase64(compressedJson)));
@@ -12611,9 +12611,9 @@ var require_Encoding = __commonJS({
12611
12611
  this.encodeUnicodeCodePoint = function(codePoint) {
12612
12612
  var mapped = _this.unicodeMappings[codePoint];
12613
12613
  if (!mapped) {
12614
- var str = String.fromCharCode(codePoint);
12614
+ var str2 = String.fromCharCode(codePoint);
12615
12615
  var hexCode = "0x" + utils_1.padStart(codePoint.toString(16), 4, "0");
12616
- var msg = _this.name + ' cannot encode "' + str + '" (' + hexCode + ")";
12616
+ var msg = _this.name + ' cannot encode "' + str2 + '" (' + hexCode + ")";
12617
12617
  throw new Error(msg);
12618
12618
  }
12619
12619
  return { code: mapped[0], name: mapped[1] };
@@ -19549,7 +19549,7 @@ var require_FlateStream = __commonJS({
19549
19549
  FlateStream3.prototype.readBlock = function() {
19550
19550
  var buffer;
19551
19551
  var len;
19552
- var str = this.stream;
19552
+ var str2 = this.stream;
19553
19553
  var hdr = this.getBits(3);
19554
19554
  if (hdr & 1) {
19555
19555
  this.eof = true;
@@ -19557,19 +19557,19 @@ var require_FlateStream = __commonJS({
19557
19557
  hdr >>= 1;
19558
19558
  if (hdr === 0) {
19559
19559
  var b = void 0;
19560
- if ((b = str.getByte()) === -1) {
19560
+ if ((b = str2.getByte()) === -1) {
19561
19561
  throw new Error("Bad block header in flate stream");
19562
19562
  }
19563
19563
  var blockLen = b;
19564
- if ((b = str.getByte()) === -1) {
19564
+ if ((b = str2.getByte()) === -1) {
19565
19565
  throw new Error("Bad block header in flate stream");
19566
19566
  }
19567
19567
  blockLen |= b << 8;
19568
- if ((b = str.getByte()) === -1) {
19568
+ if ((b = str2.getByte()) === -1) {
19569
19569
  throw new Error("Bad block header in flate stream");
19570
19570
  }
19571
19571
  var check2 = b;
19572
- if ((b = str.getByte()) === -1) {
19572
+ if ((b = str2.getByte()) === -1) {
19573
19573
  throw new Error("Bad block header in flate stream");
19574
19574
  }
19575
19575
  check2 |= b << 8;
@@ -19583,12 +19583,12 @@ var require_FlateStream = __commonJS({
19583
19583
  var end = bufferLength + blockLen;
19584
19584
  this.bufferLength = end;
19585
19585
  if (blockLen === 0) {
19586
- if (str.peekByte() === -1) {
19586
+ if (str2.peekByte() === -1) {
19587
19587
  this.eof = true;
19588
19588
  }
19589
19589
  } else {
19590
19590
  for (var n = bufferLength; n < end; ++n) {
19591
- if ((b = str.getByte()) === -1) {
19591
+ if ((b = str2.getByte()) === -1) {
19592
19592
  this.eof = true;
19593
19593
  break;
19594
19594
  }
@@ -19688,12 +19688,12 @@ var require_FlateStream = __commonJS({
19688
19688
  }
19689
19689
  };
19690
19690
  FlateStream3.prototype.getBits = function(bits2) {
19691
- var str = this.stream;
19691
+ var str2 = this.stream;
19692
19692
  var codeSize = this.codeSize;
19693
19693
  var codeBuf = this.codeBuf;
19694
19694
  var b;
19695
19695
  while (codeSize < bits2) {
19696
- if ((b = str.getByte()) === -1) {
19696
+ if ((b = str2.getByte()) === -1) {
19697
19697
  throw new Error("Bad encoding in flate stream");
19698
19698
  }
19699
19699
  codeBuf |= b << codeSize;
@@ -19705,14 +19705,14 @@ var require_FlateStream = __commonJS({
19705
19705
  return b;
19706
19706
  };
19707
19707
  FlateStream3.prototype.getCode = function(table) {
19708
- var str = this.stream;
19708
+ var str2 = this.stream;
19709
19709
  var codes = table[0];
19710
19710
  var maxLen = table[1];
19711
19711
  var codeSize = this.codeSize;
19712
19712
  var codeBuf = this.codeBuf;
19713
19713
  var b;
19714
19714
  while (codeSize < maxLen) {
19715
- if ((b = str.getByte()) === -1) {
19715
+ if ((b = str2.getByte()) === -1) {
19716
19716
  break;
19717
19717
  }
19718
19718
  codeBuf |= b << codeSize;
@@ -29788,11 +29788,11 @@ var require_fontkit_umd = __commonJS({
29788
29788
  return Buffer3.compare(this, b) === 0;
29789
29789
  };
29790
29790
  Buffer3.prototype.inspect = function inspect2() {
29791
- var str = "";
29791
+ var str2 = "";
29792
29792
  var max2 = exports2.INSPECT_MAX_BYTES;
29793
- str = this.toString("hex", 0, max2).replace(/(.{2})/g, "$1 ").trim();
29794
- if (this.length > max2) str += " ... ";
29795
- return "<Buffer " + str + ">";
29793
+ str2 = this.toString("hex", 0, max2).replace(/(.{2})/g, "$1 ").trim();
29794
+ if (this.length > max2) str2 += " ... ";
29795
+ return "<Buffer " + str2 + ">";
29796
29796
  };
29797
29797
  if (customInspectSymbol) {
29798
29798
  Buffer3.prototype[customInspectSymbol] = Buffer3.prototype.inspect;
@@ -30594,14 +30594,14 @@ var require_fontkit_umd = __commonJS({
30594
30594
  return this;
30595
30595
  };
30596
30596
  var INVALID_BASE64_RE = /[^+/0-9A-Za-z-_]/g;
30597
- function base64clean(str) {
30598
- str = str.split("=")[0];
30599
- str = str.trim().replace(INVALID_BASE64_RE, "");
30600
- if (str.length < 2) return "";
30601
- while (str.length % 4 !== 0) {
30602
- str = str + "=";
30597
+ function base64clean(str2) {
30598
+ str2 = str2.split("=")[0];
30599
+ str2 = str2.trim().replace(INVALID_BASE64_RE, "");
30600
+ if (str2.length < 2) return "";
30601
+ while (str2.length % 4 !== 0) {
30602
+ str2 = str2 + "=";
30603
30603
  }
30604
- return str;
30604
+ return str2;
30605
30605
  }
30606
30606
  function utf8ToBytes(string4, units) {
30607
30607
  units = units || Infinity;
@@ -30651,19 +30651,19 @@ var require_fontkit_umd = __commonJS({
30651
30651
  }
30652
30652
  return bytes;
30653
30653
  }
30654
- function asciiToBytes(str) {
30654
+ function asciiToBytes(str2) {
30655
30655
  var byteArray = [];
30656
- for (var i3 = 0; i3 < str.length; ++i3) {
30657
- byteArray.push(str.charCodeAt(i3) & 255);
30656
+ for (var i3 = 0; i3 < str2.length; ++i3) {
30657
+ byteArray.push(str2.charCodeAt(i3) & 255);
30658
30658
  }
30659
30659
  return byteArray;
30660
30660
  }
30661
- function utf16leToBytes(str, units) {
30661
+ function utf16leToBytes(str2, units) {
30662
30662
  var c2, hi, lo;
30663
30663
  var byteArray = [];
30664
- for (var i3 = 0; i3 < str.length; ++i3) {
30664
+ for (var i3 = 0; i3 < str2.length; ++i3) {
30665
30665
  if ((units -= 2) < 0) break;
30666
- c2 = str.charCodeAt(i3);
30666
+ c2 = str2.charCodeAt(i3);
30667
30667
  hi = c2 >> 8;
30668
30668
  lo = c2 % 256;
30669
30669
  byteArray.push(lo);
@@ -30671,8 +30671,8 @@ var require_fontkit_umd = __commonJS({
30671
30671
  }
30672
30672
  return byteArray;
30673
30673
  }
30674
- function base64ToBytes(str) {
30675
- return base64Js.toByteArray(base64clean(str));
30674
+ function base64ToBytes(str2) {
30675
+ return base64Js.toByteArray(base64clean(str2));
30676
30676
  }
30677
30677
  function blitBuffer(src2, dst, offset, length) {
30678
30678
  for (var i3 = 0; i3 < length; ++i3) {
@@ -31272,7 +31272,7 @@ var require_fontkit_umd = __commonJS({
31272
31272
  var i3 = 1;
31273
31273
  var args = arguments;
31274
31274
  var len2 = args.length;
31275
- var str = String(f3).replace(formatRegExp, function(x3) {
31275
+ var str2 = String(f3).replace(formatRegExp, function(x3) {
31276
31276
  if (x3 === "%%") return "%";
31277
31277
  if (i3 >= len2) return x3;
31278
31278
  switch (x3) {
@@ -31292,12 +31292,12 @@ var require_fontkit_umd = __commonJS({
31292
31292
  });
31293
31293
  for (var x2 = args[i3]; i3 < len2; x2 = args[++i3]) {
31294
31294
  if (isNull(x2) || !isObject2(x2)) {
31295
- str += " " + x2;
31295
+ str2 += " " + x2;
31296
31296
  } else {
31297
- str += " " + inspect(x2);
31297
+ str2 += " " + inspect(x2);
31298
31298
  }
31299
31299
  }
31300
- return str;
31300
+ return str2;
31301
31301
  }
31302
31302
  function deprecate(fn5, msg) {
31303
31303
  if (isUndefined(global$1.process)) {
@@ -31388,16 +31388,16 @@ var require_fontkit_umd = __commonJS({
31388
31388
  // "name": intentionally not styling
31389
31389
  "regexp": "red"
31390
31390
  };
31391
- function stylizeWithColor(str, styleType) {
31391
+ function stylizeWithColor(str2, styleType) {
31392
31392
  var style = inspect.styles[styleType];
31393
31393
  if (style) {
31394
- return "\x1B[" + inspect.colors[style][0] + "m" + str + "\x1B[" + inspect.colors[style][1] + "m";
31394
+ return "\x1B[" + inspect.colors[style][0] + "m" + str2 + "\x1B[" + inspect.colors[style][1] + "m";
31395
31395
  } else {
31396
- return str;
31396
+ return str2;
31397
31397
  }
31398
31398
  }
31399
- function stylizeNoColor(str, styleType) {
31400
- return str;
31399
+ function stylizeNoColor(str2, styleType) {
31400
+ return str2;
31401
31401
  }
31402
31402
  function arrayToHash(array2) {
31403
31403
  var hash2 = {};
@@ -31513,49 +31513,49 @@ var require_fontkit_umd = __commonJS({
31513
31513
  return output2;
31514
31514
  }
31515
31515
  function formatProperty(ctx, value, recurseTimes, visibleKeys, key2, array2) {
31516
- var name, str, desc;
31516
+ var name, str2, desc;
31517
31517
  desc = Object.getOwnPropertyDescriptor(value, key2) || {
31518
31518
  value: value[key2]
31519
31519
  };
31520
31520
  if (desc.get) {
31521
31521
  if (desc.set) {
31522
- str = ctx.stylize("[Getter/Setter]", "special");
31522
+ str2 = ctx.stylize("[Getter/Setter]", "special");
31523
31523
  } else {
31524
- str = ctx.stylize("[Getter]", "special");
31524
+ str2 = ctx.stylize("[Getter]", "special");
31525
31525
  }
31526
31526
  } else {
31527
31527
  if (desc.set) {
31528
- str = ctx.stylize("[Setter]", "special");
31528
+ str2 = ctx.stylize("[Setter]", "special");
31529
31529
  }
31530
31530
  }
31531
31531
  if (!hasOwnProperty(visibleKeys, key2)) {
31532
31532
  name = "[" + key2 + "]";
31533
31533
  }
31534
- if (!str) {
31534
+ if (!str2) {
31535
31535
  if (ctx.seen.indexOf(desc.value) < 0) {
31536
31536
  if (isNull(recurseTimes)) {
31537
- str = formatValue2(ctx, desc.value, null);
31537
+ str2 = formatValue2(ctx, desc.value, null);
31538
31538
  } else {
31539
- str = formatValue2(ctx, desc.value, recurseTimes - 1);
31539
+ str2 = formatValue2(ctx, desc.value, recurseTimes - 1);
31540
31540
  }
31541
- if (str.indexOf("\n") > -1) {
31541
+ if (str2.indexOf("\n") > -1) {
31542
31542
  if (array2) {
31543
- str = str.split("\n").map(function(line) {
31543
+ str2 = str2.split("\n").map(function(line) {
31544
31544
  return " " + line;
31545
31545
  }).join("\n").substr(2);
31546
31546
  } else {
31547
- str = "\n" + str.split("\n").map(function(line) {
31547
+ str2 = "\n" + str2.split("\n").map(function(line) {
31548
31548
  return " " + line;
31549
31549
  }).join("\n");
31550
31550
  }
31551
31551
  }
31552
31552
  } else {
31553
- str = ctx.stylize("[Circular]", "special");
31553
+ str2 = ctx.stylize("[Circular]", "special");
31554
31554
  }
31555
31555
  }
31556
31556
  if (isUndefined(name)) {
31557
31557
  if (array2 && key2.match(/^\d+$/)) {
31558
- return str;
31558
+ return str2;
31559
31559
  }
31560
31560
  name = JSON.stringify("" + key2);
31561
31561
  if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
@@ -31566,7 +31566,7 @@ var require_fontkit_umd = __commonJS({
31566
31566
  name = ctx.stylize(name, "string");
31567
31567
  }
31568
31568
  }
31569
- return name + ": " + str;
31569
+ return name + ": " + str2;
31570
31570
  }
31571
31571
  function reduceToSingleString(output2, base, braces) {
31572
31572
  var length = output2.reduce(function(prev, cur) {
@@ -32396,19 +32396,19 @@ var require_fontkit_umd = __commonJS({
32396
32396
  var ret = p4.data;
32397
32397
  n -= ret.length;
32398
32398
  while (p4 = p4.next) {
32399
- var str = p4.data;
32400
- var nb = n > str.length ? str.length : n;
32401
- if (nb === str.length) ret += str;
32402
- else ret += str.slice(0, n);
32399
+ var str2 = p4.data;
32400
+ var nb = n > str2.length ? str2.length : n;
32401
+ if (nb === str2.length) ret += str2;
32402
+ else ret += str2.slice(0, n);
32403
32403
  n -= nb;
32404
32404
  if (n === 0) {
32405
- if (nb === str.length) {
32405
+ if (nb === str2.length) {
32406
32406
  ++c2;
32407
32407
  if (p4.next) list.head = p4.next;
32408
32408
  else list.head = list.tail = null;
32409
32409
  } else {
32410
32410
  list.head = p4;
32411
- p4.data = str.slice(nb);
32411
+ p4.data = str2.slice(nb);
32412
32412
  }
32413
32413
  break;
32414
32414
  }
@@ -33028,12 +33028,12 @@ var require_fontkit_umd = __commonJS({
33028
33028
  this.encoder = encoder;
33029
33029
  this.addBOM = true;
33030
33030
  }
33031
- PrependBOMWrapper.prototype.write = function(str) {
33031
+ PrependBOMWrapper.prototype.write = function(str2) {
33032
33032
  if (this.addBOM) {
33033
- str = BOMChar + str;
33033
+ str2 = BOMChar + str2;
33034
33034
  this.addBOM = false;
33035
33035
  }
33036
- return this.encoder.write(str);
33036
+ return this.encoder.write(str2);
33037
33037
  };
33038
33038
  PrependBOMWrapper.prototype.end = function() {
33039
33039
  return this.encoder.end();
@@ -33116,30 +33116,30 @@ var require_fontkit_umd = __commonJS({
33116
33116
  function InternalEncoder(options, codec2) {
33117
33117
  this.enc = codec2.enc;
33118
33118
  }
33119
- InternalEncoder.prototype.write = function(str) {
33120
- return Buffer$1.from(str, this.enc);
33119
+ InternalEncoder.prototype.write = function(str2) {
33120
+ return Buffer$1.from(str2, this.enc);
33121
33121
  };
33122
33122
  InternalEncoder.prototype.end = function() {
33123
33123
  };
33124
33124
  function InternalEncoderBase64(options, codec2) {
33125
33125
  this.prevStr = "";
33126
33126
  }
33127
- InternalEncoderBase64.prototype.write = function(str) {
33128
- str = this.prevStr + str;
33129
- var completeQuads = str.length - str.length % 4;
33130
- this.prevStr = str.slice(completeQuads);
33131
- str = str.slice(0, completeQuads);
33132
- return Buffer$1.from(str, "base64");
33127
+ InternalEncoderBase64.prototype.write = function(str2) {
33128
+ str2 = this.prevStr + str2;
33129
+ var completeQuads = str2.length - str2.length % 4;
33130
+ this.prevStr = str2.slice(completeQuads);
33131
+ str2 = str2.slice(0, completeQuads);
33132
+ return Buffer$1.from(str2, "base64");
33133
33133
  };
33134
33134
  InternalEncoderBase64.prototype.end = function() {
33135
33135
  return Buffer$1.from(this.prevStr, "base64");
33136
33136
  };
33137
33137
  function InternalEncoderCesu8(options, codec2) {
33138
33138
  }
33139
- InternalEncoderCesu8.prototype.write = function(str) {
33140
- var buf = Buffer$1.alloc(str.length * 3), bufIdx = 0;
33141
- for (var i3 = 0; i3 < str.length; i3++) {
33142
- var charCode = str.charCodeAt(i3);
33139
+ InternalEncoderCesu8.prototype.write = function(str2) {
33140
+ var buf = Buffer$1.alloc(str2.length * 3), bufIdx = 0;
33141
+ for (var i3 = 0; i3 < str2.length; i3++) {
33142
+ var charCode = str2.charCodeAt(i3);
33143
33143
  if (charCode < 128) buf[bufIdx++] = charCode;
33144
33144
  else if (charCode < 2048) {
33145
33145
  buf[bufIdx++] = 192 + (charCode >>> 6);
@@ -33217,8 +33217,8 @@ var require_fontkit_umd = __commonJS({
33217
33217
  Utf16BECodec.prototype.bomAware = true;
33218
33218
  function Utf16BEEncoder() {
33219
33219
  }
33220
- Utf16BEEncoder.prototype.write = function(str) {
33221
- var buf = Buffer$2.from(str, "ucs2");
33220
+ Utf16BEEncoder.prototype.write = function(str2) {
33221
+ var buf = Buffer$2.from(str2, "ucs2");
33222
33222
  for (var i3 = 0; i3 < buf.length; i3 += 2) {
33223
33223
  var tmp = buf[i3];
33224
33224
  buf[i3] = buf[i3 + 1];
@@ -33260,8 +33260,8 @@ var require_fontkit_umd = __commonJS({
33260
33260
  if (options.addBOM === void 0) options.addBOM = true;
33261
33261
  this.encoder = codec2.iconv.getEncoder("utf-16le", options);
33262
33262
  }
33263
- Utf16Encoder.prototype.write = function(str) {
33264
- return this.encoder.write(str);
33263
+ Utf16Encoder.prototype.write = function(str2) {
33264
+ return this.encoder.write(str2);
33265
33265
  };
33266
33266
  Utf16Encoder.prototype.end = function() {
33267
33267
  return this.encoder.end();
@@ -33330,8 +33330,8 @@ var require_fontkit_umd = __commonJS({
33330
33330
  function Utf7Encoder(options, codec2) {
33331
33331
  this.iconv = codec2.iconv;
33332
33332
  }
33333
- Utf7Encoder.prototype.write = function(str) {
33334
- return Buffer$3.from(str.replace(nonDirectChars, function(chunk2) {
33333
+ Utf7Encoder.prototype.write = function(str2) {
33334
+ return Buffer$3.from(str2.replace(nonDirectChars, function(chunk2) {
33335
33335
  return "+" + (chunk2 === "+" ? "" : this.iconv.encode(chunk2, "utf16-be").toString("base64").replace(/=+$/, "")) + "-";
33336
33336
  }.bind(this)));
33337
33337
  };
@@ -33406,10 +33406,10 @@ var require_fontkit_umd = __commonJS({
33406
33406
  this.base64Accum = Buffer$3.alloc(6);
33407
33407
  this.base64AccumIdx = 0;
33408
33408
  }
33409
- Utf7IMAPEncoder.prototype.write = function(str) {
33410
- var inBase64 = this.inBase64, base64Accum = this.base64Accum, base64AccumIdx = this.base64AccumIdx, buf = Buffer$3.alloc(str.length * 5 + 10), bufIdx = 0;
33411
- for (var i3 = 0; i3 < str.length; i3++) {
33412
- var uChar = str.charCodeAt(i3);
33409
+ Utf7IMAPEncoder.prototype.write = function(str2) {
33410
+ var inBase64 = this.inBase64, base64Accum = this.base64Accum, base64AccumIdx = this.base64AccumIdx, buf = Buffer$3.alloc(str2.length * 5 + 10), bufIdx = 0;
33411
+ for (var i3 = 0; i3 < str2.length; i3++) {
33412
+ var uChar = str2.charCodeAt(i3);
33413
33413
  if (32 <= uChar && uChar <= 126) {
33414
33414
  if (inBase64) {
33415
33415
  if (base64AccumIdx > 0) {
@@ -33536,10 +33536,10 @@ var require_fontkit_umd = __commonJS({
33536
33536
  function SBCSEncoder(options, codec2) {
33537
33537
  this.encodeBuf = codec2.encodeBuf;
33538
33538
  }
33539
- SBCSEncoder.prototype.write = function(str) {
33540
- var buf = Buffer$4.alloc(str.length);
33541
- for (var i3 = 0; i3 < str.length; i3++) {
33542
- buf[i3] = this.encodeBuf[str.charCodeAt(i3)];
33539
+ SBCSEncoder.prototype.write = function(str2) {
33540
+ var buf = Buffer$4.alloc(str2.length);
33541
+ for (var i3 = 0; i3 < str2.length; i3++) {
33542
+ buf[i3] = this.encodeBuf[str2.charCodeAt(i3)];
33543
33543
  }
33544
33544
  return buf;
33545
33545
  };
@@ -34319,12 +34319,12 @@ var require_fontkit_umd = __commonJS({
34319
34319
  this.defaultCharSingleByte = codec2.defCharSB;
34320
34320
  this.gb18030 = codec2.gb18030;
34321
34321
  }
34322
- DBCSEncoder.prototype.write = function(str) {
34323
- var newBuf = Buffer$5.alloc(str.length * (this.gb18030 ? 4 : 3)), leadSurrogate = this.leadSurrogate, seqObj = this.seqObj, nextChar = -1, i3 = 0, j = 0;
34322
+ DBCSEncoder.prototype.write = function(str2) {
34323
+ var newBuf = Buffer$5.alloc(str2.length * (this.gb18030 ? 4 : 3)), leadSurrogate = this.leadSurrogate, seqObj = this.seqObj, nextChar = -1, i3 = 0, j = 0;
34324
34324
  while (true) {
34325
34325
  if (nextChar === -1) {
34326
- if (i3 == str.length) break;
34327
- var uCode = str.charCodeAt(i3++);
34326
+ if (i3 == str2.length) break;
34327
+ var uCode = str2.charCodeAt(i3++);
34328
34328
  } else {
34329
34329
  var uCode = nextChar;
34330
34330
  nextChar = -1;
@@ -43175,10 +43175,10 @@ var require_fontkit_umd = __commonJS({
43175
43175
  return Buffer$7.isNativeEncoding(encoding) || iconv.encodingExists(encoding);
43176
43176
  };
43177
43177
  original.BufferByteLength = Buffer$7.byteLength;
43178
- Buffer$7.byteLength = SlowBuffer.byteLength = function(str, encoding) {
43178
+ Buffer$7.byteLength = SlowBuffer.byteLength = function(str2, encoding) {
43179
43179
  encoding = String(encoding || "utf8").toLowerCase();
43180
- if (Buffer$7.isNativeEncoding(encoding)) return original.BufferByteLength.call(this, str, encoding);
43181
- return iconv.encode(str, encoding).length;
43180
+ if (Buffer$7.isNativeEncoding(encoding)) return original.BufferByteLength.call(this, str2, encoding);
43181
+ return iconv.encode(str2, encoding).length;
43182
43182
  };
43183
43183
  original.BufferToString = Buffer$7.prototype.toString;
43184
43184
  Buffer$7.prototype.toString = function(encoding, start, end) {
@@ -43255,10 +43255,10 @@ var require_fontkit_umd = __commonJS({
43255
43255
  iconv.encodings = null;
43256
43256
  iconv.defaultCharUnicode = "\uFFFD";
43257
43257
  iconv.defaultCharSingleByte = "?";
43258
- iconv.encode = function encode5(str, encoding, options) {
43259
- str = "" + (str || "");
43258
+ iconv.encode = function encode5(str2, encoding, options) {
43259
+ str2 = "" + (str2 || "");
43260
43260
  var encoder = iconv.getEncoder(encoding, options);
43261
- var res = encoder.write(str);
43261
+ var res = encoder.write(str2);
43262
43262
  var trail = encoder.end();
43263
43263
  return trail && trail.length > 0 ? Buffer3.concat([res, trail]) : res;
43264
43264
  };
@@ -45809,10 +45809,10 @@ var require_fontkit_umd = __commonJS({
45809
45809
  })();
45810
45810
  var toStr = Object.prototype.toString;
45811
45811
  var isArguments = function isArguments2(value) {
45812
- var str = toStr.call(value);
45813
- var isArgs2 = str === "[object Arguments]";
45812
+ var str2 = toStr.call(value);
45813
+ var isArgs2 = str2 === "[object Arguments]";
45814
45814
  if (!isArgs2) {
45815
- isArgs2 = str !== "[object Array]" && value !== null && typeof value === "object" && typeof value.length === "number" && value.length >= 0 && toStr.call(value.callee) === "[object Function]";
45815
+ isArgs2 = str2 !== "[object Array]" && value !== null && typeof value === "object" && typeof value.length === "number" && value.length >= 0 && toStr.call(value.callee) === "[object Function]";
45816
45816
  }
45817
45817
  return isArgs2;
45818
45818
  };
@@ -46596,21 +46596,21 @@ var require_fontkit_umd = __commonJS({
46596
46596
  return stream2.readInt32BE();
46597
46597
  }
46598
46598
  if (value === 30) {
46599
- var str = "";
46599
+ var str2 = "";
46600
46600
  while (true) {
46601
46601
  var b = stream2.readUInt8();
46602
46602
  var n1 = b >> 4;
46603
46603
  if (n1 === FLOAT_EOF) {
46604
46604
  break;
46605
46605
  }
46606
- str += FLOAT_LOOKUP[n1];
46606
+ str2 += FLOAT_LOOKUP[n1];
46607
46607
  var n2 = b & 15;
46608
46608
  if (n2 === FLOAT_EOF) {
46609
46609
  break;
46610
46610
  }
46611
- str += FLOAT_LOOKUP[n2];
46611
+ str2 += FLOAT_LOOKUP[n2];
46612
46612
  }
46613
- return parseFloat(str);
46613
+ return parseFloat(str2);
46614
46614
  }
46615
46615
  return null;
46616
46616
  };
@@ -46619,8 +46619,8 @@ var require_fontkit_umd = __commonJS({
46619
46619
  value = 32768;
46620
46620
  }
46621
46621
  if ((value | 0) !== value) {
46622
- var str = "" + value;
46623
- return 1 + Math.ceil((str.length + 1) / 2);
46622
+ var str2 = "" + value;
46623
+ return 1 + Math.ceil((str2.length + 1) / 2);
46624
46624
  } else if (-107 <= value && value <= 107) {
46625
46625
  return 1;
46626
46626
  } else if (108 <= value && value <= 1131 || -1131 <= value && value <= -108) {
@@ -46638,14 +46638,14 @@ var require_fontkit_umd = __commonJS({
46638
46638
  return stream2.writeInt32BE(val);
46639
46639
  } else if ((val | 0) !== val) {
46640
46640
  stream2.writeUInt8(30);
46641
- var str = "" + val;
46642
- for (var i3 = 0; i3 < str.length; i3 += 2) {
46643
- var c1 = str[i3];
46641
+ var str2 = "" + val;
46642
+ for (var i3 = 0; i3 < str2.length; i3 += 2) {
46643
+ var c1 = str2[i3];
46644
46644
  var n1 = FLOAT_ENCODE_LOOKUP[c1] || +c1;
46645
- if (i3 === str.length - 1) {
46645
+ if (i3 === str2.length - 1) {
46646
46646
  var n2 = FLOAT_EOF;
46647
46647
  } else {
46648
- var c2 = str[i3 + 1];
46648
+ var c2 = str2[i3 + 1];
46649
46649
  var n2 = FLOAT_ENCODE_LOOKUP[c2] || +c2;
46650
46650
  }
46651
46651
  stream2.writeUInt8(n1 << 4 | n2 & 15);
@@ -50821,7 +50821,7 @@ var require_fontkit_umd = __commonJS({
50821
50821
  }
50822
50822
  function fill_window(s) {
50823
50823
  var _w_size = s.w_size;
50824
- var p4, n, m, more, str;
50824
+ var p4, n, m, more, str2;
50825
50825
  do {
50826
50826
  more = s.window_size - s.lookahead - s.strstart;
50827
50827
  if (s.strstart >= _w_size + (_w_size - MIN_LOOKAHEAD)) {
@@ -50849,14 +50849,14 @@ var require_fontkit_umd = __commonJS({
50849
50849
  n = read_buf(s.strm, s.window, s.strstart + s.lookahead, more);
50850
50850
  s.lookahead += n;
50851
50851
  if (s.lookahead + s.insert >= MIN_MATCH$1) {
50852
- str = s.strstart - s.insert;
50853
- s.ins_h = s.window[str];
50854
- s.ins_h = (s.ins_h << s.hash_shift ^ s.window[str + 1]) & s.hash_mask;
50852
+ str2 = s.strstart - s.insert;
50853
+ s.ins_h = s.window[str2];
50854
+ s.ins_h = (s.ins_h << s.hash_shift ^ s.window[str2 + 1]) & s.hash_mask;
50855
50855
  while (s.insert) {
50856
- s.ins_h = (s.ins_h << s.hash_shift ^ s.window[str + MIN_MATCH$1 - 1]) & s.hash_mask;
50857
- s.prev[str & s.w_mask] = s.head[s.ins_h];
50858
- s.head[s.ins_h] = str;
50859
- str++;
50856
+ s.ins_h = (s.ins_h << s.hash_shift ^ s.window[str2 + MIN_MATCH$1 - 1]) & s.hash_mask;
50857
+ s.prev[str2 & s.w_mask] = s.head[s.ins_h];
50858
+ s.head[s.ins_h] = str2;
50859
+ str2++;
50860
50860
  s.insert--;
50861
50861
  if (s.lookahead + s.insert < MIN_MATCH$1) {
50862
50862
  break;
@@ -51629,7 +51629,7 @@ var require_fontkit_umd = __commonJS({
51629
51629
  function deflateSetDictionary(strm, dictionary2) {
51630
51630
  var dictLength = dictionary2.length;
51631
51631
  var s;
51632
- var str, n;
51632
+ var str2, n;
51633
51633
  var wrap;
51634
51634
  var avail;
51635
51635
  var next;
@@ -51667,15 +51667,15 @@ var require_fontkit_umd = __commonJS({
51667
51667
  strm.input = dictionary2;
51668
51668
  fill_window(s);
51669
51669
  while (s.lookahead >= MIN_MATCH$1) {
51670
- str = s.strstart;
51670
+ str2 = s.strstart;
51671
51671
  n = s.lookahead - (MIN_MATCH$1 - 1);
51672
51672
  do {
51673
- s.ins_h = (s.ins_h << s.hash_shift ^ s.window[str + MIN_MATCH$1 - 1]) & s.hash_mask;
51674
- s.prev[str & s.w_mask] = s.head[s.ins_h];
51675
- s.head[s.ins_h] = str;
51676
- str++;
51673
+ s.ins_h = (s.ins_h << s.hash_shift ^ s.window[str2 + MIN_MATCH$1 - 1]) & s.hash_mask;
51674
+ s.prev[str2 & s.w_mask] = s.head[s.ins_h];
51675
+ s.head[s.ins_h] = str2;
51676
+ str2++;
51677
51677
  } while (--n);
51678
- s.strstart = str;
51678
+ s.strstart = str2;
51679
51679
  s.lookahead = MIN_MATCH$1 - 1;
51680
51680
  fill_window(s);
51681
51681
  }
@@ -51728,12 +51728,12 @@ var require_fontkit_umd = __commonJS({
51728
51728
  _utf8len[q] = q >= 252 ? 6 : q >= 248 ? 5 : q >= 240 ? 4 : q >= 224 ? 3 : q >= 192 ? 2 : 1;
51729
51729
  }
51730
51730
  _utf8len[254] = _utf8len[254] = 1;
51731
- var string2buf = function string2buf2(str) {
51732
- var buf, c2, c22, m_pos, i3, str_len = str.length, buf_len = 0;
51731
+ var string2buf = function string2buf2(str2) {
51732
+ var buf, c2, c22, m_pos, i3, str_len = str2.length, buf_len = 0;
51733
51733
  for (m_pos = 0; m_pos < str_len; m_pos++) {
51734
- c2 = str.charCodeAt(m_pos);
51734
+ c2 = str2.charCodeAt(m_pos);
51735
51735
  if ((c2 & 64512) === 55296 && m_pos + 1 < str_len) {
51736
- c22 = str.charCodeAt(m_pos + 1);
51736
+ c22 = str2.charCodeAt(m_pos + 1);
51737
51737
  if ((c22 & 64512) === 56320) {
51738
51738
  c2 = 65536 + (c2 - 55296 << 10) + (c22 - 56320);
51739
51739
  m_pos++;
@@ -51743,9 +51743,9 @@ var require_fontkit_umd = __commonJS({
51743
51743
  }
51744
51744
  buf = new common.Buf8(buf_len);
51745
51745
  for (i3 = 0, m_pos = 0; i3 < buf_len; m_pos++) {
51746
- c2 = str.charCodeAt(m_pos);
51746
+ c2 = str2.charCodeAt(m_pos);
51747
51747
  if ((c2 & 64512) === 55296 && m_pos + 1 < str_len) {
51748
- c22 = str.charCodeAt(m_pos + 1);
51748
+ c22 = str2.charCodeAt(m_pos + 1);
51749
51749
  if ((c22 & 64512) === 56320) {
51750
51750
  c2 = 65536 + (c2 - 55296 << 10) + (c22 - 56320);
51751
51751
  m_pos++;
@@ -51784,10 +51784,10 @@ var require_fontkit_umd = __commonJS({
51784
51784
  var buf2binstring_1 = function buf2binstring_12(buf) {
51785
51785
  return buf2binstring(buf, buf.length);
51786
51786
  };
51787
- var binstring2buf = function binstring2buf2(str) {
51788
- var buf = new common.Buf8(str.length);
51787
+ var binstring2buf = function binstring2buf2(str2) {
51788
+ var buf = new common.Buf8(str2.length);
51789
51789
  for (var i3 = 0, len2 = buf.length; i3 < len2; i3++) {
51790
- buf[i3] = str.charCodeAt(i3);
51790
+ buf[i3] = str2.charCodeAt(i3);
51791
51791
  }
51792
51792
  return buf;
51793
51793
  };
@@ -57197,7 +57197,7 @@ var require_fontkit_umd = __commonJS({
57197
57197
  this.tags = dfa2.tags;
57198
57198
  }
57199
57199
  var _proto = StateMachine2.prototype;
57200
- _proto.match = function match(str) {
57200
+ _proto.match = function match(str2) {
57201
57201
  var _ref;
57202
57202
  var self2 = this;
57203
57203
  return _ref = {}, _ref[Symbol.iterator] = /* @__PURE__ */ regeneratorRuntime.mark(function _callee() {
@@ -57212,11 +57212,11 @@ var require_fontkit_umd = __commonJS({
57212
57212
  lastState = null;
57213
57213
  p4 = 0;
57214
57214
  case 5:
57215
- if (!(p4 < str.length)) {
57215
+ if (!(p4 < str2.length)) {
57216
57216
  _context.next = 21;
57217
57217
  break;
57218
57218
  }
57219
- c2 = str[p4];
57219
+ c2 = str2[p4];
57220
57220
  lastState = state;
57221
57221
  state = self2.stateTable[state][c2];
57222
57222
  if (!(state === FAIL_STATE)) {
@@ -57261,13 +57261,13 @@ var require_fontkit_umd = __commonJS({
57261
57261
  }, _callee);
57262
57262
  }), _ref;
57263
57263
  };
57264
- _proto.apply = function apply3(str, actions) {
57265
- for (var _iterator2 = _createForOfIteratorHelperLoose$e(this.match(str)), _step2; !(_step2 = _iterator2()).done; ) {
57264
+ _proto.apply = function apply3(str2, actions) {
57265
+ for (var _iterator2 = _createForOfIteratorHelperLoose$e(this.match(str2)), _step2; !(_step2 = _iterator2()).done; ) {
57266
57266
  var _step$value = _step2.value, start = _step$value[0], end = _step$value[1], tags = _step$value[2];
57267
57267
  for (var _iterator22 = _createForOfIteratorHelperLoose$e(tags), _step22; !(_step22 = _iterator22()).done; ) {
57268
57268
  var tag2 = _step22.value;
57269
57269
  if (typeof actions[tag2] === "function") {
57270
- actions[tag2](start, end, str.slice(start, end + 1));
57270
+ actions[tag2](start, end, str2.slice(start, end + 1));
57271
57271
  }
57272
57272
  }
57273
57273
  }
@@ -59881,9 +59881,9 @@ var require_fontkit_umd = __commonJS({
59881
59881
  var stream2 = this._font.stream;
59882
59882
  var pos = stream2.pos;
59883
59883
  var cff = this._font.CFF2 || this._font["CFF "];
59884
- var str = cff.topDict.CharStrings[this.id];
59885
- var end = str.offset + str.length;
59886
- stream2.pos = str.offset;
59884
+ var str2 = cff.topDict.CharStrings[this.id];
59885
+ var end = str2.offset + str2.length;
59886
+ stream2.pos = str2.offset;
59887
59887
  var path = new Path();
59888
59888
  var stack = [];
59889
59889
  var trans = [];
@@ -66278,8 +66278,8 @@ function identlike(chars3) {
66278
66278
  }
66279
66279
  return { type: Tok.Ident, value: v };
66280
66280
  }
66281
- function tokenize(str = "") {
66282
- let chars3 = str.trim();
66281
+ function tokenize(str2 = "") {
66282
+ let chars3 = str2.trim();
66283
66283
  let tokens = [];
66284
66284
  let ch;
66285
66285
  _i = 0;
@@ -70353,20 +70353,20 @@ var init_strings = __esm({
70353
70353
  }
70354
70354
  return padding + value;
70355
70355
  };
70356
- stringAsByteArray = (str) => {
70357
- const buffer = new Uint8Array(str.length);
70358
- copyStringIntoBuffer(str, buffer, 0);
70356
+ stringAsByteArray = (str2) => {
70357
+ const buffer = new Uint8Array(str2.length);
70358
+ copyStringIntoBuffer(str2, buffer, 0);
70359
70359
  return buffer;
70360
70360
  };
70361
- copyStringIntoBuffer = (str, buffer, offset) => {
70362
- const length = str.length;
70361
+ copyStringIntoBuffer = (str2, buffer, offset) => {
70362
+ const length = str2.length;
70363
70363
  for (let idx = 0; idx < length; idx++) {
70364
- buffer[offset++] = str.charCodeAt(idx);
70364
+ buffer[offset++] = str2.charCodeAt(idx);
70365
70365
  }
70366
70366
  return length;
70367
70367
  };
70368
70368
  addRandomSuffix = (prefix, suffixLength = 4) => `${prefix}-${Math.floor(Math.random() * Math.pow(10, suffixLength))}`;
70369
- escapeRegExp = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
70369
+ escapeRegExp = (str2) => str2.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
70370
70370
  cleanText = (text) => text.replace(/\t|\u0085|\u2028|\u2029/g, " ").replace(/[\b\v]/g, "");
70371
70371
  escapedNewlineChars = ["\\n", "\\f", "\\r", "\\u000B"];
70372
70372
  newlineChars = ["\n", "\f", "\r", "\v"];
@@ -70528,11 +70528,11 @@ var init_arrays = __esm({
70528
70528
  return mergedBuffer;
70529
70529
  };
70530
70530
  arrayAsString = (array2) => {
70531
- let str = "";
70531
+ let str2 = "";
70532
70532
  for (let idx = 0, len = array2.length; idx < len; idx++) {
70533
- str += charFromCode(array2[idx]);
70533
+ str2 += charFromCode(array2[idx]);
70534
70534
  }
70535
- return str;
70535
+ return str2;
70536
70536
  };
70537
70537
  byAscendingId = (a, b) => a.id - b.id;
70538
70538
  sortedUniq = (array2, indexer) => {
@@ -71568,11 +71568,11 @@ var init_utils = __esm({
71568
71568
  return bytes;
71569
71569
  };
71570
71570
  arrayToString = (array2) => {
71571
- let str = "";
71571
+ let str2 = "";
71572
71572
  for (let i2 = 0; i2 < array2.length; i2++) {
71573
- str += String.fromCharCode(array2[i2]);
71573
+ str2 += String.fromCharCode(array2[i2]);
71574
71574
  }
71575
- return str;
71575
+ return str2;
71576
71576
  };
71577
71577
  decompressJson = (compressedJson) => arrayToString(unzlibSync(decodeFromBase642(compressedJson)));
71578
71578
  padStart2 = (value, length, padChar) => {
@@ -71801,9 +71801,9 @@ var init_Encoding = __esm({
71801
71801
  this.encodeUnicodeCodePoint = (codePoint) => {
71802
71802
  const mapped = this.unicodeMappings[codePoint];
71803
71803
  if (!mapped) {
71804
- const str = String.fromCharCode(codePoint);
71804
+ const str2 = String.fromCharCode(codePoint);
71805
71805
  const hexCode = `0x${padStart2(codePoint.toString(16), 4, "0")}`;
71806
- const msg = `${this.name} cannot encode "${str}" (${hexCode})`;
71806
+ const msg = `${this.name} cannot encode "${str2}" (${hexCode})`;
71807
71807
  throw new Error(msg);
71808
71808
  }
71809
71809
  return { code: mapped[0], name: mapped[1] };
@@ -80910,7 +80910,7 @@ var init_FlateStream = __esm({
80910
80910
  readBlock() {
80911
80911
  let buffer;
80912
80912
  let len;
80913
- const str = this.stream;
80913
+ const str2 = this.stream;
80914
80914
  let hdr = this.getBits(3);
80915
80915
  if (hdr & 1) {
80916
80916
  this.eof = true;
@@ -80918,19 +80918,19 @@ var init_FlateStream = __esm({
80918
80918
  hdr >>= 1;
80919
80919
  if (hdr === 0) {
80920
80920
  let b;
80921
- if ((b = str.getByte()) === -1) {
80921
+ if ((b = str2.getByte()) === -1) {
80922
80922
  throw new Error("Bad block header in flate stream");
80923
80923
  }
80924
80924
  let blockLen = b;
80925
- if ((b = str.getByte()) === -1) {
80925
+ if ((b = str2.getByte()) === -1) {
80926
80926
  throw new Error("Bad block header in flate stream");
80927
80927
  }
80928
80928
  blockLen |= b << 8;
80929
- if ((b = str.getByte()) === -1) {
80929
+ if ((b = str2.getByte()) === -1) {
80930
80930
  throw new Error("Bad block header in flate stream");
80931
80931
  }
80932
80932
  let check2 = b;
80933
- if ((b = str.getByte()) === -1) {
80933
+ if ((b = str2.getByte()) === -1) {
80934
80934
  throw new Error("Bad block header in flate stream");
80935
80935
  }
80936
80936
  check2 |= b << 8;
@@ -80944,12 +80944,12 @@ var init_FlateStream = __esm({
80944
80944
  const end = bufferLength + blockLen;
80945
80945
  this.bufferLength = end;
80946
80946
  if (blockLen === 0) {
80947
- if (str.peekByte() === -1) {
80947
+ if (str2.peekByte() === -1) {
80948
80948
  this.eof = true;
80949
80949
  }
80950
80950
  } else {
80951
80951
  for (let n = bufferLength; n < end; ++n) {
80952
- if ((b = str.getByte()) === -1) {
80952
+ if ((b = str2.getByte()) === -1) {
80953
80953
  this.eof = true;
80954
80954
  break;
80955
80955
  }
@@ -81049,12 +81049,12 @@ var init_FlateStream = __esm({
81049
81049
  }
81050
81050
  }
81051
81051
  getBits(bits2) {
81052
- const str = this.stream;
81052
+ const str2 = this.stream;
81053
81053
  let codeSize = this.codeSize;
81054
81054
  let codeBuf = this.codeBuf;
81055
81055
  let b;
81056
81056
  while (codeSize < bits2) {
81057
- if ((b = str.getByte()) === -1) {
81057
+ if ((b = str2.getByte()) === -1) {
81058
81058
  throw new Error("Bad encoding in flate stream");
81059
81059
  }
81060
81060
  codeBuf |= b << codeSize;
@@ -81066,14 +81066,14 @@ var init_FlateStream = __esm({
81066
81066
  return b;
81067
81067
  }
81068
81068
  getCode(table) {
81069
- const str = this.stream;
81069
+ const str2 = this.stream;
81070
81070
  const codes = table[0];
81071
81071
  const maxLen = table[1];
81072
81072
  let codeSize = this.codeSize;
81073
81073
  let codeBuf = this.codeBuf;
81074
81074
  let b;
81075
81075
  while (codeSize < maxLen) {
81076
- if ((b = str.getByte()) === -1) {
81076
+ if ((b = str2.getByte()) === -1) {
81077
81077
  break;
81078
81078
  }
81079
81079
  codeBuf |= b << codeSize;
@@ -81813,7 +81813,7 @@ var init_PDFObjectParser = __esm({
81813
81813
  if (this.cryptoFactory && ref) {
81814
81814
  const transformer = this.cryptoFactory.createCipherTransform(ref.objectNumber, ref.generationNumber);
81815
81815
  const arr = transformer.decryptBytes(PDFHexString_default.of(value).asBytes());
81816
- value = arr.reduce((str, byte) => str + byte.toString(16).padStart(2, "0"), "");
81816
+ value = arr.reduce((str2, byte) => str2 + byte.toString(16).padStart(2, "0"), "");
81817
81817
  }
81818
81818
  return PDFHexString_default.of(value);
81819
81819
  }
@@ -86755,8 +86755,8 @@ var require_src = __commonJS({
86755
86755
  get structure() {
86756
86756
  const res = [];
86757
86757
  let indention = 0;
86758
- function write(str) {
86759
- res.push(" ".repeat(indention) + str);
86758
+ function write(str2) {
86759
+ res.push(" ".repeat(indention) + str2);
86760
86760
  }
86761
86761
  function dfs(node2) {
86762
86762
  const idStr = node2.id ? "#" + node2.id : "";
@@ -100257,16 +100257,16 @@ var init_dist = __esm({
100257
100257
  if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) {
100258
100258
  return UTF8Decoder.decode(heapOrArray.subarray(idx, endPtr));
100259
100259
  }
100260
- var str = "";
100260
+ var str2 = "";
100261
100261
  while (idx < endPtr) {
100262
100262
  var u0 = heapOrArray[idx++];
100263
100263
  if (!(u0 & 128)) {
100264
- str += String.fromCharCode(u0);
100264
+ str2 += String.fromCharCode(u0);
100265
100265
  continue;
100266
100266
  }
100267
100267
  var u1 = heapOrArray[idx++] & 63;
100268
100268
  if ((u0 & 224) == 192) {
100269
- str += String.fromCharCode((u0 & 31) << 6 | u1);
100269
+ str2 += String.fromCharCode((u0 & 31) << 6 | u1);
100270
100270
  continue;
100271
100271
  }
100272
100272
  var u2 = heapOrArray[idx++] & 63;
@@ -100277,13 +100277,13 @@ var init_dist = __esm({
100277
100277
  u0 = (u0 & 7) << 18 | u1 << 12 | u2 << 6 | heapOrArray[idx++] & 63;
100278
100278
  }
100279
100279
  if (u0 < 65536) {
100280
- str += String.fromCharCode(u0);
100280
+ str2 += String.fromCharCode(u0);
100281
100281
  } else {
100282
100282
  var ch = u0 - 65536;
100283
- str += String.fromCharCode(55296 | ch >> 10, 56320 | ch & 1023);
100283
+ str2 += String.fromCharCode(55296 | ch >> 10, 56320 | ch & 1023);
100284
100284
  }
100285
100285
  }
100286
- return str;
100286
+ return str2;
100287
100287
  };
100288
100288
  var UTF8ToString = (ptr, maxBytesToRead) => {
100289
100289
  assert2(typeof ptr == "number", `UTF8ToString expects a number (got ${typeof ptr})`);
@@ -100429,10 +100429,10 @@ var init_dist = __esm({
100429
100429
  }
100430
100430
  };
100431
100431
  var FS_stdin_getChar_buffer = [];
100432
- var lengthBytesUTF8 = (str) => {
100432
+ var lengthBytesUTF8 = (str2) => {
100433
100433
  var len = 0;
100434
- for (var i2 = 0; i2 < str.length; ++i2) {
100435
- var c2 = str.charCodeAt(i2);
100434
+ for (var i2 = 0; i2 < str2.length; ++i2) {
100435
+ var c2 = str2.charCodeAt(i2);
100436
100436
  if (c2 <= 127) {
100437
100437
  len++;
100438
100438
  } else if (c2 <= 2047) {
@@ -100446,16 +100446,16 @@ var init_dist = __esm({
100446
100446
  }
100447
100447
  return len;
100448
100448
  };
100449
- var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
100450
- assert2(typeof str === "string", `stringToUTF8Array expects a string (got ${typeof str})`);
100449
+ var stringToUTF8Array = (str2, heap, outIdx, maxBytesToWrite) => {
100450
+ assert2(typeof str2 === "string", `stringToUTF8Array expects a string (got ${typeof str2})`);
100451
100451
  if (!(maxBytesToWrite > 0))
100452
100452
  return 0;
100453
100453
  var startIdx = outIdx;
100454
100454
  var endIdx = outIdx + maxBytesToWrite - 1;
100455
- for (var i2 = 0; i2 < str.length; ++i2) {
100456
- var u = str.charCodeAt(i2);
100455
+ for (var i2 = 0; i2 < str2.length; ++i2) {
100456
+ var u = str2.charCodeAt(i2);
100457
100457
  if (u >= 55296 && u <= 57343) {
100458
- var u1 = str.charCodeAt(++i2);
100458
+ var u1 = str2.charCodeAt(++i2);
100459
100459
  u = 65536 + ((u & 1023) << 10) | u1 & 1023;
100460
100460
  }
100461
100461
  if (u <= 127) {
@@ -101051,7 +101051,7 @@ var init_dist = __esm({
101051
101051
  processData(url2);
101052
101052
  }
101053
101053
  };
101054
- var FS_modeStringToFlags = (str) => {
101054
+ var FS_modeStringToFlags = (str2) => {
101055
101055
  var flagModes = {
101056
101056
  "r": 0,
101057
101057
  "r+": 2,
@@ -101060,9 +101060,9 @@ var init_dist = __esm({
101060
101060
  "a": 1024 | 64 | 1,
101061
101061
  "a+": 1024 | 64 | 2
101062
101062
  };
101063
- var flags = flagModes[str];
101063
+ var flags = flagModes[str2];
101064
101064
  if (typeof flags == "undefined") {
101065
- throw new Error(`Unknown file open mode: ${str}`);
101065
+ throw new Error(`Unknown file open mode: ${str2}`);
101066
101066
  }
101067
101067
  return flags;
101068
101068
  };
@@ -102768,9 +102768,9 @@ var init_dist = __esm({
102768
102768
  return -e4.errno;
102769
102769
  }
102770
102770
  }
102771
- var stringToUTF8 = (str, outPtr, maxBytesToWrite) => {
102771
+ var stringToUTF8 = (str2, outPtr, maxBytesToWrite) => {
102772
102772
  assert2(typeof maxBytesToWrite == "number", "stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!");
102773
- return stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite);
102773
+ return stringToUTF8Array(str2, HEAPU8, outPtr, maxBytesToWrite);
102774
102774
  };
102775
102775
  function ___syscall_getdents64(fd2, dirp, count) {
102776
102776
  try {
@@ -103128,10 +103128,10 @@ var init_dist = __esm({
103128
103128
  }
103129
103129
  return getEnvStrings.strings;
103130
103130
  };
103131
- var stringToAscii = (str, buffer) => {
103132
- for (var i2 = 0; i2 < str.length; ++i2) {
103133
- assert2(str.charCodeAt(i2) === (str.charCodeAt(i2) & 255));
103134
- HEAP8[buffer++] = str.charCodeAt(i2);
103131
+ var stringToAscii = (str2, buffer) => {
103132
+ for (var i2 = 0; i2 < str2.length; ++i2) {
103133
+ assert2(str2.charCodeAt(i2) === (str2.charCodeAt(i2) & 255));
103134
+ HEAP8[buffer++] = str2.charCodeAt(i2);
103135
103135
  }
103136
103136
  HEAP8[buffer] = 0;
103137
103137
  };
@@ -103260,13 +103260,13 @@ var init_dist = __esm({
103260
103260
  endPtr = idx << 1;
103261
103261
  if (endPtr - ptr > 32 && UTF16Decoder)
103262
103262
  return UTF16Decoder.decode(HEAPU8.subarray(ptr, endPtr));
103263
- var str = "";
103263
+ var str2 = "";
103264
103264
  for (var i2 = 0; !(i2 >= maxBytesToRead / 2); ++i2) {
103265
103265
  var codeUnit = HEAP16[ptr + i2 * 2 >> 1];
103266
103266
  if (codeUnit == 0) break;
103267
- str += String.fromCharCode(codeUnit);
103267
+ str2 += String.fromCharCode(codeUnit);
103268
103268
  }
103269
- return str;
103269
+ return str2;
103270
103270
  };
103271
103271
  var uleb128Encode = (n, target) => {
103272
103272
  assert2(n < 16384);
@@ -103448,18 +103448,18 @@ var init_dist = __esm({
103448
103448
  HEAP8.set(array2, buffer);
103449
103449
  };
103450
103450
  var stackAlloc = (sz) => __emscripten_stack_alloc(sz);
103451
- var stringToUTF8OnStack = (str) => {
103452
- var size = lengthBytesUTF8(str) + 1;
103451
+ var stringToUTF8OnStack = (str2) => {
103452
+ var size = lengthBytesUTF8(str2) + 1;
103453
103453
  var ret = stackAlloc(size);
103454
- stringToUTF8(str, ret, size);
103454
+ stringToUTF8(str2, ret, size);
103455
103455
  return ret;
103456
103456
  };
103457
103457
  var ccall = (ident2, returnType, argTypes, args, opts) => {
103458
103458
  var toC = {
103459
- "string": (str) => {
103459
+ "string": (str2) => {
103460
103460
  var ret2 = 0;
103461
- if (str !== null && str !== void 0 && str !== 0) {
103462
- ret2 = stringToUTF8OnStack(str);
103461
+ if (str2 !== null && str2 !== void 0 && str2 !== 0) {
103462
+ ret2 = stringToUTF8OnStack(str2);
103463
103463
  }
103464
103464
  return ret2;
103465
103465
  },
@@ -103507,16 +103507,16 @@ var init_dist = __esm({
103507
103507
  setWasmTableEntry(index2, null);
103508
103508
  freeTableIndexes.push(index2);
103509
103509
  };
103510
- var stringToUTF16 = (str, outPtr, maxBytesToWrite) => {
103510
+ var stringToUTF16 = (str2, outPtr, maxBytesToWrite) => {
103511
103511
  assert2(outPtr % 2 == 0, "Pointer passed to stringToUTF16 must be aligned to two bytes!");
103512
103512
  assert2(typeof maxBytesToWrite == "number", "stringToUTF16(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!");
103513
103513
  maxBytesToWrite ??= 2147483647;
103514
103514
  if (maxBytesToWrite < 2) return 0;
103515
103515
  maxBytesToWrite -= 2;
103516
103516
  var startPtr = outPtr;
103517
- var numCharsToWrite = maxBytesToWrite < str.length * 2 ? maxBytesToWrite / 2 : str.length;
103517
+ var numCharsToWrite = maxBytesToWrite < str2.length * 2 ? maxBytesToWrite / 2 : str2.length;
103518
103518
  for (var i2 = 0; i2 < numCharsToWrite; ++i2) {
103519
- var codeUnit = str.charCodeAt(i2);
103519
+ var codeUnit = str2.charCodeAt(i2);
103520
103520
  HEAP16[outPtr >> 1] = codeUnit;
103521
103521
  outPtr += 2;
103522
103522
  }
@@ -106120,14 +106120,14 @@ function promiseAllObject(promisesObj) {
106120
106120
  }
106121
106121
  function randomString(length = 10) {
106122
106122
  const chars3 = "abcdefghijklmnopqrstuvwxyz";
106123
- let str = "";
106123
+ let str2 = "";
106124
106124
  for (let i2 = 0; i2 < length; i2++) {
106125
- str += chars3[Math.floor(Math.random() * chars3.length)];
106125
+ str2 += chars3[Math.floor(Math.random() * chars3.length)];
106126
106126
  }
106127
- return str;
106127
+ return str2;
106128
106128
  }
106129
- function esc(str) {
106130
- return JSON.stringify(str);
106129
+ function esc(str2) {
106130
+ return JSON.stringify(str2);
106131
106131
  }
106132
106132
  function slugify(input2) {
106133
106133
  return input2.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/[\s_-]+/g, "-").replace(/^-+|-+$/g, "");
@@ -106241,8 +106241,8 @@ var primitiveTypes = /* @__PURE__ */ new Set([
106241
106241
  "symbol",
106242
106242
  "undefined"
106243
106243
  ]);
106244
- function escapeRegex(str) {
106245
- return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
106244
+ function escapeRegex(str2) {
106245
+ return str2.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
106246
106246
  }
106247
106247
  function clone(inst, def, params) {
106248
106248
  const cl = new inst._zod.constr(def ?? inst._zod.def);
@@ -106496,13 +106496,13 @@ function getSizableOrigin(input2) {
106496
106496
  return "unknown";
106497
106497
  }
106498
106498
  var highSurrogate = /[\uD800-\uDBFF]/;
106499
- function codePointLength(str) {
106500
- const units = str.length;
106501
- if (!highSurrogate.test(str))
106499
+ function codePointLength(str2) {
106500
+ const units = str2.length;
106501
+ if (!highSurrogate.test(str2))
106502
106502
  return units;
106503
106503
  let count = units;
106504
106504
  for (let i2 = 0; i2 < units - 1; i2++) {
106505
- if ((str.charCodeAt(i2) & 64512) === 55296 && (str.charCodeAt(i2 + 1) & 64512) === 56320) {
106505
+ if ((str2.charCodeAt(i2) & 64512) === 55296 && (str2.charCodeAt(i2 + 1) & 64512) === 56320) {
106506
106506
  count--;
106507
106507
  i2++;
106508
106508
  }
@@ -120700,13 +120700,13 @@ function _promise(Class2, innerType) {
120700
120700
  }
120701
120701
  // @__NO_SIDE_EFFECTS__
120702
120702
  function _custom(Class2, fn5, _params) {
120703
- const norm2 = normalizeParams(_params);
120704
- norm2.abort ?? (norm2.abort = true);
120703
+ const norm3 = normalizeParams(_params);
120704
+ norm3.abort ?? (norm3.abort = true);
120705
120705
  const schema = new Class2({
120706
120706
  type: "custom",
120707
120707
  check: "custom",
120708
120708
  fn: fn5,
120709
- ...norm2
120709
+ ...norm3
120710
120710
  });
120711
120711
  return schema;
120712
120712
  }
@@ -134845,8 +134845,8 @@ function combCharAt(cur, len, i2, ch) {
134845
134845
  const out = Array.from(cur);
134846
134846
  while (out.length < len) out.push(" ");
134847
134847
  out[i2] = ch === "" ? " " : ch;
134848
- const str = out.slice(0, len).join("");
134849
- return str.trim() === "" ? "" : str;
134848
+ const str2 = out.slice(0, len).join("");
134849
+ return str2.trim() === "" ? "" : str2;
134850
134850
  }
134851
134851
  function combEntries(slots, chars3) {
134852
134852
  const out = [];
@@ -134949,9 +134949,9 @@ function buildMarks({
134949
134949
  return s != null ? { markFontSize: s } : {};
134950
134950
  };
134951
134951
  const out = /* @__PURE__ */ new Map();
134952
- const onPage2 = (page) => pageFilter === void 0 || page === pageFilter;
134952
+ const onPage3 = (page) => pageFilter === void 0 || page === pageFilter;
134953
134953
  const push = (page, m) => {
134954
- if (!onPage2(page)) return;
134954
+ if (!onPage3(page)) return;
134955
134955
  let arr = out.get(page);
134956
134956
  if (!arr) {
134957
134957
  arr = [];
@@ -136202,6 +136202,13 @@ function editDistance(a, b) {
136202
136202
  }
136203
136203
  return prev[b.length];
136204
136204
  }
136205
+ var MIN_VALUE_PREFIX = 4;
136206
+ function prefixHits(key, ids) {
136207
+ const lk = key.toLowerCase();
136208
+ if (lk.length < MIN_VALUE_PREFIX) return [];
136209
+ return [...new Set([...ids].filter((id) => id.toLowerCase().startsWith(lk)))];
136210
+ }
136211
+ var ambiguous = (hits2) => `ambiguous: it starts ${String(hits2.length)} ids; give more characters`;
136205
136212
  function suggestIds(key, items2) {
136206
136213
  const out = [];
136207
136214
  const add = (id) => {
@@ -136212,9 +136219,11 @@ function suggestIds(key, items2) {
136212
136219
  for (const it of items2) if (normLabel(it.label) === nk) add(it.id);
136213
136220
  }
136214
136221
  const lk = key.toLowerCase();
136215
- if (lk.length >= 4) {
136216
- for (const it of items2) if (it.id.toLowerCase().startsWith(lk)) add(it.id);
136217
- }
136222
+ for (const id of prefixHits(
136223
+ key,
136224
+ items2.map((it) => it.id)
136225
+ ))
136226
+ add(id);
136218
136227
  if (lk.length <= 64) {
136219
136228
  const limit = Math.max(2, Math.floor(lk.length / 4));
136220
136229
  items2.map((it) => ({ id: it.id, d: editDistance(lk, it.id.toLowerCase()) })).filter((x2) => x2.d <= limit).sort((x2, y) => x2.d - y.d).slice(0, 3).forEach((x2) => {
@@ -136291,6 +136300,9 @@ function matchOption(options, raw, groupLabel = "") {
136291
136300
  suggestions: bare
136292
136301
  };
136293
136302
  }
136303
+ const pre = prefixHits(v, ids);
136304
+ if (pre.length === 1) return { id: pre[0] };
136305
+ if (pre.length > 1) return { reason: ambiguous(pre), suggestions: pre.slice(0, 5) };
136294
136306
  const labels = options.map((o) => JSON.stringify(labelOf(o))).join(", ");
136295
136307
  return { reason: `no option has this id or label (options: ${labels})`, suggestions: ids };
136296
136308
  }
@@ -136309,18 +136321,26 @@ function matchColumn(columns, key) {
136309
136321
  return { reason: "unknown column", suggestions: suggestIds(key, columns) };
136310
136322
  }
136311
136323
  var MAX_SUGGESTED = 50;
136312
- function nestedOwners(entries) {
136324
+ function nestedIdOwners(entries) {
136313
136325
  const out = /* @__PURE__ */ new Map();
136314
- const put = (id, what, owner) => {
136315
- if (!out.has(id)) out.set(id, { what, owner });
136326
+ const put = (id, kind, what, owner) => {
136327
+ if (!out.has(id)) out.set(id, { kind, what, owner });
136316
136328
  };
136317
136329
  for (const e4 of entries) {
136318
- if (e4.kind === "choice") for (const o of e4.options) put(o.id, "an option", e4);
136319
- if (e4.kind === "table_rows") for (const c2 of e4.columns) put(c2.id, "a column", e4);
136320
- if (e4.kind !== "field") for (const m of e4.members) put(m.id, "a cell", e4);
136330
+ if (e4.kind === "field") continue;
136331
+ if (e4.kind === "choice") for (const o of e4.options) put(o.id, "option", "an option", e4);
136332
+ if (e4.kind === "table") for (const c2 of e4.cells) put(c2.id, "cell", "a cell", e4);
136333
+ if (e4.kind === "table_rows") for (const c2 of e4.columns) put(c2.id, "column", "a column", e4);
136334
+ for (const m of e4.members) put(m.id, "member", "a cell", e4);
136321
136335
  }
136322
136336
  return out;
136323
136337
  }
136338
+ function nestedOwner(owners, key) {
136339
+ const exact = owners.get(key);
136340
+ if (exact) return exact;
136341
+ const hits2 = prefixHits(key, owners.keys());
136342
+ return hits2.length === 1 ? owners.get(hits2[0]) : void 0;
136343
+ }
136324
136344
  function mapInternal(schema, input2, loadImage2) {
136325
136345
  if (!isRecord(input2)) throw new TypeError("values must be an object keyed by agent id");
136326
136346
  const entries = agentEntries(schema);
@@ -136401,7 +136421,13 @@ function mapInternal(schema, input2, loadImage2) {
136401
136421
  const sid = `${e4.id}.${cellId}`;
136402
136422
  const cell = e4.cells.find((c3) => c3.id === cellId);
136403
136423
  if (!cell) {
136404
- skip(sid, "not a cell of this table", suggestIds(cellId, e4.cells));
136424
+ owners ??= nestedIdOwners(entries);
136425
+ const own2 = nestedOwner(owners, cellId);
136426
+ skip(
136427
+ sid,
136428
+ own2 && own2.owner.id !== e4.id ? `not a cell of this table: it is ${own2.what} of "${own2.owner.label}" (${own2.owner.id})` : "not a cell of this table",
136429
+ suggestIds(cellId, e4.cells)
136430
+ );
136405
136431
  continue;
136406
136432
  }
136407
136433
  if (v === null || v === void 0) continue;
@@ -136469,13 +136495,24 @@ function mapInternal(schema, input2, loadImage2) {
136469
136495
  for (const [key, raw] of Object.entries(input2)) {
136470
136496
  const e4 = byId.get(key);
136471
136497
  if (!e4) {
136472
- owners ??= nestedOwners(entries);
136473
- const own2 = owners.get(key);
136498
+ owners ??= nestedIdOwners(entries);
136499
+ const hits2 = owners.has(key) ? [] : prefixHits(key, [...byId.keys(), ...owners.keys()]);
136500
+ const own2 = owners.get(key) ?? (hits2.length === 1 ? owners.get(hits2[0]) : void 0);
136474
136501
  if (own2) {
136502
+ const full = owners.has(key) ? key : hits2[0];
136503
+ const what = full === key ? own2.what : `${own2.what} (${full})`;
136475
136504
  skip(
136476
136505
  key,
136477
- `not a top-level id: this is ${own2.what} of "${own2.owner.label}" (${own2.owner.id}); pass it inside that entry's value`,
136478
- [own2.owner.id]
136506
+ own2.what === "an option" ? `not a top-level id: this is ${what} of "${own2.owner.label}" (${own2.owner.id}); pass it as that group's value, or give it alone with true (a radio takes one option)` : `not a top-level id: this is ${what} of "${own2.owner.label}" (${own2.owner.id}); pass it inside that entry's value`,
136507
+ full === key ? [own2.owner.id] : [own2.owner.id, full]
136508
+ );
136509
+ } else if (hits2.length > 1) {
136510
+ skip(key, ambiguous(hits2), hits2.slice(0, 5));
136511
+ } else if (hits2.length === 1) {
136512
+ skip(
136513
+ key,
136514
+ Object.prototype.hasOwnProperty.call(input2, hits2[0]) ? `a short id of ${hits2[0]}, which is given too: give each entry once` : `unknown id: did you mean ${hits2[0]}? give the full id`,
136515
+ hits2
136479
136516
  );
136480
136517
  } else {
136481
136518
  skip(key, "unknown id", suggested++ < MAX_SUGGESTED ? suggestIds(key, entries) : void 0);
@@ -136635,15 +136672,75 @@ var CheckCopyError = class extends Error {
136635
136672
  this.at = { ...at };
136636
136673
  }
136637
136674
  };
136638
- async function buildCheckPdf(stamped, entries, status, fonts, banner = true, tags = true) {
136675
+ async function buildCheckPdf(stamped, entries, status, fonts, banner = true, tags = true, avoid = {}) {
136639
136676
  const at = { stage: "load" };
136640
136677
  try {
136641
- return await drawCheckPdf(stamped, entries, status, fonts, banner, tags, at);
136678
+ return await drawCheckPdf(stamped, entries, status, fonts, banner, tags, avoid, at);
136642
136679
  } catch (e4) {
136643
136680
  throw new CheckCopyError(at, e4);
136644
136681
  }
136645
136682
  }
136646
- async function drawCheckPdf(stamped, entries, status, fonts, banner, tags, at) {
136683
+ var TAG_REACH = 30;
136684
+ function gapOf(a, b) {
136685
+ const dx = Math.max(0, b.x - (a.x + a.w), a.x - (b.x + b.w));
136686
+ const dy = Math.max(0, b.y - (a.y + a.h), a.y - (b.y + b.h));
136687
+ return Math.hypot(dx, dy);
136688
+ }
136689
+ function leaderOf(tag, box) {
136690
+ const cx2 = tag.x + tag.w / 2;
136691
+ const cy2 = tag.y + tag.h / 2;
136692
+ const end = {
136693
+ x: Math.min(Math.max(cx2, box.x), box.x + box.w),
136694
+ y: Math.min(Math.max(cy2, box.y), box.y + box.h)
136695
+ };
136696
+ const start = {
136697
+ x: Math.min(Math.max(end.x, tag.x), tag.x + tag.w),
136698
+ y: Math.min(Math.max(end.y, tag.y), tag.y + tag.h)
136699
+ };
136700
+ return { start, end };
136701
+ }
136702
+ function crosses(a, b, r) {
136703
+ let t0 = 0;
136704
+ let t1 = 1;
136705
+ const dx = b.x - a.x;
136706
+ const dy = b.y - a.y;
136707
+ const edges = [
136708
+ [-dx, a.x - r.x],
136709
+ [dx, r.x + r.w - a.x],
136710
+ [-dy, a.y - r.y],
136711
+ [dy, r.y + r.h - a.y]
136712
+ ];
136713
+ for (const [p4, q] of edges) {
136714
+ if (p4 === 0) {
136715
+ if (q < 0) return false;
136716
+ continue;
136717
+ }
136718
+ const t = q / p4;
136719
+ if (p4 < 0) t0 = Math.max(t0, t);
136720
+ else t1 = Math.min(t1, t);
136721
+ if (t0 > t1) return false;
136722
+ }
136723
+ return true;
136724
+ }
136725
+ function overlapArea(a, b) {
136726
+ const w = Math.min(a.x + a.w, b.x + b.w) - Math.max(a.x, b.x);
136727
+ const h = Math.min(a.y + a.h, b.y + b.h) - Math.max(a.y, b.y);
136728
+ return w > 0 && h > 0 ? w * h : 0;
136729
+ }
136730
+ function captionSide(box, printed) {
136731
+ let left = Infinity;
136732
+ let right = Infinity;
136733
+ const reach = Math.max(4 * box.h, 24);
136734
+ for (const g of printed) {
136735
+ const shared = Math.min(g.y + g.h, box.y + box.h) - Math.max(g.y, box.y);
136736
+ if (shared < 0.4 * Math.min(g.h, box.h)) continue;
136737
+ if (g.x >= box.x + box.w) right = Math.min(right, g.x - (box.x + box.w));
136738
+ else if (g.x + g.w <= box.x) left = Math.min(left, box.x - (g.x + g.w));
136739
+ }
136740
+ if (Math.min(left, right) > reach) return null;
136741
+ return left < right ? "left" : "right";
136742
+ }
136743
+ async function drawCheckPdf(stamped, entries, status, fonts, banner, tags, avoid, at) {
136647
136744
  const step = (stage, id) => {
136648
136745
  at.stage = stage;
136649
136746
  at.id = id;
@@ -136672,7 +136769,7 @@ async function drawCheckPdf(stamped, entries, status, fonts, banner, tags, at) {
136672
136769
  if (bb) boxes.push({ id: e4.id, page: e4.group.page, box: bb, st, thin: false, tagged: true });
136673
136770
  if (e4.kind === "choice") {
136674
136771
  for (const o of e4.options)
136675
- boxes.push({ id: o.id, page: o.page, box: o, st, thin: true, tagged: true });
136772
+ boxes.push({ id: o.id, page: o.page, box: o, st, thin: true, tagged: true, owner: e4.id });
136676
136773
  }
136677
136774
  if (e4.kind === "table") {
136678
136775
  for (const c2 of e4.cells)
@@ -136688,6 +136785,22 @@ async function drawCheckPdf(stamped, entries, status, fonts, banner, tags, at) {
136688
136785
  return { x: b.box.xpct / 100 * pw, y: ph - b.box.ypct / 100 * ph - h, w, h };
136689
136786
  };
136690
136787
  const placedTags = /* @__PURE__ */ new Map();
136788
+ const inkByPage = /* @__PURE__ */ new Map();
136789
+ const inkOf = (page, pw, ph) => {
136790
+ let ink = inkByPage.get(page);
136791
+ if (!ink) {
136792
+ ink = [];
136793
+ for (const r of avoid.printed?.[page] ?? []) ink.push({ x: r.x, y: r.y, w: r.w, h: r.h });
136794
+ for (const mk of avoid.marks?.get(page) ?? []) {
136795
+ const b = mk.box;
136796
+ const w = b.wPct / 100 * pw;
136797
+ const h = b.hPct / 100 * ph;
136798
+ ink.push({ x: b.xPct / 100 * pw, y: ph - b.yPct / 100 * ph - h, w, h });
136799
+ }
136800
+ inkByPage.set(page, ink);
136801
+ }
136802
+ return ink;
136803
+ };
136691
136804
  const HEAD = 4;
136692
136805
  const headColor = rgb3(0.15, 0.35, 0.75);
136693
136806
  const wanted = [];
@@ -136796,6 +136909,7 @@ async function drawCheckPdf(stamped, entries, status, fonts, banner, tags, at) {
136796
136909
  const tag = asciiOnly(short.get(b.id) ?? b.id);
136797
136910
  const tw = helv.widthOfTextAtSize(tag, SIZE) + 1.6;
136798
136911
  const th = SIZE + 1.2;
136912
+ const self2 = { x: x2, y, w, h };
136799
136913
  const right = x2 + w - tw;
136800
136914
  const wide = w > 3 * tw;
136801
136915
  const above = { x: wide ? right : x2, y: y + h + 0.2 };
@@ -136805,16 +136919,83 @@ async function drawCheckPdf(stamped, entries, status, fonts, banner, tags, at) {
136805
136919
  const side = { x: x2 + w + 0.8, y: y + h - th };
136806
136920
  const left = { x: x2 - tw - 0.8, y: y + h - th };
136807
136921
  const inside = { x: x2, y: y + h - th - 0.2 };
136808
- const candidates = b.thin ? [below, belowRight, above, aboveOther, side, left] : [above, aboveOther, below, belowRight, side, left];
136809
- const others = boxes.filter((o) => o !== b && o.page === b.page).map((o) => rectOf(o, pw, ph));
136922
+ const win = {
136923
+ x: x2 - TAG_REACH - tw,
136924
+ y: y - TAG_REACH - th,
136925
+ w: w + 2 * (TAG_REACH + tw),
136926
+ h: h + 2 * (TAG_REACH + th)
136927
+ };
136928
+ const ink = inkOf(b.page, pw, ph).filter((r) => hits(r, win));
136929
+ const caption = b.thin ? captionSide(self2, ink) : null;
136930
+ const candidates = b.thin ? caption === "left" ? [below, belowRight, above, aboveOther, side, left] : [below, belowRight, above, aboveOther, left, side] : [above, aboveOther, below, belowRight, side, left];
136931
+ const others = boxes.filter((o) => o !== b && o.page === b.page && o.id !== b.owner).map((o) => rectOf(o, pw, ph)).filter((r) => hits(r, win));
136810
136932
  const taken = placedTags.get(b.page) ?? [];
136933
+ const takenNear = taken.filter((r) => hits(r, win));
136934
+ const rectAt = (c2) => ({ x: c2.x, y: c2.y, w: tw, h: th });
136935
+ const onPage3 = (r) => r.x >= 0 && r.y >= 0 && r.x + r.w <= pw && r.y + r.h <= ph;
136936
+ const clearOfInk = (r) => !ink.some((o) => hits(r, o));
136811
136937
  const fits = (c2) => {
136812
- const r = { x: c2.x, y: c2.y, w: tw, h: th };
136813
- return r.x >= 0 && r.y >= 0 && r.x + r.w <= pw && r.y + r.h <= ph && !others.some((o) => hits(r, o)) && !taken.some((o) => hits(r, o));
136814
- };
136815
- const spot = candidates.find(fits) ?? (y + h + 0.2 + th <= ph && !b.thin ? above : inside);
136816
- taken.push({ x: spot.x, y: spot.y, w: tw, h: th });
136938
+ const r = rectAt(c2);
136939
+ return onPage3(r) && clearOfInk(r) && !others.some((o) => hits(r, o)) && !takenNear.some((o) => hits(r, o));
136940
+ };
136941
+ let spot = candidates.find(fits);
136942
+ let leader = false;
136943
+ if (!spot) {
136944
+ const ring = [];
136945
+ const stepX = Math.max(2, tw / 3);
136946
+ const stepY = Math.max(1.5, th / 2);
136947
+ for (let yy = y - TAG_REACH - th; yy <= y + h + TAG_REACH; yy += stepY) {
136948
+ for (let xx = x2 - TAG_REACH - tw; xx <= x2 + w + TAG_REACH; xx += stepX) {
136949
+ const r = rectAt({ x: xx, y: yy });
136950
+ if (hits(r, self2)) continue;
136951
+ const d = gapOf(r, self2);
136952
+ if (d <= TAG_REACH) ring.push({ x: xx, y: yy, d });
136953
+ }
136954
+ }
136955
+ ring.sort((p4, q) => p4.d - q.d);
136956
+ const fitsAt = (c2) => c2.fits ??= fits(c2);
136957
+ const DETOUR = 12;
136958
+ const crossesInk = (c2) => {
136959
+ if (c2.d <= 1.5) return false;
136960
+ const { start, end } = leaderOf(rectAt(c2), self2);
136961
+ return ink.some(
136962
+ (o) => crosses(start, end, { x: o.x - 1, y: o.y - 1, w: o.w + 2, h: o.h + 2 })
136963
+ );
136964
+ };
136965
+ const sameLine3 = (c2) => c2.y + th / 2 >= y && c2.y + th / 2 <= y + h;
136966
+ const first2 = ring.find(fitsAt);
136967
+ let near;
136968
+ let best = Infinity;
136969
+ for (const c2 of ring) {
136970
+ if (!first2 || c2.d > first2.d + DETOUR) break;
136971
+ if (!fitsAt(c2)) continue;
136972
+ const score = c2.d + (crossesInk(c2) ? DETOUR : 0) + (sameLine3(c2) ? 0 : DETOUR / 2);
136973
+ if (score < best) {
136974
+ best = score;
136975
+ near = c2;
136976
+ }
136977
+ }
136978
+ if (near) {
136979
+ spot = near;
136980
+ leader = near.d > 1.5;
136981
+ }
136982
+ }
136983
+ if (!spot && onPage3(rectAt(inside)) && clearOfInk(rectAt(inside))) spot = inside;
136984
+ if (!spot) {
136985
+ const cost = (c2) => {
136986
+ const r = rectAt(c2);
136987
+ const covered = ink.reduce((n, o) => n + overlapArea(r, o), 0);
136988
+ const crowd = [...others, ...takenNear].filter((o) => hits(r, o)).length;
136989
+ return covered * 100 + crowd;
136990
+ };
136991
+ spot = [...candidates, inside].filter((c2) => onPage3(rectAt(c2))).reduce((best, c2) => !best || cost(c2) < cost(best) ? c2 : best, void 0) ?? inside;
136992
+ }
136993
+ taken.push(rectAt(spot));
136817
136994
  placedTags.set(b.page, taken);
136995
+ if (leader) {
136996
+ const { start, end } = leaderOf(rectAt(spot), self2);
136997
+ page.drawLine({ start, end, thickness: 0.3, color, opacity: 0.8 });
136998
+ }
136818
136999
  page.drawRectangle({
136819
137000
  x: spot.x,
136820
137001
  y: spot.y,
@@ -136883,7 +137064,8 @@ async function fillAgentPdf(a) {
136883
137064
  (id) => skippedIds.has(id) ? "skipped" : warned.has(id) ? "warned" : m.filledIds.has(id) ? "filled" : "empty",
136884
137065
  a.fonts,
136885
137066
  a.checkBanner !== false,
136886
- a.checkTags !== false
137067
+ a.checkTags !== false,
137068
+ { printed: a.checkPrinted, marks: marksByPage }
136887
137069
  );
136888
137070
  res.checkPdf = built.pdf;
136889
137071
  warnings.push(...built.notes);
@@ -137518,16 +137700,16 @@ function compactView(agent, requested, next, maxChars = COMPACT_MAX_CHARS) {
137518
137700
  const full = { ...base, sections: nestBySection(entries) };
137519
137701
  if (pages.length <= 1 || JSON.stringify(full).length <= maxChars) return full;
137520
137702
  const overview = pages.map((page) => {
137521
- const onPage2 = entries.filter((e4) => e4.page === page);
137703
+ const onPage3 = entries.filter((e4) => e4.page === page);
137522
137704
  const titles = [];
137523
- for (const e4 of onPage2) {
137705
+ for (const e4 of onPage3) {
137524
137706
  const t = e4.section?.title;
137525
137707
  if (t && !titles.includes(t)) titles.push(t);
137526
137708
  }
137527
137709
  const row = {
137528
137710
  page,
137529
- fields: onPage2.length,
137530
- required: onPage2.filter((e4) => e4.required === true).length
137711
+ fields: onPage3.length,
137712
+ required: onPage3.filter((e4) => e4.required === true).length
137531
137713
  };
137532
137714
  if (titles.length) row.sections = titles.slice(0, OVERVIEW_TITLES_PER_PAGE);
137533
137715
  return row;
@@ -137678,8 +137860,8 @@ async function estimateAnalyze(e4) {
137678
137860
 
137679
137861
  // src/fill.ts
137680
137862
  import { randomBytes as randomBytes2 } from "node:crypto";
137681
- import { promises as fsp2, readFileSync as readFileSync2, statSync } from "node:fs";
137682
- import { basename, dirname as dirname3, isAbsolute as isAbsolute2, join as join4, relative, resolve as resolve2 } from "node:path";
137863
+ import { promises as fsp2, readFileSync as readFileSync3, statSync } from "node:fs";
137864
+ import { basename, dirname as dirname4, isAbsolute as isAbsolute2, join as join5, relative, resolve as resolve2 } from "node:path";
137683
137865
 
137684
137866
  // src/config.ts
137685
137867
  import { homedir } from "node:os";
@@ -137797,8 +137979,295 @@ function loadFonts(dir = defaultFontsDir()) {
137797
137979
  }
137798
137980
  }
137799
137981
 
137982
+ // src/render.ts
137983
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
137984
+ import { createRequire as createRequire2 } from "node:module";
137985
+ import { dirname as dirname3, join as join4 } from "node:path";
137986
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
137987
+ import { deflateSync } from "node:zlib";
137988
+ var DEFAULT_DPI = 110;
137989
+ var MAX_DPI = 200;
137990
+ var MIN_DPI = 36;
137991
+ var MAX_SIDE_PX = 3e3;
137992
+ var loading = null;
137993
+ function wasmPath() {
137994
+ const here = dirname3(fileURLToPath2(import.meta.url));
137995
+ const bundled = join4(here, "pdfium.wasm");
137996
+ if (existsSync2(bundled)) return bundled;
137997
+ const req = createRequire2(import.meta.url);
137998
+ return req.resolve("@embedpdf/pdfium/pdfium.wasm");
137999
+ }
138000
+ async function loadPdfium() {
138001
+ let wasm;
138002
+ try {
138003
+ wasm = readFileSync2(wasmPath());
138004
+ } catch {
138005
+ throw new ToolError("renderer_missing", "The page renderer (pdfium.wasm) could not be read.", {
138006
+ hint: "Reinstall @fenfill/mcp (npx -y @fenfill/mcp@latest). fill_form's check_pdf still works without it."
138007
+ });
138008
+ }
138009
+ const { init: init2 } = await Promise.resolve().then(() => (init_dist(), dist_exports));
138010
+ const quiet = () => void 0;
138011
+ const mod = await init2({
138012
+ wasmBinary: wasm.buffer.slice(wasm.byteOffset, wasm.byteOffset + wasm.byteLength),
138013
+ // The loader would print to stdout, which is the JSON-RPC channel.
138014
+ print: quiet,
138015
+ printErr: quiet
138016
+ });
138017
+ mod.PDFiumExt_Init();
138018
+ return mod;
138019
+ }
138020
+ function pdfium() {
138021
+ loading ??= loadPdfium().catch((e4) => {
138022
+ loading = null;
138023
+ throw e4;
138024
+ });
138025
+ return loading;
138026
+ }
138027
+ var FPDF_ANNOT = 1;
138028
+ var FPDF_REVERSE_BYTE_ORDER = 16;
138029
+ async function withDoc(pdf, fn5) {
138030
+ const m = await pdfium();
138031
+ const p4 = m.pdfium;
138032
+ const heap = () => p4.HEAPU8;
138033
+ const ptr = p4.wasmExports.malloc(pdf.length);
138034
+ if (!ptr) throw new ToolError("render_failed", "Not enough memory to render this page.");
138035
+ let doc = 0;
138036
+ try {
138037
+ heap().set(pdf, ptr);
138038
+ doc = m.FPDF_LoadMemDocument(ptr, pdf.length, "");
138039
+ if (!doc) {
138040
+ throw new ToolError("render_failed", "The page renderer couldn't open this PDF.", {
138041
+ hint: "Use fill_form with check_pdf instead and open the .check.pdf."
138042
+ });
138043
+ }
138044
+ return await fn5(m, doc, heap);
138045
+ } finally {
138046
+ if (doc) m.FPDF_CloseDocument(doc);
138047
+ p4.wasmExports.free(ptr);
138048
+ }
138049
+ }
138050
+ function onPage(m, doc, page, heap, fn5) {
138051
+ const count = m.FPDF_GetPageCount(doc);
138052
+ if (page < 1 || page > count) {
138053
+ throw new ToolError("invalid_page", `The PDF has ${String(count)} pages.`, {
138054
+ hint: `Pass page between 1 and ${String(count)}.`
138055
+ });
138056
+ }
138057
+ const pg = m.FPDF_LoadPage(doc, page - 1);
138058
+ if (!pg) throw new ToolError("render_failed", "The page renderer couldn't load this page.");
138059
+ try {
138060
+ return fn5(m, pg, heap);
138061
+ } finally {
138062
+ m.FPDF_ClosePage(pg);
138063
+ }
138064
+ }
138065
+ function withPage(pdf, page, fn5) {
138066
+ return withDoc(pdf, (m, doc, heap) => onPage(m, doc, page, heap, fn5));
138067
+ }
138068
+ async function renderPage(pdf, page, dpi, crop, maxSide = MAX_SIDE_PX) {
138069
+ return withPage(pdf, page, (m, pg, heap) => {
138070
+ const wPt = m.FPDF_GetPageWidthF(pg);
138071
+ const hPt = m.FPDF_GetPageHeightF(pg);
138072
+ const c2 = crop ?? { x: 0, y: 0, w: 1, h: 1 };
138073
+ let scale2 = dpi / 72;
138074
+ const longest = Math.max(wPt * c2.w, hPt * c2.h) * scale2;
138075
+ if (longest > maxSide) scale2 *= maxSide / longest;
138076
+ const fullW = Math.max(1, Math.round(wPt * scale2));
138077
+ const fullH = Math.max(1, Math.round(hPt * scale2));
138078
+ const x0 = Math.round(c2.x * fullW);
138079
+ const y0 = Math.round(c2.y * fullH);
138080
+ const width = Math.max(1, Math.min(fullW - x0, Math.round(c2.w * fullW)));
138081
+ const height = Math.max(1, Math.min(fullH - y0, Math.round(c2.h * fullH)));
138082
+ const bmp = m.FPDFBitmap_Create(width, height, 0);
138083
+ if (!bmp) throw new ToolError("render_failed", "Not enough memory to render this page.");
138084
+ try {
138085
+ m.FPDFBitmap_FillRect(bmp, 0, 0, width, height, 4294967295);
138086
+ m.FPDF_RenderPageBitmap(
138087
+ bmp,
138088
+ pg,
138089
+ -x0,
138090
+ -y0,
138091
+ fullW,
138092
+ fullH,
138093
+ 0,
138094
+ FPDF_ANNOT | FPDF_REVERSE_BYTE_ORDER
138095
+ );
138096
+ const stride = m.FPDFBitmap_GetStride(bmp);
138097
+ const buf = m.FPDFBitmap_GetBuffer(bmp);
138098
+ const rgba = new Uint8Array(width * 4 * height);
138099
+ const h8 = heap();
138100
+ for (let y = 0; y < height; y++) {
138101
+ const row = buf + y * stride;
138102
+ rgba.set(h8.subarray(row, row + width * 4), y * width * 4);
138103
+ }
138104
+ return { width, height, rgba, scale: scale2 };
138105
+ } finally {
138106
+ m.FPDFBitmap_Destroy(bmp);
138107
+ }
138108
+ });
138109
+ }
138110
+ var textMemo = /* @__PURE__ */ new WeakMap();
138111
+ function memoOf(pdf) {
138112
+ let byPage = textMemo.get(pdf);
138113
+ if (!byPage) {
138114
+ byPage = /* @__PURE__ */ new Map();
138115
+ textMemo.set(pdf, byPage);
138116
+ }
138117
+ return byPage;
138118
+ }
138119
+ function pageText(pdf, page) {
138120
+ const byPage = memoOf(pdf);
138121
+ let text = byPage.get(page);
138122
+ if (!text) {
138123
+ text = withPage(pdf, page, readText);
138124
+ byPage.set(page, text);
138125
+ text.catch(() => byPage.delete(page));
138126
+ }
138127
+ return text;
138128
+ }
138129
+ function readText(m, pg, heap) {
138130
+ const widthPt = m.FPDF_GetPageWidthF(pg);
138131
+ const heightPt = m.FPDF_GetPageHeightF(pg);
138132
+ const glyphs = [];
138133
+ const own2 = [];
138134
+ const tp = m.FPDFText_LoadPage(pg);
138135
+ if (!tp) return { widthPt, heightPt, glyphs, own: own2 };
138136
+ const p4 = m.pdfium;
138137
+ const out = p4.wasmExports.malloc(32);
138138
+ const rgba = p4.wasmExports.malloc(16);
138139
+ const dev = p4.wasmExports.malloc(8);
138140
+ const DEV = 64;
138141
+ const devW = Math.max(1, Math.round(widthPt * DEV));
138142
+ const devH = Math.max(1, Math.round(heightPt * DEV));
138143
+ const shown = (x2, y) => {
138144
+ m.FPDF_PageToDevice(pg, 0, 0, devW, devH, 0, x2, y, dev, dev + 4);
138145
+ const [dx, dy] = new Int32Array(heap().buffer, dev, 2);
138146
+ return [dx / devW, dy / devH];
138147
+ };
138148
+ try {
138149
+ if (!out || !rgba || !dev) {
138150
+ throw new ToolError("render_failed", "Not enough memory to read this page's text.");
138151
+ }
138152
+ const n = m.FPDFText_CountChars(tp);
138153
+ for (let i2 = 0; i2 < n; i2++) {
138154
+ const u = m.FPDFText_GetUnicode(tp, i2);
138155
+ if (u <= 32 || u === 160 || u === 65534 || u === 65535) continue;
138156
+ if (!m.FPDFText_GetCharBox(tp, i2, out, out + 8, out + 16, out + 24)) continue;
138157
+ const [left, right, bottom, top] = new Float64Array(heap().buffer, out, 4);
138158
+ if (!(right > left) || !(top > bottom)) continue;
138159
+ let lum = null;
138160
+ if (m.FPDFText_GetFillColor(tp, i2, rgba, rgba + 4, rgba + 8, rgba + 12)) {
138161
+ const [r, g, b, a] = new Uint32Array(heap().buffer, rgba, 4);
138162
+ lum = 255 - (255 - (0.299 * r + 0.587 * g + 0.114 * b)) * (a / 255);
138163
+ }
138164
+ const [ax, ay] = shown(left, top);
138165
+ const [bx, by] = shown(right, bottom);
138166
+ glyphs.push({
138167
+ x: Math.min(ax, bx),
138168
+ y: Math.min(ay, by),
138169
+ w: Math.abs(bx - ax),
138170
+ h: Math.abs(by - ay),
138171
+ char: String.fromCodePoint(u),
138172
+ i: i2,
138173
+ lum
138174
+ });
138175
+ own2.push({ left, bottom, right, top });
138176
+ }
138177
+ } finally {
138178
+ if (out) p4.wasmExports.free(out);
138179
+ if (rgba) p4.wasmExports.free(rgba);
138180
+ if (dev) p4.wasmExports.free(dev);
138181
+ m.FPDFText_ClosePage(tp);
138182
+ }
138183
+ return { widthPt, heightPt, glyphs, own: own2 };
138184
+ }
138185
+ async function printedBoxes(pdf, pages) {
138186
+ const out = {};
138187
+ const wanted = [...new Set(pages)];
138188
+ const byPage = memoOf(pdf);
138189
+ if (wanted.some((page) => !byPage.has(page))) {
138190
+ try {
138191
+ await withDoc(pdf, (m, doc, heap) => {
138192
+ for (const page of wanted) {
138193
+ if (byPage.has(page)) continue;
138194
+ try {
138195
+ byPage.set(page, Promise.resolve(onPage(m, doc, page, heap, readText)));
138196
+ } catch {
138197
+ }
138198
+ }
138199
+ });
138200
+ } catch {
138201
+ }
138202
+ }
138203
+ for (const page of wanted) {
138204
+ const text = byPage.get(page);
138205
+ if (!text) continue;
138206
+ try {
138207
+ out[page] = (await text).own.map((g) => ({
138208
+ x: g.left,
138209
+ y: g.bottom,
138210
+ w: g.right - g.left,
138211
+ h: g.top - g.bottom
138212
+ }));
138213
+ } catch {
138214
+ }
138215
+ }
138216
+ return out;
138217
+ }
138218
+ var CRC_TABLE2 = (() => {
138219
+ const t = new Uint32Array(256);
138220
+ for (let n = 0; n < 256; n++) {
138221
+ let c2 = n;
138222
+ for (let k4 = 0; k4 < 8; k4++) c2 = c2 & 1 ? 3988292384 ^ c2 >>> 1 : c2 >>> 1;
138223
+ t[n] = c2 >>> 0;
138224
+ }
138225
+ return t;
138226
+ })();
138227
+ function crc322(bytes) {
138228
+ let c2 = 4294967295;
138229
+ for (const b of bytes) c2 = CRC_TABLE2[(c2 ^ b) & 255] ^ c2 >>> 8;
138230
+ return (c2 ^ 4294967295) >>> 0;
138231
+ }
138232
+ function chunk(type, data) {
138233
+ const body = Buffer.concat([Buffer.from(type, "latin1"), data]);
138234
+ const out = Buffer.alloc(body.length + 8);
138235
+ out.writeUInt32BE(data.length, 0);
138236
+ body.copy(out, 4);
138237
+ out.writeUInt32BE(crc322(body), body.length + 4);
138238
+ return out;
138239
+ }
138240
+ function encodePng2(r) {
138241
+ const row = 1 + r.width * 3;
138242
+ const raw = Buffer.alloc(row * r.height);
138243
+ for (let y = 0; y < r.height; y++) {
138244
+ const src = y * r.width * 4;
138245
+ const dst = y * row;
138246
+ raw[dst] = 0;
138247
+ for (let x2 = 0; x2 < r.width; x2++) {
138248
+ const s = src + x2 * 4;
138249
+ const d = dst + 1 + x2 * 3;
138250
+ raw[d] = r.rgba[s];
138251
+ raw[d + 1] = r.rgba[s + 1];
138252
+ raw[d + 2] = r.rgba[s + 2];
138253
+ }
138254
+ }
138255
+ const ihdr = Buffer.alloc(13);
138256
+ ihdr.writeUInt32BE(r.width, 0);
138257
+ ihdr.writeUInt32BE(r.height, 4);
138258
+ ihdr.set([8, 2, 0, 0, 0], 8);
138259
+ return new Uint8Array(
138260
+ Buffer.concat([
138261
+ Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]),
138262
+ chunk("IHDR", ihdr),
138263
+ chunk("IDAT", deflateSync(raw, { level: 6 })),
138264
+ chunk("IEND", new Uint8Array(0))
138265
+ ])
138266
+ );
138267
+ }
138268
+
137800
138269
  // src/version.ts
137801
- var VERSION = true ? "0.2.2" : "0.0.0-dev";
138270
+ var VERSION = true ? "0.2.3" : "0.0.0-dev";
137802
138271
  var USER_AGENT = `fenfill-mcp/${VERSION}`;
137803
138272
 
137804
138273
  // src/fill.ts
@@ -137864,7 +138333,7 @@ async function resolveOutputPath(outputPath, opts) {
137864
138333
  if (!out.toLowerCase().endsWith(".pdf")) {
137865
138334
  throw new ToolError("invalid_output_path", "output_path must end in .pdf.");
137866
138335
  }
137867
- const dir = dirname3(out);
138336
+ const dir = dirname4(out);
137868
138337
  let realDir;
137869
138338
  try {
137870
138339
  realDir = await fsp2.realpath(dir);
@@ -137874,7 +138343,7 @@ async function resolveOutputPath(outputPath, opts) {
137874
138343
  hint: "Create the folder first, or pick an existing one."
137875
138344
  });
137876
138345
  }
137877
- const realOut = join4(realDir, basename(out));
138346
+ const realOut = join5(realDir, basename(out));
137878
138347
  let realCache = resolve2(opts.cacheRoot);
137879
138348
  try {
137880
138349
  realCache = await fsp2.realpath(realCache);
@@ -137921,7 +138390,7 @@ async function resolveOutputPath(outputPath, opts) {
137921
138390
  return out;
137922
138391
  }
137923
138392
  async function writeOutputAtomic(out, pdf, overwrite) {
137924
- const tmp = join4(dirname3(out), `.${basename(out)}.${randomBytes2(6).toString("hex")}.tmp`);
138393
+ const tmp = join5(dirname4(out), `.${basename(out)}.${randomBytes2(6).toString("hex")}.tmp`);
137925
138394
  let fh = null;
137926
138395
  const exists = () => new ToolError("output_exists", "A file already exists at output_path.", {
137927
138396
  hint: "Pick a new file name, or pass overwrite=true to replace it."
@@ -137964,7 +138433,7 @@ function loadImage(p4) {
137964
138433
  const st = statSync(abs2);
137965
138434
  if (!st.isFile()) throw new Error("image_path is not a file.");
137966
138435
  if (st.size > MAX_IMAGE_BYTES2) throw new Error("The signature image is over 5 MB.");
137967
- return new Uint8Array(readFileSync2(abs2));
138436
+ return new Uint8Array(readFileSync3(abs2));
137968
138437
  }
137969
138438
  function isPasswordError(e4) {
137970
138439
  return e4 instanceof Error && /password/i.test(e4.message);
@@ -137991,6 +138460,8 @@ async function checkPathFor(outputAbs, opts) {
137991
138460
  return resolveOutputPath(outputAbs.replace(/\.pdf$/i, ".check.pdf"), opts);
137992
138461
  }
137993
138462
  async function stampAndWrite(a) {
138463
+ const pages = Array.isArray(a.render.pages) ? a.render.pages.map((p4) => p4.page).filter((p4) => typeof p4 === "number") : [];
138464
+ const printed = a.checkAbs ? await printedBoxes(a.pdfBytes, pages) : void 0;
137994
138465
  let res;
137995
138466
  try {
137996
138467
  res = await fillAgentPdf({
@@ -138002,7 +138473,8 @@ async function stampAndWrite(a) {
138002
138473
  logoBytes: a.logoBytes,
138003
138474
  loadImage,
138004
138475
  infoTags: OUTPUT_TAGS,
138005
- check: !!a.checkAbs
138476
+ check: !!a.checkAbs,
138477
+ checkPrinted: printed
138006
138478
  });
138007
138479
  } catch (e4) {
138008
138480
  if (isPasswordError(e4)) throw passwordError();
@@ -139478,7 +139950,7 @@ var EchoGuard = class {
139478
139950
  let hit = false;
139479
139951
  if (this.seen.has(n)) {
139480
139952
  if (n.length < ECHO_REFUSE_MIN) {
139481
- warn.add(w.id);
139953
+ if (!w.quiet) warn.add(w.id);
139482
139954
  continue;
139483
139955
  }
139484
139956
  hit = true;
@@ -139649,6 +140121,7 @@ var bad = (msg) => {
139649
140121
  var isRec2 = (x2) => typeof x2 === "object" && x2 !== null && !Array.isArray(x2);
139650
140122
  var isNum = (x2) => typeof x2 === "number" && Number.isFinite(x2);
139651
140123
  var round = (n, d = 4) => Math.round(n * 10 ** d) / 10 ** d;
140124
+ var REF_NAME = /^[A-Za-z][A-Za-z0-9_-]{0,31}$/;
139652
140125
  function index(s) {
139653
140126
  const field = /* @__PURE__ */ new Map();
139654
140127
  for (const f3 of s.fields) if (f3 && typeof f3.id === "string") field.set(f3.id, f3);
@@ -139671,8 +140144,18 @@ function index(s) {
139671
140144
  return { s, field, group, owner, section };
139672
140145
  }
139673
140146
  var MIN_ID_PREFIX = 6;
139674
- function resolveId(d, raw, kinds = ["field", "group"], name = "id") {
139675
- if (typeof raw !== "string" || !raw) return bad(`${name} is required`);
140147
+ function resolveId(d, given, kinds = ["field", "group"], name = "id") {
140148
+ if (typeof given !== "string" || !given) return bad(`${name} is required`);
140149
+ let raw = given;
140150
+ if (raw.startsWith("$")) {
140151
+ const made = d.refs?.get(raw.slice(1));
140152
+ if (made === void 0) {
140153
+ return bad(
140154
+ `${name} ${raw}: no earlier op of this batch made "${raw.slice(1)}" (give that op ref: "${raw.slice(1)}"; a rejected op makes nothing)`
140155
+ );
140156
+ }
140157
+ raw = made;
140158
+ }
139676
140159
  const pools = kinds.map(
139677
140160
  (k4) => k4 === "field" ? d.field : k4 === "group" ? d.group : d.section
139678
140161
  );
@@ -139751,13 +140234,13 @@ function checkFraction(v, name, min = 0, max2 = 1) {
139751
140234
  return n;
139752
140235
  }
139753
140236
  var ON_PAGE = "the box must lie on the page (x + w \u2264 1, y + h \u2264 1, fractions of the page)";
139754
- function onPage(b) {
140237
+ function onPage2(b) {
139755
140238
  const eps = 1e-6;
139756
140239
  return !(b.x < -eps || b.y < -eps || b.x + b.w > 1 + eps || b.y + b.h > 1 + eps);
139757
140240
  }
139758
140241
  function checkBoxOnPage(b) {
139759
140242
  if (b.w <= 0 || b.h <= 0) bad("the box must have a positive width and height");
139760
- if (!onPage(b)) bad(ON_PAGE);
140243
+ if (!onPage2(b)) bad(ON_PAGE);
139761
140244
  }
139762
140245
  function boxArg(v, name = "box") {
139763
140246
  if (!isRec2(v)) return bad(`${name} {x, y, w, h} is required (fractions of the page, top-left)`);
@@ -139966,13 +140449,13 @@ function checkIndex(v, n, name) {
139966
140449
  }
139967
140450
  return v;
139968
140451
  }
139969
- function clusterCenters(centers, gap) {
140452
+ function clusterCenters(centers, gap2) {
139970
140453
  if (centers.length === 0) return [];
139971
140454
  const ordered = [...centers].sort((a, b) => a - b);
139972
140455
  let cluster = [ordered[0]];
139973
140456
  const means = [];
139974
140457
  for (const c2 of ordered.slice(1)) {
139975
- if (c2 - cluster[cluster.length - 1] > gap) {
140458
+ if (c2 - cluster[cluster.length - 1] > gap2) {
139976
140459
  means.push(cluster.reduce((s, v) => s + v, 0) / cluster.length);
139977
140460
  cluster = [c2];
139978
140461
  } else {
@@ -140889,6 +141372,8 @@ var OP_NAMES = [
140889
141372
  "set_options",
140890
141373
  "add_option",
140891
141374
  "remove_option",
141375
+ "comb_add_cell",
141376
+ "comb_remove_cell",
140892
141377
  "set_required",
140893
141378
  "set_description",
140894
141379
  "set_placeholder",
@@ -141084,6 +141569,7 @@ function applyOne(d, op, warnings, opts) {
141084
141569
  case "retype": {
141085
141570
  const { f: f3, g } = needId(d, op.id);
141086
141571
  if (typeof op.type !== "string") return bad("type is required");
141572
+ if (op.type === "comb") return retypeComb(d, op, g ? void 0 : f3, warnings);
141087
141573
  if (g) {
141088
141574
  if (g.kind === "table") {
141089
141575
  return bad(
@@ -141117,6 +141603,7 @@ function applyOne(d, op, warnings, opts) {
141117
141603
  return { touched: [fld.id] };
141118
141604
  }
141119
141605
  case "add": {
141606
+ if (op.type === "comb") return addComb(d, op);
141120
141607
  const page = pageOf(d, op.page);
141121
141608
  const box = boxArg(op.box);
141122
141609
  if (typeof op.label !== "string")
@@ -141152,7 +141639,13 @@ function applyOne(d, op, warnings, opts) {
141152
141639
  d.s.fields.push(f3);
141153
141640
  d.field.set(id, f3);
141154
141641
  const snapped = snapField(d, f3, raw, opts, warnings);
141155
- return { touched: [id], added: id, geometry: id, snapped };
141642
+ return {
141643
+ touched: [id],
141644
+ added: id,
141645
+ geometry: id,
141646
+ snapped,
141647
+ section: sectionOf(d, page, id)
141648
+ };
141156
141649
  }
141157
141650
  case "delete": {
141158
141651
  const { f: f3, g } = needId(d, op.id);
@@ -141188,26 +141681,18 @@ function applyOne(d, op, warnings, opts) {
141188
141681
  g.kind === "table" ? "a table's formats live on its cells: set_format a cell (it applies to the cell's whole column or row), or set_column_type" : "set_format applies to a field, or to a comb group (cell_type, date_format)"
141189
141682
  );
141190
141683
  }
141191
- const comb = g;
141192
- const dated = op.format.date_format !== void 0 && op.format.date_format !== null;
141193
- for (const [k4, v] of Object.entries(op.format)) {
141194
- if (k4 !== "cell_type" && k4 !== "date_format")
141195
- bad(`a comb group's format keys are cell_type and date_format, not ${k4}`);
141196
- if (k4 === "date_format" && v !== null) checkCombDateFormat(d, g, v);
141197
- if (v === null) delete comb[k4];
141198
- else comb[k4] = v;
141199
- }
141200
- if (dated) {
141201
- if (op.format.cell_type !== void 0 && op.format.cell_type !== "date")
141202
- bad('date_format needs cell_type "date": leave cell_type out, or pass "date"');
141203
- comb.cell_type = "date";
141204
- }
141205
- return { touched: [g.id], comb: g.id };
141684
+ return setCombFormat(d, g, op.format);
141206
141685
  }
141207
141686
  const fld = f3;
141208
141687
  const own2 = d.owner.get(fld.id);
141209
- if (own2 && (own2.kind === "comb" || own2.kind === "choice")) {
141210
- bad(`this is a member of ${String(own2.kind)} group ${own2.id}, whose kind fixes its format`);
141688
+ if (own2?.kind === "comb") {
141689
+ warnings.push(
141690
+ `${fld.id}: a comb's cell takes its comb's format; applied to comb ${own2.id}`
141691
+ );
141692
+ return setCombFormat(d, own2, op.format);
141693
+ }
141694
+ if (own2?.kind === "choice") {
141695
+ bad(`this is a member of choice group ${own2.id}, whose kind fixes its format`);
141211
141696
  }
141212
141697
  if (fld.type === "signature" && !isRec2(fld.format)) fld.format = {};
141213
141698
  const next = { ...isRec2(fld.format) ? fld.format : {} };
@@ -141276,9 +141761,18 @@ function applyOne(d, op, warnings, opts) {
141276
141761
  delete f3.signing_requirement;
141277
141762
  d.owner.set(f3.id, g);
141278
141763
  }
141764
+ const ranks = fs.map((f3) => f3.order).filter((o) => typeof o === "number");
141765
+ if (ranks.length) g.order = Math.min(...ranks);
141279
141766
  d.s.groups.push(g);
141280
141767
  d.group.set(gid, g);
141281
- return { touched: [gid], added: gid };
141768
+ if (op.kind === "comb") setCombTyping(d, g, op.cell_type, op.date_format);
141769
+ return {
141770
+ touched: [gid],
141771
+ added: gid,
141772
+ members: readingMembers(d, g).map((m) => m.id),
141773
+ section: sectionOf(d, page, gid),
141774
+ ...op.kind === "comb" ? { comb: gid } : {}
141775
+ };
141282
141776
  }
141283
141777
  case "ungroup": {
141284
141778
  const g = needGroup(d, op.id);
@@ -141367,6 +141861,44 @@ function applyOne(d, op, warnings, opts) {
141367
141861
  removeFields(d, /* @__PURE__ */ new Set([oid]));
141368
141862
  return { touched: [g.id], deleted: [oid] };
141369
141863
  }
141864
+ case "comb_add_cell": {
141865
+ const g = needGroup(d, op.id);
141866
+ if (g.kind !== "comb") return bad("comb_add_cell applies to a comb group id");
141867
+ const box = boxArg(op.box);
141868
+ const ms = members2(d, g);
141869
+ const f3 = combCell(g, box, ms.find((m) => typeof m.section_id === "string")?.section_id);
141870
+ d.s.fields.push(f3);
141871
+ d.field.set(f3.id, f3);
141872
+ d.owner.set(f3.id, g);
141873
+ g.members = [...Array.isArray(g.members) ? g.members : [], f3.id];
141874
+ keepDateFormat(d, g, op.date_format);
141875
+ return {
141876
+ touched: [g.id, f3.id],
141877
+ added: f3.id,
141878
+ comb: g.id,
141879
+ members: readingMembers(d, g).map((m) => m.id)
141880
+ };
141881
+ }
141882
+ case "comb_remove_cell": {
141883
+ const f3 = needField(d, op.id);
141884
+ const g = d.owner.get(f3.id);
141885
+ if (!g || g.kind !== "comb") return bad(`${f3.id} is not a cell of a comb`);
141886
+ if (Array.isArray(f3.cells) && f3.cells.length > 1)
141887
+ return bad(
141888
+ `${f3.id} is one field over ${String(f3.cells.length)} printed cells: delete it, or retype the comb`
141889
+ );
141890
+ if (combSlotCount(d, g) - 1 < 2)
141891
+ return bad("a comb keeps at least 2 cells; delete or ungroup it instead");
141892
+ dropMembers(d, g, /* @__PURE__ */ new Set([f3.id]));
141893
+ removeFields(d, /* @__PURE__ */ new Set([f3.id]));
141894
+ keepDateFormat(d, g, op.date_format);
141895
+ return {
141896
+ touched: [g.id],
141897
+ deleted: [f3.id],
141898
+ comb: g.id,
141899
+ members: readingMembers(d, g).map((m) => m.id)
141900
+ };
141901
+ }
141370
141902
  case "set_required": {
141371
141903
  const { f: f3, g } = needId(d, op.id);
141372
141904
  if (typeof op.required !== "boolean") return bad("required must be true or false");
@@ -141585,11 +142117,188 @@ function setSectionTitle(d, op) {
141585
142117
  if (issues.length) return bad(issues.map((i2) => `${i2.path} ${i2.reason}`).join("; "));
141586
142118
  return { touched: [], section: { id: sid, title: sec.title } };
141587
142119
  }
141588
- function checkCombDateFormat(d, g, v) {
141589
- const slots = members2(d, g).reduce(
142120
+ function combSlotCount(d, g) {
142121
+ return members2(d, g).reduce(
141590
142122
  (n, m) => n + (Array.isArray(m.cells) && m.cells.length > 1 ? m.cells.length : 1),
141591
142123
  0
141592
142124
  );
142125
+ }
142126
+ var CELL_TYPES = ["char", "integer", "date"];
142127
+ var MAX_COMB_CELLS = 100;
142128
+ function combCell(g, b, section) {
142129
+ return {
142130
+ id: randomUUID2(),
142131
+ label: "",
142132
+ type: "text",
142133
+ page: g.page,
142134
+ section_id: typeof section === "string" ? section : null,
142135
+ xpct: b.x * 100,
142136
+ ypct: b.y * 100,
142137
+ wpct: b.w * 100,
142138
+ hpct: b.h * 100,
142139
+ group: g.id
142140
+ };
142141
+ }
142142
+ function combBoxes(cells, box) {
142143
+ if (Array.isArray(cells)) {
142144
+ if (cells.length < 2 || cells.length > MAX_COMB_CELLS)
142145
+ return bad(`cells lists 2\u2013${String(MAX_COMB_CELLS)} cell boxes`);
142146
+ return cells.map((c2, i2) => boxArg(c2, `cells[${String(i2)}]`));
142147
+ }
142148
+ if (!Number.isInteger(cells) || cells < 2 || cells > MAX_COMB_CELLS) {
142149
+ return bad(
142150
+ `cells is the number of printed cells (2\u2013${String(MAX_COMB_CELLS)}), cut from the box in equal widths, or a list of the cells' own boxes [{x, y, w, h}, \u2026] (for cells split by printed separators)`
142151
+ );
142152
+ }
142153
+ const b = box();
142154
+ const n = cells;
142155
+ return Array.from({ length: n }, (_, i2) => ({
142156
+ x: b.x + i2 * b.w / n,
142157
+ y: b.y,
142158
+ w: b.w / n,
142159
+ h: b.h
142160
+ }));
142161
+ }
142162
+ function newComb(d, a) {
142163
+ const g = {
142164
+ id: randomUUID2(),
142165
+ kind: "comb",
142166
+ label: a.label,
142167
+ page: a.page,
142168
+ members: [],
142169
+ cell_type: "char"
142170
+ };
142171
+ const cells = a.boxes.map((b) => combCell(g, b, a.section));
142172
+ for (const f3 of cells) {
142173
+ d.s.fields.push(f3);
142174
+ d.field.set(f3.id, f3);
142175
+ d.owner.set(f3.id, g);
142176
+ }
142177
+ g.members = cells.map((f3) => f3.id);
142178
+ d.s.groups.push(g);
142179
+ d.group.set(g.id, g);
142180
+ setCombTyping(d, g, a.cellType, a.dateFormat);
142181
+ return g;
142182
+ }
142183
+ function setCombTyping(d, g, cellType, dateFormat) {
142184
+ const comb = g;
142185
+ if (cellType !== void 0) {
142186
+ if (!CELL_TYPES.includes(cellType)) bad('cell_type is "char", "integer" or "date"');
142187
+ comb.cell_type = cellType;
142188
+ }
142189
+ if (dateFormat !== void 0 && dateFormat !== null) {
142190
+ if (cellType !== void 0 && cellType !== "date")
142191
+ bad('date_format needs cell_type "date": leave cell_type out, or pass "date"');
142192
+ checkCombDateFormat(d, g, dateFormat);
142193
+ comb.cell_type = "date";
142194
+ comb.date_format = dateFormat;
142195
+ }
142196
+ }
142197
+ function keepDateFormat(d, g, given) {
142198
+ const comb = g;
142199
+ if (given !== void 0 && given !== null) return setCombTyping(d, g, void 0, given);
142200
+ if (comb.cell_type === "date" && typeof comb.date_format === "string" && comb.date_format) {
142201
+ bad(
142202
+ `comb ${g.id} is a date comb (date_format ${comb.date_format}, one letter per cell): pass date_format for its ${String(combSlotCount(d, g))} cells`
142203
+ );
142204
+ }
142205
+ }
142206
+ function setCombFormat(d, g, format) {
142207
+ const comb = g;
142208
+ const dated = format.date_format !== void 0 && format.date_format !== null;
142209
+ for (const [k4, v] of Object.entries(format)) {
142210
+ if (k4 !== "cell_type" && k4 !== "date_format")
142211
+ bad(`a comb group's format keys are cell_type and date_format, not ${k4}`);
142212
+ if (k4 === "date_format" && v !== null) checkCombDateFormat(d, g, v);
142213
+ if (v === null) delete comb[k4];
142214
+ else comb[k4] = v;
142215
+ }
142216
+ if (dated) {
142217
+ if (format.cell_type !== void 0 && format.cell_type !== "date")
142218
+ bad('date_format needs cell_type "date": leave cell_type out, or pass "date"');
142219
+ comb.cell_type = "date";
142220
+ }
142221
+ return { touched: [g.id], comb: g.id };
142222
+ }
142223
+ function addComb(d, op) {
142224
+ const page = pageOf(d, op.page);
142225
+ if (typeof op.label !== "string")
142226
+ return bad("label is required (the form's caption for this blank)");
142227
+ if (op.snap !== void 0)
142228
+ return bad("a comb takes no snap: give its cells' boxes, or its outer box and a cell count");
142229
+ const boxes = combBoxes(op.cells, () => boxArg(op.box));
142230
+ let section;
142231
+ if (op.section_id !== void 0) {
142232
+ const sid = resolveId(d, op.section_id, ["section"], "section_id");
142233
+ if (!sectionIds(d, page).has(sid)) {
142234
+ return bad(`section_id ${sid} is not a section of page ${String(page)}`);
142235
+ }
142236
+ section = sid;
142237
+ } else section = sectionForPos(d, page, boxes[0].x * 100, boxes[0].y * 100);
142238
+ const g = newComb(d, {
142239
+ page,
142240
+ boxes,
142241
+ label: op.label.trim(),
142242
+ section,
142243
+ cellType: op.cell_type,
142244
+ dateFormat: op.date_format
142245
+ });
142246
+ if (typeof op.description === "string" && op.description.trim())
142247
+ g.description = op.description.trim();
142248
+ if (op.required === true) g.required = true;
142249
+ return {
142250
+ touched: [g.id],
142251
+ added: g.id,
142252
+ comb: g.id,
142253
+ members: readingMembers(d, g).map((m) => m.id),
142254
+ section: sectionOf(d, page, g.id)
142255
+ };
142256
+ }
142257
+ function retypeComb(d, op, f3, warnings) {
142258
+ if (!f3) return bad("only a field can be retyped to a comb; ungroup a group first");
142259
+ if (d.owner.has(f3.id))
142260
+ return bad(`this is a member of group ${d.owner.get(f3.id).id}; ungroup it first`);
142261
+ if (f3.type !== "text" && f3.type !== "date")
142262
+ return bad("only a text or date field can become a comb");
142263
+ const boxes = combBoxes(op.cells, () => ({
142264
+ x: f3.xpct / 100,
142265
+ y: f3.ypct / 100,
142266
+ w: f3.wpct / 100,
142267
+ h: f3.hpct / 100
142268
+ }));
142269
+ let dateFormat = op.date_format;
142270
+ if (f3.type === "date" && (op.cell_type === void 0 || op.cell_type === "date") && dateFormat === void 0) {
142271
+ const printed = isRec2(f3.format) && typeof f3.format.date_format === "string" ? f3.format.date_format : DATE_FORMATS[0];
142272
+ const letters = printed.replace(/[^DMY]/g, "");
142273
+ if (letters.length === boxes.length) dateFormat = letters;
142274
+ else
142275
+ warnings.push(
142276
+ `${f3.id}: its date format ${printed} has ${String(letters.length)} digits, the comb ${String(boxes.length)} cells; set_format the comb's date_format (one D, M or Y per cell)`
142277
+ );
142278
+ }
142279
+ const g = newComb(d, {
142280
+ page: f3.page,
142281
+ boxes,
142282
+ label: typeof f3.label === "string" ? f3.label : "",
142283
+ section: f3.section_id,
142284
+ cellType: op.cell_type,
142285
+ dateFormat
142286
+ });
142287
+ if (f3.required === true) g.required = true;
142288
+ if (typeof f3.description === "string" && f3.description.trim()) g.description = f3.description;
142289
+ if (typeof f3.order === "number") g.order = f3.order;
142290
+ removeFields(d, /* @__PURE__ */ new Set([f3.id]));
142291
+ return {
142292
+ touched: [g.id],
142293
+ added: g.id,
142294
+ deleted: [f3.id],
142295
+ comb: g.id,
142296
+ members: readingMembers(d, g).map((m) => m.id),
142297
+ section: sectionOf(d, f3.page, g.id)
142298
+ };
142299
+ }
142300
+ function checkCombDateFormat(d, g, v) {
142301
+ const slots = combSlotCount(d, g);
141593
142302
  if (typeof v !== "string" || !/^[DMY]+$/.test(v) || v.length !== slots) {
141594
142303
  bad(
141595
142304
  `a comb's date_format has one letter (D, M or Y) per cell: this comb has ${String(slots)} cells (e.g. ${slots === 8 ? "DDMMYYYY" : slots === 6 ? "DDMMYY" : "D".repeat(Math.min(2, slots)) + "\u2026"})`
@@ -141651,6 +142360,7 @@ function applyPass(render, ops, excluded, screen, opts) {
141651
142360
  const outcomes = [];
141652
142361
  const told = [];
141653
142362
  const confirmed = [];
142363
+ const refs = /* @__PURE__ */ new Map();
141654
142364
  let applied = 0;
141655
142365
  ops.forEach((raw, i2) => {
141656
142366
  const skip = excluded.get(i2);
@@ -141660,9 +142370,20 @@ function applyPass(render, ops, excluded, screen, opts) {
141660
142370
  }
141661
142371
  const draft = structuredClone(cur);
141662
142372
  const d2 = index(draft);
142373
+ d2.refs = refs;
141663
142374
  const w = [];
141664
142375
  try {
142376
+ const given = isRec2(raw) ? raw.ref : void 0;
142377
+ if (given !== void 0 && (typeof given !== "string" || !REF_NAME.test(given)))
142378
+ bad('ref names what this op adds: a letter, then letters, digits, "_" or "-" (32 at most)');
142379
+ const ref = typeof given === "string" ? given : void 0;
142380
+ if (ref !== void 0 && refs.has(ref))
142381
+ bad(`ref "${ref}" is already taken by an earlier op of this batch`);
141665
142382
  const r = applyOne(d2, raw, w, opts);
142383
+ if (ref !== void 0 && !r.added)
142384
+ bad(
142385
+ "ref names what an op adds (add, group, add_option, comb_add_cell\u2026); this op adds nothing"
142386
+ );
141666
142387
  const issues = touchedIssues(d2, r.touched, r.tables);
141667
142388
  if (issues.length) {
141668
142389
  bad(
@@ -141704,10 +142425,12 @@ function applyPass(render, ops, excluded, screen, opts) {
141704
142425
  ...comb ? { comb } : {},
141705
142426
  ...r.order ? { order: r.order } : {},
141706
142427
  ...r.section !== void 0 ? { section: r.section } : {},
142428
+ ...r.members ? { members: r.members } : {},
141707
142429
  ...noop ? { noop: true } : {}
141708
142430
  });
141709
142431
  cur = draft;
141710
142432
  applied++;
142433
+ if (typeof ref === "string" && r.added) refs.set(ref, r.added);
141711
142434
  confirmed.push(...vouched);
141712
142435
  counts[name] = (counts[name] ?? 0) + 1;
141713
142436
  if (r.added) added.push({ op_index: i2, id: r.added });
@@ -141731,7 +142454,7 @@ function applyPass(render, ops, excluded, screen, opts) {
141731
142454
  const bb = bbox(g ? members2(d, g) : f3 ? [f3] : []);
141732
142455
  if (!bb) continue;
141733
142456
  const box = { x: bb.x / 100, y: bb.y / 100, w: bb.w / 100, h: bb.h / 100 };
141734
- if (!onPage(box)) {
142457
+ if (!onPage2(box)) {
141735
142458
  const b = { x: round(box.x), y: round(box.y), w: round(box.w), h: round(box.h) };
141736
142459
  offPage.set(
141737
142460
  i2,
@@ -141758,13 +142481,24 @@ function applyPass(render, ops, excluded, screen, opts) {
141758
142481
  }
141759
142482
  function wordingOf(s) {
141760
142483
  const out = [];
141761
- const add = (id, prop, v, page) => {
142484
+ const add = (id, prop, v, page, quiet = false) => {
141762
142485
  if (typeof v === "string" && v.trim() && typeof id === "string")
141763
- out.push({ id, ...typeof page === "number" ? { page } : {}, prop, text: v });
142486
+ out.push({
142487
+ id,
142488
+ ...typeof page === "number" ? { page } : {},
142489
+ prop,
142490
+ text: v,
142491
+ ...quiet ? { quiet: true } : {}
142492
+ });
141764
142493
  };
141765
142494
  const rec = (x2) => typeof x2 === "object" && x2 !== null && !Array.isArray(x2) ? x2 : null;
142495
+ const combCells2 = /* @__PURE__ */ new Set();
142496
+ for (const g of s.groups) {
142497
+ if (g.kind === "comb" && Array.isArray(g.members)) for (const m of g.members) combCells2.add(m);
142498
+ }
141766
142499
  for (const f3 of s.fields) {
141767
- for (const k4 of ["label", "description", "placeholder"]) add(f3.id, k4, f3[k4]);
142500
+ for (const k4 of ["label", "description", "placeholder"])
142501
+ add(f3.id, k4, f3[k4], void 0, k4 === "label" && combCells2.has(f3.id));
141768
142502
  const fmt3 = rec(f3.format);
141769
142503
  if (fmt3) for (const k4 of ["date_format", "symbol"]) add(f3.id, `format.${k4}`, fmt3[k4]);
141770
142504
  }
@@ -141812,210 +142546,6 @@ function describeWording(wording, name = (id) => id) {
141812
142546
  ).join(", ");
141813
142547
  }
141814
142548
 
141815
- // src/render.ts
141816
- import { existsSync as existsSync2, readFileSync as readFileSync3 } from "node:fs";
141817
- import { createRequire as createRequire2 } from "node:module";
141818
- import { dirname as dirname4, join as join5 } from "node:path";
141819
- import { fileURLToPath as fileURLToPath2 } from "node:url";
141820
- import { deflateSync } from "node:zlib";
141821
- var DEFAULT_DPI = 110;
141822
- var MAX_DPI = 200;
141823
- var MIN_DPI = 36;
141824
- var MAX_SIDE_PX = 3e3;
141825
- var loading = null;
141826
- function wasmPath() {
141827
- const here = dirname4(fileURLToPath2(import.meta.url));
141828
- const bundled = join5(here, "pdfium.wasm");
141829
- if (existsSync2(bundled)) return bundled;
141830
- const req = createRequire2(import.meta.url);
141831
- return req.resolve("@embedpdf/pdfium/pdfium.wasm");
141832
- }
141833
- async function loadPdfium() {
141834
- let wasm;
141835
- try {
141836
- wasm = readFileSync3(wasmPath());
141837
- } catch {
141838
- throw new ToolError("renderer_missing", "The page renderer (pdfium.wasm) could not be read.", {
141839
- hint: "Reinstall @fenfill/mcp (npx -y @fenfill/mcp@latest). fill_form's check_pdf still works without it."
141840
- });
141841
- }
141842
- const { init: init2 } = await Promise.resolve().then(() => (init_dist(), dist_exports));
141843
- const quiet = () => void 0;
141844
- const mod = await init2({
141845
- wasmBinary: wasm.buffer.slice(wasm.byteOffset, wasm.byteOffset + wasm.byteLength),
141846
- // The loader would print to stdout, which is the JSON-RPC channel.
141847
- print: quiet,
141848
- printErr: quiet
141849
- });
141850
- mod.PDFiumExt_Init();
141851
- return mod;
141852
- }
141853
- function pdfium() {
141854
- loading ??= loadPdfium().catch((e4) => {
141855
- loading = null;
141856
- throw e4;
141857
- });
141858
- return loading;
141859
- }
141860
- var FPDF_ANNOT = 1;
141861
- var FPDF_REVERSE_BYTE_ORDER = 16;
141862
- async function withPage(pdf, page, fn5) {
141863
- const m = await pdfium();
141864
- const p4 = m.pdfium;
141865
- const heap = () => p4.HEAPU8;
141866
- const ptr = p4.wasmExports.malloc(pdf.length);
141867
- if (!ptr) throw new ToolError("render_failed", "Not enough memory to render this page.");
141868
- let doc = 0;
141869
- let pg = 0;
141870
- try {
141871
- heap().set(pdf, ptr);
141872
- doc = m.FPDF_LoadMemDocument(ptr, pdf.length, "");
141873
- if (!doc) {
141874
- throw new ToolError("render_failed", "The page renderer couldn't open this PDF.", {
141875
- hint: "Use fill_form with check_pdf instead and open the .check.pdf."
141876
- });
141877
- }
141878
- const count = m.FPDF_GetPageCount(doc);
141879
- if (page < 1 || page > count) {
141880
- throw new ToolError("invalid_page", `The PDF has ${String(count)} pages.`, {
141881
- hint: `Pass page between 1 and ${String(count)}.`
141882
- });
141883
- }
141884
- pg = m.FPDF_LoadPage(doc, page - 1);
141885
- if (!pg) throw new ToolError("render_failed", "The page renderer couldn't load this page.");
141886
- return fn5(m, pg, heap);
141887
- } finally {
141888
- if (pg) m.FPDF_ClosePage(pg);
141889
- if (doc) m.FPDF_CloseDocument(doc);
141890
- p4.wasmExports.free(ptr);
141891
- }
141892
- }
141893
- async function renderPage(pdf, page, dpi, crop, maxSide = MAX_SIDE_PX) {
141894
- return withPage(pdf, page, (m, pg, heap) => {
141895
- const wPt = m.FPDF_GetPageWidthF(pg);
141896
- const hPt = m.FPDF_GetPageHeightF(pg);
141897
- const c2 = crop ?? { x: 0, y: 0, w: 1, h: 1 };
141898
- let scale2 = dpi / 72;
141899
- const longest = Math.max(wPt * c2.w, hPt * c2.h) * scale2;
141900
- if (longest > maxSide) scale2 *= maxSide / longest;
141901
- const fullW = Math.max(1, Math.round(wPt * scale2));
141902
- const fullH = Math.max(1, Math.round(hPt * scale2));
141903
- const x0 = Math.round(c2.x * fullW);
141904
- const y0 = Math.round(c2.y * fullH);
141905
- const width = Math.max(1, Math.min(fullW - x0, Math.round(c2.w * fullW)));
141906
- const height = Math.max(1, Math.min(fullH - y0, Math.round(c2.h * fullH)));
141907
- const bmp = m.FPDFBitmap_Create(width, height, 0);
141908
- if (!bmp) throw new ToolError("render_failed", "Not enough memory to render this page.");
141909
- try {
141910
- m.FPDFBitmap_FillRect(bmp, 0, 0, width, height, 4294967295);
141911
- m.FPDF_RenderPageBitmap(
141912
- bmp,
141913
- pg,
141914
- -x0,
141915
- -y0,
141916
- fullW,
141917
- fullH,
141918
- 0,
141919
- FPDF_ANNOT | FPDF_REVERSE_BYTE_ORDER
141920
- );
141921
- const stride = m.FPDFBitmap_GetStride(bmp);
141922
- const buf = m.FPDFBitmap_GetBuffer(bmp);
141923
- const rgba = new Uint8Array(width * 4 * height);
141924
- const h8 = heap();
141925
- for (let y = 0; y < height; y++) {
141926
- const row = buf + y * stride;
141927
- rgba.set(h8.subarray(row, row + width * 4), y * width * 4);
141928
- }
141929
- return { width, height, rgba, scale: scale2 };
141930
- } finally {
141931
- m.FPDFBitmap_Destroy(bmp);
141932
- }
141933
- });
141934
- }
141935
- async function pageText(pdf, page) {
141936
- return withPage(pdf, page, (m, pg, heap) => {
141937
- const widthPt = m.FPDF_GetPageWidthF(pg);
141938
- const heightPt = m.FPDF_GetPageHeightF(pg);
141939
- const glyphs = [];
141940
- const tp = m.FPDFText_LoadPage(pg);
141941
- if (!tp) return { widthPt, heightPt, glyphs };
141942
- const p4 = m.pdfium;
141943
- const out = p4.wasmExports.malloc(32);
141944
- try {
141945
- const n = m.FPDFText_CountChars(tp);
141946
- for (let i2 = 0; i2 < n; i2++) {
141947
- const u = m.FPDFText_GetUnicode(tp, i2);
141948
- if (u <= 32 || u === 160 || u === 65534 || u === 65535) continue;
141949
- if (!m.FPDFText_GetCharBox(tp, i2, out, out + 8, out + 16, out + 24)) continue;
141950
- const [left, right, bottom, top] = new Float64Array(heap().buffer, out, 4);
141951
- if (!(right > left) || !(top > bottom)) continue;
141952
- glyphs.push({
141953
- x: left / widthPt,
141954
- y: (heightPt - top) / heightPt,
141955
- // PDF space is bottom-left: invert Y
141956
- w: (right - left) / widthPt,
141957
- h: (top - bottom) / heightPt,
141958
- char: String.fromCodePoint(u)
141959
- });
141960
- }
141961
- } finally {
141962
- p4.wasmExports.free(out);
141963
- m.FPDFText_ClosePage(tp);
141964
- }
141965
- return { widthPt, heightPt, glyphs };
141966
- });
141967
- }
141968
- var CRC_TABLE2 = (() => {
141969
- const t = new Uint32Array(256);
141970
- for (let n = 0; n < 256; n++) {
141971
- let c2 = n;
141972
- for (let k4 = 0; k4 < 8; k4++) c2 = c2 & 1 ? 3988292384 ^ c2 >>> 1 : c2 >>> 1;
141973
- t[n] = c2 >>> 0;
141974
- }
141975
- return t;
141976
- })();
141977
- function crc322(bytes) {
141978
- let c2 = 4294967295;
141979
- for (const b of bytes) c2 = CRC_TABLE2[(c2 ^ b) & 255] ^ c2 >>> 8;
141980
- return (c2 ^ 4294967295) >>> 0;
141981
- }
141982
- function chunk(type, data) {
141983
- const body = Buffer.concat([Buffer.from(type, "latin1"), data]);
141984
- const out = Buffer.alloc(body.length + 8);
141985
- out.writeUInt32BE(data.length, 0);
141986
- body.copy(out, 4);
141987
- out.writeUInt32BE(crc322(body), body.length + 4);
141988
- return out;
141989
- }
141990
- function encodePng2(r) {
141991
- const row = 1 + r.width * 3;
141992
- const raw = Buffer.alloc(row * r.height);
141993
- for (let y = 0; y < r.height; y++) {
141994
- const src = y * r.width * 4;
141995
- const dst = y * row;
141996
- raw[dst] = 0;
141997
- for (let x2 = 0; x2 < r.width; x2++) {
141998
- const s = src + x2 * 4;
141999
- const d = dst + 1 + x2 * 3;
142000
- raw[d] = r.rgba[s];
142001
- raw[d + 1] = r.rgba[s + 1];
142002
- raw[d + 2] = r.rgba[s + 2];
142003
- }
142004
- }
142005
- const ihdr = Buffer.alloc(13);
142006
- ihdr.writeUInt32BE(r.width, 0);
142007
- ihdr.writeUInt32BE(r.height, 4);
142008
- ihdr.set([8, 2, 0, 0, 0], 8);
142009
- return new Uint8Array(
142010
- Buffer.concat([
142011
- Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]),
142012
- chunk("IHDR", ihdr),
142013
- chunk("IDAT", deflateSync(raw, { level: 6 })),
142014
- chunk("IEND", new Uint8Array(0))
142015
- ])
142016
- );
142017
- }
142018
-
142019
142549
  // src/snap.ts
142020
142550
  import { createHash as createHash2 } from "node:crypto";
142021
142551
 
@@ -142220,11 +142750,11 @@ function underlineFor(r, b) {
142220
142750
  const line = cands.at(0);
142221
142751
  if (!line) return null;
142222
142752
  const cx2 = b.x + b.w / 2;
142223
- const crosses = (v) => v.y0 <= line.y0 - 4 && v.y1 >= line.y0 - MEET;
142753
+ const crosses2 = (v) => v.y0 <= line.y0 - 4 && v.y1 >= line.y0 - MEET;
142224
142754
  let x0 = line.x0;
142225
142755
  let x1 = line.x1;
142226
142756
  for (const v of r.v) {
142227
- if (!crosses(v)) continue;
142757
+ if (!crosses2(v)) continue;
142228
142758
  if (v.x1 < cx2 && v.x1 + 1 > x0) x0 = v.x1 + 1;
142229
142759
  if (v.x0 > cx2 && v.x0 - 1 < x1) x1 = v.x0 - 1;
142230
142760
  }
@@ -142306,13 +142836,17 @@ function pageOfId(render, id) {
142306
142836
  }
142307
142837
  function snapPages(ops, pageOfId2) {
142308
142838
  const out = /* @__PURE__ */ new Set();
142839
+ const refPage = /* @__PURE__ */ new Map();
142840
+ const pageOf2 = (id) => typeof id !== "string" ? void 0 : id.startsWith("$") ? refPage.get(id.slice(1)) : pageOfId2(id);
142309
142841
  for (const o of ops) {
142310
142842
  if (typeof o !== "object" || o === null) continue;
142311
142843
  const op = o;
142844
+ const here = typeof op.page === "number" ? op.page : pageOf2(op.id) ?? (Array.isArray(op.ids) ? pageOf2(op.ids[0]) : void 0);
142845
+ if (typeof op.ref === "string" && here !== void 0) refPage.set(op.ref, here);
142312
142846
  if (op.snap === void 0) continue;
142313
142847
  if (op.op === "add" && typeof op.page === "number") out.add(op.page);
142314
- else if (typeof op.id === "string") {
142315
- const p4 = pageOfId2(op.id);
142848
+ else {
142849
+ const p4 = pageOf2(op.id);
142316
142850
  if (p4 !== void 0) out.add(p4);
142317
142851
  }
142318
142852
  }
@@ -142363,6 +142897,9 @@ var FONT_MIN_PT = 3;
142363
142897
  var OVERLAP_MIN_CHARS = 2;
142364
142898
  var CELL_TOL = 25e-4;
142365
142899
  var BLANK_CHARS = /^[_.\-‐-―…·•‧⋯─━┄┅┈┉_]$/u;
142900
+ var PALE_LUM = 165;
142901
+ var WHITE_LUM = 250;
142902
+ var QUOTE_MAX = 40;
142366
142903
  var multiline = (f3) => isRec2(f3.format) && f3.format.variant === "multiline";
142367
142904
  var singleLine = (f3) => f3.type === "text" && !multiline(f3) || f3.type === "date" && !(f3.cells && f3.cells.length > 1);
142368
142905
  function pinned(f3) {
@@ -142412,10 +142949,31 @@ async function stampedSizes(pdf, render, page) {
142412
142949
  }
142413
142950
  return out;
142414
142951
  }
142415
- async function placementWarnings2(pdf, render, ids, opts = {}) {
142416
- const checked = fieldsOf(render, ids).filter((f3) => f3.type === "text" || f3.type === "date");
142417
- if (!checked.length) return [];
142952
+ function quoteOf(gs) {
142953
+ const sorted = [...gs].sort((a, b) => a.i - b.i);
142954
+ let out = "";
142955
+ sorted.forEach((g, k4) => {
142956
+ if (k4 > 0 && g.i - sorted[k4 - 1].i > 1) out += " ";
142957
+ out += g.char;
142958
+ });
142959
+ return out.length > QUOTE_MAX ? `${out.slice(0, QUOTE_MAX - 1)}\u2026` : out;
142960
+ }
142961
+ function isHint(gs, box, cellX, pageW, pageH) {
142962
+ if (!gs.every((g) => g.lum !== null && g.lum >= PALE_LUM && g.lum < WHITE_LUM)) return false;
142963
+ const start = Math.min(...gs.map((g) => g.x));
142964
+ const reach = Math.min(Math.max(box.h * pageH, 8), 20) / pageW;
142965
+ const near = (edge) => start >= edge - reach && start - edge <= reach;
142966
+ return near(box.x) || cellX !== null && near(cellX);
142967
+ }
142968
+ async function placementReport(pdf, render, ids, opts = {}) {
142969
+ const idList = [...ids];
142970
+ const checked = fieldsOf(render, idList).filter(
142971
+ (f3) => f3.type === "text" || f3.type === "date" || f3.type === "signature"
142972
+ );
142973
+ const choices = choicesOf(render, idList);
142418
142974
  const out = [];
142975
+ const notes = [];
142976
+ if (!checked.length && !choices.length) return { warnings: out, notes };
142419
142977
  let snap = null;
142420
142978
  if (opts.cells) {
142421
142979
  try {
@@ -142456,16 +143014,18 @@ async function placementWarnings2(pdf, render, ids, opts = {}) {
142456
143014
  const by = f3.ypct / 100;
142457
143015
  const bw = f3.wpct / 100;
142458
143016
  const bh = f3.hpct / 100;
142459
- const inside = pt.glyphs.filter((g) => {
143017
+ const covered = pt.glyphs.filter((g) => {
142460
143018
  if (BLANK_CHARS.test(g.char)) return false;
142461
143019
  const cx2 = g.x + g.w / 2;
142462
143020
  const cy2 = g.y + g.h / 2;
142463
143021
  return cx2 > bx && cx2 < bx + bw && cy2 > by && cy2 < by + bh;
142464
- }).length;
143022
+ });
143023
+ let cellX = null;
142465
143024
  if (snap && singleLine(f3)) {
142466
143025
  const r = snap(f3.page, { x: bx, y: by, w: bw, h: bh }, "cell");
142467
143026
  if ("box" in r) {
142468
143027
  const c2 = r.box;
143028
+ cellX = c2.x;
142469
143029
  const past = {
142470
143030
  above: c2.y - by,
142471
143031
  below: by + bh - (c2.y + c2.h),
@@ -142482,15 +143042,298 @@ async function placementWarnings2(pdf, render, ids, opts = {}) {
142482
143042
  }
142483
143043
  }
142484
143044
  }
142485
- if (inside >= OVERLAP_MIN_CHARS) {
143045
+ if (covered.length >= OVERLAP_MIN_CHARS) {
143046
+ const quote = JSON.stringify(quoteOf(covered));
143047
+ if (isHint(covered, { x: bx, w: bw, h: bh }, cellX, pt.widthPt, pt.heightPt)) {
143048
+ notes.push(
143049
+ `${f3.id}: the box covers the pale hint ${quote} printed at its left edge; a hint is written over, so this is no misplacement`
143050
+ );
143051
+ } else {
143052
+ out.push(
143053
+ `${f3.id}: the box covers ${String(covered.length)} printed characters (${quote}), so the value would print over them; move or shrink it onto the blank (snap can help)`
143054
+ );
143055
+ }
143056
+ }
143057
+ }
143058
+ for (const g of choices) {
143059
+ const page = g.page;
143060
+ if (typeof page !== "number") continue;
143061
+ let pt = texts.get(page);
143062
+ if (!pt) {
143063
+ try {
143064
+ pt = await pageText(pdf, page);
143065
+ } catch {
143066
+ continue;
143067
+ }
143068
+ texts.set(page, pt);
143069
+ }
143070
+ out.push(...optionWarnings(render, g, page, pt));
143071
+ }
143072
+ return { warnings: out, notes };
143073
+ }
143074
+ var TICK_CHARS = /^[\u2610-\u2612\u25a0-\u25a1\u25fb-\u25fe\u2713-\u2718\uf000-\uf0ff]$/u;
143075
+ var norm2 = (s) => s.normalize("NFC").toLowerCase().replace(/^[^\p{L}\p{N}]+|[^\p{L}\p{N}]+$/gu, "");
143076
+ function choicesOf(render, ids) {
143077
+ const groups = new Map(render.groups.map((g) => [g.id, g]));
143078
+ const byId = new Map(render.fields.map((f3) => [f3.id, f3]));
143079
+ const out = /* @__PURE__ */ new Map();
143080
+ for (const id of ids) {
143081
+ const f3 = byId.get(id);
143082
+ const g = groups.get(id) ?? (f3 && typeof f3.group === "string" ? groups.get(f3.group) : void 0);
143083
+ if (g?.kind === "choice") out.set(g.id, g);
143084
+ }
143085
+ return [...out.values()];
143086
+ }
143087
+ var wordsMemo = /* @__PURE__ */ new WeakMap();
143088
+ function wordsOf(pt) {
143089
+ let words = wordsMemo.get(pt);
143090
+ if (!words) {
143091
+ words = buildWords(pt);
143092
+ wordsMemo.set(pt, words);
143093
+ }
143094
+ return words;
143095
+ }
143096
+ function buildWords(pt) {
143097
+ const gs = pt.glyphs.filter((g) => !BLANK_CHARS.test(g.char) && !TICK_CHARS.test(g.char)).map((g) => ({
143098
+ i: g.i,
143099
+ char: g.char,
143100
+ x: g.x * pt.widthPt,
143101
+ y: g.y * pt.heightPt,
143102
+ w: g.w * pt.widthPt,
143103
+ h: g.h * pt.heightPt
143104
+ })).sort((a, b) => a.i - b.i);
143105
+ const words = [];
143106
+ let cur = [];
143107
+ const flush = () => {
143108
+ if (!cur.length) return;
143109
+ const x0 = Math.min(...cur.map((g) => g.x));
143110
+ const y0 = Math.min(...cur.map((g) => g.y));
143111
+ const x1 = Math.max(...cur.map((g) => g.x + g.w));
143112
+ const y1 = Math.max(...cur.map((g) => g.y + g.h));
143113
+ words.push({ text: cur.map((g) => g.char).join(""), x: x0, y: y0, w: x1 - x0, h: y1 - y0 });
143114
+ cur = [];
143115
+ };
143116
+ for (const g of gs) {
143117
+ const prev = cur.at(-1);
143118
+ if (prev && (g.i - prev.i > 1 || g.x - (prev.x + prev.w) > 0.5 * Math.max(prev.h, g.h) || !sameLine2(prev, g, 0.3))) {
143119
+ flush();
143120
+ }
143121
+ cur.push(g);
143122
+ }
143123
+ flush();
143124
+ return words;
143125
+ }
143126
+ function sameLine2(a, b, frac = 0.4) {
143127
+ const shared = Math.min(a.y + a.h, b.y + b.h) - Math.max(a.y, b.y);
143128
+ return shared >= frac * Math.min(a.h, b.h);
143129
+ }
143130
+ function gap(a, b) {
143131
+ const dx = Math.max(0, b.x - (a.x + a.w), a.x - (b.x + b.w));
143132
+ const dy = Math.max(0, b.y - (a.y + a.h), a.y - (b.y + b.h));
143133
+ return Math.hypot(dx, dy);
143134
+ }
143135
+ var CAPTION_REACH = 200;
143136
+ function optionWarnings(render, g, page, pt) {
143137
+ const byId = new Map(render.fields.map((f3) => [f3.id, f3]));
143138
+ const options = (Array.isArray(g.members) ? g.members : []).map((id) => byId.get(id)).filter((f3) => !!f3 && f3.page === page);
143139
+ if (options.length < 2) return [];
143140
+ const words = wordsOf(pt);
143141
+ if (!words.length) return [];
143142
+ const boxOf3 = (f3) => ({
143143
+ x: f3.xpct / 100 * pt.widthPt,
143144
+ y: f3.ypct / 100 * pt.heightPt,
143145
+ w: f3.wpct / 100 * pt.widthPt,
143146
+ h: f3.hpct / 100 * pt.heightPt
143147
+ });
143148
+ const boxes = options.map(boxOf3);
143149
+ const pad = Math.max(12, 2 * median3(boxes.map((b) => b.w)));
143150
+ const left = Math.min(...boxes.map((b) => b.x)) - pad;
143151
+ const right = Math.max(...boxes.map((b) => b.x + b.w)) + pad;
143152
+ const inSpan = (w) => w.x + w.w > left && w.x < right;
143153
+ const matches = (t, first) => t === first || first.length >= 4 && t.startsWith(first) || t.length >= 4 && first.startsWith(t) && first.length - t.length <= 2;
143154
+ const found = /* @__PURE__ */ new Map();
143155
+ const claims = [];
143156
+ for (const o of options) {
143157
+ const label = typeof o.label === "string" ? o.label : "";
143158
+ const tokens = label.split(/\s+/).map(norm2).filter(Boolean);
143159
+ const first = tokens.find((t) => t.length >= 2 && new RegExp("\\p{L}", "u").test(t)) ?? tokens[0];
143160
+ if (!first) continue;
143161
+ const box = boxOf3(o);
143162
+ const near = (w) => sameLine2(w, box) || Math.max(w.y - (box.y + box.h), box.y - (w.y + w.h)) <= 1.5 * Math.max(box.h, w.h);
143163
+ for (const w of words) {
143164
+ if (!inSpan(w) || !near(w) || !matches(norm2(w.text), first)) continue;
143165
+ const d = gap(w, box);
143166
+ if (d <= CAPTION_REACH) claims.push({ o, box, w, d });
143167
+ }
143168
+ }
143169
+ claims.sort((a, b) => a.d - b.d);
143170
+ const claimed = /* @__PURE__ */ new Set();
143171
+ for (const { o, box, w: best } of claims) {
143172
+ if (found.has(o.id) || claimed.has(best)) continue;
143173
+ claimed.add(best);
143174
+ const inline = sameLine2(best, box);
143175
+ const side = inline ? best.x + best.w / 2 >= box.x + box.w / 2 ? "before" : "after" : best.y > box.y ? "before" : "after";
143176
+ found.set(o.id, { box, caption: best, side, inline });
143177
+ }
143178
+ const sides = [...found.values()].map((f3) => f3.side);
143179
+ const before = sides.filter((x2) => x2 === "before").length;
143180
+ const after = sides.length - before;
143181
+ if (before === after) return [];
143182
+ if (Math.max(before, after) < 2) return [];
143183
+ const usual = before > after ? "before" : "after";
143184
+ const inlineCount = [...found.values()].filter((f3) => f3.inline).length;
143185
+ const besideCaptions = inlineCount >= 2 && inlineCount * 2 > found.size;
143186
+ const captions = new Map([...found].map(([id, f3]) => [f3.caption, id]));
143187
+ const quote = (w) => JSON.stringify(w.text);
143188
+ const out = [];
143189
+ for (const o of options) {
143190
+ const f3 = found.get(o.id);
143191
+ if (!f3) continue;
143192
+ const why = [];
143193
+ if (f3.side !== usual) {
143194
+ why.push(
143195
+ `its box is ${f3.side === "before" ? "before" : "after"} its caption ${quote(f3.caption)} in reading order, but this question's other boxes are ${usual} theirs (one question never mixes sides)`
143196
+ );
143197
+ }
143198
+ const { box } = f3;
143199
+ const ahead = usual === "before";
143200
+ if (!besideCaptions) {
143201
+ if (why.length) out.push(`${o.id}: ${why.join("; and ")}`);
143202
+ continue;
143203
+ }
143204
+ const onLine = words.filter((w) => inSpan(w) && sameLine2(w, box) && norm2(w.text)).filter((w) => ahead ? w.x >= box.x + box.w * 0.5 : w.x + w.w <= box.x + box.w * 0.5).sort((a, b) => ahead ? a.x - b.x : b.x + b.w - (a.x + a.w));
143205
+ let next = onLine[0];
143206
+ if (!next) {
143207
+ const reach = 2.5 * Math.max(box.h, 8);
143208
+ const rows = words.filter(
143209
+ (w) => inSpan(w) && norm2(w.text) && !sameLine2(w, box) && (ahead ? w.y >= box.y + box.h * 0.5 && w.y - (box.y + box.h) <= reach : w.y + w.h <= box.y + box.h * 0.5 && box.y - (w.y + w.h) <= reach)
143210
+ );
143211
+ const edge = ahead ? rows.reduce((m, w) => !m || w.y < m.y ? w : m, void 0) : rows.reduce((m, w) => !m || w.y + w.h > m.y + m.h ? w : m, void 0);
143212
+ if (edge) {
143213
+ const line = rows.filter((w) => sameLine2(w, edge));
143214
+ next = line.sort((a, b) => ahead ? a.x - b.x : b.x + b.w - (a.x + a.w))[0];
143215
+ }
143216
+ }
143217
+ const owner = next ? captions.get(next) : void 0;
143218
+ if (next && owner && owner !== o.id) {
143219
+ why.push(
143220
+ `the printed text ${ahead ? "after" : "before"} its box is ${quote(next)}, the caption of option ${owner}, so a tick there reads as that option`
143221
+ );
143222
+ }
143223
+ if (why.length) {
142486
143224
  out.push(
142487
- `${f3.id}: the box covers ${String(inside)} printed characters (a caption or hint), so the value would print over them; move or shrink it onto the blank (snap can help)`
143225
+ `${o.id}: ${why.join("; and ")}; a box goes ${usual === "before" ? "just before" : "just after"} its own caption ${quote(f3.caption)} (on the line ${usual === "before" ? "above when its caption starts a line" : "below when its caption ends a line"})`
142488
143226
  );
142489
143227
  }
142490
143228
  }
142491
143229
  return out;
142492
143230
  }
142493
143231
 
143232
+ // src/project.ts
143233
+ var str = (v) => typeof v === "string" ? v : "";
143234
+ var optStr = (v) => typeof v === "string" && v !== "" ? v : null;
143235
+ function typing(f3, type) {
143236
+ if (type === "date") return { date_format: dateFormatOf(f3) };
143237
+ const variant = f3.format?.variant;
143238
+ if (type === "text" && (variant === "number" || variant === "currency")) return { variant };
143239
+ return {};
143240
+ }
143241
+ function entryOf(e4, page, section) {
143242
+ const item = e4.kind === "field" ? e4.field : e4.group;
143243
+ const base = {
143244
+ id: e4.id,
143245
+ type: e4.type,
143246
+ label: str(item.label),
143247
+ page,
143248
+ section,
143249
+ required: item.required === true,
143250
+ description: optStr(item.description),
143251
+ placeholder: optStr(item.placeholder),
143252
+ autofill: e4.kind === "field" ? optStr(e4.field.autofill) : null
143253
+ };
143254
+ switch (e4.kind) {
143255
+ case "field": {
143256
+ const f3 = e4.field;
143257
+ if (e4.type === "comb") base.max_length = Array.isArray(f3.cells) ? f3.cells.length : 0;
143258
+ Object.assign(base, typing(f3, e4.type));
143259
+ if (e4.type === "signature") base.signing_requirement = f3.signing_requirement ?? "appearance";
143260
+ return base;
143261
+ }
143262
+ case "choice":
143263
+ base.options = e4.options.map((o) => ({ id: o.id, label: str(o.label) }));
143264
+ return base;
143265
+ case "comb":
143266
+ base.max_length = e4.maxLength;
143267
+ base.cell_type = e4.cellType;
143268
+ base.date_format = e4.cellType === "date" ? optStr(e4.group.date_format) : null;
143269
+ return base;
143270
+ case "table_rows":
143271
+ base.columns = e4.columns.map((c2) => ({
143272
+ id: c2.id,
143273
+ label: c2.label,
143274
+ type: c2.type,
143275
+ ...typing(c2.field, c2.type)
143276
+ }));
143277
+ base.max_rows = e4.maxRows;
143278
+ return base;
143279
+ case "table": {
143280
+ const g = e4.group;
143281
+ const heads = (v) => Array.isArray(v) ? v.map((h) => str(h)) : [];
143282
+ base.orientation = g.orientation === "row" ? "row" : "col";
143283
+ base.header_cols = heads(g.header_cols);
143284
+ base.header_rows = heads(g.header_rows);
143285
+ base.cells = e4.cells.map((c2) => ({
143286
+ id: c2.id,
143287
+ row: c2.row,
143288
+ col: c2.col,
143289
+ type: c2.type,
143290
+ label: c2.label,
143291
+ ...typing(c2.field, c2.type)
143292
+ }));
143293
+ return base;
143294
+ }
143295
+ }
143296
+ }
143297
+ function projectAgentSchema(render, meta3 = {}) {
143298
+ const schema = normalizeSchema(render);
143299
+ const byId = new Map(agentEntries(schema).map((e4) => [e4.id, e4]));
143300
+ const fieldById = buildFieldById(schema.fields);
143301
+ const grouped = new Set(schema.groups.flatMap((g) => g.members));
143302
+ const fields = [];
143303
+ const pages = [];
143304
+ const seen = /* @__PURE__ */ new Set();
143305
+ for (const p4 of schema.pages) {
143306
+ if (seen.has(p4.page)) continue;
143307
+ seen.add(p4.page);
143308
+ pages.push({ page: p4.page, width: p4.width, height: p4.height });
143309
+ const { items: items2 } = buildPageItems(
143310
+ p4,
143311
+ schema.fields.filter((f3) => f3.page === p4.page && !grouped.has(f3.id)),
143312
+ schema.groups.filter((g) => g.page === p4.page),
143313
+ (g) => resolveMembers(g, fieldById)
143314
+ );
143315
+ let section = null;
143316
+ for (const it of items2) {
143317
+ if (it.kind === "header") {
143318
+ section = { id: it.section.id, title: str(it.section.title) };
143319
+ continue;
143320
+ }
143321
+ const sid = it.kind === "field" ? it.field.section_id : it.members[0]?.section_id ?? null;
143322
+ const e4 = byId.get(it.kind === "field" ? it.field.id : it.group.id);
143323
+ if (!e4) continue;
143324
+ fields.push(entryOf(e4, p4.page, sid != null && section?.id === sid ? section : null));
143325
+ }
143326
+ }
143327
+ return {
143328
+ schema_version: 1,
143329
+ template_id: meta3.template_id ?? null,
143330
+ name: meta3.name ?? null,
143331
+ page_count: pages.length,
143332
+ pages,
143333
+ fields
143334
+ };
143335
+ }
143336
+
142494
143337
  // src/preview.ts
142495
143338
  var OVERLAYS = ["full", "outline", "none"];
142496
143339
  var MAX_ZOOM = 8;
@@ -142504,6 +143347,22 @@ function boxOf(fs) {
142504
143347
  const y1 = Math.max(...fs.map((f3) => f3.ypct + f3.hpct));
142505
143348
  return { x: r4(x0 / 100), y: r4(y0 / 100), w: r4((x1 - x0) / 100), h: r4((y1 - y0) / 100) };
142506
143349
  }
143350
+ function combCells(members3) {
143351
+ const out = [];
143352
+ for (const m of members3) {
143353
+ const cells = Array.isArray(m.cells) ? m.cells : [];
143354
+ if (cells.length > 1) {
143355
+ cells.forEach((c2, index2) => {
143356
+ out.push({
143357
+ id: m.id,
143358
+ index: index2,
143359
+ box: { x: r4(c2.x / 100), y: r4(c2.y / 100), w: r4(c2.w / 100), h: r4(c2.h / 100) }
143360
+ });
143361
+ });
143362
+ } else out.push({ id: m.id, box: boxOf([m]) });
143363
+ }
143364
+ return out;
143365
+ }
142507
143366
  var topId2 = (id) => id.split(/[.[]/, 1)[0];
142508
143367
  function idPages(entries) {
142509
143368
  const pages = /* @__PURE__ */ new Map();
@@ -142519,11 +143378,19 @@ function legendRows(render, page) {
142519
143378
  const schema = normalizeSchema(render);
142520
143379
  const entries = agentEntries(schema);
142521
143380
  const short = shortIds(checkTagIds(entries));
142522
- const onPage2 = entries.filter(
143381
+ let combShort = null;
143382
+ const combTag = (id) => {
143383
+ combShort ??= shortIds([
143384
+ ...checkTagIds(entries),
143385
+ ...entries.flatMap((e4) => e4.kind === "comb" ? e4.members.map((m) => m.id) : [])
143386
+ ]);
143387
+ return combShort.get(id) ?? id;
143388
+ };
143389
+ const onPage3 = entries.filter(
142523
143390
  (e4) => e4.kind === "field" ? e4.field.page === page : e4.group.page === page
142524
143391
  );
142525
143392
  const legend = [];
142526
- for (const e4 of onPage2) {
143393
+ for (const e4 of onPage3) {
142527
143394
  const box = boxOf(e4.kind === "field" ? [e4.field] : e4.members);
142528
143395
  if (!box) continue;
142529
143396
  const row = {
@@ -142538,6 +143405,27 @@ function legendRows(render, page) {
142538
143405
  if (fmt3 && typeof fmt3 === "object" && !Array.isArray(fmt3) && Object.keys(fmt3).length) {
142539
143406
  row.format = fmt3;
142540
143407
  }
143408
+ if (e4.type === "date") row.date_format = dateFormatOf(e4.field);
143409
+ if (e4.type === "comb") {
143410
+ row.max_length = combCells([e4.field]).length;
143411
+ row.comb_cells = combCells([e4.field]).map((c2) => ({
143412
+ tag: combTag(c2.id),
143413
+ index: c2.index,
143414
+ box: c2.box
143415
+ }));
143416
+ }
143417
+ }
143418
+ if (e4.kind === "comb") {
143419
+ row.cell_type = e4.cellType;
143420
+ row.max_length = e4.maxLength;
143421
+ if (e4.dateFormat) row.date_format = e4.dateFormat;
143422
+ const fmt3 = e4.dateFormat ?? "";
143423
+ row.comb_cells = combCells(e4.members).map((c2, i2) => ({
143424
+ tag: combTag(c2.id),
143425
+ ...c2.index !== void 0 ? { index: c2.index } : {},
143426
+ box: c2.box,
143427
+ ...fmt3.length === e4.maxLength && fmt3[i2] ? { date_part: fmt3[i2] } : {}
143428
+ }));
142541
143429
  }
142542
143430
  if (e4.kind === "choice") {
142543
143431
  row.options = e4.options.map((o) => ({
@@ -142562,7 +143450,8 @@ function legendRows(render, page) {
142562
143450
  col: c2.col,
142563
143451
  type: c2.type,
142564
143452
  label: c2.label,
142565
- box: boxOf([c2.field])
143453
+ box: boxOf([c2.field]),
143454
+ ...c2.type === "date" ? { date_format: dateFormatOf(c2.field) } : {}
142566
143455
  }));
142567
143456
  }
142568
143457
  if (e4.kind === "table_rows") {
@@ -142571,7 +143460,8 @@ function legendRows(render, page) {
142571
143460
  id: c2.id,
142572
143461
  label: c2.label,
142573
143462
  type: c2.type,
142574
- box: boxOf([c2.field])
143463
+ box: boxOf([c2.field]),
143464
+ ...c2.type === "date" ? { date_format: dateFormatOf(c2.field) } : {}
142575
143465
  }));
142576
143466
  const body = expBodyRows(
142577
143467
  e4.group,
@@ -142600,15 +143490,17 @@ function legendRows(render, page) {
142600
143490
  }
142601
143491
  return legend;
142602
143492
  }
143493
+ var combKey = (c2) => `cell@${c2.box.x.toFixed(4)},${c2.box.y.toFixed(4)}` + (c2.index !== void 0 ? `#${String(c2.index)}` : "");
142603
143494
  var membersOf = (r) => [
142604
143495
  ...r.options ?? [],
142605
143496
  ...r.cells ?? [],
142606
- ...r.columns ?? []
143497
+ ...r.columns ?? [],
143498
+ ...(r.comb_cells ?? []).map((c2) => ({ ...c2, id: combKey(c2) }))
142607
143499
  ];
142608
143500
  function legendPrints(rows) {
142609
143501
  const out = /* @__PURE__ */ new Map();
142610
143502
  for (const r of rows) {
142611
- const { tag: _tag, options: _o, cells: _c, columns: _cols, ...own2 } = r;
143503
+ const { tag: _tag, options: _o, cells: _c, columns: _cols, comb_cells: _cc, ...own2 } = r;
142612
143504
  out.set(r.id, JSON.stringify(own2));
142613
143505
  for (const m of membersOf(r)) {
142614
143506
  const { tag: _t, ...rest } = m;
@@ -142631,7 +143523,8 @@ function legendChanges(before, now) {
142631
143523
  if (r.options) row.options = r.options.filter(differs);
142632
143524
  if (r.cells) row.cells = r.cells.filter(differs);
142633
143525
  if (r.columns) row.columns = r.columns.filter(differs);
142634
- for (const k4 of ["options", "cells", "columns"]) {
143526
+ if (r.comb_cells) row.comb_cells = r.comb_cells.filter((c2) => differs({ id: combKey(c2) }));
143527
+ for (const k4 of ["options", "cells", "columns", "comb_cells"]) {
142635
143528
  if (row[k4]?.length === 0) delete row[k4];
142636
143529
  }
142637
143530
  row.members_changed = n;
@@ -142642,7 +143535,7 @@ function legendChanges(before, now) {
142642
143535
  const moved = [];
142643
143536
  for (const id of before.keys()) {
142644
143537
  if (id.includes("/") || top.has(id)) continue;
142645
- const into = parent.get(id);
143538
+ const into = parent.get(id) ?? now.find((r) => r.comb_cells?.some((c2) => id.startsWith(c2.tag)))?.id;
142646
143539
  if (into) moved.push({ id, into });
142647
143540
  else removed.push(id);
142648
143541
  }
@@ -142658,6 +143551,7 @@ async function previewPage(a) {
142658
143551
  hint: `Pages with fields: ${pages.join(", ") || "none"}.`
142659
143552
  });
142660
143553
  }
143554
+ const printed = overlay === "full" ? await printedBoxes(a.pdfBytes, [a.page]) : void 0;
142661
143555
  let res;
142662
143556
  try {
142663
143557
  res = await fillAgentPdf({
@@ -142673,7 +143567,8 @@ async function previewPage(a) {
142673
143567
  // preview_page's JSON carries the colour key; the banner would only
142674
143568
  // cover the top of page 1.
142675
143569
  checkBanner: false,
142676
- checkTags: overlay === "full"
143570
+ checkTags: overlay === "full",
143571
+ checkPrinted: printed
142677
143572
  });
142678
143573
  } catch (e4) {
142679
143574
  if (isPasswordError(e4)) throw passwordError();
@@ -142705,7 +143600,16 @@ async function previewPage(a) {
142705
143600
  const listed = a.crop ? legend.filter((r) => {
142706
143601
  const c2 = a.crop;
142707
143602
  return r.box.x < c2.x + c2.w && c2.x < r.box.x + r.box.w && r.box.y < c2.y + c2.h && c2.y < r.box.y + r.box.h;
142708
- }) : legend;
143603
+ }) : (
143604
+ // A whole page lists its combs without their cells: a dense page's
143605
+ // legend would outgrow what a client takes in one result (the PL licence
143606
+ // page 1, 74 fields, passed 25k tokens). A crop lists them.
143607
+ legend.map((r) => {
143608
+ if (!r.comb_cells) return r;
143609
+ const { comb_cells: _cells, ...rest } = r;
143610
+ return rest;
143611
+ })
143612
+ );
142709
143613
  return {
142710
143614
  png: encodePng2(raster),
142711
143615
  width: raster.width,
@@ -143279,18 +144183,26 @@ async function sweepCache(cache3, now) {
143279
144183
  }
143280
144184
 
143281
144185
  // src/values.ts
143282
- function expandKeys(values2, pool3) {
143283
- const given = Object.keys(values2);
144186
+ function fullId(key, pool3, given) {
144187
+ if (pool3.includes(key)) return key;
144188
+ const hits2 = prefixHits(key, pool3);
144189
+ return hits2.length === 1 && !given.includes(hits2[0]) ? hits2[0] : key;
144190
+ }
144191
+ function topId3(key, pools, given) {
144192
+ const all = pools[pools.length - 1];
144193
+ if (all.includes(key)) return key;
144194
+ const pool3 = pools.find((p4) => prefixHits(key, p4).length > 0) ?? all;
144195
+ return fullId(key, pool3, given);
144196
+ }
144197
+ function expandKeys(obj, pool3) {
144198
+ const given = Object.keys(obj);
143284
144199
  const taken = /* @__PURE__ */ new Set();
143285
144200
  const pairs = [];
143286
144201
  for (const key of given) {
143287
- let id = key;
143288
- if (!pool3.includes(key) && key.length >= MIN_ID_PREFIX) {
143289
- const hits2 = pool3.filter((p4) => p4.startsWith(key));
143290
- if (hits2.length === 1 && !given.includes(hits2[0]) && !taken.has(hits2[0])) id = hits2[0];
143291
- }
144202
+ let id = fullId(key, pool3, given);
144203
+ if (id !== key && taken.has(id)) id = key;
143292
144204
  taken.add(id);
143293
- pairs.push([id, values2[key]]);
144205
+ pairs.push([id, obj[key]]);
143294
144206
  }
143295
144207
  return Object.fromEntries(pairs);
143296
144208
  }
@@ -143315,13 +144227,51 @@ function expandValueKeys(render, values2) {
143315
144227
  return values2;
143316
144228
  }
143317
144229
  const byId = new Map(entries.map((e4) => [e4.id, e4]));
143318
- const top = expandKeys(values2, [...byId.keys()]);
143319
- return Object.fromEntries(
143320
- Object.entries(top).map(([id, v]) => {
143321
- const e4 = byId.get(id);
143322
- return [id, e4 ? expandNested(e4, v) : v];
143323
- })
143324
- );
144230
+ const nested = nestedIdOwners(entries);
144231
+ const tagged = [.../* @__PURE__ */ new Set([...byId.keys(), ...checkTagIds(entries)])];
144232
+ const combCells2 = entries.flatMap((e4) => e4.kind === "comb" ? e4.members.map((m) => m.id) : []);
144233
+ const pool3 = [...byId.keys(), ...nested.keys()];
144234
+ const pools = [tagged, [...tagged, ...combCells2], pool3];
144235
+ const given = Object.keys(values2);
144236
+ const taken = /* @__PURE__ */ new Set();
144237
+ const pairs = [];
144238
+ const moved = [];
144239
+ for (const key of given) {
144240
+ const raw = values2[key];
144241
+ let id = topId3(key, pools, given);
144242
+ if (id !== key && taken.has(id)) id = key;
144243
+ taken.add(id);
144244
+ const n = byId.has(id) ? void 0 : nested.get(id);
144245
+ if (n?.kind === "cell") {
144246
+ moved.push({ owner: n.owner, id, key, v: raw });
144247
+ continue;
144248
+ }
144249
+ if (n?.kind === "option" && (raw === true || raw === false || raw == null)) {
144250
+ if (raw === true) moved.push({ owner: n.owner, id, key, v: raw });
144251
+ continue;
144252
+ }
144253
+ const e4 = byId.get(id);
144254
+ pairs.push([id, e4 ? expandNested(e4, raw) : raw]);
144255
+ }
144256
+ const top = Object.fromEntries(pairs);
144257
+ for (const m of moved) {
144258
+ const gid = m.owner.id;
144259
+ const has = Object.prototype.hasOwnProperty.call(top, gid);
144260
+ const cur = has ? top[gid] : void 0;
144261
+ if (m.owner.kind === "table") {
144262
+ if (!has) top[gid] = Object.fromEntries([[m.id, m.v]]);
144263
+ else if (isRec2(cur) && !Object.prototype.hasOwnProperty.call(cur, m.id)) {
144264
+ top[gid] = Object.fromEntries([...Object.entries(cur), [m.id, m.v]]);
144265
+ } else top[m.key] = m.v;
144266
+ } else if (m.owner.kind === "choice") {
144267
+ if (m.owner.type === "multiselect" && (!has || Array.isArray(cur) || typeof cur === "string")) {
144268
+ const list = !has ? [] : Array.isArray(cur) ? cur : [cur];
144269
+ top[gid] = [...list, m.id];
144270
+ } else if (!has) top[gid] = m.id;
144271
+ else top[m.key] = m.v;
144272
+ }
144273
+ }
144274
+ return top;
143325
144275
  }
143326
144276
 
143327
144277
  // src/server.ts
@@ -143337,7 +144287,7 @@ var INSTRUCTIONS = [
143337
144287
  var TEMPLATE_ID = external_exports.string().regex(/^[A-Za-z0-9-]{1,64}$/, "a fenfill template id").describe("Template id (from list_templates).");
143338
144288
  var PAGES = external_exports.string().max(2e3).optional().describe('1-based pages, e.g. "1-3,5". Omit for all.');
143339
144289
  var VALUES = external_exports.record(external_exports.string(), external_exports.unknown()).describe(
143340
- "Field id \u2192 value (see description). An id may be shortened to an unambiguous prefix of 6+ characters (the preview tags), a table's cell or column id inside its value too; a key that matches nothing is listed in skipped."
144290
+ "Field id \u2192 value (see description). Any id may be shortened to an unambiguous prefix of 4+ characters (the preview tags show 6), a table's cell or column id inside its value and an option id in a choice's value too. A table cell's id given at the top level goes into its table; an option's id given true selects it (a radio's value, or one more item of a multiselect). A date comb (a comb group with cell_type date) takes the whole date as one string: YYYY-MM-DD (laid out by its date_format), or its max_length digits in printed order; a single field drawn over cells takes one character per cell, as typed. A key that matches nothing, or starts several ids, is listed in skipped with candidates."
143341
144291
  );
143342
144292
  var OUTPUT_PATH = external_exports.string().min(1).max(4096).describe("Absolute path (or ~/\u2026) of the new .pdf to write.");
143343
144293
  var OVERWRITE = external_exports.boolean().optional().describe("Replace output_path if it exists.");
@@ -143750,27 +144700,40 @@ function createFenfillServer(opts = {}) {
143750
144700
  "get_template",
143751
144701
  {
143752
144702
  title: "Get a template's fields",
143753
- description: "Get a saved template's fillable fields (ids, types, labels) for fill_template. Use pages to narrow a large form. unanalyzed_pages (when present) lists pages fenfill never analyzed: they have no fields yet; reanalyze_template with kind scratch analyzes them.",
143754
- inputSchema: { template_id: TEMPLATE_ID, pages: PAGES },
144703
+ description: `Get a saved template's fillable fields (ids, types, labels) for fill_template. Use pages to narrow a large form. With local edits (edit_template) it lists your working copy, as fill_template and preview_page use it (edited: true): new ids, deletions, sections and order show before you save; version: "saved" lists fenfill's saved version instead. unanalyzed_pages (when present) lists pages fenfill never analyzed: they have no fields yet; reanalyze_template with kind scratch analyzes them.`,
144704
+ inputSchema: {
144705
+ template_id: TEMPLATE_ID,
144706
+ pages: PAGES,
144707
+ version: external_exports.enum(["working", "saved"]).optional().describe(
144708
+ `"working" (default): your local edits when there are any, else the saved template. "saved": fenfill's saved version, whatever you edited.`
144709
+ )
144710
+ },
143755
144711
  annotations: { readOnlyHint: true, openWorldHint: true }
143756
144712
  },
143757
- run("get_template", async ({ template_id, pages }, _extra, signal) => {
143758
- const { body } = await api().getJson(
144713
+ run("get_template", async ({ template_id, pages, version: version2 }, _extra, signal) => {
144714
+ const { body: saved } = await api().getJson(
143759
144715
  `/templates/${encodeURIComponent(template_id)}`,
143760
144716
  { signal }
143761
144717
  );
143762
144718
  const requested = pages?.trim() ? parsePageSpec(pages) : null;
143763
- const { unanalyzed } = analyzedPagesOf(body);
144719
+ const { unanalyzed } = analyzedPagesOf(saved);
144720
+ const wc = await templateEdits(template_id);
144721
+ const listWorking = !!wc && version2 !== "saved";
144722
+ const body = listWorking ? {
144723
+ ...saved,
144724
+ fields: projectAgentSchema(wc.render, { template_id, name: saved.name }).fields
144725
+ } : saved;
143764
144726
  return {
143765
144727
  template_id: body.template_id ?? template_id,
143766
144728
  ...unanalyzed.length ? {
143767
144729
  unanalyzed_pages: unanalyzed,
143768
144730
  unanalyzed_note: 'These pages were never analyzed, so they have no fields yet. reanalyze_template {template_id, pages, kind: "scratch"} analyzes them (1 page scan per page).'
143769
144731
  } : {},
143770
- ...await templateEdits(template_id) ? {
144732
+ ...wc ? {
143771
144733
  has_local_edits: true,
143772
- local_edits: "This template has local edits (edit_template) that fill_template and preview_page use; the fields listed are fenfill's saved version. save_template keeps them; edit_template with discard: true drops them."
143773
- } : { has_local_edits: false },
144734
+ edited: listWorking,
144735
+ local_edits: listWorking ? "The fields listed are your local working copy (edit_template), as fill_template and preview_page use it; fenfill's saved version differs until save_template. edit_template with discard: true drops the edits." : `This template has local edits (edit_template) that fill_template and preview_page use; the fields listed are fenfill's saved version (version: "saved"). save_template keeps the edits; edit_template with discard: true drops them.`
144736
+ } : { has_local_edits: false, edited: false },
143774
144737
  ...compactView(
143775
144738
  body,
143776
144739
  requested,
@@ -143832,7 +144795,7 @@ function createFenfillServer(opts = {}) {
143832
144795
  "preview_page",
143833
144796
  {
143834
144797
  title: "Preview a page with its field boxes",
143835
- description: `Render one page as a PNG with every field box outlined (green filled, orange warning, red skipped, grey empty) and tagged with its id prefix, plus a legend: tag \u2192 id, type, label, box (page fractions, top-left origin, as edit_template uses), format and font_pt; options, table cells (row, col) and table_rows columns with their own boxes. placement_warnings ([] = checked, clean) covers every box shown: much larger text than the page's other fields, a box over printed text (not on scans), a box past its ruled cell. Use it as a read-only placement audit. values (see that parameter) stamp test values. overlay: "outline" drops the tags, "none" shows the page with only the stamped values (to read print under a tag, or after check_copy_failed). crop + zoom magnify a region; legend: "changed" lists only what changed since your last preview of the page (moved_into: fields now inside a table or group). It renders the local working copy (edit_template) when one exists, else the saved or analyzed version (edited: true/false). Rendered on this machine: nothing is written to disk and the values are never sent anywhere.`,
144798
+ description: `Render one page as a PNG with every field box outlined (green filled, orange warning, red skipped, grey empty) and tagged with its id prefix, plus a legend: tag \u2192 id, type, label, box (page fractions, top-left origin, as edit_template uses), format and font_pt; options, table cells (row, col), table_rows columns and (in a crop) comb cells with their own boxes. placement_warnings ([] = checked, clean) covers every box shown: text much larger than its neighbours', a box over printed text (not on scans; a pale hint at its left edge is a placement_note), a box past its ruled cell, an option box on the wrong side of its caption. Use it as a read-only placement audit. values (see that parameter) stamp test values. overlay: "outline" drops the tags, "none" shows only the stamped page (e.g. after check_copy_failed). crop + zoom magnify a region; legend: "changed" lists only what changed since your last preview of the page (moved_into: fields now inside a table or group). It renders the local working copy (edit_template) when one exists, else the saved or analyzed version (edited: true/false). Rendered on this machine: nothing is written to disk and the values are never sent anywhere.`,
143836
144799
  inputSchema: {
143837
144800
  path: TARGET_PATH,
143838
144801
  template_id: TARGET_TEMPLATE,
@@ -143856,7 +144819,7 @@ function createFenfillServer(opts = {}) {
143856
144819
  `Which legend rows to return: "all" (default), "changed" (only what changed since your last preview of this page, or, the first time, since fenfill's version; plus removed ids), or "none".`
143857
144820
  ),
143858
144821
  overlay: external_exports.enum(OVERLAYS).optional().describe(
143859
- 'What is drawn over the page: "full" (default) = every box outlined and tagged, table headers printed; "outline" = the boxes only, no id tags and no table header texts; "none" = nothing, the page as a fill stamps it. Use "outline" or "none" when a tag covers a caption, a tick box or a stamped value. The legend and placement_warnings are the same in all three.'
144822
+ 'What is drawn over the page: "full" (default) = every box outlined and tagged, table headers printed; the tags keep off the printed text and the stamped values (a tag with no room beside its box is moved off and joined to it by a thin line); "outline" = the boxes only, no id tags and no table header texts; "none" = nothing, the page as a fill stamps it. Use "outline" or "none" when an outline covers what you must read, or on a scan (no text layer: there a tag may still cover print). The legend and placement_warnings are the same in all three.'
143860
144823
  )
143861
144824
  },
143862
144825
  annotations: { readOnlyHint: true, openWorldHint: true }
@@ -143898,12 +144861,12 @@ function createFenfillServer(opts = {}) {
143898
144861
  zoom: args.zoom,
143899
144862
  overlay: args.overlay
143900
144863
  });
143901
- const placement = await placementWarnings2(
144864
+ const placement = await placementReport(
143902
144865
  bytes,
143903
144866
  render,
143904
144867
  pv.legend.map((r) => r.id),
143905
144868
  { pageWide: true, cells: true }
143906
- ).catch(() => []);
144869
+ ).catch(() => ({ warnings: [], notes: [] }));
143907
144870
  const sizes = await stampedSizes(bytes, render, args.page).catch(
143908
144871
  () => /* @__PURE__ */ new Map()
143909
144872
  );
@@ -143916,7 +144879,12 @@ function createFenfillServer(opts = {}) {
143916
144879
  const shownIds = new Set(pv.legend.map((r) => r.id));
143917
144880
  const diff = mode === "changed" ? legendChanges(before, full) : null;
143918
144881
  const changes = diff && {
143919
- changed: diff.changed.filter((r) => shownIds.has(r.id)),
144882
+ // A whole page lists combs without their cells, as its full legend does.
144883
+ changed: diff.changed.filter((r) => shownIds.has(r.id)).map((r) => {
144884
+ if (args.crop || !r.comb_cells) return r;
144885
+ const { comb_cells: _cells, ...rest } = r;
144886
+ return rest;
144887
+ }),
143920
144888
  removed: diff.removed,
143921
144889
  moved_into: diff.moved_into
143922
144890
  };
@@ -143934,7 +144902,7 @@ function createFenfillServer(opts = {}) {
143934
144902
  overlay: "outline",
143935
144903
  colours: "green = filled, orange = filled with a warning, red = skipped, grey dashed = empty; a radio/multiselect option has a thin box"
143936
144904
  } : {
143937
- colours: "green = filled, orange = filled with a warning, red = skipped, grey dashed = empty; a radio/multiselect option has a thin box tagged below it"
144905
+ colours: "green = filled, orange = filled with a warning, red = skipped, grey dashed = empty; a radio/multiselect option has a thin box tagged beside it, off its caption (a tag moved further off has a thin line to its box)"
143938
144906
  },
143939
144907
  ...args.crop ? { crop: args.crop } : {},
143940
144908
  ...mode === "none" ? {} : changes ? {
@@ -143947,7 +144915,9 @@ function createFenfillServer(opts = {}) {
143947
144915
  ...pv.skipped.length ? { skipped: pv.skipped } : {},
143948
144916
  // Always present: [] means checked and clean, never "not computed".
143949
144917
  warnings: pv.warnings,
143950
- placement_warnings: placement
144918
+ placement_warnings: placement.warnings,
144919
+ // A pale hint under a box (written over, not a misplacement).
144920
+ ...placement.notes.length ? { placement_notes: placement.notes } : {}
143951
144921
  };
143952
144922
  log("info", "tool ok", { tool: "preview_page", ms: Date.now() - t0 });
143953
144923
  return {
@@ -143973,7 +144943,7 @@ function createFenfillServer(opts = {}) {
143973
144943
  path: TARGET_PATH,
143974
144944
  template_id: TARGET_TEMPLATE,
143975
144945
  ops: external_exports.array(external_exports.record(external_exports.string(), external_exports.unknown())).max(MAX_OPS).optional().describe(
143976
- `Edit ops, applied in order (max ${String(MAX_OPS)}), each all-or-nothing; a box only has to lie on the page after the whole batch (so move then resize is fine). Fields: set_box {id, x, y, w, h, snap?} (absolute top-left + size; a group scales its members); move {id, dx, dy} or {id, x, y, snap?} (new top-left); resize {id, w, h}; add {page, type: text|multiline|date|checkbox|signature, box: {x, y, w, h}, label, description?, placeholder?, required?, section_id?, snap?} (diff_summary.added gives the new id); snap: "underline" fits the box onto the printed rule under it, "cell" into the ruled box around it, "answer" into that cell's blank part below (or after) its printed caption (read from the page on this machine; a miss keeps your box and warns); relabel {id, label}; retype {id, type} (a radio/multiselect group: radio|multiselect); delete {id}; set_format {id, format: {...}} (font_size, text_anchor, variant, date_format: DD/MM/YYYY|MM/DD/YYYY|YYYY-MM-DD|DD.MM.YYYY|DD-MM-YYYY; null removes a key; on a table cell it applies to the cell's whole column/row; a comb group: cell_type char|integer|date, or date_format with one D/M/Y letter per cell, e.g. DDMMYYYY, which makes it a date comb; diff_summary.ops shows the comb's cell_type, date_format and max_length); set_required {id, required}; set_description {id, description}; set_placeholder {id, placeholder} (null clears); set_autofill {id, autofill: a browser token (name, given-name, family-name, email, tel, street-address, postal-code, bday, \u2026) or null}. Groups: group {ids, kind: "choice"|"comb", label, multiple?} (standalone fields on one page; choice turns them into checkbox options); ungroup {id}; set_options {id, options: ["label", \u2026] in listed order, or [{id, label}]}; add_option {id: group, label, box, index?} and remove_option {id: group, option} keep the group's id. Tables: group {kind: "table", label, cells: [[id|null, \u2026], \u2026] (rows \xD7 columns) or ids (laid out from their boxes), header_cols?, header_rows?, orientation?: "col"|"row" (the axis whose lines carry the types; default col), format?: classic|expandable|checkbox_matrix}; table_insert {id, axis: "row"|"col", index, box?: {y, h} for a row / {x, w} for a column (default: one pitch past the edge, or centred in the gap), header?, type?}; table_delete {id, axis, index, keep_cells?}; table_add_cell {id, row, col, box?} (fills an empty slot); table_adopt {id, field, row, col} (moves a loose field into an empty slot); set_column_type {id, index, type: text|number|currency|date|checkbox, date_format?} (index along the typed axis); set_orientation {id, orientation} (resets every cell to text); set_header {id, axis, index, text}; set_headers {id, axis, texts: [...], start?} (several at once). Order: reorder {page, ids} moves those top-level entries together, in that order, to where the first sat (stamps order; geometry no longer decides); diff_summary.ops shows the order now listed. A section is listed as one run where its first entry stands, so entries of different sections never stand together: set_section {ids, section_id | null} moves fields or groups of one page to another of its sections (get_template shows each section's section_id; null = no section), and set_section_title {page, section_id, title} renames one. A reorder whose ids cannot come out as asked and that would change nothing in the listing is rejected. Every cell of one column (or row, when orientation is row) has one type.`
144946
+ `Edit ops, applied in order (max ${String(MAX_OPS)}), each all-or-nothing; a box only has to lie on the page after the whole batch (so move then resize is fine). Fields: set_box {id, x, y, w, h, snap?} (absolute top-left + size; a group scales its members); move {id, dx, dy} or {id, x, y, snap?} (new top-left); resize {id, w, h}; add {page, type: text|multiline|date|checkbox|signature, box: {x, y, w, h}, label, description?, placeholder?, required?, section_id?, snap?} (diff_summary.added gives the new id, diff_summary.ops the section it landed in: without section_id, that of the nearest field at or above it); snap: "underline" fits the box onto the printed rule under it, "cell" into the ruled box around it, "answer" into that cell's blank part below (or after) its printed caption (read from the page on this machine; a miss keeps your box and warns); relabel {id, label}; retype {id, type} (a radio/multiselect group: radio|multiselect); delete {id}; set_format {id, format: {...}} (font_size, text_anchor, variant, date_format: DD/MM/YYYY|MM/DD/YYYY|YYYY-MM-DD|DD.MM.YYYY|DD-MM-YYYY; null removes a key; on a table cell it applies to the cell's whole column/row; a comb group: cell_type char|integer|date, or date_format with one D/M/Y letter per cell, e.g. DDMMYYYY, which makes it a date comb; diff_summary.ops shows the comb's cell_type, date_format and max_length); set_required {id, required}; set_description {id, description}; set_placeholder {id, placeholder} (null clears); set_autofill {id, autofill: a browser token (name, given-name, family-name, email, tel, street-address, postal-code, bday, \u2026) or null}. Groups: group {ids, kind: "choice"|"comb", label, multiple?} (standalone fields on one page; choice turns them into checkbox options; the members keep their ids, and diff_summary.ops lists them in reading order with the group's section; the group stands where its earliest member stood); ungroup {id}; set_options {id, options: ["label", \u2026] in listed order, or [{id, label}]}; add_option {id: group, label, box, index?} and remove_option {id: group, option} keep the group's id. Combs in one op: add {type: "comb", page, label, cells: N (box cut into N equal cells) | [{x, y, w, h}, \u2026] (each printed cell's box, for cells split by separators), box?, cell_type?, date_format?, section_id?} (its cells have no label); retype {id, type: "comb", cells, cell_type?, date_format?} turns a text/date field into a comb over its box, keeping label, section, order and required; comb_add_cell {id: comb, box, date_format?} and comb_remove_cell {id: cell, date_format?} (a date comb needs its new date_format, one letter per cell); group {kind: "comb"} takes cell_type and date_format too, and set_format on a comb's cell applies to its comb. Refs: any op that adds something takes ref: "name", and later ops of the same call write "$name" for its id (set_format {id: "$dob", \u2026}). Tables: group {kind: "table", label, cells: [[id|null, \u2026], \u2026] (rows \xD7 columns) or ids (laid out from their boxes), header_cols?, header_rows?, orientation?: "col"|"row" (the axis whose lines carry the types; default col), format?: classic|expandable|checkbox_matrix}; table_insert {id, axis: "row"|"col", index, box?: {y, h} for a row / {x, w} for a column (default: one pitch past the edge, or centred in the gap), header?, type?}; table_delete {id, axis, index, keep_cells?}; table_add_cell {id, row, col, box?} (fills an empty slot); table_adopt {id, field, row, col} (moves a loose field into an empty slot); set_column_type {id, index, type: text|number|currency|date|checkbox, date_format?} (index along the typed axis); set_orientation {id, orientation} (resets every cell to text); set_header {id, axis, index, text}; set_headers {id, axis, texts: [...], start?} (several at once). Order: reorder {page, ids} moves those top-level entries together, in that order, to where whichever of them is listed first now stands (not ids[0]'s place); every other entry keeps its relative order (stamps order; geometry no longer decides). A partial list moves only what it names: to put B right after A, list both; chained partial reorders are simplest replaced by one with the page's whole list. diff_summary.ops shows the order now listed. A section is listed as one run where its first entry stands, so entries of different sections never stand together: set_section {ids, section_id | null} moves fields or groups of one page to another of its sections (get_template shows each section's section_id; null = no section), and set_section_title {page, section_id, title} renames one. A reorder whose ids cannot come out as asked and that would change nothing in the listing is rejected. Every cell of one column (or row, when orientation is row) has one type.`
143977
144947
  ),
143978
144948
  discard: external_exports.boolean().optional().describe(
143979
144949
  "Drop the local working copy first (any ops then apply to fenfill's version). ops may be left out with it."
@@ -144075,12 +145045,15 @@ function createFenfillServer(opts = {}) {
144075
145045
  confirmWording: confirm_wording === true
144076
145046
  });
144077
145047
  let placement = [];
145048
+ let placementNotes = [];
144078
145049
  if (r.applied > 0) {
144079
145050
  const ids = [
144080
145051
  ...r.diff_summary.touched.map((t) => t.id),
144081
145052
  ...r.diff_summary.added.map((a) => a.id)
144082
145053
  ];
144083
- placement = await blank().then((pdf) => placementWarnings2(pdf, r.render, ids, { cells: true })).catch(() => []);
145054
+ const report = await blank().then((pdf) => placementReport(pdf, r.render, ids, { cells: true })).catch(() => ({ warnings: [], notes: [] }));
145055
+ placement = report.warnings;
145056
+ placementNotes = report.notes;
144084
145057
  }
144085
145058
  const inherited = wc.inherited_wording === true || wc.writer?.owner !== owner && changedWording(wc.base, wc.render).length > 0;
144086
145059
  const out = {
@@ -144115,6 +145088,7 @@ function createFenfillServer(opts = {}) {
144115
145088
  (i2) => `${i2.id ? `${i2.id}: ` : ""}${i2.path} ${i2.reason} (fenfill would refuse to save this; fix it with another op)`
144116
145089
  )
144117
145090
  ],
145091
+ ...placementNotes.length ? { notes: placementNotes } : {},
144118
145092
  has_edits: hasEdits,
144119
145093
  ops_applied_total: changed ? out.ops_applied : wc.ops_applied,
144120
145094
  saveable: !!saveTarget,