@fenfill/mcp 0.2.3 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -7211,6 +7211,88 @@ var require_dist = __commonJS({
7211
7211
  }
7212
7212
  });
7213
7213
 
7214
+ // ../../app/t/[template_id]/bidiText.ts
7215
+ function inRtlBlock(cp) {
7216
+ for (const [a, b] of RTL_BLOCKS) {
7217
+ if (cp < a) return false;
7218
+ if (cp <= b) return true;
7219
+ }
7220
+ return false;
7221
+ }
7222
+ function stripBidiControls(text) {
7223
+ return text.replace(BIDI_CONTROLS, "");
7224
+ }
7225
+ function needsBidi(text) {
7226
+ for (const ch of text) {
7227
+ if (inRtlBlock(ch.codePointAt(0) ?? 0)) return true;
7228
+ }
7229
+ return false;
7230
+ }
7231
+ function marksNeedBidi(marksByPage) {
7232
+ for (const marks of marksByPage.values()) {
7233
+ for (const m of marks) {
7234
+ if (m.text && needsBidi(m.text)) return true;
7235
+ }
7236
+ }
7237
+ return false;
7238
+ }
7239
+ function strongDirection(ch) {
7240
+ const cp = ch.codePointAt(0) ?? 0;
7241
+ if (cp === 8207 || cp === 1564) return "rtl";
7242
+ if (cp === 8206) return "ltr";
7243
+ if (!LETTER.test(ch)) return null;
7244
+ for (const [a, b] of NEUTRAL_LETTERS) if (cp >= a && cp <= b) return null;
7245
+ return inRtlBlock(cp) ? "rtl" : "ltr";
7246
+ }
7247
+ function isRtlDominant(text) {
7248
+ for (const ch of text) {
7249
+ const d = strongDirection(ch);
7250
+ if (d) return d === "rtl";
7251
+ }
7252
+ return false;
7253
+ }
7254
+ function bidiAnchor(anchor2, rtl) {
7255
+ if (!rtl) return anchor2;
7256
+ switch (anchor2) {
7257
+ case "top-left":
7258
+ return "top-right";
7259
+ case "middle-left":
7260
+ return "middle-right";
7261
+ case "bottom-left":
7262
+ return "bottom-right";
7263
+ default:
7264
+ return anchor2;
7265
+ }
7266
+ }
7267
+ function stampsRtl(text) {
7268
+ return needsBidi(text) && isRtlDominant(text);
7269
+ }
7270
+ var RTL_BLOCKS, BIDI_CONTROLS, NEUTRAL_LETTERS, LETTER;
7271
+ var init_bidiText = __esm({
7272
+ "../../app/t/[template_id]/bidiText.ts"() {
7273
+ "use strict";
7274
+ RTL_BLOCKS = [
7275
+ [1424, 2303],
7276
+ [64285, 65023],
7277
+ [65136, 65279],
7278
+ [67584, 69631],
7279
+ [124928, 126975]
7280
+ ];
7281
+ BIDI_CONTROLS = /[\u061c\u200e\u200f\u202a-\u202e\u2066-\u2069]/g;
7282
+ NEUTRAL_LETTERS = [
7283
+ [697, 698],
7284
+ [710, 719],
7285
+ [748, 748],
7286
+ [884, 884],
7287
+ [11823, 11823],
7288
+ [42623, 42623],
7289
+ [42775, 42783],
7290
+ [42888, 42888]
7291
+ ];
7292
+ LETTER = new RegExp("\\p{L}", "u");
7293
+ }
7294
+ });
7295
+
7214
7296
  // ../../node_modules/pdf-lib/node_modules/tslib/tslib.es6.js
7215
7297
  var tslib_es6_exports = {};
7216
7298
  __export(tslib_es6_exports, {
@@ -58065,7 +58147,7 @@ var require_fontkit_umd = __commonJS({
58065
58147
  plan.addStage(["pref"]);
58066
58148
  plan.addStage(recordPref);
58067
58149
  plan.addStage(["rkrf", "abvf", "blwf", "half", "pstf", "vatu", "cjct"]);
58068
- plan.addStage(reorder2);
58150
+ plan.addStage(reorder3);
58069
58151
  plan.addStage(["abvs", "blws", "pres", "psts", "dist", "abvm", "blwm"]);
58070
58152
  };
58071
58153
  UniversalShaper2.assignFeatures = function assignFeatures(plan, glyphs) {
@@ -58130,7 +58212,7 @@ var require_fontkit_umd = __commonJS({
58130
58212
  }
58131
58213
  }
58132
58214
  }
58133
- function reorder2(font, glyphs) {
58215
+ function reorder3(font, glyphs) {
58134
58216
  var dottedCircle = font.glyphForCodePoint(9676).id;
58135
58217
  for (var start = 0, end = nextSyllable$1(glyphs, 0); start < glyphs.length; start = end, end = nextSyllable$1(glyphs, start)) {
58136
58218
  var i3 = void 0, j = void 0;
@@ -99623,6 +99705,1043 @@ var init_decryptPdf = __esm({
99623
99705
  }
99624
99706
  });
99625
99707
 
99708
+ // ../../node_modules/bidi-js/dist/bidi.js
99709
+ var require_bidi = __commonJS({
99710
+ "../../node_modules/bidi-js/dist/bidi.js"(exports, module) {
99711
+ "use strict";
99712
+ (function(global2, factory) {
99713
+ typeof exports === "object" && typeof module !== "undefined" ? module.exports = factory() : typeof define === "function" && define.amd ? define(factory) : (global2 = typeof globalThis !== "undefined" ? globalThis : global2 || self, global2.bidi_js = factory());
99714
+ })(exports, (function() {
99715
+ "use strict";
99716
+ function bidiFactory2() {
99717
+ var bidi2 = (function(exports2) {
99718
+ var DATA = {
99719
+ "R": "13k,1a,2,3,3,2+1j,ch+16,a+1,5+2,2+n,5,a,4,6+16,4+3,h+1b,4mo,179q,2+9,2+11,2i9+7y,2+68,4,3+4,5+13,4+3,2+4k,3+29,8+cf,1t+7z,w+17,3+3m,1t+3z,16o1+5r,8+30,8+mc,29+1r,29+4v,75+73",
99720
+ "EN": "1c+9,3d+1,6,187+9,513,4+5,7+9,sf+j,175h+9,qw+q,161f+1d,4xt+a,25i+9",
99721
+ "ES": "17,2,6dp+1,f+1,av,16vr,mx+1,4o,2",
99722
+ "ET": "z+2,3h+3,b+1,ym,3e+1,2o,p4+1,8,6u,7c,g6,1wc,1n9+4,30+1b,2n,6d,qhx+1,h0m,a+1,49+2,63+1,4+1,6bb+3,12jj",
99723
+ "AN": "16o+5,2j+9,2+1,35,ed,1ff2+9,87+u",
99724
+ "CS": "18,2+1,b,2u,12k,55v,l,17v0,2,3,53,2+1,b",
99725
+ "B": "a,3,f+2,2v,690",
99726
+ "S": "9,2,k",
99727
+ "WS": "c,k,4f4,1vk+a,u,1j,335",
99728
+ "ON": "x+1,4+4,h+5,r+5,r+3,z,5+3,2+1,2+1,5,2+2,3+4,o,w,ci+1,8+d,3+d,6+8,2+g,39+1,9,6+1,2,33,b8,3+1,3c+1,7+1,5r,b,7h+3,sa+5,2,3i+6,jg+3,ur+9,2v,ij+1,9g+9,7+a,8m,4+1,49+x,14u,2+2,c+2,e+2,e+2,e+1,i+n,e+e,2+p,u+2,e+2,36+1,2+3,2+1,b,2+2,6+5,2,2,2,h+1,5+4,6+3,3+f,16+2,5+3l,3+81,1y+p,2+40,q+a,m+13,2r+ch,2+9e,75+hf,3+v,2+2w,6e+5,f+6,75+2a,1a+p,2+2g,d+5x,r+b,6+3,4+o,g,6+1,6+2,2k+1,4,2j,5h+z,1m+1,1e+f,t+2,1f+e,d+3,4o+3,2s+1,w,535+1r,h3l+1i,93+2,2s,b+1,3l+x,2v,4g+3,21+3,kz+1,g5v+1,5a,j+9,n+v,2,3,2+8,2+1,3+2,2,3,46+1,4+4,h+5,r+5,r+a,3h+2,4+6,b+4,78,1r+24,4+c,4,1hb,ey+6,103+j,16j+c,1ux+7,5+g,fsh,jdq+1t,4,57+2e,p1,1m,1m,1m,1m,4kt+1,7j+17,5+2r,d+e,3+e,2+e,2+10,m+4,w,1n+5,1q,4z+5,4b+rb,9+c,4+c,4+37,d+2g,8+b,l+b,5+1j,9+9,7+13,9+t,3+1,27+3c,2+29,2+3q,d+d,3+4,4+2,6+6,a+o,8+6,a+2,e+6,16+42,2+1i",
99729
+ "BN": "0+8,6+d,2s+5,2+p,e,4m9,1kt+2,2b+5,5+5,17q9+v,7k,6p+8,6+1,119d+3,440+7,96s+1,1ekf+1,1ekf+1,1ekf+1,1ekf+1,1ekf+1,1ekf+1,1ekf+1,1ekf+1,1ekf+1,1ekf+1,1ekf+1,1ekf+75,6p+2rz,1ben+1,1ekf+1,1ekf+1",
99730
+ "NSM": "lc+33,7o+6,7c+18,2,2+1,2+1,2,21+a,1d+k,h,2u+6,3+5,3+1,2+3,10,v+q,2k+a,1n+8,a,p+3,2+8,2+2,2+4,18+2,3c+e,2+v,1k,2,5+7,5,4+6,b+1,u,1n,5+3,9,l+1,r,3+1,1m,5+1,5+1,3+2,4,v+1,4,c+1,1m,5+4,2+1,5,l+1,n+5,2,1n,3,2+3,9,8+1,c+1,v,1q,d,1f,4,1m+2,6+2,2+3,8+1,c+1,u,1n,g+1,l+1,t+1,1m+1,5+3,9,l+1,u,21,8+2,2,2j,3+6,d+7,2r,3+8,c+5,23+1,s,2,2,1k+d,2+4,2+1,6+a,2+z,a,2v+3,2+5,2+1,3+1,q+1,5+2,h+3,e,3+1,7,g,jk+2,qb+2,u+2,u+1,v+1,1t+1,2+6,9,3+a,a,1a+2,3c+1,z,3b+2,5+1,a,7+2,64+1,3,1n,2+6,2,2,3+7,7+9,3,1d+g,1s+3,1d,2+4,2,6,15+8,d+1,x+3,3+1,2+2,1l,2+1,4,2+2,1n+7,3+1,49+2,2+c,2+6,5,7,4+1,5j+1l,2+4,k1+w,2db+2,3y,2p+v,ff+3,30+1,n9x+3,2+9,x+1,29+1,7l,4,5,q+1,6,48+1,r+h,e,13+7,q+a,1b+2,1d,3+3,3+1,14,1w+5,3+1,3+1,d,9,1c,1g,2+2,3+1,6+1,2,17+1,9,6n,3,5,fn5,ki+f,h+f,r2,6b,46+4,1af+2,2+1,6+3,15+2,5,4m+1,fy+3,as+1,4a+a,4x,1j+e,1l+2,1e+3,3+1,1y+2,11+4,2+7,1r,d+1,1h+8,b+3,3,2o+2,3,2+1,7,4h,4+7,m+1,1m+1,4,12+6,4+4,5g+7,3+2,2,o,2d+5,2,5+1,2+1,6n+3,7+1,2+1,s+1,2e+7,3,2+1,2z,2,3+5,2,2u+2,3+3,2+4,78+8,2+1,75+1,2,5,41+3,3+1,5,x+5,3+1,15+5,3+3,9,a+5,3+2,1b+c,2+1,bb+6,2+5,2d+l,3+6,2+1,2+1,3f+5,4,2+1,2+6,2,21+1,4,2,9o+1,f0c+4,1o+6,t5,1s+3,2a,f5l+1,43t+2,i+7,3+6,v+3,45+2,1j0+1i,5+1d,9,f,n+4,2+e,11t+6,2+g,3+6,2+1,2+4,7a+6,c6+3,15t+6,32+6,gzhy+6n",
99731
+ "AL": "16w,3,2,e+1b,z+2,2+2s,g+1,8+1,b+m,2+t,s+2i,c+e,4h+f,1d+1e,1bwe+dp,3+3z,x+c,2+1,35+3y,2rm+z,5+7,b+5,dt+l,c+u,17nl+27,1t+27,4x+6n,3+d",
99732
+ "LRO": "6ct",
99733
+ "RLO": "6cu",
99734
+ "LRE": "6cq",
99735
+ "RLE": "6cr",
99736
+ "PDF": "6cs",
99737
+ "LRI": "6ee",
99738
+ "RLI": "6ef",
99739
+ "FSI": "6eg",
99740
+ "PDI": "6eh"
99741
+ };
99742
+ var TYPES = {};
99743
+ var TYPES_TO_NAMES = {};
99744
+ TYPES.L = 1;
99745
+ TYPES_TO_NAMES[1] = "L";
99746
+ Object.keys(DATA).forEach(function(type, i2) {
99747
+ TYPES[type] = 1 << i2 + 1;
99748
+ TYPES_TO_NAMES[TYPES[type]] = type;
99749
+ });
99750
+ Object.freeze(TYPES);
99751
+ var ISOLATE_INIT_TYPES = TYPES.LRI | TYPES.RLI | TYPES.FSI;
99752
+ var STRONG_TYPES = TYPES.L | TYPES.R | TYPES.AL;
99753
+ var NEUTRAL_ISOLATE_TYPES = TYPES.B | TYPES.S | TYPES.WS | TYPES.ON | TYPES.FSI | TYPES.LRI | TYPES.RLI | TYPES.PDI;
99754
+ var BN_LIKE_TYPES = TYPES.BN | TYPES.RLE | TYPES.LRE | TYPES.RLO | TYPES.LRO | TYPES.PDF;
99755
+ var TRAILING_TYPES = TYPES.S | TYPES.WS | TYPES.B | ISOLATE_INIT_TYPES | TYPES.PDI | BN_LIKE_TYPES;
99756
+ var map2 = null;
99757
+ function parseData() {
99758
+ if (!map2) {
99759
+ map2 = /* @__PURE__ */ new Map();
99760
+ var loop = function(type2) {
99761
+ if (DATA.hasOwnProperty(type2)) {
99762
+ var lastCode = 0;
99763
+ DATA[type2].split(",").forEach(function(range4) {
99764
+ var ref = range4.split("+");
99765
+ var skip = ref[0];
99766
+ var step = ref[1];
99767
+ skip = parseInt(skip, 36);
99768
+ step = step ? parseInt(step, 36) : 0;
99769
+ map2.set(lastCode += skip, TYPES[type2]);
99770
+ for (var i2 = 0; i2 < step; i2++) {
99771
+ map2.set(++lastCode, TYPES[type2]);
99772
+ }
99773
+ });
99774
+ }
99775
+ };
99776
+ for (var type in DATA) loop(type);
99777
+ }
99778
+ }
99779
+ function getBidiCharType(char) {
99780
+ parseData();
99781
+ return map2.get(char.codePointAt(0)) || TYPES.L;
99782
+ }
99783
+ function getBidiCharTypeName(char) {
99784
+ return TYPES_TO_NAMES[getBidiCharType(char)];
99785
+ }
99786
+ var data$1 = {
99787
+ "pairs": "14>1,1e>2,u>2,2wt>1,1>1,1ge>1,1wp>1,1j>1,f>1,hm>1,1>1,u>1,u6>1,1>1,+5,28>1,w>1,1>1,+3,b8>1,1>1,+3,1>3,-1>-1,3>1,1>1,+2,1s>1,1>1,x>1,th>1,1>1,+2,db>1,1>1,+3,3>1,1>1,+2,14qm>1,1>1,+1,4q>1,1e>2,u>2,2>1,+1",
99788
+ "canonical": "6f1>-6dx,6dy>-6dx,6ec>-6ed,6ee>-6ed,6ww>2jj,-2ji>2jj,14r4>-1e7l,1e7m>-1e7l,1e7m>-1e5c,1e5d>-1e5b,1e5c>-14qx,14qy>-14qx,14vn>-1ecg,1ech>-1ecg,1edu>-1ecg,1eci>-1ecg,1eda>-1ecg,1eci>-1ecg,1eci>-168q,168r>-168q,168s>-14ye,14yf>-14ye"
99789
+ };
99790
+ function parseCharacterMap(encodedString, includeReverse) {
99791
+ var radix = 36;
99792
+ var lastCode = 0;
99793
+ var map3 = /* @__PURE__ */ new Map();
99794
+ var reverseMap = includeReverse && /* @__PURE__ */ new Map();
99795
+ var prevPair;
99796
+ encodedString.split(",").forEach(function visit2(entry) {
99797
+ if (entry.indexOf("+") !== -1) {
99798
+ for (var i2 = +entry; i2--; ) {
99799
+ visit2(prevPair);
99800
+ }
99801
+ } else {
99802
+ prevPair = entry;
99803
+ var ref = entry.split(">");
99804
+ var a = ref[0];
99805
+ var b = ref[1];
99806
+ a = String.fromCodePoint(lastCode += parseInt(a, radix));
99807
+ b = String.fromCodePoint(lastCode += parseInt(b, radix));
99808
+ map3.set(a, b);
99809
+ includeReverse && reverseMap.set(b, a);
99810
+ }
99811
+ });
99812
+ return { map: map3, reverseMap };
99813
+ }
99814
+ var openToClose, closeToOpen, canonical;
99815
+ function parse$1() {
99816
+ if (!openToClose) {
99817
+ var ref = parseCharacterMap(data$1.pairs, true);
99818
+ var map3 = ref.map;
99819
+ var reverseMap = ref.reverseMap;
99820
+ openToClose = map3;
99821
+ closeToOpen = reverseMap;
99822
+ canonical = parseCharacterMap(data$1.canonical, false).map;
99823
+ }
99824
+ }
99825
+ function openingToClosingBracket(char) {
99826
+ parse$1();
99827
+ return openToClose.get(char) || null;
99828
+ }
99829
+ function closingToOpeningBracket(char) {
99830
+ parse$1();
99831
+ return closeToOpen.get(char) || null;
99832
+ }
99833
+ function getCanonicalBracket(char) {
99834
+ parse$1();
99835
+ return canonical.get(char) || null;
99836
+ }
99837
+ var TYPE_L = TYPES.L;
99838
+ var TYPE_R = TYPES.R;
99839
+ var TYPE_EN = TYPES.EN;
99840
+ var TYPE_ES = TYPES.ES;
99841
+ var TYPE_ET = TYPES.ET;
99842
+ var TYPE_AN = TYPES.AN;
99843
+ var TYPE_CS = TYPES.CS;
99844
+ var TYPE_B = TYPES.B;
99845
+ var TYPE_S = TYPES.S;
99846
+ var TYPE_ON = TYPES.ON;
99847
+ var TYPE_BN = TYPES.BN;
99848
+ var TYPE_NSM = TYPES.NSM;
99849
+ var TYPE_AL = TYPES.AL;
99850
+ var TYPE_LRO = TYPES.LRO;
99851
+ var TYPE_RLO = TYPES.RLO;
99852
+ var TYPE_LRE = TYPES.LRE;
99853
+ var TYPE_RLE = TYPES.RLE;
99854
+ var TYPE_PDF = TYPES.PDF;
99855
+ var TYPE_LRI = TYPES.LRI;
99856
+ var TYPE_RLI = TYPES.RLI;
99857
+ var TYPE_FSI = TYPES.FSI;
99858
+ var TYPE_PDI = TYPES.PDI;
99859
+ function getEmbeddingLevels(string4, baseDirection) {
99860
+ var MAX_DEPTH = 125;
99861
+ var charTypes = new Uint32Array(string4.length);
99862
+ for (var i2 = 0; i2 < string4.length; i2++) {
99863
+ charTypes[i2] = getBidiCharType(string4[i2]);
99864
+ }
99865
+ var charTypeCounts = /* @__PURE__ */ new Map();
99866
+ function changeCharType(i3, type2) {
99867
+ var oldType = charTypes[i3];
99868
+ charTypes[i3] = type2;
99869
+ charTypeCounts.set(oldType, charTypeCounts.get(oldType) - 1);
99870
+ if (oldType & NEUTRAL_ISOLATE_TYPES) {
99871
+ charTypeCounts.set(NEUTRAL_ISOLATE_TYPES, charTypeCounts.get(NEUTRAL_ISOLATE_TYPES) - 1);
99872
+ }
99873
+ charTypeCounts.set(type2, (charTypeCounts.get(type2) || 0) + 1);
99874
+ if (type2 & NEUTRAL_ISOLATE_TYPES) {
99875
+ charTypeCounts.set(NEUTRAL_ISOLATE_TYPES, (charTypeCounts.get(NEUTRAL_ISOLATE_TYPES) || 0) + 1);
99876
+ }
99877
+ }
99878
+ var embedLevels = new Uint8Array(string4.length);
99879
+ var isolationPairs = /* @__PURE__ */ new Map();
99880
+ var paragraphs = [];
99881
+ var paragraph = null;
99882
+ for (var i$1 = 0; i$1 < string4.length; i$1++) {
99883
+ if (!paragraph) {
99884
+ paragraphs.push(paragraph = {
99885
+ start: i$1,
99886
+ end: string4.length - 1,
99887
+ // 3.3.1 P2-P3: Determine the paragraph level
99888
+ level: baseDirection === "rtl" ? 1 : baseDirection === "ltr" ? 0 : determineAutoEmbedLevel(i$1, false)
99889
+ });
99890
+ }
99891
+ if (charTypes[i$1] & TYPE_B) {
99892
+ paragraph.end = i$1;
99893
+ paragraph = null;
99894
+ }
99895
+ }
99896
+ var FORMATTING_TYPES = TYPE_RLE | TYPE_LRE | TYPE_RLO | TYPE_LRO | ISOLATE_INIT_TYPES | TYPE_PDI | TYPE_PDF | TYPE_B;
99897
+ var nextEven = function(n) {
99898
+ return n + (n & 1 ? 1 : 2);
99899
+ };
99900
+ var nextOdd = function(n) {
99901
+ return n + (n & 1 ? 2 : 1);
99902
+ };
99903
+ for (var paraIdx = 0; paraIdx < paragraphs.length; paraIdx++) {
99904
+ paragraph = paragraphs[paraIdx];
99905
+ var statusStack = [{
99906
+ _level: paragraph.level,
99907
+ _override: 0,
99908
+ //0=neutral, 1=L, 2=R
99909
+ _isolate: 0
99910
+ //bool
99911
+ }];
99912
+ var stackTop = void 0;
99913
+ var overflowIsolateCount = 0;
99914
+ var overflowEmbeddingCount = 0;
99915
+ var validIsolateCount = 0;
99916
+ charTypeCounts.clear();
99917
+ for (var i$2 = paragraph.start; i$2 <= paragraph.end; i$2++) {
99918
+ var charType = charTypes[i$2];
99919
+ stackTop = statusStack[statusStack.length - 1];
99920
+ charTypeCounts.set(charType, (charTypeCounts.get(charType) || 0) + 1);
99921
+ if (charType & NEUTRAL_ISOLATE_TYPES) {
99922
+ charTypeCounts.set(NEUTRAL_ISOLATE_TYPES, (charTypeCounts.get(NEUTRAL_ISOLATE_TYPES) || 0) + 1);
99923
+ }
99924
+ if (charType & FORMATTING_TYPES) {
99925
+ if (charType & (TYPE_RLE | TYPE_LRE)) {
99926
+ embedLevels[i$2] = stackTop._level;
99927
+ var level = (charType === TYPE_RLE ? nextOdd : nextEven)(stackTop._level);
99928
+ if (level <= MAX_DEPTH && !overflowIsolateCount && !overflowEmbeddingCount) {
99929
+ statusStack.push({
99930
+ _level: level,
99931
+ _override: 0,
99932
+ _isolate: 0
99933
+ });
99934
+ } else if (!overflowIsolateCount) {
99935
+ overflowEmbeddingCount++;
99936
+ }
99937
+ } else if (charType & (TYPE_RLO | TYPE_LRO)) {
99938
+ embedLevels[i$2] = stackTop._level;
99939
+ var level$1 = (charType === TYPE_RLO ? nextOdd : nextEven)(stackTop._level);
99940
+ if (level$1 <= MAX_DEPTH && !overflowIsolateCount && !overflowEmbeddingCount) {
99941
+ statusStack.push({
99942
+ _level: level$1,
99943
+ _override: charType & TYPE_RLO ? TYPE_R : TYPE_L,
99944
+ _isolate: 0
99945
+ });
99946
+ } else if (!overflowIsolateCount) {
99947
+ overflowEmbeddingCount++;
99948
+ }
99949
+ } else if (charType & ISOLATE_INIT_TYPES) {
99950
+ if (charType & TYPE_FSI) {
99951
+ charType = determineAutoEmbedLevel(i$2 + 1, true) === 1 ? TYPE_RLI : TYPE_LRI;
99952
+ }
99953
+ embedLevels[i$2] = stackTop._level;
99954
+ if (stackTop._override) {
99955
+ changeCharType(i$2, stackTop._override);
99956
+ }
99957
+ var level$2 = (charType === TYPE_RLI ? nextOdd : nextEven)(stackTop._level);
99958
+ if (level$2 <= MAX_DEPTH && overflowIsolateCount === 0 && overflowEmbeddingCount === 0) {
99959
+ validIsolateCount++;
99960
+ statusStack.push({
99961
+ _level: level$2,
99962
+ _override: 0,
99963
+ _isolate: 1,
99964
+ _isolInitIndex: i$2
99965
+ });
99966
+ } else {
99967
+ overflowIsolateCount++;
99968
+ }
99969
+ } else if (charType & TYPE_PDI) {
99970
+ if (overflowIsolateCount > 0) {
99971
+ overflowIsolateCount--;
99972
+ } else if (validIsolateCount > 0) {
99973
+ overflowEmbeddingCount = 0;
99974
+ while (!statusStack[statusStack.length - 1]._isolate) {
99975
+ statusStack.pop();
99976
+ }
99977
+ var isolInitIndex = statusStack[statusStack.length - 1]._isolInitIndex;
99978
+ if (isolInitIndex != null) {
99979
+ isolationPairs.set(isolInitIndex, i$2);
99980
+ isolationPairs.set(i$2, isolInitIndex);
99981
+ }
99982
+ statusStack.pop();
99983
+ validIsolateCount--;
99984
+ }
99985
+ stackTop = statusStack[statusStack.length - 1];
99986
+ embedLevels[i$2] = stackTop._level;
99987
+ if (stackTop._override) {
99988
+ changeCharType(i$2, stackTop._override);
99989
+ }
99990
+ } else if (charType & TYPE_PDF) {
99991
+ if (overflowIsolateCount === 0) {
99992
+ if (overflowEmbeddingCount > 0) {
99993
+ overflowEmbeddingCount--;
99994
+ } else if (!stackTop._isolate && statusStack.length > 1) {
99995
+ statusStack.pop();
99996
+ stackTop = statusStack[statusStack.length - 1];
99997
+ }
99998
+ }
99999
+ embedLevels[i$2] = stackTop._level;
100000
+ } else if (charType & TYPE_B) {
100001
+ embedLevels[i$2] = paragraph.level;
100002
+ }
100003
+ } else {
100004
+ embedLevels[i$2] = stackTop._level;
100005
+ if (stackTop._override && charType !== TYPE_BN) {
100006
+ changeCharType(i$2, stackTop._override);
100007
+ }
100008
+ }
100009
+ }
100010
+ var levelRuns = [];
100011
+ var currentRun = null;
100012
+ for (var i$3 = paragraph.start; i$3 <= paragraph.end; i$3++) {
100013
+ var charType$1 = charTypes[i$3];
100014
+ if (!(charType$1 & BN_LIKE_TYPES)) {
100015
+ var lvl = embedLevels[i$3];
100016
+ var isIsolInit = charType$1 & ISOLATE_INIT_TYPES;
100017
+ var isPDI = charType$1 === TYPE_PDI;
100018
+ if (currentRun && lvl === currentRun._level) {
100019
+ currentRun._end = i$3;
100020
+ currentRun._endsWithIsolInit = isIsolInit;
100021
+ } else {
100022
+ levelRuns.push(currentRun = {
100023
+ _start: i$3,
100024
+ _end: i$3,
100025
+ _level: lvl,
100026
+ _startsWithPDI: isPDI,
100027
+ _endsWithIsolInit: isIsolInit
100028
+ });
100029
+ }
100030
+ }
100031
+ }
100032
+ var isolatingRunSeqs = [];
100033
+ for (var runIdx = 0; runIdx < levelRuns.length; runIdx++) {
100034
+ var run = levelRuns[runIdx];
100035
+ if (!run._startsWithPDI || run._startsWithPDI && !isolationPairs.has(run._start)) {
100036
+ var seqRuns = [currentRun = run];
100037
+ for (var pdiIndex = void 0; currentRun && currentRun._endsWithIsolInit && (pdiIndex = isolationPairs.get(currentRun._end)) != null; ) {
100038
+ for (var i$4 = runIdx + 1; i$4 < levelRuns.length; i$4++) {
100039
+ if (levelRuns[i$4]._start === pdiIndex) {
100040
+ seqRuns.push(currentRun = levelRuns[i$4]);
100041
+ break;
100042
+ }
100043
+ }
100044
+ }
100045
+ var seqIndices = [];
100046
+ for (var i$5 = 0; i$5 < seqRuns.length; i$5++) {
100047
+ var run$1 = seqRuns[i$5];
100048
+ for (var j = run$1._start; j <= run$1._end; j++) {
100049
+ seqIndices.push(j);
100050
+ }
100051
+ }
100052
+ var firstLevel = embedLevels[seqIndices[0]];
100053
+ var prevLevel = paragraph.level;
100054
+ for (var i$6 = seqIndices[0] - 1; i$6 >= 0; i$6--) {
100055
+ if (!(charTypes[i$6] & BN_LIKE_TYPES)) {
100056
+ prevLevel = embedLevels[i$6];
100057
+ break;
100058
+ }
100059
+ }
100060
+ var lastIndex = seqIndices[seqIndices.length - 1];
100061
+ var lastLevel = embedLevels[lastIndex];
100062
+ var nextLevel = paragraph.level;
100063
+ if (!(charTypes[lastIndex] & ISOLATE_INIT_TYPES)) {
100064
+ for (var i$7 = lastIndex + 1; i$7 <= paragraph.end; i$7++) {
100065
+ if (!(charTypes[i$7] & BN_LIKE_TYPES)) {
100066
+ nextLevel = embedLevels[i$7];
100067
+ break;
100068
+ }
100069
+ }
100070
+ }
100071
+ isolatingRunSeqs.push({
100072
+ _seqIndices: seqIndices,
100073
+ _sosType: Math.max(prevLevel, firstLevel) % 2 ? TYPE_R : TYPE_L,
100074
+ _eosType: Math.max(nextLevel, lastLevel) % 2 ? TYPE_R : TYPE_L
100075
+ });
100076
+ }
100077
+ }
100078
+ for (var seqIdx = 0; seqIdx < isolatingRunSeqs.length; seqIdx++) {
100079
+ var ref = isolatingRunSeqs[seqIdx];
100080
+ var seqIndices$1 = ref._seqIndices;
100081
+ var sosType = ref._sosType;
100082
+ var eosType = ref._eosType;
100083
+ var embedDirection = embedLevels[seqIndices$1[0]] & 1 ? TYPE_R : TYPE_L;
100084
+ if (charTypeCounts.get(TYPE_NSM)) {
100085
+ for (var si = 0; si < seqIndices$1.length; si++) {
100086
+ var i$8 = seqIndices$1[si];
100087
+ if (charTypes[i$8] & TYPE_NSM) {
100088
+ var prevType = sosType;
100089
+ for (var sj = si - 1; sj >= 0; sj--) {
100090
+ if (!(charTypes[seqIndices$1[sj]] & BN_LIKE_TYPES)) {
100091
+ prevType = charTypes[seqIndices$1[sj]];
100092
+ break;
100093
+ }
100094
+ }
100095
+ changeCharType(i$8, prevType & (ISOLATE_INIT_TYPES | TYPE_PDI) ? TYPE_ON : prevType);
100096
+ }
100097
+ }
100098
+ }
100099
+ if (charTypeCounts.get(TYPE_EN)) {
100100
+ for (var si$1 = 0; si$1 < seqIndices$1.length; si$1++) {
100101
+ var i$9 = seqIndices$1[si$1];
100102
+ if (charTypes[i$9] & TYPE_EN) {
100103
+ for (var sj$1 = si$1 - 1; sj$1 >= -1; sj$1--) {
100104
+ var prevCharType = sj$1 === -1 ? sosType : charTypes[seqIndices$1[sj$1]];
100105
+ if (prevCharType & STRONG_TYPES) {
100106
+ if (prevCharType === TYPE_AL) {
100107
+ changeCharType(i$9, TYPE_AN);
100108
+ }
100109
+ break;
100110
+ }
100111
+ }
100112
+ }
100113
+ }
100114
+ }
100115
+ if (charTypeCounts.get(TYPE_AL)) {
100116
+ for (var si$2 = 0; si$2 < seqIndices$1.length; si$2++) {
100117
+ var i$10 = seqIndices$1[si$2];
100118
+ if (charTypes[i$10] & TYPE_AL) {
100119
+ changeCharType(i$10, TYPE_R);
100120
+ }
100121
+ }
100122
+ }
100123
+ if (charTypeCounts.get(TYPE_ES) || charTypeCounts.get(TYPE_CS)) {
100124
+ for (var si$3 = 1; si$3 < seqIndices$1.length - 1; si$3++) {
100125
+ var i$11 = seqIndices$1[si$3];
100126
+ if (charTypes[i$11] & (TYPE_ES | TYPE_CS)) {
100127
+ var prevType$1 = 0, nextType = 0;
100128
+ for (var sj$2 = si$3 - 1; sj$2 >= 0; sj$2--) {
100129
+ prevType$1 = charTypes[seqIndices$1[sj$2]];
100130
+ if (!(prevType$1 & BN_LIKE_TYPES)) {
100131
+ break;
100132
+ }
100133
+ }
100134
+ for (var sj$3 = si$3 + 1; sj$3 < seqIndices$1.length; sj$3++) {
100135
+ nextType = charTypes[seqIndices$1[sj$3]];
100136
+ if (!(nextType & BN_LIKE_TYPES)) {
100137
+ break;
100138
+ }
100139
+ }
100140
+ if (prevType$1 === nextType && (charTypes[i$11] === TYPE_ES ? prevType$1 === TYPE_EN : prevType$1 & (TYPE_EN | TYPE_AN))) {
100141
+ changeCharType(i$11, prevType$1);
100142
+ }
100143
+ }
100144
+ }
100145
+ }
100146
+ if (charTypeCounts.get(TYPE_EN)) {
100147
+ for (var si$4 = 0; si$4 < seqIndices$1.length; si$4++) {
100148
+ var i$12 = seqIndices$1[si$4];
100149
+ if (charTypes[i$12] & TYPE_EN) {
100150
+ for (var sj$4 = si$4 - 1; sj$4 >= 0 && charTypes[seqIndices$1[sj$4]] & (TYPE_ET | BN_LIKE_TYPES); sj$4--) {
100151
+ changeCharType(seqIndices$1[sj$4], TYPE_EN);
100152
+ }
100153
+ for (si$4++; si$4 < seqIndices$1.length && charTypes[seqIndices$1[si$4]] & (TYPE_ET | BN_LIKE_TYPES | TYPE_EN); si$4++) {
100154
+ if (charTypes[seqIndices$1[si$4]] !== TYPE_EN) {
100155
+ changeCharType(seqIndices$1[si$4], TYPE_EN);
100156
+ }
100157
+ }
100158
+ }
100159
+ }
100160
+ }
100161
+ if (charTypeCounts.get(TYPE_ET) || charTypeCounts.get(TYPE_ES) || charTypeCounts.get(TYPE_CS)) {
100162
+ for (var si$5 = 0; si$5 < seqIndices$1.length; si$5++) {
100163
+ var i$13 = seqIndices$1[si$5];
100164
+ if (charTypes[i$13] & (TYPE_ET | TYPE_ES | TYPE_CS)) {
100165
+ changeCharType(i$13, TYPE_ON);
100166
+ for (var sj$5 = si$5 - 1; sj$5 >= 0 && charTypes[seqIndices$1[sj$5]] & BN_LIKE_TYPES; sj$5--) {
100167
+ changeCharType(seqIndices$1[sj$5], TYPE_ON);
100168
+ }
100169
+ for (var sj$6 = si$5 + 1; sj$6 < seqIndices$1.length && charTypes[seqIndices$1[sj$6]] & BN_LIKE_TYPES; sj$6++) {
100170
+ changeCharType(seqIndices$1[sj$6], TYPE_ON);
100171
+ }
100172
+ }
100173
+ }
100174
+ }
100175
+ if (charTypeCounts.get(TYPE_EN)) {
100176
+ for (var si$6 = 0, prevStrongType = sosType; si$6 < seqIndices$1.length; si$6++) {
100177
+ var i$14 = seqIndices$1[si$6];
100178
+ var type = charTypes[i$14];
100179
+ if (type & TYPE_EN) {
100180
+ if (prevStrongType === TYPE_L) {
100181
+ changeCharType(i$14, TYPE_L);
100182
+ }
100183
+ } else if (type & STRONG_TYPES) {
100184
+ prevStrongType = type;
100185
+ }
100186
+ }
100187
+ }
100188
+ if (charTypeCounts.get(NEUTRAL_ISOLATE_TYPES)) {
100189
+ var R_TYPES_FOR_N_STEPS = TYPE_R | TYPE_EN | TYPE_AN;
100190
+ var STRONG_TYPES_FOR_N_STEPS = R_TYPES_FOR_N_STEPS | TYPE_L;
100191
+ var bracketPairs = [];
100192
+ {
100193
+ var openerStack = [];
100194
+ for (var si$7 = 0; si$7 < seqIndices$1.length; si$7++) {
100195
+ if (charTypes[seqIndices$1[si$7]] & NEUTRAL_ISOLATE_TYPES) {
100196
+ var char = string4[seqIndices$1[si$7]];
100197
+ var oppositeBracket = void 0;
100198
+ if (openingToClosingBracket(char) !== null) {
100199
+ if (openerStack.length < 63) {
100200
+ openerStack.push({ char, seqIndex: si$7 });
100201
+ } else {
100202
+ break;
100203
+ }
100204
+ } else if ((oppositeBracket = closingToOpeningBracket(char)) !== null) {
100205
+ for (var stackIdx = openerStack.length - 1; stackIdx >= 0; stackIdx--) {
100206
+ var stackChar = openerStack[stackIdx].char;
100207
+ if (stackChar === oppositeBracket || stackChar === closingToOpeningBracket(getCanonicalBracket(char)) || openingToClosingBracket(getCanonicalBracket(stackChar)) === char) {
100208
+ bracketPairs.push([openerStack[stackIdx].seqIndex, si$7]);
100209
+ openerStack.length = stackIdx;
100210
+ break;
100211
+ }
100212
+ }
100213
+ }
100214
+ }
100215
+ }
100216
+ bracketPairs.sort(function(a, b) {
100217
+ return a[0] - b[0];
100218
+ });
100219
+ }
100220
+ for (var pairIdx = 0; pairIdx < bracketPairs.length; pairIdx++) {
100221
+ var ref$1 = bracketPairs[pairIdx];
100222
+ var openSeqIdx = ref$1[0];
100223
+ var closeSeqIdx = ref$1[1];
100224
+ var foundStrongType = false;
100225
+ var useStrongType = 0;
100226
+ for (var si$8 = openSeqIdx + 1; si$8 < closeSeqIdx; si$8++) {
100227
+ var i$15 = seqIndices$1[si$8];
100228
+ if (charTypes[i$15] & STRONG_TYPES_FOR_N_STEPS) {
100229
+ foundStrongType = true;
100230
+ var lr = charTypes[i$15] & R_TYPES_FOR_N_STEPS ? TYPE_R : TYPE_L;
100231
+ if (lr === embedDirection) {
100232
+ useStrongType = lr;
100233
+ break;
100234
+ }
100235
+ }
100236
+ }
100237
+ if (foundStrongType && !useStrongType) {
100238
+ useStrongType = sosType;
100239
+ for (var si$9 = openSeqIdx - 1; si$9 >= 0; si$9--) {
100240
+ var i$16 = seqIndices$1[si$9];
100241
+ if (charTypes[i$16] & STRONG_TYPES_FOR_N_STEPS) {
100242
+ var lr$1 = charTypes[i$16] & R_TYPES_FOR_N_STEPS ? TYPE_R : TYPE_L;
100243
+ if (lr$1 !== embedDirection) {
100244
+ useStrongType = lr$1;
100245
+ } else {
100246
+ useStrongType = embedDirection;
100247
+ }
100248
+ break;
100249
+ }
100250
+ }
100251
+ }
100252
+ if (useStrongType) {
100253
+ charTypes[seqIndices$1[openSeqIdx]] = charTypes[seqIndices$1[closeSeqIdx]] = useStrongType;
100254
+ if (useStrongType !== embedDirection) {
100255
+ for (var si$10 = openSeqIdx + 1; si$10 < seqIndices$1.length; si$10++) {
100256
+ if (!(charTypes[seqIndices$1[si$10]] & BN_LIKE_TYPES)) {
100257
+ if (getBidiCharType(string4[seqIndices$1[si$10]]) & TYPE_NSM) {
100258
+ charTypes[seqIndices$1[si$10]] = useStrongType;
100259
+ }
100260
+ break;
100261
+ }
100262
+ }
100263
+ }
100264
+ if (useStrongType !== embedDirection) {
100265
+ for (var si$11 = closeSeqIdx + 1; si$11 < seqIndices$1.length; si$11++) {
100266
+ if (!(charTypes[seqIndices$1[si$11]] & BN_LIKE_TYPES)) {
100267
+ if (getBidiCharType(string4[seqIndices$1[si$11]]) & TYPE_NSM) {
100268
+ charTypes[seqIndices$1[si$11]] = useStrongType;
100269
+ }
100270
+ break;
100271
+ }
100272
+ }
100273
+ }
100274
+ }
100275
+ }
100276
+ for (var si$12 = 0; si$12 < seqIndices$1.length; si$12++) {
100277
+ if (charTypes[seqIndices$1[si$12]] & NEUTRAL_ISOLATE_TYPES) {
100278
+ var niRunStart = si$12, niRunEnd = si$12;
100279
+ var prevType$2 = sosType;
100280
+ for (var si2 = si$12 - 1; si2 >= 0; si2--) {
100281
+ if (charTypes[seqIndices$1[si2]] & BN_LIKE_TYPES) {
100282
+ niRunStart = si2;
100283
+ } else {
100284
+ prevType$2 = charTypes[seqIndices$1[si2]] & R_TYPES_FOR_N_STEPS ? TYPE_R : TYPE_L;
100285
+ break;
100286
+ }
100287
+ }
100288
+ var nextType$1 = eosType;
100289
+ for (var si2$1 = si$12 + 1; si2$1 < seqIndices$1.length; si2$1++) {
100290
+ if (charTypes[seqIndices$1[si2$1]] & (NEUTRAL_ISOLATE_TYPES | BN_LIKE_TYPES)) {
100291
+ niRunEnd = si2$1;
100292
+ } else {
100293
+ nextType$1 = charTypes[seqIndices$1[si2$1]] & R_TYPES_FOR_N_STEPS ? TYPE_R : TYPE_L;
100294
+ break;
100295
+ }
100296
+ }
100297
+ for (var sj$7 = niRunStart; sj$7 <= niRunEnd; sj$7++) {
100298
+ charTypes[seqIndices$1[sj$7]] = prevType$2 === nextType$1 ? prevType$2 : embedDirection;
100299
+ }
100300
+ si$12 = niRunEnd;
100301
+ }
100302
+ }
100303
+ }
100304
+ }
100305
+ for (var i$17 = paragraph.start; i$17 <= paragraph.end; i$17++) {
100306
+ var level$3 = embedLevels[i$17];
100307
+ var type$1 = charTypes[i$17];
100308
+ if (level$3 & 1) {
100309
+ if (type$1 & (TYPE_L | TYPE_EN | TYPE_AN)) {
100310
+ embedLevels[i$17]++;
100311
+ }
100312
+ } else {
100313
+ if (type$1 & TYPE_R) {
100314
+ embedLevels[i$17]++;
100315
+ } else if (type$1 & (TYPE_AN | TYPE_EN)) {
100316
+ embedLevels[i$17] += 2;
100317
+ }
100318
+ }
100319
+ if (type$1 & BN_LIKE_TYPES) {
100320
+ embedLevels[i$17] = i$17 === 0 ? paragraph.level : embedLevels[i$17 - 1];
100321
+ }
100322
+ if (i$17 === paragraph.end || getBidiCharType(string4[i$17]) & (TYPE_S | TYPE_B)) {
100323
+ for (var j$1 = i$17; j$1 >= 0 && getBidiCharType(string4[j$1]) & TRAILING_TYPES; j$1--) {
100324
+ embedLevels[j$1] = paragraph.level;
100325
+ }
100326
+ }
100327
+ }
100328
+ }
100329
+ return {
100330
+ levels: embedLevels,
100331
+ paragraphs
100332
+ };
100333
+ function determineAutoEmbedLevel(start, isFSI) {
100334
+ for (var i3 = start; i3 < string4.length; i3++) {
100335
+ var charType2 = charTypes[i3];
100336
+ if (charType2 & (TYPE_R | TYPE_AL)) {
100337
+ return 1;
100338
+ }
100339
+ if (charType2 & (TYPE_B | TYPE_L) || isFSI && charType2 === TYPE_PDI) {
100340
+ return 0;
100341
+ }
100342
+ if (charType2 & ISOLATE_INIT_TYPES) {
100343
+ var pdi = indexOfMatchingPDI(i3);
100344
+ i3 = pdi === -1 ? string4.length : pdi;
100345
+ }
100346
+ }
100347
+ return 0;
100348
+ }
100349
+ function indexOfMatchingPDI(isolateStart) {
100350
+ var isolationLevel = 1;
100351
+ for (var i3 = isolateStart + 1; i3 < string4.length; i3++) {
100352
+ var charType2 = charTypes[i3];
100353
+ if (charType2 & TYPE_B) {
100354
+ break;
100355
+ }
100356
+ if (charType2 & TYPE_PDI) {
100357
+ if (--isolationLevel === 0) {
100358
+ return i3;
100359
+ }
100360
+ } else if (charType2 & ISOLATE_INIT_TYPES) {
100361
+ isolationLevel++;
100362
+ }
100363
+ }
100364
+ return -1;
100365
+ }
100366
+ }
100367
+ var data = "14>1,j>2,t>2,u>2,1a>g,2v3>1,1>1,1ge>1,1wd>1,b>1,1j>1,f>1,ai>3,-2>3,+1,8>1k0,-1jq>1y7,-1y6>1hf,-1he>1h6,-1h5>1ha,-1h8>1qi,-1pu>1,6>3u,-3s>7,6>1,1>1,f>1,1>1,+2,3>1,1>1,+13,4>1,1>1,6>1eo,-1ee>1,3>1mg,-1me>1mk,-1mj>1mi,-1mg>1mi,-1md>1,1>1,+2,1>10k,-103>1,1>1,4>1,5>1,1>1,+10,3>1,1>8,-7>8,+1,-6>7,+1,a>1,1>1,u>1,u6>1,1>1,+5,26>1,1>1,2>1,2>2,8>1,7>1,4>1,1>1,+5,b8>1,1>1,+3,1>3,-2>1,2>1,1>1,+2,c>1,3>1,1>1,+2,h>1,3>1,a>1,1>1,2>1,3>1,1>1,d>1,f>1,3>1,1a>1,1>1,6>1,7>1,13>1,k>1,1>1,+19,4>1,1>1,+2,2>1,1>1,+18,m>1,a>1,1>1,lk>1,1>1,4>1,2>1,f>1,3>1,1>1,+3,db>1,1>1,+3,3>1,1>1,+2,14qm>1,1>1,+1,6>1,4j>1,j>2,t>2,u>2,2>1,+1";
100368
+ var mirrorMap;
100369
+ function parse6() {
100370
+ if (!mirrorMap) {
100371
+ var ref = parseCharacterMap(data, true);
100372
+ var map3 = ref.map;
100373
+ var reverseMap = ref.reverseMap;
100374
+ reverseMap.forEach(function(value, key) {
100375
+ map3.set(key, value);
100376
+ });
100377
+ mirrorMap = map3;
100378
+ }
100379
+ }
100380
+ function getMirroredCharacter(char) {
100381
+ parse6();
100382
+ return mirrorMap.get(char) || null;
100383
+ }
100384
+ function getMirroredCharactersMap(string4, embeddingLevels, start, end) {
100385
+ var strLen = string4.length;
100386
+ start = Math.max(0, start == null ? 0 : +start);
100387
+ end = Math.min(strLen - 1, end == null ? strLen - 1 : +end);
100388
+ var map3 = /* @__PURE__ */ new Map();
100389
+ for (var i2 = start; i2 <= end; i2++) {
100390
+ if (embeddingLevels[i2] & 1) {
100391
+ var mirror = getMirroredCharacter(string4[i2]);
100392
+ if (mirror !== null) {
100393
+ map3.set(i2, mirror);
100394
+ }
100395
+ }
100396
+ }
100397
+ return map3;
100398
+ }
100399
+ function getReorderSegments(string4, embeddingLevelsResult, start, end) {
100400
+ var strLen = string4.length;
100401
+ start = Math.max(0, start == null ? 0 : +start);
100402
+ end = Math.min(strLen - 1, end == null ? strLen - 1 : +end);
100403
+ var segments2 = [];
100404
+ embeddingLevelsResult.paragraphs.forEach(function(paragraph) {
100405
+ var lineStart = Math.max(start, paragraph.start);
100406
+ var lineEnd = Math.min(end, paragraph.end);
100407
+ if (lineStart < lineEnd) {
100408
+ var lineLevels = embeddingLevelsResult.levels.slice(lineStart, lineEnd + 1);
100409
+ for (var i2 = lineEnd; i2 >= lineStart && getBidiCharType(string4[i2]) & TRAILING_TYPES; i2--) {
100410
+ lineLevels[i2] = paragraph.level;
100411
+ }
100412
+ var maxLevel = paragraph.level;
100413
+ var minOddLevel = Infinity;
100414
+ for (var i$1 = 0; i$1 < lineLevels.length; i$1++) {
100415
+ var level = lineLevels[i$1];
100416
+ if (level > maxLevel) {
100417
+ maxLevel = level;
100418
+ }
100419
+ if (level < minOddLevel) {
100420
+ minOddLevel = level | 1;
100421
+ }
100422
+ }
100423
+ for (var lvl = maxLevel; lvl >= minOddLevel; lvl--) {
100424
+ for (var i$2 = 0; i$2 < lineLevels.length; i$2++) {
100425
+ if (lineLevels[i$2] >= lvl) {
100426
+ var segStart = i$2;
100427
+ while (i$2 + 1 < lineLevels.length && lineLevels[i$2 + 1] >= lvl) {
100428
+ i$2++;
100429
+ }
100430
+ if (i$2 > segStart) {
100431
+ segments2.push([segStart + lineStart, i$2 + lineStart]);
100432
+ }
100433
+ }
100434
+ }
100435
+ }
100436
+ }
100437
+ });
100438
+ return segments2;
100439
+ }
100440
+ function getReorderedString(string4, embedLevelsResult, start, end) {
100441
+ var indices = getReorderedIndices(string4, embedLevelsResult, start, end);
100442
+ var chars3 = [].concat(string4);
100443
+ indices.forEach(function(charIndex, i2) {
100444
+ chars3[i2] = (embedLevelsResult.levels[charIndex] & 1 ? getMirroredCharacter(string4[charIndex]) : null) || string4[charIndex];
100445
+ });
100446
+ return chars3.join("");
100447
+ }
100448
+ function getReorderedIndices(string4, embedLevelsResult, start, end) {
100449
+ var segments2 = getReorderSegments(string4, embedLevelsResult, start, end);
100450
+ var indices = [];
100451
+ for (var i2 = 0; i2 < string4.length; i2++) {
100452
+ indices[i2] = i2;
100453
+ }
100454
+ segments2.forEach(function(ref) {
100455
+ var start2 = ref[0];
100456
+ var end2 = ref[1];
100457
+ var slice = indices.slice(start2, end2 + 1);
100458
+ for (var i3 = slice.length; i3--; ) {
100459
+ indices[end2 - i3] = slice[i3];
100460
+ }
100461
+ });
100462
+ return indices;
100463
+ }
100464
+ exports2.closingToOpeningBracket = closingToOpeningBracket;
100465
+ exports2.getBidiCharType = getBidiCharType;
100466
+ exports2.getBidiCharTypeName = getBidiCharTypeName;
100467
+ exports2.getCanonicalBracket = getCanonicalBracket;
100468
+ exports2.getEmbeddingLevels = getEmbeddingLevels;
100469
+ exports2.getMirroredCharacter = getMirroredCharacter;
100470
+ exports2.getMirroredCharactersMap = getMirroredCharactersMap;
100471
+ exports2.getReorderSegments = getReorderSegments;
100472
+ exports2.getReorderedIndices = getReorderedIndices;
100473
+ exports2.getReorderedString = getReorderedString;
100474
+ exports2.openingToClosingBracket = openingToClosingBracket;
100475
+ Object.defineProperty(exports2, "__esModule", { value: true });
100476
+ return exports2;
100477
+ })({});
100478
+ return bidi2;
100479
+ }
100480
+ return bidiFactory2;
100481
+ }));
100482
+ }
100483
+ });
100484
+
100485
+ // ../../app/t/[template_id]/arabicShaping.ts
100486
+ function joiningType(cp) {
100487
+ const forms = FORMS.get(cp);
100488
+ if (forms) return forms.length === 4 ? "D" : forms.length === 2 ? "R" : "U";
100489
+ if (cp === 1600 || cp === 8205) return "C";
100490
+ if (cp === 8204) return "U";
100491
+ return TRANSPARENT.test(String.fromCodePoint(cp)) ? "T" : "U";
100492
+ }
100493
+ function shapeArabic(text) {
100494
+ const cps = Array.from(text, (ch) => ch.codePointAt(0) ?? 0);
100495
+ if (!cps.some((cp) => FORMS.has(cp))) return text;
100496
+ const types = cps.map(joiningType);
100497
+ const prevOf = (i2) => {
100498
+ let j = i2 - 1;
100499
+ while (j >= 0 && types[j] === "T") j--;
100500
+ return j;
100501
+ };
100502
+ const nextOf = (i2) => {
100503
+ let j = i2 + 1;
100504
+ while (j < cps.length && types[j] === "T") j++;
100505
+ return j < cps.length ? j : -1;
100506
+ };
100507
+ const out = [];
100508
+ for (let i2 = 0; i2 < cps.length; i2++) {
100509
+ const cp = cps[i2];
100510
+ const forms = FORMS.get(cp);
100511
+ if (!forms) {
100512
+ out.push(cp);
100513
+ continue;
100514
+ }
100515
+ const p4 = prevOf(i2);
100516
+ const n = nextOf(i2);
100517
+ const joinPrev = joinsRight(types[i2]) && p4 >= 0 && joinsLeft(types[p4]);
100518
+ const lig = cp === LAM && n >= 0 ? LAM_ALEF.get(cps[n]) : void 0;
100519
+ if (lig) {
100520
+ out.push(joinPrev ? lig[1] : lig[0]);
100521
+ for (let k4 = i2 + 1; k4 < n; k4++) out.push(cps[k4]);
100522
+ i2 = n;
100523
+ continue;
100524
+ }
100525
+ const joinNext = joinsLeft(types[i2]) && n >= 0 && joinsRight(types[n]);
100526
+ const form = forms.length === 4 ? joinPrev ? joinNext ? 3 : 1 : joinNext ? 2 : 0 : joinPrev && forms.length === 2 ? 1 : 0;
100527
+ out.push(forms[form]);
100528
+ }
100529
+ return out.map((c2) => String.fromCodePoint(c2)).join("");
100530
+ }
100531
+ var FORMS, LAM, LAM_ALEF, TRANSPARENT, joinsLeft, joinsRight;
100532
+ var init_arabicShaping = __esm({
100533
+ "../../app/t/[template_id]/arabicShaping.ts"() {
100534
+ "use strict";
100535
+ FORMS = /* @__PURE__ */ new Map([
100536
+ [1569, [65152]],
100537
+ // hamza (non-joining)
100538
+ [1570, [65153, 65154]],
100539
+ // alef with madda above
100540
+ [1571, [65155, 65156]],
100541
+ // alef with hamza above
100542
+ [1572, [65157, 65158]],
100543
+ // waw with hamza above
100544
+ [1573, [65159, 65160]],
100545
+ // alef with hamza below
100546
+ [1574, [65161, 65162, 65163, 65164]],
100547
+ // yeh with hamza above
100548
+ [1575, [65165, 65166]],
100549
+ // alef
100550
+ [1576, [65167, 65168, 65169, 65170]],
100551
+ // beh
100552
+ [1577, [65171, 65172]],
100553
+ // teh marbuta
100554
+ [1578, [65173, 65174, 65175, 65176]],
100555
+ // teh
100556
+ [1579, [65177, 65178, 65179, 65180]],
100557
+ // theh
100558
+ [1580, [65181, 65182, 65183, 65184]],
100559
+ // jeem
100560
+ [1581, [65185, 65186, 65187, 65188]],
100561
+ // hah
100562
+ [1582, [65189, 65190, 65191, 65192]],
100563
+ // khah
100564
+ [1583, [65193, 65194]],
100565
+ // dal
100566
+ [1584, [65195, 65196]],
100567
+ // thal
100568
+ [1585, [65197, 65198]],
100569
+ // reh
100570
+ [1586, [65199, 65200]],
100571
+ // zain
100572
+ [1587, [65201, 65202, 65203, 65204]],
100573
+ // seen
100574
+ [1588, [65205, 65206, 65207, 65208]],
100575
+ // sheen
100576
+ [1589, [65209, 65210, 65211, 65212]],
100577
+ // sad
100578
+ [1590, [65213, 65214, 65215, 65216]],
100579
+ // dad
100580
+ [1591, [65217, 65218, 65219, 65220]],
100581
+ // tah
100582
+ [1592, [65221, 65222, 65223, 65224]],
100583
+ // zah
100584
+ [1593, [65225, 65226, 65227, 65228]],
100585
+ // ain
100586
+ [1594, [65229, 65230, 65231, 65232]],
100587
+ // ghain
100588
+ [1601, [65233, 65234, 65235, 65236]],
100589
+ // feh
100590
+ [1602, [65237, 65238, 65239, 65240]],
100591
+ // qaf
100592
+ [1603, [65241, 65242, 65243, 65244]],
100593
+ // kaf
100594
+ [1604, [65245, 65246, 65247, 65248]],
100595
+ // lam
100596
+ [1605, [65249, 65250, 65251, 65252]],
100597
+ // meem
100598
+ [1606, [65253, 65254, 65255, 65256]],
100599
+ // noon
100600
+ [1607, [65257, 65258, 65259, 65260]],
100601
+ // heh
100602
+ [1608, [65261, 65262]],
100603
+ // waw
100604
+ [1609, [65263, 65264, 64488, 64489]],
100605
+ // alef maksura (init/medi in Forms-A)
100606
+ [1610, [65265, 65266, 65267, 65268]],
100607
+ // yeh
100608
+ [1662, [64342, 64343, 64344, 64345]],
100609
+ // peh
100610
+ [1670, [64378, 64379, 64380, 64381]],
100611
+ // tcheh
100612
+ [1688, [64394, 64395]],
100613
+ // jeh
100614
+ [1705, [64398, 64399, 64400, 64401]],
100615
+ // keheh
100616
+ [1711, [64402, 64403, 64404, 64405]],
100617
+ // gaf
100618
+ [1740, [64508, 64509, 64510, 64511]]
100619
+ // farsi yeh
100620
+ ]);
100621
+ LAM = 1604;
100622
+ LAM_ALEF = /* @__PURE__ */ new Map([
100623
+ [1570, [65269, 65270]],
100624
+ [1571, [65271, 65272]],
100625
+ [1573, [65273, 65274]],
100626
+ [1575, [65275, 65276]]
100627
+ ]);
100628
+ TRANSPARENT = /[\p{Mn}\p{Me}\p{Cf}]/u;
100629
+ joinsLeft = (j) => j === "D" || j === "C";
100630
+ joinsRight = (j) => j === "D" || j === "R" || j === "C";
100631
+ }
100632
+ });
100633
+
100634
+ // ../../app/t/[template_id]/rtlStamp.ts
100635
+ var rtlStamp_exports = {};
100636
+ __export(rtlStamp_exports, {
100637
+ shapeArabic: () => shapeArabic,
100638
+ visualLine: () => visualLine,
100639
+ visualLines: () => visualLines
100640
+ });
100641
+ function bmpStandIns(b, text) {
100642
+ let out = "";
100643
+ for (const ch of text) {
100644
+ out += ch.length === 1 ? ch : (STAND_IN[b.getBidiCharTypeName(ch)] ?? "a").repeat(2);
100645
+ }
100646
+ return out;
100647
+ }
100648
+ function visualLines(text, lines, rtl) {
100649
+ bidi ??= (0, import_bidi_js.default)();
100650
+ const b = bidi;
100651
+ const base = rtl ? 1 : 0;
100652
+ const standIns = bmpStandIns(b, text);
100653
+ const { levels } = b.getEmbeddingLevels(standIns, rtl ? "rtl" : "ltr");
100654
+ const mirrored = b.getMirroredCharactersMap(standIns, levels);
100655
+ let at = 0;
100656
+ return lines.map((line) => {
100657
+ const cells = [];
100658
+ const from = at;
100659
+ for (const ch of line) {
100660
+ while (at < text.length && !text.startsWith(ch, at) && (text[at] === " " || text[at] === "\n")) {
100661
+ at++;
100662
+ }
100663
+ if (!text.startsWith(ch, at)) {
100664
+ at = from;
100665
+ return visualLine(line, rtl);
100666
+ }
100667
+ cells.push({
100668
+ ch: mirrored.get(at) ?? ch,
100669
+ level: levels[at],
100670
+ type: b.getBidiCharTypeName(standIns[at])
100671
+ });
100672
+ at += ch.length;
100673
+ }
100674
+ for (let k4 = cells.length - 1; k4 >= 0 && TRAILING.has(cells[k4].type); k4--) {
100675
+ cells[k4].level = base;
100676
+ }
100677
+ return stripBidiControls(
100678
+ reorder(cells, base).map((c2) => c2.ch).join("")
100679
+ );
100680
+ });
100681
+ }
100682
+ function visualLine(line, rtl) {
100683
+ return visualLines(line, [line], rtl)[0] ?? "";
100684
+ }
100685
+ function reorder(cells, base) {
100686
+ let max2 = base;
100687
+ let minOdd = Infinity;
100688
+ for (const c2 of cells) {
100689
+ max2 = Math.max(max2, c2.level);
100690
+ minOdd = Math.min(minOdd, c2.level | 1);
100691
+ }
100692
+ const out = cells.slice();
100693
+ for (let lvl = max2; lvl >= minOdd; lvl--) {
100694
+ for (let i2 = 0; i2 < out.length; i2++) {
100695
+ if (out[i2].level < lvl) continue;
100696
+ let j = i2;
100697
+ while (j + 1 < out.length && out[j + 1].level >= lvl) j++;
100698
+ const run = out.slice(i2, j + 1).reverse();
100699
+ out.splice(i2, run.length, ...run);
100700
+ i2 = j;
100701
+ }
100702
+ }
100703
+ return out;
100704
+ }
100705
+ var import_bidi_js, bidi, STAND_IN, TRAILING;
100706
+ var init_rtlStamp = __esm({
100707
+ "../../app/t/[template_id]/rtlStamp.ts"() {
100708
+ "use strict";
100709
+ import_bidi_js = __toESM(require_bidi());
100710
+ init_bidiText();
100711
+ init_arabicShaping();
100712
+ STAND_IN = {
100713
+ L: "a",
100714
+ R: "\u05D0",
100715
+ AL: "\u0627",
100716
+ EN: "0",
100717
+ AN: "\u0660",
100718
+ ES: "+",
100719
+ ET: "#",
100720
+ CS: ",",
100721
+ NSM: "\u0300",
100722
+ BN: "\u200B",
100723
+ WS: " ",
100724
+ S: " ",
100725
+ ON: "!"
100726
+ };
100727
+ TRAILING = /* @__PURE__ */ new Set([
100728
+ "WS",
100729
+ "S",
100730
+ "B",
100731
+ "LRI",
100732
+ "RLI",
100733
+ "FSI",
100734
+ "PDI",
100735
+ "BN",
100736
+ "LRE",
100737
+ "RLE",
100738
+ "LRO",
100739
+ "RLO",
100740
+ "PDF"
100741
+ ]);
100742
+ }
100743
+ });
100744
+
99626
100745
  // node_modules/@embedpdf/pdfium/dist/index.js
99627
100746
  var dist_exports = {};
99628
100747
  __export(dist_exports, {
@@ -99673,11 +100792,11 @@ var init_dist = __esm({
99673
100792
  var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
99674
100793
  if (ENVIRONMENT_IS_NODE) {
99675
100794
  const { createRequire: createRequire3 } = await import("module");
99676
- let dirname5 = import.meta.url;
99677
- if (dirname5.startsWith("data:")) {
99678
- dirname5 = "/";
100795
+ let dirname6 = import.meta.url;
100796
+ if (dirname6.startsWith("data:")) {
100797
+ dirname6 = "/";
99679
100798
  }
99680
- var require3 = createRequire3(dirname5);
100799
+ var require3 = createRequire3(dirname6);
99681
100800
  }
99682
100801
  var moduleOverrides = Object.assign({}, Module);
99683
100802
  var thisProgram = "./this.program";
@@ -108640,8 +109759,8 @@ function handleArrayResult(result, final, index2) {
108640
109759
  }
108641
109760
  var $ZodArray = /* @__PURE__ */ $constructor("$ZodArray", (inst, def) => {
108642
109761
  $ZodType.init(inst, def);
108643
- const memo2 = globalConfig.memoizer;
108644
- memo2?.attach(inst);
109762
+ const memo3 = globalConfig.memoizer;
109763
+ memo3?.attach(inst);
108645
109764
  inst._zod.parse = (payload, ctx) => {
108646
109765
  const input2 = payload.value;
108647
109766
  if (!Array.isArray(input2)) {
@@ -108653,7 +109772,7 @@ var $ZodArray = /* @__PURE__ */ $constructor("$ZodArray", (inst, def) => {
108653
109772
  });
108654
109773
  return payload;
108655
109774
  }
108656
- payload.value = memo2 ? memo2.alloc(inst, payload, Array(input2.length), ctx) : Array(input2.length);
109775
+ payload.value = memo3 ? memo3.alloc(inst, payload, Array(input2.length), ctx) : Array(input2.length);
108657
109776
  const proms = [];
108658
109777
  const abortEarly = ctx?.abortEarly;
108659
109778
  for (let i2 = 0; i2 < input2.length; i2++) {
@@ -108812,8 +109931,8 @@ var $ZodObject = /* @__PURE__ */ $constructor("$ZodObject", (inst, def) => {
108812
109931
  const isObject2 = isObject;
108813
109932
  const catchall = def.catchall;
108814
109933
  let value;
108815
- const memo2 = globalConfig.memoizer;
108816
- memo2?.attach(inst);
109934
+ const memo3 = globalConfig.memoizer;
109935
+ memo3?.attach(inst);
108817
109936
  inst._zod.parse = (payload, ctx) => {
108818
109937
  value ?? (value = _normalized.value);
108819
109938
  const input2 = payload.value;
@@ -108826,7 +109945,7 @@ var $ZodObject = /* @__PURE__ */ $constructor("$ZodObject", (inst, def) => {
108826
109945
  });
108827
109946
  return payload;
108828
109947
  }
108829
- payload.value = memo2 ? memo2.alloc(inst, payload, {}, ctx) : {};
109948
+ payload.value = memo3 ? memo3.alloc(inst, payload, {}, ctx) : {};
108830
109949
  const proms = [];
108831
109950
  const shape = value.shape;
108832
109951
  const abortEarly = ctx?.abortEarly;
@@ -108859,11 +109978,11 @@ var $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) =>
108859
109978
  $ZodObject.init(inst, def);
108860
109979
  const superParse = inst._zod.parse;
108861
109980
  const _normalized = cached(() => normalizeDef(def));
108862
- const memo2 = globalConfig.memoizer;
109981
+ const memo3 = globalConfig.memoizer;
108863
109982
  const generateFastpass = (shape) => {
108864
109983
  const normalized = _normalized.value;
108865
109984
  const syms = normalized.symbolKeys;
108866
- const doc = new Doc(["payload", "ctx"], { shape, inst, memo: memo2, syms });
109985
+ const doc = new Doc(["payload", "ctx"], { shape, inst, memo: memo3, syms });
108867
109986
  const parseStr = (k4) => `shape[${k4}]._zod.run({ value: input[${k4}], issues: [] }, ctx)`;
108868
109987
  const prefixStr = (id, k4) => `
108869
109988
  let ${id}_ab = false;
@@ -108883,7 +110002,7 @@ var $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) =>
108883
110002
  for (const key of normalized.allKeys) {
108884
110003
  ids[key] = `key_${counter++}`;
108885
110004
  }
108886
- doc.write(memo2 ? `const newResult = memo.alloc(inst, payload, {}, ctx);` : `const newResult = {};`);
110005
+ doc.write(memo3 ? `const newResult = memo.alloc(inst, payload, {}, ctx);` : `const newResult = {};`);
108887
110006
  for (const key of normalized.allKeys) {
108888
110007
  if (key === "__proto__")
108889
110008
  continue;
@@ -109317,8 +110436,8 @@ function handleIntersectionResults(result, left, right) {
109317
110436
  var $ZodTuple = /* @__PURE__ */ $constructor("$ZodTuple", (inst, def) => {
109318
110437
  $ZodType.init(inst, def);
109319
110438
  const items2 = def.items;
109320
- const memo2 = globalConfig.memoizer;
109321
- memo2?.attach(inst);
110439
+ const memo3 = globalConfig.memoizer;
110440
+ memo3?.attach(inst);
109322
110441
  inst._zod.parse = (payload, ctx) => {
109323
110442
  const input2 = payload.value;
109324
110443
  if (!Array.isArray(input2)) {
@@ -109330,7 +110449,7 @@ var $ZodTuple = /* @__PURE__ */ $constructor("$ZodTuple", (inst, def) => {
109330
110449
  });
109331
110450
  return payload;
109332
110451
  }
109333
- payload.value = memo2 ? memo2.alloc(inst, payload, [], ctx) : [];
110452
+ payload.value = memo3 ? memo3.alloc(inst, payload, [], ctx) : [];
109334
110453
  const proms = [];
109335
110454
  const optinStart = getTupleOptStart(items2, "optin");
109336
110455
  const optoutStart = getTupleOptStart(items2, "optout");
@@ -109439,8 +110558,8 @@ function handleTupleResults(itemResults, final, items2, input2, optoutStart) {
109439
110558
  }
109440
110559
  var $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
109441
110560
  $ZodType.init(inst, def);
109442
- const memo2 = globalConfig.memoizer;
109443
- memo2?.attach(inst);
110561
+ const memo3 = globalConfig.memoizer;
110562
+ memo3?.attach(inst);
109444
110563
  inst._zod.parse = (payload, ctx) => {
109445
110564
  const input2 = payload.value;
109446
110565
  if (!isPlainObject(input2)) {
@@ -109455,7 +110574,7 @@ var $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
109455
110574
  const proms = [];
109456
110575
  const values2 = def.keyType._zod.values;
109457
110576
  if (values2 && !def.partial) {
109458
- payload.value = memo2 ? memo2.alloc(inst, payload, {}, ctx) : {};
110577
+ payload.value = memo3 ? memo3.alloc(inst, payload, {}, ctx) : {};
109459
110578
  const recordKeys = /* @__PURE__ */ new Set();
109460
110579
  for (const key of values2) {
109461
110580
  if (typeof key === "string" || typeof key === "number" || typeof key === "symbol") {
@@ -109519,7 +110638,7 @@ var $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
109519
110638
  });
109520
110639
  }
109521
110640
  } else {
109522
- payload.value = memo2 ? memo2.alloc(inst, payload, {}, ctx) : {};
110641
+ payload.value = memo3 ? memo3.alloc(inst, payload, {}, ctx) : {};
109523
110642
  let unrecognized;
109524
110643
  for (const key of Reflect.ownKeys(input2)) {
109525
110644
  if (key === "__proto__")
@@ -109594,8 +110713,8 @@ var $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
109594
110713
  });
109595
110714
  var $ZodMap = /* @__PURE__ */ $constructor("$ZodMap", (inst, def) => {
109596
110715
  $ZodType.init(inst, def);
109597
- const memo2 = globalConfig.memoizer;
109598
- memo2?.attach(inst);
110716
+ const memo3 = globalConfig.memoizer;
110717
+ memo3?.attach(inst);
109599
110718
  inst._zod.parse = (payload, ctx) => {
109600
110719
  const input2 = payload.value;
109601
110720
  if (!(input2 instanceof Map)) {
@@ -109608,7 +110727,7 @@ var $ZodMap = /* @__PURE__ */ $constructor("$ZodMap", (inst, def) => {
109608
110727
  return payload;
109609
110728
  }
109610
110729
  const proms = [];
109611
- payload.value = memo2 ? memo2.alloc(inst, payload, /* @__PURE__ */ new Map(), ctx) : /* @__PURE__ */ new Map();
110730
+ payload.value = memo3 ? memo3.alloc(inst, payload, /* @__PURE__ */ new Map(), ctx) : /* @__PURE__ */ new Map();
109612
110731
  const abortEarly = ctx?.abortEarly;
109613
110732
  let seen = payload.issues.length;
109614
110733
  for (const [key, value] of input2) {
@@ -109664,8 +110783,8 @@ function handleMapResult(keyResult, valueResult, final, key, input2, inst, ctx)
109664
110783
  }
109665
110784
  var $ZodSet = /* @__PURE__ */ $constructor("$ZodSet", (inst, def) => {
109666
110785
  $ZodType.init(inst, def);
109667
- const memo2 = globalConfig.memoizer;
109668
- memo2?.attach(inst);
110786
+ const memo3 = globalConfig.memoizer;
110787
+ memo3?.attach(inst);
109669
110788
  inst._zod.parse = (payload, ctx) => {
109670
110789
  const input2 = payload.value;
109671
110790
  if (!(input2 instanceof Set)) {
@@ -109678,7 +110797,7 @@ var $ZodSet = /* @__PURE__ */ $constructor("$ZodSet", (inst, def) => {
109678
110797
  return payload;
109679
110798
  }
109680
110799
  const proms = [];
109681
- payload.value = memo2 ? memo2.alloc(inst, payload, /* @__PURE__ */ new Set(), ctx) : /* @__PURE__ */ new Set();
110800
+ payload.value = memo3 ? memo3.alloc(inst, payload, /* @__PURE__ */ new Set(), ctx) : /* @__PURE__ */ new Set();
109682
110801
  const abortEarly = ctx?.abortEarly;
109683
110802
  let seen = payload.issues.length;
109684
110803
  for (const item of input2) {
@@ -134756,6 +135875,9 @@ function groupFormatOf(group) {
134756
135875
  return void 0;
134757
135876
  }
134758
135877
 
135878
+ // ../../app/t/[template_id]/agentValues.ts
135879
+ init_bidiText();
135880
+
134759
135881
  // ../../app/t/[template_id]/fillKeys.ts
134760
135882
  function buildFieldById(fields) {
134761
135883
  const m = /* @__PURE__ */ new Map();
@@ -135090,6 +136212,163 @@ function buildMarks({
135090
136212
  return out;
135091
136213
  }
135092
136214
 
136215
+ // ../../app/t/[template_id]/fontRuns.ts
136216
+ function splitByCoverage(text, pick2, joinsPrevious) {
136217
+ const runs = [];
136218
+ let current;
136219
+ let prevCp = -1;
136220
+ for (const ch of Array.from(text)) {
136221
+ const cp = ch.codePointAt(0) ?? 0;
136222
+ if (current !== void 0 && joinsPrevious?.(cp, prevCp) === true) {
136223
+ current.text += ch;
136224
+ prevCp = cp;
136225
+ continue;
136226
+ }
136227
+ const key = pick2(cp);
136228
+ prevCp = cp;
136229
+ if (current !== void 0 && current.key === key) {
136230
+ current.text += ch;
136231
+ } else {
136232
+ current = { key, text: ch };
136233
+ runs.push(current);
136234
+ }
136235
+ }
136236
+ return runs;
136237
+ }
136238
+ function splitByDirection(text, dirOf) {
136239
+ const out = [];
136240
+ let cur;
136241
+ for (const ch of Array.from(text)) {
136242
+ const d = dirOf(ch.codePointAt(0) ?? 0);
136243
+ if (cur === void 0 || d === "rtl" && cur.ltr || d === "ltr" && cur.rtl) {
136244
+ cur = { text: "", rtl: false, ltr: false };
136245
+ out.push(cur);
136246
+ }
136247
+ cur.text += ch;
136248
+ if (d === "rtl") cur.rtl = true;
136249
+ if (d === "ltr") cur.ltr = true;
136250
+ }
136251
+ return out.map(({ text: t, rtl }) => ({ text: t, rtl }));
136252
+ }
136253
+ var JP_FACE_SHA256 = "811055f9af5d0955fbf075c391ddfef287720593bbf48ff06d6812a7c2949f41";
136254
+ var JP_FACE_BYTES = 5793848;
136255
+ var JP_SCRIPT_RANGES = [
136256
+ [11904, 12255],
136257
+ // CJK Radicals Supplement + Kangxi Radicals
136258
+ [12288, 12351],
136259
+ // CJK Symbols and Punctuation
136260
+ [12352, 12447],
136261
+ // Hiragana
136262
+ [12448, 12543],
136263
+ // Katakana
136264
+ [12784, 12799],
136265
+ // Katakana Phonetic Extensions
136266
+ [12800, 13055],
136267
+ // Enclosed CJK Letters and Months
136268
+ [13056, 13311],
136269
+ // CJK Compatibility
136270
+ [13312, 19903],
136271
+ // CJK Unified Ideographs Extension A
136272
+ [19968, 40959],
136273
+ // CJK Unified Ideographs
136274
+ [63744, 64255],
136275
+ // CJK Compatibility Ideographs
136276
+ [65072, 65103],
136277
+ // CJK Compatibility Forms
136278
+ [65280, 65519],
136279
+ // Halfwidth and Fullwidth Forms
136280
+ [131072, 173791],
136281
+ // Extension B
136282
+ [173824, 191471],
136283
+ // Extensions C–F
136284
+ [194560, 195103],
136285
+ // CJK Compatibility Ideographs Supplement
136286
+ [196608, 201551]
136287
+ // Extension G
136288
+ ];
136289
+ var JP_SYMBOL_RANGES = [
136290
+ [8413, 8414],
136291
+ // combining enclosing circle / square
136292
+ [8458, 8458],
136293
+ // ℊ script small g
136294
+ [8978, 8978],
136295
+ // ⌒ arc
136296
+ [9001, 9002],
136297
+ // 〈〉 angle brackets (Misc Technical)
136298
+ [9136, 9164],
136299
+ // ⎰⎱ ⎾–⏌ (Misc Technical)
136300
+ [9178, 9179],
136301
+ // ⏚⏛
136302
+ [9322, 9397],
136303
+ // ⑪–⑳ ⑴–⒇ ⒈–⒛ ⒜–⒵
136304
+ [9424, 9449],
136305
+ // ⓐ–ⓩ
136306
+ [9451, 9471],
136307
+ // ⓫–⓴ ⓵–⓾ ⓿
136308
+ [9917, 9918],
136309
+ // ⚽⚾
136310
+ [10548, 10549],
136311
+ // ⤴⤵
136312
+ [10687, 10687],
136313
+ // ⦿
136314
+ [11157, 11157],
136315
+ // ⮕
136316
+ [11834, 11835],
136317
+ // ⸺⸻ two- and three-em dash
136318
+ [12272, 12283],
136319
+ // Ideographic Description Characters
136320
+ [12549, 12771],
136321
+ // Bopomofo, Hangul Compatibility Jamo, Kanbun, CJK Strokes
136322
+ [65040, 65049],
136323
+ // Vertical Forms
136324
+ [65104, 65131],
136325
+ // Small Form Variants
136326
+ [127232, 127404],
136327
+ // Enclosed Alphanumeric Supplement (🄀–🆬)
136328
+ [127488, 127569]
136329
+ // Enclosed Ideographic Supplement (🈀–🉑)
136330
+ ];
136331
+ var JP_FACE_RANGES = [
136332
+ ...JP_SCRIPT_RANGES,
136333
+ ...JP_SYMBOL_RANGES
136334
+ ].sort((a, b) => a[0] - b[0]);
136335
+ function inRanges(ranges, cp) {
136336
+ for (const [a, b] of ranges) {
136337
+ if (cp < a) return false;
136338
+ if (cp <= b) return true;
136339
+ }
136340
+ return false;
136341
+ }
136342
+ function inJpScriptRange(cp) {
136343
+ return inRanges(JP_SCRIPT_RANGES, cp);
136344
+ }
136345
+ function inJpFaceRange(cp) {
136346
+ return inRanges(JP_FACE_RANGES, cp);
136347
+ }
136348
+ function needsJpFace(text) {
136349
+ for (const ch of text) {
136350
+ if (inJpFaceRange(ch.codePointAt(0) ?? 0)) return true;
136351
+ }
136352
+ return false;
136353
+ }
136354
+ var JP_FACE_UNICODE_RANGE = JP_FACE_RANGES.map(
136355
+ ([a, b]) => `U+${a.toString(16).toUpperCase()}-${b.toString(16).toUpperCase()}`
136356
+ ).join(", ");
136357
+ function isJpJoiner(cp) {
136358
+ return cp >= 65024 && cp <= 65039 || cp >= 917760 && cp <= 917999 || cp === 12441 || cp === 12442;
136359
+ }
136360
+ function joinsJpRun(cp, prevCp) {
136361
+ return isJpJoiner(cp) && inJpFaceRange(prevCp);
136362
+ }
136363
+ function marksNeedJpFace(marksByPage) {
136364
+ for (const marks of marksByPage.values()) {
136365
+ for (const m of marks) {
136366
+ if (m.text && needsJpFace(m.text)) return true;
136367
+ }
136368
+ }
136369
+ return false;
136370
+ }
136371
+
135093
136372
  // ../../app/t/[template_id]/normalizeSchema.ts
135094
136373
  function normalizeSigningRequirement(req) {
135095
136374
  if (req === "wet" || req === "certified" || req === "external") return "external";
@@ -135223,6 +136502,9 @@ function dataUrlToBytes(dataUrl) {
135223
136502
  return bytes;
135224
136503
  }
135225
136504
 
136505
+ // ../../app/t/[template_id]/stampPdf.ts
136506
+ init_bidiText();
136507
+
135226
136508
  // ../../app/t/[template_id]/flattenForm.ts
135227
136509
  var ANNOT_FLAG_HIDDEN = 1 << 1;
135228
136510
  var ANNOT_FLAG_NOVIEW = 1 << 5;
@@ -135408,22 +136690,6 @@ function pruneStructTree(pdfDoc, pdfLib, removedRefs, removedStructParents) {
135408
136690
  pruneNumberTree(root.lookup(PDFName2.of("ParentTree")), 0);
135409
136691
  }
135410
136692
 
135411
- // ../../app/t/[template_id]/fontRuns.ts
135412
- function splitByCoverage(text, pick2) {
135413
- const runs = [];
135414
- let current;
135415
- for (const ch of Array.from(text)) {
135416
- const key = pick2(ch.codePointAt(0) ?? 0);
135417
- if (current !== void 0 && current.key === key) {
135418
- current.text += ch;
135419
- } else {
135420
- current = { key, text: ch };
135421
- runs.push(current);
135422
- }
135423
- }
135424
- return runs;
135425
- }
135426
-
135427
136693
  // ../../app/t/[template_id]/markGeometry.ts
135428
136694
  var MARK_STROKE = 0.16;
135429
136695
  var MARK_LINES = {
@@ -135462,6 +136728,7 @@ function classifyMark(symbol2) {
135462
136728
  }
135463
136729
 
135464
136730
  // ../../app/t/[template_id]/textFit.ts
136731
+ init_bidiText();
135465
136732
  var TEXT_PAD_PT = 4;
135466
136733
  var PAD_MAX_FRACTION = 0.18;
135467
136734
  function multilinePadPt(boxDimPt) {
@@ -135482,6 +136749,41 @@ function autoTextStartPt(boxHeightPt) {
135482
136749
  }
135483
136750
  var LINE_HEIGHT_FACTOR = 1.2;
135484
136751
  var MULTILINE_MIN_FONT_SIZE = 5;
136752
+ var NO_LINE_START = new Set(
136753
+ Array.from(
136754
+ "\uFF09\u300D\u300F\u3011\u3015\u3009\u300B\uFF5D\uFF3D\u3019\u3017\u301F\u2019\u201D\u301E\uFF63\uFF64\uFF61\uFF65\uFF70\uFF9E\uFF9F\uFF67\uFF68\uFF69\uFF6A\uFF6B\uFF6C\uFF6D\uFF6E\uFF6F\u3001\u3002\uFF0C\uFF0E\u30FB\uFF1A\uFF1B\uFF1F\uFF01\u30FC\u3005\u303B\u309D\u309E\u30FD\u30FE\u3041\u3043\u3045\u3047\u3049\u3063\u3083\u3085\u3087\u308E\u3095\u3096\u30A1\u30A3\u30A5\u30A7\u30A9\u30C3\u30E3\u30E5\u30E7\u30EE\u30F5\u30F6\u309B\u309C\u2025\u2026\u301C\uFF5E\u30A0\u3000\uFF05\u2030\xB0\u2032\u2033\u2103\u2109\uFFE0\xA2)]},.:;!?/-%"
136755
+ ).map((ch) => ch.codePointAt(0) ?? 0)
136756
+ );
136757
+ var NO_LINE_END = new Set(
136758
+ Array.from("\uFF08\u300C\u300E\u3010\u3014\u3008\u300A\uFF5B\uFF3B\u3018\u3016\u301D\u2018\u201C\uFF62([{\uFFE5\uFF04\uFFE1\uFFE6\xA5$\xA3\u20AC").map((ch) => ch.codePointAt(0) ?? 0)
136759
+ );
136760
+ function cannotStartLine(cp) {
136761
+ return NO_LINE_START.has(cp) || cp >= 12784 && cp <= 12799 || // small katakana ㇰ-ㇿ
136762
+ cp === 12441 || // combining voicing marks
136763
+ cp === 12442 || cp >= 65024 && cp <= 65039 || // variation selectors
136764
+ cp >= 917760 && cp <= 917999;
136765
+ }
136766
+ function cjkPieces(word) {
136767
+ const chars3 = Array.from(word);
136768
+ if (chars3.length < 2) return [word];
136769
+ const pieces = [];
136770
+ let piece = chars3[0];
136771
+ let prev = chars3[0].codePointAt(0) ?? 0;
136772
+ for (let i2 = 1; i2 < chars3.length; i2++) {
136773
+ const cp = chars3[i2].codePointAt(0) ?? 0;
136774
+ const breakable = (inJpScriptRange(prev) || inJpScriptRange(cp)) && !cannotStartLine(cp) && !NO_LINE_END.has(prev);
136775
+ if (breakable) {
136776
+ pieces.push(piece);
136777
+ piece = chars3[i2];
136778
+ } else {
136779
+ piece += chars3[i2];
136780
+ }
136781
+ prev = cp;
136782
+ }
136783
+ pieces.push(piece);
136784
+ return pieces;
136785
+ }
136786
+ var hangIdeoSpaces = (line) => line.replace(/\u3000+$/, "");
135485
136787
  function wrapLines(text, availWidth, size, measure) {
135486
136788
  const out = [];
135487
136789
  for (const para of text.split("\n")) {
@@ -135490,15 +136792,21 @@ function wrapLines(text, availWidth, size, measure) {
135490
136792
  continue;
135491
136793
  }
135492
136794
  let line = "";
135493
- for (const word of para.split(" ")) {
135494
- const trial = line === "" ? word : `${line} ${word}`;
135495
- if (line !== "" && measure(trial, size) > availWidth) {
135496
- out.push(line);
135497
- line = word;
135498
- } else {
135499
- line = trial;
135500
- }
135501
- }
136795
+ const words = para.split(" ");
136796
+ words.forEach((word, wi) => {
136797
+ const pieces = cjkPieces(word);
136798
+ pieces.forEach((piece, i2) => {
136799
+ const sep = i2 === 0 ? " " : "";
136800
+ const trial = line === "" ? piece : `${line}${sep}${piece}`;
136801
+ const last2 = wi === words.length - 1 && i2 === pieces.length - 1;
136802
+ if (line !== "" && measure(last2 ? trial : hangIdeoSpaces(trial), size) > availWidth) {
136803
+ out.push(hangIdeoSpaces(line));
136804
+ line = piece;
136805
+ } else {
136806
+ line = trial;
136807
+ }
136808
+ });
136809
+ });
135502
136810
  out.push(line);
135503
136811
  }
135504
136812
  return out;
@@ -135575,6 +136883,7 @@ function layoutMultiline({
135575
136883
  async function embedStampFaces(pdfDoc, fontkit, fonts) {
135576
136884
  const interFont = await pdfDoc.embedFont(fonts.inter, { subset: true });
135577
136885
  const dejaFont = await pdfDoc.embedFont(fonts.deja, { subset: true });
136886
+ const jpFont = fonts.jp ? await pdfDoc.embedFont(fonts.jp, { subset: true }) : void 0;
135578
136887
  const interKit = fontkit.create(new Uint8Array(fonts.inter));
135579
136888
  const covers = (cp) => {
135580
136889
  try {
@@ -135583,7 +136892,8 @@ async function embedStampFaces(pdfDoc, fontkit, fonts) {
135583
136892
  return false;
135584
136893
  }
135585
136894
  };
135586
- const splitRuns = (t) => splitByCoverage(t, (cp) => covers(cp) ? interFont : dejaFont).map((r) => ({
136895
+ const pick2 = jpFont ? (cp) => inJpFaceRange(cp) ? jpFont : covers(cp) ? interFont : dejaFont : (cp) => covers(cp) ? interFont : dejaFont;
136896
+ const splitRuns = (t) => (jpFont ? splitByCoverage(t, pick2, joinsJpRun) : splitByCoverage(t, pick2)).map((r) => ({
135587
136897
  font: r.key,
135588
136898
  text: r.text
135589
136899
  }));
@@ -135595,13 +136905,48 @@ async function embedStampFaces(pdfDoc, fontkit, fonts) {
135595
136905
  cx2 += r.font.widthOfTextAtSize(r.text, s);
135596
136906
  }
135597
136907
  };
136908
+ const drawVisual = (page, t, x2, y, s, color) => {
136909
+ let cx2 = x2;
136910
+ for (const r of splitRuns(t)) {
136911
+ for (const piece of splitByDirection(r.text, (cp) => fontkitDirection(interKit, cp))) {
136912
+ const text = piece.rtl ? Array.from(piece.text).reverse().join("") : piece.text;
136913
+ page.drawText(text, { x: cx2, y, size: s, font: r.font, color });
136914
+ cx2 += r.font.widthOfTextAtSize(text, s);
136915
+ }
136916
+ }
136917
+ };
135598
136918
  let dejaSet;
136919
+ let jpSet;
135599
136920
  const hasGlyph = (cp) => {
135600
136921
  if (covers(cp)) return true;
135601
136922
  dejaSet ??= new Set(dejaFont.getCharacterSet());
135602
- return dejaSet.has(cp);
135603
- };
135604
- return { measure, draw, hasGlyph };
136923
+ if (dejaSet.has(cp)) return true;
136924
+ if (!jpFont) return false;
136925
+ jpSet ??= new Set(jpFont.getCharacterSet());
136926
+ return jpSet.has(cp);
136927
+ };
136928
+ return { measure, draw, drawVisual, hasGlyph };
136929
+ }
136930
+ var directionMemo = /* @__PURE__ */ new Map();
136931
+ function fontkitDirection(kit, cp) {
136932
+ let d = directionMemo.get(cp);
136933
+ if (d === void 0) {
136934
+ const ch = String.fromCodePoint(cp);
136935
+ d = kit.layout(`${ch}a`).direction === "rtl" ? "rtl" : kit.layout(`${ch}\u05D0`).direction === "rtl" ? "neutral" : "ltr";
136936
+ directionMemo.set(cp, d);
136937
+ }
136938
+ return d;
136939
+ }
136940
+ var jpFacePromise;
136941
+ function loadJpStampFace() {
136942
+ jpFacePromise ??= fetch("/fonts/NotoSansJP-Regular.ttf").then((r) => {
136943
+ if (!r.ok) throw new Error("HTTP " + String(r.status));
136944
+ return r.arrayBuffer();
136945
+ }).catch(() => {
136946
+ jpFacePromise = void 0;
136947
+ throw new Error("Could not load the Japanese font.");
136948
+ });
136949
+ return jpFacePromise;
135605
136950
  }
135606
136951
  async function stampPdf({
135607
136952
  pdfBytes,
@@ -135636,7 +136981,13 @@ async function stampPdf({
135636
136981
  return r.arrayBuffer();
135637
136982
  })
135638
136983
  ]);
135639
- const faces = await embedStampFaces(pdfDoc, fontkit, { inter: interBytes, deja: dejaBytes });
136984
+ const jp = marksNeedJpFace(marksByPage) ? fonts?.jp ?? await loadJpStampFace() : void 0;
136985
+ const faces = await embedStampFaces(pdfDoc, fontkit, {
136986
+ inter: interBytes,
136987
+ deja: dejaBytes,
136988
+ jp
136989
+ });
136990
+ const rtlLayer = marksNeedBidi(marksByPage) ? await Promise.resolve().then(() => (init_rtlStamp(), rtlStamp_exports)) : void 0;
135640
136991
  const pdfPages = pdfDoc.getPages();
135641
136992
  const INK = rgb3(0.1, 0.1, 0.1);
135642
136993
  const { measure } = faces;
@@ -135711,6 +137062,17 @@ async function stampPdf({
135711
137062
  return;
135712
137063
  }
135713
137064
  if (text === "") return;
137065
+ const bidi2 = rtlLayer && needsBidi(text) ? rtlLayer : void 0;
137066
+ const rtl = bidi2 !== void 0 && isRtlDominant(text);
137067
+ const body = bidi2 ? bidi2.shapeArabic(text) : text;
137068
+ const measureText = bidi2 ? (t, s) => measure(stripBidiControls(t), s) : measure;
137069
+ const toDraw = (lines) => bidi2 ? bidi2.visualLines(body, lines, rtl) : lines;
137070
+ const drawLine2 = bidi2 ? (t, x3, y2, s) => {
137071
+ faces.drawVisual(page, t, x3, y2, s, INK);
137072
+ } : (t, x3, y2, s) => {
137073
+ drawMixed(page, t, x3, y2, s);
137074
+ };
137075
+ const anchorOf = (a) => bidiAnchor(a ?? DEFAULT_TEXT_ANCHOR, rtl);
135714
137076
  if (center) {
135715
137077
  const shape = classifyMark(text);
135716
137078
  if (shape) {
@@ -135719,15 +137081,22 @@ async function stampPdf({
135719
137081
  }
135720
137082
  let size2 = m.markFontSize != null ? m.checkbox ? m.markFontSize : Math.min(m.markFontSize, Math.min(h, w)) : m.checkbox ? Math.min(h, w) * CHECKBOX_AUTO_FILL : Math.min(Math.min(h, w) * 0.8, 16);
135721
137083
  size2 = Math.max(6, size2);
135722
- const tw2 = measure(text, size2);
135723
- drawMixed(page, text, x0 + (w - tw2) / 2, y0 + (h - size2 * 0.7) / 2, size2);
137084
+ const tw2 = measureText(body, size2);
137085
+ drawLine2(toDraw([body])[0], x0 + (w - tw2) / 2, y0 + (h - size2 * 0.7) / 2, size2);
135724
137086
  return;
135725
137087
  }
135726
137088
  if (m.multiline) {
135727
137089
  const start = m.fontSize ?? MULTILINE_DEFAULT_FONT_SIZE;
135728
137090
  const padX = multilinePadPt(w);
135729
137091
  const padY = multilinePadPt(h);
135730
- const { size: size2, lines } = m.autoFit === false ? { size: start, lines: wrapLines(text, w - 2 * padX, start, measure) } : fitWrapped(text, w - 2 * padX, h - 2 * padY, start, measure, MULTILINE_MIN_FONT_SIZE);
137092
+ const { size: size2, lines } = m.autoFit === false ? { size: start, lines: wrapLines(body, w - 2 * padX, start, measureText) } : fitWrapped(
137093
+ body,
137094
+ w - 2 * padX,
137095
+ h - 2 * padY,
137096
+ start,
137097
+ measureText,
137098
+ MULTILINE_MIN_FONT_SIZE
137099
+ );
135731
137100
  const placed = layoutMultiline({
135732
137101
  x0,
135733
137102
  y0,
@@ -135735,28 +137104,28 @@ async function stampPdf({
135735
137104
  h,
135736
137105
  size: size2,
135737
137106
  lines,
135738
- anchor: m.anchor ?? DEFAULT_TEXT_ANCHOR,
137107
+ anchor: anchorOf(m.anchor),
135739
137108
  padX,
135740
137109
  padY,
135741
- measure
137110
+ measure: measureText
137111
+ });
137112
+ const drawn = toDraw(lines);
137113
+ placed.forEach((p4, i2) => {
137114
+ if (p4.text !== "") drawLine2(drawn[i2], p4.x, p4.y, size2);
135742
137115
  });
135743
- for (const p4 of placed) {
135744
- if (p4.text === "") continue;
135745
- drawMixed(page, p4.text, p4.x, p4.y, size2);
135746
- }
135747
137116
  onPlacement?.({
135748
137117
  key: m.key,
135749
137118
  page: pageNum,
135750
137119
  multiline: true,
135751
137120
  size: size2,
135752
137121
  startSize: start,
135753
- fits: lines.length * size2 * LINE_HEIGHT_FACTOR <= h - 2 * padY + 0.01 && lines.every((l) => measure(l, size2) <= w - 2 * padX + 0.01)
137122
+ fits: lines.length * size2 * LINE_HEIGHT_FACTOR <= h - 2 * padY + 0.01 && lines.every((l) => measureText(l, size2) <= w - 2 * padX + 0.01)
135754
137123
  });
135755
137124
  return;
135756
137125
  }
135757
137126
  const startPt = m.autoFit ? autoTextStartPt(h) : m.fontSize ?? DEFAULT_FONT_SIZE;
135758
- const size = fitFontSize(text, w - 2 * pad, startPt, measure);
135759
- const tw = measure(text, size);
137127
+ const size = fitFontSize(body, w - 2 * pad, startPt, measureText);
137128
+ const tw = measureText(body, size);
135760
137129
  const { x: x2, y } = anchorPdfXY({
135761
137130
  x0,
135762
137131
  y0,
@@ -135764,10 +137133,10 @@ async function stampPdf({
135764
137133
  h,
135765
137134
  tw,
135766
137135
  size,
135767
- anchor: m.anchor ?? DEFAULT_TEXT_ANCHOR,
137136
+ anchor: anchorOf(m.anchor),
135768
137137
  pad
135769
137138
  });
135770
- drawMixed(page, text, x2, y, size);
137139
+ drawLine2(toDraw([body])[0], x2, y, size);
135771
137140
  onPlacement?.({
135772
137141
  key: m.key,
135773
137142
  page: pageNum,
@@ -136834,6 +138203,7 @@ async function drawCheckPdf(stamped, entries, status, fonts, banner, tags, avoid
136834
138203
  const { default: fontkit } = await Promise.resolve().then(() => __toESM(require_fontkit_umd()));
136835
138204
  doc.registerFontkit(fontkit);
136836
138205
  const faces = await embedStampFaces(doc, fontkit, fonts);
138206
+ const rtlLayer = wanted.some((h) => needsBidi(h.text)) ? await Promise.resolve().then(() => (init_rtlStamp(), rtlStamp_exports)) : void 0;
136837
138207
  const unreadable = /* @__PURE__ */ new Set();
136838
138208
  for (const h of wanted) {
136839
138209
  step("table headers", h.gid);
@@ -136848,34 +138218,44 @@ async function drawCheckPdf(stamped, entries, status, fonts, banner, tags, avoid
136848
138218
  const inside = w >= 40 && ht >= HEAD + 1;
136849
138219
  const room = inside ? w - 1 : prefix === "R" ? Math.min(120, cx2 - 1) : Math.max(2 * w, 30);
136850
138220
  const chars3 = Array.from(
136851
- `${prefix}: ${h.text}`,
138221
+ h.text,
136852
138222
  (ch) => faces.hasGlyph(ch.codePointAt(0) ?? 0) ? ch : "?"
136853
138223
  );
136854
- if (chars3.join("") !== `${prefix}: ${h.text}` && !unreadable.has(h.gid)) {
138224
+ if (chars3.join("") !== h.text && !unreadable.has(h.gid)) {
136855
138225
  unreadable.add(h.gid);
136856
138226
  notes.push(
136857
138227
  `${h.gid}: the check copy cannot draw some header characters (shown as "?"); the legend's header_rows / header_cols hold the full text`
136858
138228
  );
136859
138229
  }
136860
- const cut = (n) => `${chars3.slice(0, n).join("")}\u2026`;
136861
- let text = chars3.join("");
136862
- if (chars3.length > 4 && faces.measure(text, HEAD) > room) {
136863
- let lo = 3;
138230
+ const bidi2 = rtlLayer && needsBidi(h.text) ? rtlLayer : void 0;
138231
+ const rtl = stampsRtl(h.text);
138232
+ const lead = rtl ? `\u2066${prefix}:\u2069 ` : `${prefix}: `;
138233
+ const shaped = (t) => bidi2 ? bidi2.shapeArabic(t) : t;
138234
+ const width = (t) => faces.measure(bidi2 ? stripBidiControls(bidi2.shapeArabic(t)) : t, HEAD);
138235
+ const cut = (n) => `${lead}${chars3.slice(0, n).join("")}\u2026`;
138236
+ let text = `${lead}${chars3.join("")}`;
138237
+ if (chars3.length > 1 && width(text) > room) {
138238
+ let lo = 0;
136864
138239
  let hi = chars3.length - 2;
136865
138240
  while (lo < hi) {
136866
138241
  const mid = Math.ceil((lo + hi) / 2);
136867
- if (faces.measure(cut(mid), HEAD) <= room) lo = mid;
138242
+ if (width(cut(mid)) <= room) lo = mid;
136868
138243
  else hi = mid - 1;
136869
138244
  }
136870
138245
  text = cut(lo);
136871
138246
  }
136872
- const tw = faces.measure(text, HEAD);
136873
- const x2 = inside ? cx2 + 0.6 : prefix === "R" ? cx2 - tw - 0.8 : cx2;
138247
+ const body = shaped(text);
138248
+ const tw = width(text);
138249
+ const x2 = inside ? rtl ? cx2 + w - 0.6 - tw : cx2 + 0.6 : prefix === "R" ? cx2 - tw - 0.8 : cx2;
136874
138250
  const y = inside ? top - HEAD - 0.4 - h.below : prefix === "R" ? top - ht / 2 - HEAD / 2 : top + 0.6;
136875
138251
  heads.push({
136876
138252
  head: h,
136877
138253
  draw: () => {
136878
- faces.draw(page, text, x2, y, HEAD, headColor);
138254
+ if (bidi2) {
138255
+ faces.drawVisual(page, bidi2.visualLine(body, rtl), x2, y, HEAD, headColor);
138256
+ } else {
138257
+ faces.draw(page, text, x2, y, HEAD, headColor);
138258
+ }
136879
138259
  }
136880
138260
  });
136881
138261
  const taken = placedTags.get(cell.field.page) ?? [];
@@ -137024,6 +138404,14 @@ async function drawCheckPdf(stamped, entries, status, fonts, banner, tags, avoid
137024
138404
  step("save");
137025
138405
  return { pdf: await doc.save(), notes };
137026
138406
  }
138407
+ var UnsupportedScriptError = class extends Error {
138408
+ ids;
138409
+ constructor(ids) {
138410
+ super(`These values need a Japanese font that wasn't provided: ${ids.join(", ")}`);
138411
+ this.name = "UnsupportedScriptError";
138412
+ this.ids = ids;
138413
+ }
138414
+ };
137027
138415
  async function fillAgentPdf(a) {
137028
138416
  if (!isRecord(a.render)) throw new TypeError("render must be the template's schema object");
137029
138417
  const schema = normalizeSchema(a.render);
@@ -137035,6 +138423,13 @@ async function fillAgentPdf(a) {
137035
138423
  values: m.values,
137036
138424
  rowCounts: m.rowCounts
137037
138425
  });
138426
+ if (!a.fonts.jp && marksNeedJpFace(marksByPage)) {
138427
+ const ids = /* @__PURE__ */ new Set();
138428
+ for (const marks of marksByPage.values()) {
138429
+ for (const mk of marks) if (needsJpFace(mk.text)) ids.add(ownerOf(mk.key, m.keyIds));
138430
+ }
138431
+ throw new UnsupportedScriptError([...ids]);
138432
+ }
137038
138433
  const placements = [];
137039
138434
  const pdf = await stampPdf({
137040
138435
  pdfBytes: a.pdfBytes,
@@ -137860,8 +139255,8 @@ async function estimateAnalyze(e4) {
137860
139255
 
137861
139256
  // src/fill.ts
137862
139257
  import { randomBytes as randomBytes2 } from "node:crypto";
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";
139258
+ import { promises as fsp3, readFileSync as readFileSync3, statSync } from "node:fs";
139259
+ import { basename, dirname as dirname5, isAbsolute as isAbsolute2, join as join6, relative, resolve as resolve2 } from "node:path";
137865
139260
 
137866
139261
  // src/config.ts
137867
139262
  import { homedir } from "node:os";
@@ -137979,10 +139374,193 @@ function loadFonts(dir = defaultFontsDir()) {
137979
139374
  }
137980
139375
  }
137981
139376
 
139377
+ // src/jpFont.ts
139378
+ import { createHash as createHash2 } from "node:crypto";
139379
+ import { promises as fsp2 } from "node:fs";
139380
+ import { dirname as dirname3, join as join4 } from "node:path";
139381
+
139382
+ // src/version.ts
139383
+ var VERSION = true ? "0.2.4" : "0.0.0-dev";
139384
+ var USER_AGENT = `fenfill-mcp/${VERSION}`;
139385
+
139386
+ // src/jpFont.ts
139387
+ var DEFAULT_JP_FONT_URL = "https://fenfill.com/fonts/NotoSansJP-Regular.ttf";
139388
+ var JP_FONT_FILE = "NotoSansJP-Regular.ttf";
139389
+ var JP_FONT_TIMEOUT_MS = 3e4;
139390
+ var IS_WIN2 = process.platform === "win32";
139391
+ var JpFontError = class extends Error {
139392
+ reason;
139393
+ status;
139394
+ constructor(reason, message, status) {
139395
+ super(message);
139396
+ this.name = "JpFontError";
139397
+ this.reason = reason;
139398
+ this.status = status;
139399
+ }
139400
+ };
139401
+ function jpFontPath(cacheDir) {
139402
+ return join4(cacheDir, "fonts", JP_FONT_FILE);
139403
+ }
139404
+ var sha256 = (b) => createHash2("sha256").update(b).digest("hex");
139405
+ var memo2 = /* @__PURE__ */ new Map();
139406
+ function ensureJpFace(o) {
139407
+ const url2 = o.url ?? DEFAULT_JP_FONT_URL;
139408
+ const key = `${o.cacheDir}\0${url2}`;
139409
+ const hit = memo2.get(key);
139410
+ if (hit) return hit;
139411
+ const p4 = load({ ...o, url: url2 }).catch((e4) => {
139412
+ memo2.delete(key);
139413
+ throw e4;
139414
+ });
139415
+ memo2.set(key, p4);
139416
+ return p4;
139417
+ }
139418
+ async function load(o) {
139419
+ const path = jpFontPath(o.cacheDir);
139420
+ try {
139421
+ const buf = await fsp2.readFile(path);
139422
+ if (sha256(buf) === JP_FACE_SHA256) return toArrayBuffer(buf);
139423
+ await fsp2.rm(path, { force: true });
139424
+ } catch {
139425
+ }
139426
+ const bytes = await download(o);
139427
+ if (bytes.byteLength !== JP_FACE_BYTES || sha256(bytes) !== JP_FACE_SHA256) {
139428
+ throw new JpFontError("hash_mismatch", "The downloaded font doesn't match its pinned sha256.");
139429
+ }
139430
+ try {
139431
+ await writeFont(path, bytes);
139432
+ } catch (e4) {
139433
+ log("warn", "could not cache the Japanese font; using it for this session only", {
139434
+ error: errText(e4)
139435
+ });
139436
+ }
139437
+ return toArrayBuffer(bytes);
139438
+ }
139439
+ async function download(o) {
139440
+ const fetchImpl = o.fetchImpl ?? fetch;
139441
+ const ctl = new AbortController();
139442
+ let timedOut = false;
139443
+ const timer = setTimeout(() => {
139444
+ timedOut = true;
139445
+ ctl.abort();
139446
+ }, o.timeoutMs ?? JP_FONT_TIMEOUT_MS);
139447
+ try {
139448
+ let res;
139449
+ try {
139450
+ res = await fetchImpl(o.url, {
139451
+ method: "GET",
139452
+ headers: { "User-Agent": USER_AGENT },
139453
+ redirect: "follow",
139454
+ signal: ctl.signal
139455
+ });
139456
+ } catch (e4) {
139457
+ if (timedOut) throw new JpFontError("timeout", "The font download timed out.");
139458
+ throw new JpFontError("network", `The font download failed: ${errText(e4)}`);
139459
+ }
139460
+ if (!res.ok) {
139461
+ throw new JpFontError(
139462
+ "http_status",
139463
+ `The font download returned HTTP ${res.status}.`,
139464
+ res.status
139465
+ );
139466
+ }
139467
+ if (!sameHttpsHost(o.url, res)) {
139468
+ await res.body?.cancel().catch(() => void 0);
139469
+ throw new JpFontError("http_status", "The font download was redirected to another host.");
139470
+ }
139471
+ const declared = Number(res.headers.get("content-length") ?? NaN);
139472
+ if (Number.isFinite(declared) && declared !== JP_FACE_BYTES) {
139473
+ ctl.abort();
139474
+ if (declared > JP_FACE_BYTES) {
139475
+ throw new JpFontError("too_large", "The font download is larger than expected.");
139476
+ }
139477
+ throw new JpFontError(
139478
+ "hash_mismatch",
139479
+ "The downloaded font doesn't match its pinned sha256."
139480
+ );
139481
+ }
139482
+ try {
139483
+ return await readCapped(res, ctl);
139484
+ } catch (e4) {
139485
+ if (e4 instanceof JpFontError) throw e4;
139486
+ if (timedOut) throw new JpFontError("timeout", "The font download timed out.");
139487
+ throw new JpFontError("network", `The font download failed: ${errText(e4)}`);
139488
+ }
139489
+ } finally {
139490
+ clearTimeout(timer);
139491
+ }
139492
+ }
139493
+ function sameHttpsHost(requested, res) {
139494
+ if (!res.url) return !res.redirected;
139495
+ try {
139496
+ const a = new URL(requested);
139497
+ const b = new URL(res.url);
139498
+ return b.protocol === "https:" && b.host === a.host;
139499
+ } catch {
139500
+ return false;
139501
+ }
139502
+ }
139503
+ async function readCapped(res, ctl) {
139504
+ const tooLarge = () => {
139505
+ ctl.abort();
139506
+ return new JpFontError("too_large", "The font download is larger than expected.");
139507
+ };
139508
+ if (!res.body) {
139509
+ const b = new Uint8Array(await res.arrayBuffer());
139510
+ if (b.byteLength > JP_FACE_BYTES) throw tooLarge();
139511
+ return b;
139512
+ }
139513
+ const reader = res.body.getReader();
139514
+ const chunks = [];
139515
+ let total = 0;
139516
+ for (; ; ) {
139517
+ const { done, value } = await reader.read();
139518
+ if (done) break;
139519
+ total += value.byteLength;
139520
+ if (total > JP_FACE_BYTES) {
139521
+ await reader.cancel().catch(() => void 0);
139522
+ throw tooLarge();
139523
+ }
139524
+ chunks.push(value);
139525
+ }
139526
+ const out = new Uint8Array(total);
139527
+ let off = 0;
139528
+ for (const c2 of chunks) {
139529
+ out.set(c2, off);
139530
+ off += c2.byteLength;
139531
+ }
139532
+ return out;
139533
+ }
139534
+ async function writeFont(path, bytes) {
139535
+ const dir = dirname3(path);
139536
+ await fsp2.mkdir(dir, { recursive: true, mode: 448 });
139537
+ if (!IS_WIN2) await fsp2.chmod(dir, 448);
139538
+ await writeFileAtomic(path, bytes, 384);
139539
+ }
139540
+ function errText(e4) {
139541
+ const cause = e4 instanceof Error && e4.cause instanceof Error ? ` (${e4.cause.message})` : "";
139542
+ return e4 instanceof Error ? `${e4.message}${cause}` : String(e4);
139543
+ }
139544
+ function jpFontReason(e4) {
139545
+ if (!(e4 instanceof JpFontError)) return errText(e4);
139546
+ switch (e4.reason) {
139547
+ case "network":
139548
+ return "network error";
139549
+ case "timeout":
139550
+ return "the download timed out";
139551
+ case "http_status":
139552
+ return `HTTP ${String(e4.status)}`;
139553
+ case "hash_mismatch":
139554
+ return "the file didn't match its pinned checksum";
139555
+ case "too_large":
139556
+ return "the download was larger than expected";
139557
+ }
139558
+ }
139559
+
137982
139560
  // src/render.ts
137983
139561
  import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
137984
139562
  import { createRequire as createRequire2 } from "node:module";
137985
- import { dirname as dirname3, join as join4 } from "node:path";
139563
+ import { dirname as dirname4, join as join5 } from "node:path";
137986
139564
  import { fileURLToPath as fileURLToPath2 } from "node:url";
137987
139565
  import { deflateSync } from "node:zlib";
137988
139566
  var DEFAULT_DPI = 110;
@@ -137991,8 +139569,8 @@ var MIN_DPI = 36;
137991
139569
  var MAX_SIDE_PX = 3e3;
137992
139570
  var loading = null;
137993
139571
  function wasmPath() {
137994
- const here = dirname3(fileURLToPath2(import.meta.url));
137995
- const bundled = join4(here, "pdfium.wasm");
139572
+ const here = dirname4(fileURLToPath2(import.meta.url));
139573
+ const bundled = join5(here, "pdfium.wasm");
137996
139574
  if (existsSync2(bundled)) return bundled;
137997
139575
  const req = createRequire2(import.meta.url);
137998
139576
  return req.resolve("@embedpdf/pdfium/pdfium.wasm");
@@ -138266,14 +139844,10 @@ function encodePng2(r) {
138266
139844
  );
138267
139845
  }
138268
139846
 
138269
- // src/version.ts
138270
- var VERSION = true ? "0.2.3" : "0.0.0-dev";
138271
- var USER_AGENT = `fenfill-mcp/${VERSION}`;
138272
-
138273
139847
  // src/fill.ts
138274
139848
  var MAX_INPUT_BYTES = 512 * 1024 * 1024;
138275
139849
  var MAX_IMAGE_BYTES2 = 5 * 1024 * 1024;
138276
- var IS_WIN2 = process.platform === "win32";
139850
+ var IS_WIN3 = process.platform === "win32";
138277
139851
  var OUTPUT_TAGS = { [MCP_OUTPUT_TAG]: `fenfill-mcp/${VERSION}` };
138278
139852
  var LOGO_SENTINEL = "fenfill-mcp:logo";
138279
139853
  function absPath(p4, what) {
@@ -138289,7 +139863,7 @@ async function readInputPdf(path) {
138289
139863
  const abs2 = absPath(path, "path");
138290
139864
  let st;
138291
139865
  try {
138292
- st = await fsp2.stat(abs2);
139866
+ st = await fsp3.stat(abs2);
138293
139867
  } catch {
138294
139868
  throw new ToolError("file_not_found", "No file at that path.", {
138295
139869
  hint: "Check the path (it must be absolute or start with ~/)."
@@ -138297,7 +139871,7 @@ async function readInputPdf(path) {
138297
139871
  }
138298
139872
  if (!st.isFile()) throw new ToolError("not_a_file", "That path is not a file.");
138299
139873
  if (st.size > MAX_INPUT_BYTES) throw new ToolError("file_too_large", "The file is too large.");
138300
- const bytes = new Uint8Array(await fsp2.readFile(abs2));
139874
+ const bytes = new Uint8Array(await fsp3.readFile(abs2));
138301
139875
  const head = Buffer.from(bytes.subarray(0, 1024)).toString("latin1");
138302
139876
  if (!head.includes("%PDF-")) {
138303
139877
  throw new ToolError("not_pdf", "The file is not a PDF.", { hint: "Pass a PDF file." });
@@ -138316,13 +139890,13 @@ async function caseInsensitiveAt(dir) {
138316
139890
  const swapped = swapCase(dir);
138317
139891
  if (swapped !== dir) {
138318
139892
  try {
138319
- const [a, b] = await Promise.all([fsp2.stat(dir), fsp2.stat(swapped)]);
139893
+ const [a, b] = await Promise.all([fsp3.stat(dir), fsp3.stat(swapped)]);
138320
139894
  return a.dev === b.dev && a.ino === b.ino;
138321
139895
  } catch {
138322
139896
  return false;
138323
139897
  }
138324
139898
  }
138325
- return process.platform === "darwin" || IS_WIN2;
139899
+ return process.platform === "darwin" || IS_WIN3;
138326
139900
  }
138327
139901
  function isInside(child, parent) {
138328
139902
  const rel2 = relative(parent, child);
@@ -138333,20 +139907,20 @@ async function resolveOutputPath(outputPath, opts) {
138333
139907
  if (!out.toLowerCase().endsWith(".pdf")) {
138334
139908
  throw new ToolError("invalid_output_path", "output_path must end in .pdf.");
138335
139909
  }
138336
- const dir = dirname4(out);
139910
+ const dir = dirname5(out);
138337
139911
  let realDir;
138338
139912
  try {
138339
- realDir = await fsp2.realpath(dir);
138340
- if (!(await fsp2.stat(realDir)).isDirectory()) throw new Error("not a dir");
139913
+ realDir = await fsp3.realpath(dir);
139914
+ if (!(await fsp3.stat(realDir)).isDirectory()) throw new Error("not a dir");
138341
139915
  } catch {
138342
139916
  throw new ToolError("invalid_output_path", "The output folder doesn't exist.", {
138343
139917
  hint: "Create the folder first, or pick an existing one."
138344
139918
  });
138345
139919
  }
138346
- const realOut = join5(realDir, basename(out));
139920
+ const realOut = join6(realDir, basename(out));
138347
139921
  let realCache = resolve2(opts.cacheRoot);
138348
139922
  try {
138349
- realCache = await fsp2.realpath(realCache);
139923
+ realCache = await fsp3.realpath(realCache);
138350
139924
  } catch {
138351
139925
  }
138352
139926
  const ci = await caseInsensitiveAt(realDir);
@@ -138358,7 +139932,7 @@ async function resolveOutputPath(outputPath, opts) {
138358
139932
  }
138359
139933
  let existing = null;
138360
139934
  try {
138361
- existing = await fsp2.stat(out);
139935
+ existing = await fsp3.stat(out);
138362
139936
  } catch {
138363
139937
  existing = null;
138364
139938
  }
@@ -138367,12 +139941,12 @@ async function resolveOutputPath(outputPath, opts) {
138367
139941
  hint: "Write the filled PDF to a new file; the blank form stays untouched."
138368
139942
  });
138369
139943
  if (existing) {
138370
- const input2 = await fsp2.stat(opts.inputAbs);
139944
+ const input2 = await fsp3.stat(opts.inputAbs);
138371
139945
  if (existing.dev === input2.dev && existing.ino === input2.ino && input2.ino !== 0) throw same();
138372
139946
  }
138373
139947
  let realIn = opts.inputAbs;
138374
139948
  try {
138375
- realIn = await fsp2.realpath(opts.inputAbs);
139949
+ realIn = await fsp3.realpath(opts.inputAbs);
138376
139950
  } catch {
138377
139951
  }
138378
139952
  if (fold(realOut) === fold(realIn)) throw same();
@@ -138390,36 +139964,36 @@ async function resolveOutputPath(outputPath, opts) {
138390
139964
  return out;
138391
139965
  }
138392
139966
  async function writeOutputAtomic(out, pdf, overwrite) {
138393
- const tmp = join5(dirname4(out), `.${basename(out)}.${randomBytes2(6).toString("hex")}.tmp`);
139967
+ const tmp = join6(dirname5(out), `.${basename(out)}.${randomBytes2(6).toString("hex")}.tmp`);
138394
139968
  let fh = null;
138395
139969
  const exists = () => new ToolError("output_exists", "A file already exists at output_path.", {
138396
139970
  hint: "Pick a new file name, or pass overwrite=true to replace it."
138397
139971
  });
138398
139972
  try {
138399
- fh = await fsp2.open(tmp, "wx", 384);
139973
+ fh = await fsp3.open(tmp, "wx", 384);
138400
139974
  await fh.writeFile(pdf);
138401
139975
  await fh.sync();
138402
139976
  await fh.close();
138403
139977
  fh = null;
138404
139978
  if (overwrite) {
138405
- await fsp2.rename(tmp, out);
139979
+ await fsp3.rename(tmp, out);
138406
139980
  } else {
138407
139981
  try {
138408
- await fsp2.link(tmp, out);
138409
- await fsp2.rm(tmp, { force: true });
139982
+ await fsp3.link(tmp, out);
139983
+ await fsp3.rm(tmp, { force: true });
138410
139984
  } catch (e4) {
138411
139985
  if (e4.code === "EEXIST") throw exists();
138412
- if (await fsp2.stat(out).then(
139986
+ if (await fsp3.stat(out).then(
138413
139987
  () => true,
138414
139988
  () => false
138415
139989
  ))
138416
139990
  throw exists();
138417
- await fsp2.rename(tmp, out);
139991
+ await fsp3.rename(tmp, out);
138418
139992
  }
138419
139993
  }
138420
139994
  } catch (e4) {
138421
139995
  if (fh) await fh.close().catch(() => void 0);
138422
- await fsp2.rm(tmp, { force: true }).catch(() => void 0);
139996
+ await fsp3.rm(tmp, { force: true }).catch(() => void 0);
138423
139997
  if (e4 instanceof ToolError) throw e4;
138424
139998
  throw new ToolError("write_failed", "Couldn't write the output PDF.", {
138425
139999
  hint: "Check that the folder is writable.",
@@ -138435,6 +140009,36 @@ function loadImage(p4) {
138435
140009
  if (st.size > MAX_IMAGE_BYTES2) throw new Error("The signature image is over 5 MB.");
138436
140010
  return new Uint8Array(readFileSync3(abs2));
138437
140011
  }
140012
+ function unsupportedScriptError(e4, why) {
140013
+ const where = "The check covers the whole document, so preview_page refuses even when these values are on another page.";
140014
+ return new ToolError(
140015
+ "unsupported_script",
140016
+ `Japanese characters need the Noto Sans JP font, which couldn't be loaded (fields: ${e4.ids.join(", ")}).`,
140017
+ {
140018
+ hint: why ? `Couldn't download the Japanese font (${why.text}); connect to the internet once and retry, or pre-seed ${why.path} (from ${DEFAULT_JP_FONT_URL}). ${where}` : `The Japanese font isn't available to this call. ${where} Drop or replace those values, or fill this form at fenfill.com.`,
140019
+ details: { ids: e4.ids, ...why ? { reason: why.reason } : {} }
140020
+ }
140021
+ );
140022
+ }
140023
+ async function fillWithJpFace(args, jp) {
140024
+ try {
140025
+ return await fillAgentPdf(args);
140026
+ } catch (e4) {
140027
+ if (!(e4 instanceof UnsupportedScriptError)) throw e4;
140028
+ if (!jp) throw unsupportedScriptError(e4);
140029
+ let face;
140030
+ try {
140031
+ face = await jp.load();
140032
+ } catch (fe) {
140033
+ throw unsupportedScriptError(e4, {
140034
+ reason: fe instanceof JpFontError ? fe.reason : "error",
140035
+ text: jpFontReason(fe),
140036
+ path: jp.path
140037
+ });
140038
+ }
140039
+ return await fillAgentPdf({ ...args, fonts: { ...args.fonts, jp: face } });
140040
+ }
140041
+ }
138438
140042
  function isPasswordError(e4) {
138439
140043
  return e4 instanceof Error && /password/i.test(e4.message);
138440
140044
  }
@@ -138464,19 +140068,23 @@ async function stampAndWrite(a) {
138464
140068
  const printed = a.checkAbs ? await printedBoxes(a.pdfBytes, pages) : void 0;
138465
140069
  let res;
138466
140070
  try {
138467
- res = await fillAgentPdf({
138468
- pdfBytes: toArrayBuffer(a.pdfBytes),
138469
- render: a.render,
138470
- input: a.agentInput,
138471
- fonts: a.fonts,
138472
- branding: a.branding,
138473
- logoBytes: a.logoBytes,
138474
- loadImage,
138475
- infoTags: OUTPUT_TAGS,
138476
- check: !!a.checkAbs,
138477
- checkPrinted: printed
138478
- });
140071
+ res = await fillWithJpFace(
140072
+ {
140073
+ pdfBytes: toArrayBuffer(a.pdfBytes),
140074
+ render: a.render,
140075
+ input: a.agentInput,
140076
+ fonts: a.fonts,
140077
+ branding: a.branding,
140078
+ logoBytes: a.logoBytes,
140079
+ loadImage,
140080
+ infoTags: OUTPUT_TAGS,
140081
+ check: !!a.checkAbs,
140082
+ checkPrinted: printed
140083
+ },
140084
+ a.jpFace
140085
+ );
138479
140086
  } catch (e4) {
140087
+ if (e4 instanceof UnsupportedScriptError) throw unsupportedScriptError(e4);
138480
140088
  if (isPasswordError(e4)) throw passwordError();
138481
140089
  if (isFillForbiddenError(e4)) throw fillForbiddenError();
138482
140090
  throw e4;
@@ -139807,11 +141415,11 @@ function inPrintedFormat(digits2, fmt3) {
139807
141415
  let i2 = 0;
139808
141416
  return cells.map((c2) => isLetter(c2) ? d[i2++] : c2).join("");
139809
141417
  }
139810
- var LETTER = "[\\p{Lu}\\p{Ll}\\p{Lt}\\p{Lm}\\p{M}]";
139811
- var HAS_LETTER = new RegExp(LETTER, "u");
141418
+ var LETTER2 = "[\\p{Lu}\\p{Ll}\\p{Lt}\\p{Lm}\\p{M}]";
141419
+ var HAS_LETTER = new RegExp(LETTER2, "u");
139812
141420
  var DIGIT = "\\p{Nd}";
139813
- var ENDS = [new RegExp(`${LETTER}$`, "u"), new RegExp(`${DIGIT}$`, "u")];
139814
- var STARTS = [new RegExp(`^${LETTER}`, "u"), new RegExp(`^${DIGIT}`, "u")];
141421
+ var ENDS = [new RegExp(`${LETTER2}$`, "u"), new RegExp(`${DIGIT}$`, "u")];
141422
+ var STARTS = [new RegExp(`^${LETTER2}`, "u"), new RegExp(`^${DIGIT}`, "u")];
139815
141423
  var runsOn = (left, right) => ENDS.some((end, i2) => end.test(left) && STARTS[i2].test(right));
139816
141424
  function holds(n, v) {
139817
141425
  if (v.includes(" ") || !HAS_LETTER.test(v)) return true;
@@ -140994,13 +142602,37 @@ function tableIssues(d, g) {
140994
142602
  if (ids.some((id) => d.field.get(id)?.type !== "checkbox"))
140995
142603
  at("a checkbox_matrix cell isn't a checkbox");
140996
142604
  } else {
140997
- for (let i2 = 0; i2 < lineCount(v, v.axis); i2++) {
140998
- const keys = new Set(lineFields(d, v, v.axis, i2).map(typeKey));
140999
- if (keys.size > 1) at(`${axisWord(v.axis)} ${String(i2)} mixes types`);
141000
- }
142605
+ for (const i2 of mixedLines(d, g)) at(`${axisWord(v.axis)} ${String(i2)} mixes types`);
141001
142606
  }
141002
142607
  return out;
141003
142608
  }
142609
+ function mixedLines(d, g) {
142610
+ return mixedLineCells(d, g).map((l) => l.index);
142611
+ }
142612
+ function mixedLineCells(d, g) {
142613
+ const grid = g.grid;
142614
+ if (!Array.isArray(grid) || grid.some((r) => !Array.isArray(r))) return [];
142615
+ const rows = grid.length;
142616
+ const v = {
142617
+ g,
142618
+ grid,
142619
+ rows,
142620
+ cols: rows ? grid[0].length : 0,
142621
+ axis: g.orientation === "row" ? "row" : "col",
142622
+ format: formatOf(g)
142623
+ };
142624
+ if (v.format === "checkbox_matrix") return [];
142625
+ const out = [];
142626
+ for (let i2 = 0; i2 < lineCount(v, v.axis); i2++) {
142627
+ const cells = lineFields(d, v, v.axis, i2);
142628
+ const keys = new Set(cells.map(typeKey));
142629
+ if (keys.size > 1) out.push({ index: i2, ids: cells.map((f3) => f3.id), keys: [...keys] });
142630
+ }
142631
+ return out;
142632
+ }
142633
+ function lineWord(g) {
142634
+ return axisWord(g.orientation === "row" ? "row" : "col");
142635
+ }
141004
142636
 
141005
142637
  // src/validate.ts
141006
142638
  var MAX_ID = 200;
@@ -141771,7 +143403,7 @@ function applyOne(d, op, warnings, opts) {
141771
143403
  added: gid,
141772
143404
  members: readingMembers(d, g).map((m) => m.id),
141773
143405
  section: sectionOf(d, page, gid),
141774
- ...op.kind === "comb" ? { comb: gid } : {}
143406
+ ...op.kind === "comb" ? { comb: gid } : { batchOrder: { id: gid, ids: fs.map((f3) => f3.id) } }
141775
143407
  };
141776
143408
  }
141777
143409
  case "ungroup": {
@@ -141795,15 +143427,22 @@ function applyOne(d, op, warnings, opts) {
141795
143427
  if (op.options.every((o) => typeof o === "string")) {
141796
143428
  if (op.options.length !== opts2.length) {
141797
143429
  return bad(
141798
- `this group has ${String(opts2.length)} options; pass that many labels (in the order the options are listed), or [{id, label}] pairs. Add an option with add_option, or remove one with remove_option.`
143430
+ `this group has ${String(opts2.length)} options; pass that many labels (they go in the order of the ids of this call's group op that made it, else in reading order, as get_template lists them), or [{id, label}] pairs. Add an option with add_option, or remove one with remove_option.`
141799
143431
  );
141800
143432
  }
141801
- const byId = buildFieldById(d.s.fields);
141802
- const ordered = resolveMembers(g, byId);
141803
- ordered.forEach((f3, i2) => {
141804
- const live = d.field.get(f3.id);
143433
+ const reading = readingMembers(d, g).map((m) => m.id);
143434
+ const given = d.batchGroups?.get(g.id);
143435
+ const current = new Set(opts2.map((m) => m.id));
143436
+ const order = given && given.length === current.size && given.every((id) => current.has(id)) ? given : reading;
143437
+ order.forEach((id, i2) => {
143438
+ const live = d.field.get(id);
141805
143439
  if (live) live.label = op.options[i2].trim();
141806
143440
  });
143441
+ if (order.some((id, i2) => id !== reading[i2])) {
143442
+ warnings.push(
143443
+ `options_order_differs_from_reading_order: group ${g.id}'s labels follow the ids order of its group op (${order.join(", ")}), not reading order (${reading.join(", ")}); check them, or pass [{id, label}]`
143444
+ );
143445
+ }
141807
143446
  } else {
141808
143447
  for (const o of op.options) {
141809
143448
  if (!isRec2(o) || typeof o.id !== "string" || typeof o.label !== "string") {
@@ -141815,7 +143454,13 @@ function applyOne(d, op, warnings, opts) {
141815
143454
  f3.label = o.label.trim();
141816
143455
  }
141817
143456
  }
141818
- return { touched: [g.id] };
143457
+ return {
143458
+ touched: [g.id],
143459
+ options: readingMembers(d, g).map((m) => ({
143460
+ id: m.id,
143461
+ label: typeof m.label === "string" ? m.label : ""
143462
+ }))
143463
+ };
141819
143464
  }
141820
143465
  case "add_option": {
141821
143466
  const g = needGroup(d, op.id);
@@ -141945,7 +143590,7 @@ function applyOne(d, op, warnings, opts) {
141945
143590
  case "set_headers":
141946
143591
  return table(setHeaders(d, raw, warnings));
141947
143592
  case "reorder":
141948
- return reorder(d, raw, warnings);
143593
+ return reorder2(d, raw, warnings);
141949
143594
  case "set_section":
141950
143595
  return setSection(d, raw);
141951
143596
  case "set_section_title":
@@ -141954,7 +143599,7 @@ function applyOne(d, op, warnings, opts) {
141954
143599
  return bad(`unknown op "${String(op.op)}"; ops: ${OP_NAMES.join(", ")}`);
141955
143600
  }
141956
143601
  }
141957
- function reorder(d, op, warnings) {
143602
+ function reorder2(d, op, warnings) {
141958
143603
  const page = pageOf(d, op.page);
141959
143604
  if (!Array.isArray(op.ids) || op.ids.length === 0)
141960
143605
  return bad("ids must list the entries to order");
@@ -142361,6 +144006,7 @@ function applyPass(render, ops, excluded, screen, opts) {
142361
144006
  const told = [];
142362
144007
  const confirmed = [];
142363
144008
  const refs = /* @__PURE__ */ new Map();
144009
+ const batchGroups = /* @__PURE__ */ new Map();
142364
144010
  let applied = 0;
142365
144011
  ops.forEach((raw, i2) => {
142366
144012
  const skip = excluded.get(i2);
@@ -142371,6 +144017,7 @@ function applyPass(render, ops, excluded, screen, opts) {
142371
144017
  const draft = structuredClone(cur);
142372
144018
  const d2 = index(draft);
142373
144019
  d2.refs = refs;
144020
+ d2.batchGroups = batchGroups;
142374
144021
  const w = [];
142375
144022
  try {
142376
144023
  const given = isRec2(raw) ? raw.ref : void 0;
@@ -142384,12 +144031,42 @@ function applyPass(render, ops, excluded, screen, opts) {
142384
144031
  bad(
142385
144032
  "ref names what an op adds (add, group, add_option, comb_add_cell\u2026); this op adds nothing"
142386
144033
  );
142387
- const issues = touchedIssues(d2, r.touched, r.tables);
144034
+ let issues = touchedIssues(d2, r.touched, r.tables);
144035
+ if (issues.length) {
144036
+ const before = index(cur);
144037
+ const had = new Set(
144038
+ touchedIssues(
144039
+ before,
144040
+ r.touched.filter((id) => before.field.has(id) || before.group.has(id)),
144041
+ (r.tables ?? []).filter((id) => before.group.has(id))
144042
+ ).map((x2) => `${x2.path} ${x2.reason}`)
144043
+ );
144044
+ const stillMixed = (x2) => {
144045
+ const m = / (\d+) mixes types$/.exec(x2.reason);
144046
+ const g = d2.group.get(x2.id ?? "");
144047
+ const was = before.group.get(x2.id ?? "");
144048
+ if (!m || !g || !was) return false;
144049
+ const now = mixedLineCells(d2, g).find((l) => l.index === Number(m[1]));
144050
+ return !!now && mixedLineCells(before, was).some(
144051
+ (l) => now.ids.some((id) => l.ids.includes(id)) && now.keys.every((k4) => l.keys.includes(k4))
144052
+ );
144053
+ };
144054
+ issues = issues.filter((x2) => !had.has(`${x2.path} ${x2.reason}`) && !stillMixed(x2));
144055
+ }
142388
144056
  if (issues.length) {
142389
144057
  bad(
142390
144058
  issues.slice(0, 5).map((x2) => `${x2.path} ${x2.reason}`).join("; ")
142391
144059
  );
142392
144060
  }
144061
+ for (const id of r.tables ?? []) {
144062
+ const g = d2.group.get(id);
144063
+ const mixed = g ? mixedLines(d2, g) : [];
144064
+ if (!g || !mixed.length) continue;
144065
+ const word = lineWord(g);
144066
+ w.push(
144067
+ `table ${id}: ${mixed.map((n) => `${word} ${String(n)}`).join(", ")} still store${mixed.length === 1 ? "s" : ""} mixed types; fill, print and get_template use one type per ${word} (its first typed cell's), so set_column_type or set_format a cell of each to settle them`
144068
+ );
144069
+ }
142393
144070
  let vouched = [];
142394
144071
  if (screen) {
142395
144072
  const changed = changedWording(cur, draft);
@@ -142426,11 +144103,13 @@ function applyPass(render, ops, excluded, screen, opts) {
142426
144103
  ...r.order ? { order: r.order } : {},
142427
144104
  ...r.section !== void 0 ? { section: r.section } : {},
142428
144105
  ...r.members ? { members: r.members } : {},
144106
+ ...r.options ? { options: r.options } : {},
142429
144107
  ...noop ? { noop: true } : {}
142430
144108
  });
142431
144109
  cur = draft;
142432
144110
  applied++;
142433
144111
  if (typeof ref === "string" && r.added) refs.set(ref, r.added);
144112
+ if (r.batchOrder) batchGroups.set(r.batchOrder.id, r.batchOrder.ids);
142434
144113
  confirmed.push(...vouched);
142435
144114
  counts[name] = (counts[name] ?? 0) + 1;
142436
144115
  if (r.added) added.push({ op_index: i2, id: r.added });
@@ -142547,7 +144226,7 @@ function describeWording(wording, name = (id) => id) {
142547
144226
  }
142548
144227
 
142549
144228
  // src/snap.ts
142550
- import { createHash as createHash2 } from "node:crypto";
144229
+ import { createHash as createHash3 } from "node:crypto";
142551
144230
 
142552
144231
  // src/rules.ts
142553
144232
  var INK_DELTA = 45;
@@ -142881,7 +144560,7 @@ function snapOnRules(rules, box, mode) {
142881
144560
  return line ? { box: toBox(line) } : { none: "no underline under the box" };
142882
144561
  }
142883
144562
  async function prepareSnapper(pdf, pages) {
142884
- const hash2 = createHash2("sha256").update(pdf).digest("hex");
144563
+ const hash2 = createHash3("sha256").update(pdf).digest("hex");
142885
144564
  const ready = /* @__PURE__ */ new Map();
142886
144565
  for (const p4 of pages) ready.set(p4, await pageRules(pdf, hash2, p4));
142887
144566
  return (page, box, mode) => {
@@ -143554,23 +145233,27 @@ async function previewPage(a) {
143554
145233
  const printed = overlay === "full" ? await printedBoxes(a.pdfBytes, [a.page]) : void 0;
143555
145234
  let res;
143556
145235
  try {
143557
- res = await fillAgentPdf({
143558
- pdfBytes: toArrayBuffer(a.pdfBytes),
143559
- render: a.render,
143560
- input: a.values,
143561
- fonts: a.fonts,
143562
- branding: null,
143563
- logoBytes: null,
143564
- loadImage,
143565
- // "none" shows the stamped PDF itself: no check copy is built, so none can fail.
143566
- check: overlay !== "none",
143567
- // preview_page's JSON carries the colour key; the banner would only
143568
- // cover the top of page 1.
143569
- checkBanner: false,
143570
- checkTags: overlay === "full",
143571
- checkPrinted: printed
143572
- });
145236
+ res = await fillWithJpFace(
145237
+ {
145238
+ pdfBytes: toArrayBuffer(a.pdfBytes),
145239
+ render: a.render,
145240
+ input: a.values,
145241
+ fonts: a.fonts,
145242
+ branding: null,
145243
+ logoBytes: null,
145244
+ loadImage,
145245
+ // "none" shows the stamped PDF itself: no check copy is built, so none can fail.
145246
+ check: overlay !== "none",
145247
+ // preview_page's JSON carries the colour key; the banner would only
145248
+ // cover the top of page 1.
145249
+ checkBanner: false,
145250
+ checkTags: overlay === "full",
145251
+ checkPrinted: printed
145252
+ },
145253
+ a.jpFace
145254
+ );
143573
145255
  } catch (e4) {
145256
+ if (e4 instanceof UnsupportedScriptError) throw unsupportedScriptError(e4);
143574
145257
  if (isPasswordError(e4)) throw passwordError();
143575
145258
  if (isFillForbiddenError(e4)) throw fillForbiddenError();
143576
145259
  throw e4;
@@ -144088,8 +145771,8 @@ async function refreshTemplateAnalyses(deps, tid, after, requested, analyzed, wh
144088
145771
  }
144089
145772
 
144090
145773
  // src/sweep.ts
144091
- import { promises as fsp3 } from "node:fs";
144092
- import { join as join6 } from "node:path";
145774
+ import { promises as fsp4 } from "node:fs";
145775
+ import { join as join7 } from "node:path";
144093
145776
  var HOUR = 60 * 60 * 1e3;
144094
145777
  var DAY = 24 * HOUR;
144095
145778
  var SWEEP_INTERVAL_MS = DAY;
@@ -144099,14 +145782,14 @@ var OUTPUT_MARKER_MS = 365 * DAY;
144099
145782
  var LEFTOVER_MS = DAY;
144100
145783
  async function names(dir) {
144101
145784
  try {
144102
- return await fsp3.readdir(dir);
145785
+ return await fsp4.readdir(dir);
144103
145786
  } catch {
144104
145787
  return [];
144105
145788
  }
144106
145789
  }
144107
145790
  async function ageMs(path, now) {
144108
145791
  try {
144109
- const st = await fsp3.stat(path);
145792
+ const st = await fsp4.stat(path);
144110
145793
  return st.isFile() ? now - st.mtimeMs : null;
144111
145794
  } catch {
144112
145795
  return null;
@@ -144115,11 +145798,11 @@ async function ageMs(path, now) {
144115
145798
  async function dropIfOld(path, now, maxAgeMs) {
144116
145799
  const age = await ageMs(path, now);
144117
145800
  if (age === null || age <= maxAgeMs) return false;
144118
- await fsp3.rm(path, { force: true });
145801
+ await fsp4.rm(path, { force: true });
144119
145802
  return true;
144120
145803
  }
144121
145804
  async function rmdirIfEmpty(dir) {
144122
- if ((await names(dir)).length === 0) await fsp3.rmdir(dir).catch(() => void 0);
145805
+ if ((await names(dir)).length === 0) await fsp4.rmdir(dir).catch(() => void 0);
144123
145806
  }
144124
145807
  async function each(items2, fn5) {
144125
145808
  for (const n of items2) await fn5(n).catch(() => void 0);
@@ -144134,27 +145817,27 @@ async function sweepCache(cache3, now) {
144134
145817
  ["templates", "blank.pdf"],
144135
145818
  ["account", "logo.bin"]
144136
145819
  ]) {
144137
- await each(await names(join6(root, sub)), async (id) => {
144138
- const d = join6(root, sub, id);
144139
- count(await dropIfOld(join6(d, file2), now, ASSET_TTL_MS));
145820
+ await each(await names(join7(root, sub)), async (id) => {
145821
+ const d = join7(root, sub, id);
145822
+ count(await dropIfOld(join7(d, file2), now, ASSET_TTL_MS));
144140
145823
  await each(await names(d), async (n) => {
144141
- if (n.startsWith(".")) count(await dropIfOld(join6(d, n), now, LEFTOVER_MS));
145824
+ if (n.startsWith(".")) count(await dropIfOld(join7(d, n), now, LEFTOVER_MS));
144142
145825
  });
144143
145826
  await rmdirIfEmpty(d);
144144
145827
  });
144145
145828
  }
144146
- await each(await names(join6(root, "forms")), async (sha) => {
144147
- const d = join6(root, "forms", sha);
145829
+ await each(await names(join7(root, "forms")), async (sha) => {
145830
+ const d = join7(root, "forms", sha);
144148
145831
  await each(await names(d), async (n) => {
144149
145832
  const max2 = n.startsWith(".") ? LEFTOVER_MS : FORM_UNUSED_MS;
144150
- count(await dropIfOld(join6(d, n), now, max2));
145833
+ count(await dropIfOld(join7(d, n), now, max2));
144151
145834
  });
144152
145835
  await rmdirIfEmpty(d);
144153
145836
  });
144154
- const pendDir = join6(root, "pending");
145837
+ const pendDir = join7(root, "pending");
144155
145838
  await each(await names(pendDir), async (n) => {
144156
145839
  if (n.startsWith(".")) {
144157
- count(await dropIfOld(join6(pendDir, n), now, LEFTOVER_MS));
145840
+ count(await dropIfOld(join7(pendDir, n), now, LEFTOVER_MS));
144158
145841
  return;
144159
145842
  }
144160
145843
  const t = /^t-([A-Za-z0-9_-]{1,64})\.([0-9a-f]{16})\.json$/.exec(n);
@@ -144172,12 +145855,15 @@ async function sweepCache(cache3, now) {
144172
145855
  if (p4.entry && holderAlive(p4.entry)) return;
144173
145856
  count(await cache3.removePending(m[1], m[2], { stamp: p4.stamp }));
144174
145857
  });
144175
- await each(await names(join6(root, "edits")), async (n) => {
145858
+ await each(await names(join7(root, "edits")), async (n) => {
144176
145859
  const max2 = n.startsWith(".") ? LEFTOVER_MS : FORM_UNUSED_MS;
144177
- count(await dropIfOld(join6(root, "edits", n), now, max2));
145860
+ count(await dropIfOld(join7(root, "edits", n), now, max2));
145861
+ });
145862
+ await each(await names(join7(root, "fonts")), async (n) => {
145863
+ if (n.startsWith(".")) count(await dropIfOld(join7(root, "fonts", n), now, LEFTOVER_MS));
144178
145864
  });
144179
- await each(await names(join6(root, "outputs")), async (n) => {
144180
- count(await dropIfOld(join6(root, "outputs", n), now, OUTPUT_MARKER_MS));
145865
+ await each(await names(join7(root, "outputs")), async (n) => {
145866
+ count(await dropIfOld(join7(root, "outputs", n), now, OUTPUT_MARKER_MS));
144181
145867
  });
144182
145868
  return removed;
144183
145869
  }
@@ -144355,6 +146041,10 @@ function createFenfillServer(opts = {}) {
144355
146041
  await sleepTimer3(ms, void 0, { signal });
144356
146042
  });
144357
146043
  const cache3 = new Cache2(cacheDirFromEnv(env), now);
146044
+ const jpFace = {
146045
+ load: () => ensureJpFace({ cacheDir: cache3.root, fetchImpl: opts.fontFetchImpl, url: opts.jpFontUrl }),
146046
+ path: jpFontPath(cache3.root)
146047
+ };
144358
146048
  const stop = new AbortController();
144359
146049
  const owner = randomBytes5(8).toString("hex");
144360
146050
  LIVE_OWNERS.add(owner);
@@ -144557,7 +146247,7 @@ function createFenfillServer(opts = {}) {
144557
146247
  "fill_form",
144558
146248
  {
144559
146249
  title: "Fill an analyzed PDF locally",
144560
- description: `Fill a PDF you analyzed with analyze_form and write a new, flattened PDF. Runs entirely on this machine: no network, and the values never leave it. ${VALUE_SHAPES} Returns filled/skipped counts and warnings, including text shrunk hard or running past its box and filled boxes that overlap; pass check_pdf to see the result.`,
146250
+ description: `Fill a PDF you analyzed with analyze_form and write a new, flattened PDF. Runs entirely on this machine and the values never leave it; the only network use is a one-time download of the public Japanese font from fenfill.com, the first time a value needs it (it carries no form data). ${VALUE_SHAPES} Returns filled/skipped counts and warnings, including text shrunk hard or running past its box and filled boxes that overlap; pass check_pdf to see the result.`,
144561
146251
  inputSchema: {
144562
146252
  path: external_exports.string().min(1).max(4096).describe("The same blank PDF you passed to analyze_form."),
144563
146253
  values: VALUES,
@@ -144594,6 +146284,7 @@ function createFenfillServer(opts = {}) {
144594
146284
  render,
144595
146285
  agentInput: answers,
144596
146286
  fonts: loadFonts(opts.fontsDir),
146287
+ jpFace,
144597
146288
  branding: null,
144598
146289
  logoBytes: null,
144599
146290
  outputAbs,
@@ -144668,6 +146359,7 @@ function createFenfillServer(opts = {}) {
144668
146359
  render,
144669
146360
  agentInput: answers,
144670
146361
  fonts: loadFonts(opts.fontsDir),
146362
+ jpFace,
144671
146363
  branding,
144672
146364
  logoBytes: logo ? toArrayBuffer(logo) : null,
144673
146365
  outputAbs,
@@ -144795,7 +146487,7 @@ function createFenfillServer(opts = {}) {
144795
146487
  "preview_page",
144796
146488
  {
144797
146489
  title: "Preview a page with its field boxes",
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.`,
146490
+ 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), 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. Read-only audit; values 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 in a table or group). Renders the edit_template working copy if any, else the saved or analyzed version (edited: true/false). Local: nothing is written to disk, values are never sent; the sole network use is a one-time download of fenfill.com's public Japanese font when a value first needs it (no form data).`,
144799
146491
  inputSchema: {
144800
146492
  path: TARGET_PATH,
144801
146493
  template_id: TARGET_TEMPLATE,
@@ -144857,6 +146549,7 @@ function createFenfillServer(opts = {}) {
144857
146549
  values: answers,
144858
146550
  dpi: args.dpi,
144859
146551
  fonts: loadFonts(opts.fontsDir),
146552
+ jpFace,
144860
146553
  crop: args.crop,
144861
146554
  zoom: args.zoom,
144862
146555
  overlay: args.overlay
@@ -144943,7 +146636,7 @@ function createFenfillServer(opts = {}) {
144943
146636
  path: TARGET_PATH,
144944
146637
  template_id: TARGET_TEMPLATE,
144945
146638
  ops: external_exports.array(external_exports.record(external_exports.string(), external_exports.unknown())).max(MAX_OPS).optional().describe(
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.`
146639
+ `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: [{id, label}] (recommended) or ["label", \u2026]: plain labels go to the options in the order of the ids of a group op earlier in the same call, else in reading order (as get_template lists them); diff_summary.ops shows each option's 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.`
144947
146640
  ),
144948
146641
  discard: external_exports.boolean().optional().describe(
144949
146642
  "Drop the local working copy first (any ops then apply to fenfill's version). ops may be left out with it."