@pixldocs/canvas-renderer 0.5.82 → 0.5.84

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
@@ -475,29 +475,39 @@ function resolveStackGroupEffectivePositions(group, pageChildren, options) {
475
475
  const mode = group.layoutMode ?? "absolute";
476
476
  if (!isStackLayoutMode(mode)) return /* @__PURE__ */ new Map();
477
477
  const gap = group.stackSpacing ?? 8;
478
+ const padTop = group.paddingTop ?? 0;
479
+ const padLeft = group.paddingLeft ?? 0;
478
480
  const kids = group.children ?? [];
479
481
  const out = /* @__PURE__ */ new Map();
480
482
  if (isVerticalStackLayoutMode(mode)) {
481
- let prevBottom = 0;
483
+ let prevBottom = padTop;
484
+ let firstSeen = false;
482
485
  for (let i = 0; i < kids.length; i++) {
483
486
  const child = kids[i];
484
487
  const storedTop = getNodeTop(child);
485
488
  const storedLeft = getNodeLeft(child);
486
- const effectiveTop = i === 0 ? storedTop : prevBottom + gap + storedTop;
487
- out.set(child.id, { top: effectiveTop, left: storedLeft });
489
+ const mTop = child.marginTop ?? 0;
490
+ const mLeft = child.marginLeft ?? 0;
491
+ const effectiveTop = !firstSeen ? padTop + storedTop + mTop : prevBottom + gap + storedTop + mTop;
492
+ firstSeen = true;
493
+ out.set(child.id, { top: effectiveTop, left: padLeft + storedLeft + mLeft });
488
494
  const h = getNodeBounds(child, pageChildren).height;
489
- prevBottom = effectiveTop + h;
495
+ prevBottom = effectiveTop + h + (child.marginBottom ?? 0);
490
496
  }
491
497
  } else {
492
- let prevRight = 0;
498
+ let prevRight = padLeft;
499
+ let firstSeen = false;
493
500
  for (let i = 0; i < kids.length; i++) {
494
501
  const child = kids[i];
495
502
  const storedLeft = getNodeLeft(child);
496
503
  const storedTop = getNodeTop(child);
497
- const effectiveLeft = i === 0 ? storedLeft : prevRight + gap + storedLeft;
498
- out.set(child.id, { top: storedTop, left: effectiveLeft });
504
+ const mTop = child.marginTop ?? 0;
505
+ const mLeft = child.marginLeft ?? 0;
506
+ const effectiveLeft = !firstSeen ? padLeft + storedLeft + mLeft : prevRight + gap + storedLeft + mLeft;
507
+ firstSeen = true;
508
+ out.set(child.id, { top: padTop + storedTop + mTop, left: effectiveLeft });
499
509
  const w = getNodeBounds(child, pageChildren).width;
500
- prevRight = effectiveLeft + w;
510
+ prevRight = effectiveLeft + w + (child.marginRight ?? 0);
501
511
  }
502
512
  }
503
513
  return out;
@@ -522,6 +532,14 @@ function groupBoundsFromChildren(group, pageChildren, options) {
522
532
  maxX = Math.max(maxX, cl + b.width);
523
533
  maxY = Math.max(maxY, ct + b.height);
524
534
  }
535
+ if (isStack) {
536
+ const padRight = group.paddingRight ?? 0;
537
+ const padBottom = group.paddingBottom ?? 0;
538
+ return {
539
+ width: Math.max(1, maxX + padRight),
540
+ height: Math.max(1, maxY + padBottom)
541
+ };
542
+ }
525
543
  return {
526
544
  width: Math.max(1, maxX - minX),
527
545
  height: Math.max(1, maxY - minY)
@@ -584,7 +602,7 @@ function absoluteToStorePosition(absoluteLeft, absoluteTop, nodeId, pageChildren
584
602
  const prev = kids[idx - 1];
585
603
  const prevResolved = resolved.get(prev.id);
586
604
  const prevHeight = getNodeBounds(prev, pageChildren).height;
587
- const prevBottom = prevResolved ? prevResolved.top + prevHeight : 0;
605
+ const prevBottom = prevResolved ? prevResolved.top + prevHeight + (prev.marginBottom ?? 0) : 0;
588
606
  const storeTop = inParentTop - prevBottom - gap;
589
607
  return { left: storeLeft, top: Math.max(0, storeTop) };
590
608
  }
@@ -606,7 +624,7 @@ function reflowStackGroup(group, pageChildren, spacing) {
606
624
  const b = getNodeBounds(child, pageChildren);
607
625
  const currentTop = getNodeTop(child);
608
626
  const effectiveTop = i === 0 ? currentTop : prevBottom + gap;
609
- prevBottom = effectiveTop + b.height;
627
+ prevBottom = effectiveTop + b.height + (child.marginBottom ?? 0);
610
628
  if (i > 0) updates.set(child.id, { top: 0, left: firstLeft });
611
629
  }
612
630
  } else {
@@ -617,7 +635,7 @@ function reflowStackGroup(group, pageChildren, spacing) {
617
635
  const b = getNodeBounds(child, pageChildren);
618
636
  const currentLeft = getNodeLeft(child);
619
637
  const effectiveLeft = i === 0 ? currentLeft : prevRight + gap;
620
- prevRight = effectiveLeft + b.width;
638
+ prevRight = effectiveLeft + b.width + (child.marginRight ?? 0);
621
639
  if (i > 0) updates.set(child.id, { left: 0, top: firstTop });
622
640
  }
623
641
  }
@@ -769,7 +787,8 @@ const cloneCanvas = (canvas) => ({
769
787
  themeConfig: canvas.themeConfig ? {
770
788
  properties: canvas.themeConfig.properties.map((p) => ({ ...p })),
771
789
  variants: canvas.themeConfig.variants.map((v) => ({ ...v, values: { ...v.values } }))
772
- } : void 0
790
+ } : void 0,
791
+ pdfTextMode: canvas.pdfTextMode
773
792
  });
774
793
  const sameIdSet = (a, b) => {
775
794
  if (a.length !== b.length) return false;
@@ -1249,6 +1268,12 @@ const useEditorStore = create((set, get) => ({
1249
1268
  const committed = commitFromState(state, nextCanvas);
1250
1269
  return { canvas: nextCanvas, ...committed };
1251
1270
  }),
1271
+ setPdfTextMode: (mode) => set((state) => {
1272
+ if (state.canvas.pdfTextMode === mode) return {};
1273
+ const nextCanvas = { ...state.canvas, pdfTextMode: mode };
1274
+ const committed = commitFromState(state, nextCanvas);
1275
+ return { canvas: nextCanvas, ...committed };
1276
+ }),
1252
1277
  setZoom: (zoom) => set((state) => ({
1253
1278
  canvas: { ...state.canvas, zoom: Math.max(0.1, Math.min(10, zoom)) }
1254
1279
  })),
@@ -1652,7 +1677,7 @@ const useEditorStore = create((set, get) => ({
1652
1677
  const themeConfig = state.canvas.themeConfig ?? createEmptyThemeConfig();
1653
1678
  if (themeConfig.properties.some((p) => p.id === property.id)) return {};
1654
1679
  const updatedProperties = [...themeConfig.properties, property];
1655
- const updatedVariants = themeConfig.variants.map(
1680
+ const updatedVariants = property.linkedTo ? themeConfig.variants : themeConfig.variants.map(
1656
1681
  (v) => v.isDefault ? { ...v, values: { ...v.values, [property.id]: currentValue } } : v
1657
1682
  );
1658
1683
  const nextCanvas = {
@@ -1678,9 +1703,17 @@ const useEditorStore = create((set, get) => ({
1678
1703
  removeThemeProperty: (propertyId) => set((state) => {
1679
1704
  const themeConfig = state.canvas.themeConfig;
1680
1705
  if (!themeConfig) return {};
1681
- const updatedProperties = themeConfig.properties.filter((p) => p.id !== propertyId);
1706
+ const linkedChildren = themeConfig.properties.filter((p) => p.linkedTo === propertyId);
1707
+ const updatedProperties = themeConfig.properties.filter((p) => p.id !== propertyId).map((p) => p.linkedTo === propertyId ? { ...p, linkedTo: void 0 } : p);
1682
1708
  const updatedVariants = themeConfig.variants.map((v) => {
1683
- const { [propertyId]: _, ...rest } = v.values;
1709
+ const { [propertyId]: removedValue, ...rest } = v.values;
1710
+ if (linkedChildren.length && removedValue !== void 0) {
1711
+ const seeded = { ...rest };
1712
+ for (const child of linkedChildren) {
1713
+ if (seeded[child.id] === void 0) seeded[child.id] = removedValue;
1714
+ }
1715
+ return { ...v, values: seeded };
1716
+ }
1684
1717
  return { ...v, values: rest };
1685
1718
  });
1686
1719
  const nextCanvas = {
@@ -1754,7 +1787,7 @@ const useEditorStore = create((set, get) => ({
1754
1787
  const PAGE_BG_ID = "__pageBackground__";
1755
1788
  let updatedPages = [...state.canvas.pages];
1756
1789
  for (const prop of themeConfig.properties) {
1757
- const value = variant.values[prop.id];
1790
+ const value = variant.values[prop.linkedTo ?? prop.id];
1758
1791
  if (value === void 0) continue;
1759
1792
  if (prop.elementId === PAGE_BG_ID) {
1760
1793
  if (prop.targetProperty === "backgroundColor") {
@@ -1977,19 +2010,7 @@ const useEditorStore = create((set, get) => ({
1977
2010
  } else {
1978
2011
  newCollapsedSet.add(groupId);
1979
2012
  }
1980
- const currentPage = getCurrentPageFromCanvas(state.canvas);
1981
- let nextCanvas = state.canvas;
1982
- const group = findNodeById(currentPage.children, groupId);
1983
- if (group && isGroup(group)) {
1984
- nextCanvas = updateCurrentPageChildren(
1985
- nextCanvas,
1986
- (children) => updateNodeInTree(children, groupId, { collapsed: !isCollapsed })
1987
- );
1988
- }
1989
- return {
1990
- collapsedGroups: newCollapsedSet,
1991
- canvas: nextCanvas
1992
- };
2013
+ return { collapsedGroups: newCollapsedSet };
1993
2014
  }),
1994
2015
  // Convenience aliases
1995
2016
  groupElements: (ids, name) => get().groupNodes(ids, name),
@@ -2436,7 +2457,8 @@ const useEditorStore = create((set, get) => ({
2436
2457
  formBindingMode: config.formBindingMode,
2437
2458
  boundFormDefId: config.boundFormDefId,
2438
2459
  boundFormDefName: config.boundFormDefName,
2439
- themeConfig: config.themeConfig ?? void 0
2460
+ themeConfig: config.themeConfig ?? void 0,
2461
+ pdfTextMode: config.pdfTextMode ?? "selectable"
2440
2462
  };
2441
2463
  const committed = commitFromState(state, nextCanvas);
2442
2464
  const out = {
@@ -4903,7 +4925,9 @@ function extractTextBgConfig(element) {
4903
4925
  if (!Number.isFinite(n)) return void 0;
4904
4926
  return Math.max(0, Math.min(1, n));
4905
4927
  })(),
4906
- shadowAffectsBg: element.textShadowAffectsBg !== false
4928
+ shadowAffectsBg: element.textShadowAffectsBg !== false,
4929
+ shadowAffectsText: element.textShadowAffectsText !== false,
4930
+ fitToText: element.textBgFitToText === true
4907
4931
  };
4908
4932
  }
4909
4933
  function hasTextBackground(cfg) {
@@ -4959,10 +4983,6 @@ function applyTextBackground(obj, cfg) {
4959
4983
  const pR = Math.max(0, Number(bg.padRight ?? 0));
4960
4984
  const pB = Math.max(0, Number(bg.padBottom ?? 0));
4961
4985
  const pL = Math.max(0, Number(bg.padLeft ?? 0));
4962
- const x = -w / 2 - pL;
4963
- const y = -h / 2 - pT;
4964
- const bgW = w + pL + pR;
4965
- const bgH = h + pT + pB;
4966
4986
  ctx.save();
4967
4987
  const suppressShadowOnBg = bg.shadowAffectsBg === false;
4968
4988
  if (suppressShadowOnBg) {
@@ -4971,24 +4991,38 @@ function applyTextBackground(obj, cfg) {
4971
4991
  ctx.shadowOffsetX = 0;
4972
4992
  ctx.shadowOffsetY = 0;
4973
4993
  }
4974
- buildRoundedRectPath2D(
4975
- ctx,
4976
- x,
4977
- y,
4978
- bgW,
4979
- bgH,
4980
- bg.rxTL ?? 0,
4981
- bg.rxTR ?? 0,
4982
- bg.rxBR ?? 0,
4983
- bg.rxBL ?? 0
4984
- );
4985
4994
  const op = typeof bg.opacity === "number" ? Math.max(0, Math.min(1, bg.opacity)) : 1;
4986
4995
  if (op < 1) ctx.globalAlpha = (ctx.globalAlpha ?? 1) * op;
4987
4996
  ctx.fillStyle = bg.color;
4988
- ctx.fill();
4997
+ const rects = computeBgRects(this, w, h, pT, pR, pB, pL, !!bg.fitToText);
4998
+ for (const r of rects) {
4999
+ buildRoundedRectPath2D(
5000
+ ctx,
5001
+ r.x,
5002
+ r.y,
5003
+ r.w,
5004
+ r.h,
5005
+ bg.rxTL ?? 0,
5006
+ bg.rxTR ?? 0,
5007
+ bg.rxBR ?? 0,
5008
+ bg.rxBL ?? 0
5009
+ );
5010
+ ctx.fill();
5011
+ }
5012
+ ctx.restore();
5013
+ }
5014
+ const suppressShadowOnText = bg && bg.shadowAffectsText === false;
5015
+ if (suppressShadowOnText) {
5016
+ ctx.save();
5017
+ ctx.shadowColor = "transparent";
5018
+ ctx.shadowBlur = 0;
5019
+ ctx.shadowOffsetX = 0;
5020
+ ctx.shadowOffsetY = 0;
5021
+ originalRender(ctx);
4989
5022
  ctx.restore();
5023
+ } else {
5024
+ originalRender(ctx);
4990
5025
  }
4991
- originalRender(ctx);
4992
5026
  };
4993
5027
  const originalToObject = obj.toObject.bind(obj);
4994
5028
  obj.toObject = function(propertiesToInclude) {
@@ -5014,20 +5048,18 @@ function applyTextBackground(obj, cfg) {
5014
5048
  const pR = Math.max(0, Number((bg == null ? void 0 : bg.padRight) ?? 0));
5015
5049
  const pB = Math.max(0, Number((bg == null ? void 0 : bg.padBottom) ?? 0));
5016
5050
  const pL = Math.max(0, Number((bg == null ? void 0 : bg.padLeft) ?? 0));
5017
- const x = -w / 2 - pL;
5018
- const y = -h / 2 - pT;
5019
- const bgW = w + pL + pR;
5020
- const bgH = h + pT + pB;
5021
- const bgD = buildRoundedRectPathD(
5022
- x,
5023
- y,
5024
- bgW,
5025
- bgH,
5051
+ const fit = !!(bg == null ? void 0 : bg.fitToText);
5052
+ const rects = computeBgRects(this, w, h, pT, pR, pB, pL, fit);
5053
+ const bgD = rects.map((r) => buildRoundedRectPathD(
5054
+ r.x,
5055
+ r.y,
5056
+ r.w,
5057
+ r.h,
5026
5058
  (bg == null ? void 0 : bg.rxTL) ?? 0,
5027
5059
  (bg == null ? void 0 : bg.rxTR) ?? 0,
5028
5060
  (bg == null ? void 0 : bg.rxBR) ?? 0,
5029
5061
  (bg == null ? void 0 : bg.rxBL) ?? 0
5030
- );
5062
+ )).join(" ");
5031
5063
  const bgFill = (bg == null ? void 0 : bg.color) || "";
5032
5064
  const bgOpacity = typeof (bg == null ? void 0 : bg.opacity) === "number" ? Math.max(0, Math.min(1, bg.opacity)) : 1;
5033
5065
  const bgOpacityAttr = bgOpacity < 1 ? ` fill-opacity="${bgOpacity}"` : "";
@@ -5052,9 +5084,11 @@ function applyTextBackground(obj, cfg) {
5052
5084
  const shadowBgPath = `<path d="${bgD}" fill="${escapeXmlAttr(shadowColor)}" />`;
5053
5085
  bgShadowMarker = wrapShadow(shadowBgPath);
5054
5086
  }
5055
- const inner = extractGInnerMarkup(svg);
5056
- const recoloredText = recolorSvgFills(inner, shadowColor);
5057
- if (recoloredText) textShadowMarker = wrapShadow(recoloredText);
5087
+ if ((bg == null ? void 0 : bg.shadowAffectsText) !== false) {
5088
+ const inner = extractGInnerMarkup(svg);
5089
+ const recoloredText = recolorSvgFills(inner, shadowColor);
5090
+ if (recoloredText) textShadowMarker = wrapShadow(recoloredText);
5091
+ }
5058
5092
  }
5059
5093
  const openTagMatch = svg.match(/^\s*<g\b[^>]*>/);
5060
5094
  const inserted = bgShadowMarker + bgPath + textShadowMarker;
@@ -5105,6 +5139,74 @@ function buildRoundedRectPathD(x, y, w, h, rTL, rTR, rBR, rBL) {
5105
5139
  parts.push("Z");
5106
5140
  return parts.join(" ");
5107
5141
  }
5142
+ function computeBgRects(obj, w, h, pT, pR, pB, pL, fit) {
5143
+ var _a;
5144
+ if (!fit) {
5145
+ return [{
5146
+ x: -w / 2 - pL,
5147
+ y: -h / 2 - pT,
5148
+ w: w + pL + pR,
5149
+ h: h + pT + pB
5150
+ }];
5151
+ }
5152
+ const lines = (obj == null ? void 0 : obj._textLines) ?? [];
5153
+ if (!lines || lines.length === 0) {
5154
+ return [{
5155
+ x: -w / 2 - pL,
5156
+ y: -h / 2 - pT,
5157
+ w: w + pL + pR,
5158
+ h: h + pT + pB
5159
+ }];
5160
+ }
5161
+ const rects = [];
5162
+ const halfW = w / 2;
5163
+ const halfH = h / 2;
5164
+ const lineHeightRatio = Math.max(0.01, Number((obj == null ? void 0 : obj.lineHeight) ?? 1) || 1);
5165
+ let cursorY = -halfH;
5166
+ for (let i = 0; i < lines.length; i++) {
5167
+ let lineW = 0;
5168
+ let lineLeft = 0;
5169
+ let lineH = 0;
5170
+ try {
5171
+ lineW = obj.getLineWidth(i) || 0;
5172
+ } catch {
5173
+ lineW = 0;
5174
+ }
5175
+ try {
5176
+ lineLeft = ((_a = obj._getLineLeftOffset) == null ? void 0 : _a.call(obj, i)) ?? 0;
5177
+ } catch {
5178
+ lineLeft = 0;
5179
+ }
5180
+ try {
5181
+ lineH = obj.getHeightOfLine(i) || 0;
5182
+ } catch {
5183
+ lineH = 0;
5184
+ }
5185
+ const rawSlotH = i === lines.length - 1 ? lineH / lineHeightRatio : lineH;
5186
+ const usedH = cursorY + halfH;
5187
+ const slotH = Math.max(0, Math.min(rawSlotH, h - usedH));
5188
+ if (lineW <= 0 || slotH <= 0) {
5189
+ cursorY += slotH;
5190
+ continue;
5191
+ }
5192
+ rects.push({
5193
+ x: -halfW + lineLeft - pL,
5194
+ y: cursorY - pT,
5195
+ w: lineW + pL + pR,
5196
+ h: slotH + pT + pB
5197
+ });
5198
+ cursorY += slotH;
5199
+ }
5200
+ if (rects.length === 0) {
5201
+ return [{
5202
+ x: -w / 2 - pL,
5203
+ y: -h / 2 - pT,
5204
+ w: w + pL + pR,
5205
+ h: h + pT + pB
5206
+ }];
5207
+ }
5208
+ return rects;
5209
+ }
5108
5210
  function escapeXmlAttr(s) {
5109
5211
  return String(s).replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
5110
5212
  }
@@ -8124,10 +8226,14 @@ const PageCanvas = forwardRef(
8124
8226
  tr: element.textBgRxTR ?? 0,
8125
8227
  br: element.textBgRxBR ?? 0,
8126
8228
  bl: element.textBgRxBL ?? 0,
8229
+ ft: element.textBgFitToText === true,
8230
+ bo: element.textBgOpacity ?? 1,
8127
8231
  sc: element.textShadowColor ?? null,
8128
8232
  sb: element.textShadowBlur ?? 0,
8129
8233
  sx: element.textShadowOffsetX ?? 0,
8130
- sy: element.textShadowOffsetY ?? 0
8234
+ sy: element.textShadowOffsetY ?? 0,
8235
+ st: element.textShadowAffectsText !== false,
8236
+ sa: element.textShadowAffectsBg !== false
8131
8237
  }) !== (existingObj.__lastTextBgShadowJson ?? "") || // CRITICAL: Detect gradient fill/stroke changes — serialise to JSON for deep comparison
8132
8238
  JSON.stringify(element.fillGradient || null) !== (existingObj.__lastFillGradientJson ?? "null") || JSON.stringify(element.strokeGradient || null) !== (existingObj.__lastStrokeGradientJson ?? "null");
8133
8239
  const forceApplyFromPanel = syncTriggeredByPanelRef.current;
@@ -9041,10 +9147,14 @@ const PageCanvas = forwardRef(
9041
9147
  tr: element.textBgRxTR ?? 0,
9042
9148
  br: element.textBgRxBR ?? 0,
9043
9149
  bl: element.textBgRxBL ?? 0,
9150
+ ft: element.textBgFitToText === true,
9151
+ bo: element.textBgOpacity ?? 1,
9044
9152
  sc: element.textShadowColor ?? null,
9045
9153
  sb: element.textShadowBlur ?? 0,
9046
9154
  sx: element.textShadowOffsetX ?? 0,
9047
- sy: element.textShadowOffsetY ?? 0
9155
+ sy: element.textShadowOffsetY ?? 0,
9156
+ st: element.textShadowAffectsText !== false,
9157
+ sa: element.textShadowAffectsBg !== false
9048
9158
  });
9049
9159
  obj.dirty = true;
9050
9160
  } catch (err) {
@@ -10167,7 +10277,8 @@ function formDefSectionsToInferred(schemaSections, repeatableNodeMap) {
10167
10277
  })),
10168
10278
  // Honor minEntries: 0 — start with no entries, user adds via "+ Add" button.
10169
10279
  initialEntryCount: minEntries,
10170
- parentId
10280
+ parentId,
10281
+ entryNameFieldKey: def.entryNameFieldKey
10171
10282
  };
10172
10283
  if (treeNodeId) section.treeNodeId = treeNodeId;
10173
10284
  sections.push(section);
@@ -10612,6 +10723,26 @@ function baseId(id) {
10612
10723
  const REPEATABLE_KEY_REGEX = /^field_(.+)_(\d+)_(.+)$/;
10613
10724
  const NESTED_REPEATABLE_KEY_REGEX = /^field_(.+)_(\d+)_field_(.+)_(\d+)_(.+)$/;
10614
10725
  const FORMDEF_CANONICAL_KEY_REGEX = /^field_.+_N_.+$/;
10726
+ function parseEntryRange(range, max) {
10727
+ if (!range || !range.trim()) return null;
10728
+ const out = /* @__PURE__ */ new Set();
10729
+ for (const partRaw of range.split(",")) {
10730
+ const part = partRaw.trim();
10731
+ if (!part) continue;
10732
+ if (/^\d+$/.test(part)) {
10733
+ const n = parseInt(part, 10);
10734
+ if (n >= 1 && n <= max) out.add(n);
10735
+ continue;
10736
+ }
10737
+ const m = /^(\d*)\s*-\s*(\d*)$/.exec(part);
10738
+ if (!m) continue;
10739
+ const start = m[1] === "" ? 1 : Math.max(1, parseInt(m[1], 10));
10740
+ const end = m[2] === "" ? max : Math.min(max, parseInt(m[2], 10));
10741
+ for (let i = start; i <= end; i++) out.add(i);
10742
+ }
10743
+ if (out.size === 0) return null;
10744
+ return Array.from(out).sort((a, b) => a - b);
10745
+ }
10615
10746
  function applyTextCase(text, textCase) {
10616
10747
  if (!textCase || textCase === "none") return text;
10617
10748
  switch (textCase) {
@@ -10690,13 +10821,19 @@ function findElementBySourceIdInSubtree(nodes, sourceId) {
10690
10821
  }
10691
10822
  return void 0;
10692
10823
  }
10693
- function findRepeatableElementBySourceId(pages, baseNodeId, oneBasedIndex, sourceElementId) {
10824
+ function findAllRepeatableElementsBySourceId(pages, baseNodeId, oneBasedIndex, sourceElementId, expectedEntriesPerOccurrence) {
10694
10825
  var _a;
10695
10826
  const groups = collectGroupsByBaseId(pages, baseNodeId);
10696
- const group = groups[oneBasedIndex - 1];
10697
- if (!group) return void 0;
10698
- if (!isGroup(group) || !((_a = group.children) == null ? void 0 : _a.length)) return void 0;
10699
- return findElementBySourceIdInSubtree(group.children, sourceElementId) ?? (group.__sourceId === sourceElementId ? group.id : void 0);
10827
+ if (!groups.length) return [];
10828
+ const N = Math.max(1, expectedEntriesPerOccurrence ?? groups.length);
10829
+ const out = [];
10830
+ for (let occStart = 0; occStart < groups.length; occStart += N) {
10831
+ const group = groups[occStart + (oneBasedIndex - 1)];
10832
+ if (!group || !isGroup(group) || !((_a = group.children) == null ? void 0 : _a.length)) continue;
10833
+ const found = findElementBySourceIdInSubtree(group.children, sourceElementId) ?? (group.__sourceId === sourceElementId ? group.id : void 0);
10834
+ if (found) out.push(found);
10835
+ }
10836
+ return out;
10700
10837
  }
10701
10838
  function findNestedRepeatableElementBySourceId(pages, parentBaseNodeId, parentPi, childBaseNodeId, childCi, sourceElementId) {
10702
10839
  var _a, _b;
@@ -10717,6 +10854,24 @@ function findNestedRepeatableElementBySourceId(pages, parentBaseNodeId, parentPi
10717
10854
  if (!childGroup || !isGroup(childGroup) || !((_b = childGroup.children) == null ? void 0 : _b.length)) return void 0;
10718
10855
  return findElementBySourceIdInSubtree(childGroup.children, sourceElementId) ?? (childGroup.__sourceId === sourceElementId ? childGroup.id : void 0);
10719
10856
  }
10857
+ function repeatableLabelKey(label) {
10858
+ return String(label ?? "").trim().toLowerCase();
10859
+ }
10860
+ function repeatableLabelSlug(label) {
10861
+ return repeatableLabelKey(label).replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
10862
+ }
10863
+ function addToSetMap(map, key, value) {
10864
+ if (!key || !value) return;
10865
+ const set = map.get(key);
10866
+ if (set) set.add(value);
10867
+ else map.set(key, /* @__PURE__ */ new Set([value]));
10868
+ }
10869
+ function getFieldKeyAliases(fieldId) {
10870
+ const aliases = /* @__PURE__ */ new Set([fieldId]);
10871
+ const canonicalParts = fieldId.split("_N_");
10872
+ if (canonicalParts.length > 1) aliases.add(canonicalParts[canonicalParts.length - 1]);
10873
+ return Array.from(aliases).filter(Boolean);
10874
+ }
10720
10875
  function idPrefix(node) {
10721
10876
  if (isGroup(node)) return "group";
10722
10877
  const t = node.type;
@@ -10770,7 +10925,7 @@ function findRepeatableByNodeIds(pages, nodeIds) {
10770
10925
  var _a2;
10771
10926
  return !!((_a2 = n.repeatableSection) == null ? void 0 : _a2.label);
10772
10927
  };
10773
- function walk(children, parentRepeatableBaseId, parentInfo) {
10928
+ function walk(children, parentRepeatableBaseId, parentInfo, parentRepeatableEntryIndex) {
10774
10929
  var _a2, _b;
10775
10930
  if (!Array.isArray(children)) return;
10776
10931
  for (let i = 0; i < children.length; i++) {
@@ -10784,7 +10939,7 @@ function findRepeatableByNodeIds(pages, nodeIds) {
10784
10939
  const childBaseFromMeta = child.__baseNodeId;
10785
10940
  const isMatch = schemaBaseIds.has(child.id) || schemaBaseIds.has(childBase) || childBaseFromMeta != null && schemaBaseIds.has(childBaseFromMeta);
10786
10941
  if (!isMatch) {
10787
- if (isGroup(child) && Array.isArray(child.children)) walk(child.children, parentRepeatableBaseId);
10942
+ if (isGroup(child) && Array.isArray(child.children)) walk(child.children, parentRepeatableBaseId, void 0, parentRepeatableEntryIndex);
10788
10943
  j++;
10789
10944
  continue;
10790
10945
  }
@@ -10807,17 +10962,22 @@ function findRepeatableByNodeIds(pages, nodeIds) {
10807
10962
  count,
10808
10963
  node: child,
10809
10964
  baseNodeId: childBaseFromMeta ?? childBase,
10810
- parentBaseNodeId: parentRepeatableBaseId
10965
+ parentBaseNodeId: parentRepeatableBaseId,
10966
+ parentEntryIndex: parentRepeatableEntryIndex
10811
10967
  });
10812
- if (isGroup(child) && Array.isArray(child.children)) walk(child.children, childBase);
10968
+ const childEntryIndex = child.__repeatableEntryIndex;
10969
+ if (isGroup(child) && Array.isArray(child.children)) walk(child.children, effectiveChildBase, void 0, childEntryIndex);
10813
10970
  j += count;
10814
10971
  }
10815
10972
  } else if (isGroup(node) && ((_b = node.children) == null ? void 0 : _b.length)) {
10816
10973
  const nodeBase = baseId(node.id);
10817
10974
  const selfMatch = schemaBaseIds.has(node.id) || schemaBaseIds.has(nodeBase) || node.__baseNodeId != null && schemaBaseIds.has(node.__baseNodeId);
10818
- if (selfMatch && hasRepeatableSection(node)) {
10975
+ const isSelfRepeatable = selfMatch && hasRepeatableSection(node);
10976
+ let matchedSelfBase;
10977
+ if (selfMatch) matchedSelfBase = node.__baseNodeId ?? nodeBase;
10978
+ if (isSelfRepeatable) {
10819
10979
  let count = 1;
10820
- const effectiveBase = node.__baseNodeId ?? nodeBase;
10980
+ const effectiveBase = matchedSelfBase ?? nodeBase;
10821
10981
  if (node.id !== nodeBase && node.id !== effectiveBase) {
10822
10982
  while (i + count < children.length) {
10823
10983
  const next = children[i + count];
@@ -10834,10 +10994,12 @@ function findRepeatableByNodeIds(pages, nodeIds) {
10834
10994
  count,
10835
10995
  node,
10836
10996
  baseNodeId: effectiveBase,
10837
- parentBaseNodeId: parentRepeatableBaseId
10997
+ parentBaseNodeId: parentRepeatableBaseId,
10998
+ parentEntryIndex: parentRepeatableEntryIndex
10838
10999
  });
10839
11000
  }
10840
- walk(node.children, parentRepeatableBaseId);
11001
+ const nodeEntryIndex = node.__repeatableEntryIndex;
11002
+ walk(node.children, matchedSelfBase ?? parentRepeatableBaseId, void 0, nodeEntryIndex ?? parentRepeatableEntryIndex);
10841
11003
  }
10842
11004
  }
10843
11005
  }
@@ -10896,7 +11058,7 @@ function getNestedRepeatableEntryCount(parentId, parentIndex, childId, formValue
10896
11058
  return Math.max(1, maxIndex);
10897
11059
  }
10898
11060
  function applyFormDataToConfig(config, mappings, formValues, repeatableSectionsFromSchema, repeatableEntryCounts, repeatableNestedEntryCounts, displayFormatMap, repeatablePagesFromSchema) {
10899
- var _a, _b, _c, _d, _e, _f;
11061
+ var _a, _b, _c;
10900
11062
  const cloned = JSON.parse(JSON.stringify(config));
10901
11063
  if (!cloned.pages) return cloned;
10902
11064
  const dynamicFields = cloned.dynamicFields;
@@ -10946,17 +11108,56 @@ function applyFormDataToConfig(config, mappings, formValues, repeatableSectionsF
10946
11108
  }
10947
11109
  const repeatableList = (repeatableSectionsFromSchema == null ? void 0 : repeatableSectionsFromSchema.length) ? repeatableSectionsFromSchema : getRepeatableFromConfig(pages);
10948
11110
  const nodeIds = repeatableList.map((r) => r.nodeId);
11111
+ const repeatableBasesByLabel = /* @__PURE__ */ new Map();
11112
+ for (const r of repeatableList) {
11113
+ const base = baseId(r.nodeId);
11114
+ addToSetMap(repeatableBasesByLabel, repeatableLabelKey(r.label), base);
11115
+ addToSetMap(repeatableBasesByLabel, repeatableLabelSlug(r.label), base);
11116
+ }
11117
+ const repeatableTokenToBaseIds = /* @__PURE__ */ new Map();
11118
+ for (const r of repeatableList) {
11119
+ const base = baseId(r.nodeId);
11120
+ const labelBases = /* @__PURE__ */ new Set([
11121
+ base,
11122
+ ...repeatableBasesByLabel.get(repeatableLabelKey(r.label)) ?? [],
11123
+ ...repeatableBasesByLabel.get(repeatableLabelSlug(r.label)) ?? []
11124
+ ]);
11125
+ for (const targetBase of labelBases) {
11126
+ addToSetMap(repeatableTokenToBaseIds, base, targetBase);
11127
+ addToSetMap(repeatableTokenToBaseIds, r.nodeId, targetBase);
11128
+ addToSetMap(repeatableTokenToBaseIds, repeatableLabelKey(r.label), targetBase);
11129
+ addToSetMap(repeatableTokenToBaseIds, repeatableLabelSlug(r.label), targetBase);
11130
+ }
11131
+ }
11132
+ const getRepeatableBaseIdsForToken = (token) => {
11133
+ const direct = repeatableTokenToBaseIds.get(token) ?? repeatableTokenToBaseIds.get(baseId(token));
11134
+ return direct ? Array.from(direct) : [baseId(token)];
11135
+ };
10949
11136
  const entryCountFromList = (baseNodeId) => {
10950
11137
  const item = repeatableList.find((r) => baseId(r.nodeId) === baseNodeId || r.nodeId === baseNodeId);
10951
11138
  return item == null ? void 0 : item.entryCount;
10952
11139
  };
11140
+ const entryFilterFromList = (baseNodeId) => {
11141
+ var _a2;
11142
+ const item = repeatableList.find((r) => baseId(r.nodeId) === baseNodeId || r.nodeId === baseNodeId);
11143
+ const filter = item == null ? void 0 : item.entryFilter;
11144
+ return (filter == null ? void 0 : filter.mode) === "range" && ((_a2 = filter.range) == null ? void 0 : _a2.trim()) ? filter : void 0;
11145
+ };
10953
11146
  const resolvedIdMap = /* @__PURE__ */ new Map();
11147
+ const addResolved = (key, id) => {
11148
+ const arr = resolvedIdMap.get(key);
11149
+ if (arr) {
11150
+ if (!arr.includes(id)) arr.push(id);
11151
+ } else resolvedIdMap.set(key, [id]);
11152
+ };
10954
11153
  const mappedNewIds = /* @__PURE__ */ new Set();
10955
11154
  const elementIdToFieldId = /* @__PURE__ */ new Map();
10956
11155
  if (dynamicFields == null ? void 0 : dynamicFields.length) {
10957
11156
  for (const f of dynamicFields) {
10958
- const elId = (_c = (_b = f.mappings) == null ? void 0 : _b[0]) == null ? void 0 : _c.elementId;
10959
- if (elId) elementIdToFieldId.set(elId, f.id);
11157
+ for (const m of f.mappings ?? []) {
11158
+ const elId = m == null ? void 0 : m.elementId;
11159
+ if (elId) elementIdToFieldId.set(elId, f.id);
11160
+ }
10960
11161
  }
10961
11162
  }
10962
11163
  const repeatableInfosFirst = findRepeatableByNodeIds(pages, nodeIds);
@@ -10969,37 +11170,90 @@ function applyFormDataToConfig(config, mappings, formValues, repeatableSectionsF
10969
11170
  for (const r of nestedFirst) {
10970
11171
  if (r.parentBaseNodeId) nestedChildToParent.set(r.baseNodeId, r.parentBaseNodeId);
10971
11172
  }
11173
+ const getNestedBasePairs = (parentToken, childToken) => {
11174
+ const pairs = [];
11175
+ const seen = /* @__PURE__ */ new Set();
11176
+ for (const parentBaseId of getRepeatableBaseIdsForToken(parentToken)) {
11177
+ for (const childBaseId of getRepeatableBaseIdsForToken(childToken)) {
11178
+ const key = `${parentBaseId}::${childBaseId}`;
11179
+ if (seen.has(key)) continue;
11180
+ seen.add(key);
11181
+ pairs.push({ parentBaseId, childBaseId });
11182
+ }
11183
+ }
11184
+ return pairs.length ? pairs : [{ parentBaseId: baseId(parentToken), childBaseId: baseId(childToken) }];
11185
+ };
11186
+ const getNestedCountForBasePair = (parentBaseNodeId, parentIndex1Based, childBaseNodeId) => {
11187
+ let maxCount = 0;
11188
+ for (const { parentBaseId, childBaseId } of getNestedBasePairs(parentBaseNodeId, childBaseNodeId)) {
11189
+ const aliasKey = `${parentBaseId}_${parentIndex1Based}_${childBaseId}`;
11190
+ maxCount = Math.max(
11191
+ maxCount,
11192
+ (repeatableNestedEntryCounts == null ? void 0 : repeatableNestedEntryCounts[aliasKey]) ?? 0,
11193
+ getNestedRepeatableEntryCount(parentBaseId, parentIndex1Based, childBaseId, formValues)
11194
+ );
11195
+ }
11196
+ return Math.max(1, maxCount);
11197
+ };
10972
11198
  const phase1NewToOriginal = /* @__PURE__ */ new Map();
10973
- const topLevelByBase = /* @__PURE__ */ new Map();
11199
+ const entryCountByBase = /* @__PURE__ */ new Map();
11200
+ [...topLevel].sort((a, b) => {
11201
+ if (a.parentChildren !== b.parentChildren) return 0;
11202
+ return b.startIndex - a.startIndex;
11203
+ });
11204
+ const occByParent = /* @__PURE__ */ new Map();
10974
11205
  for (const r of topLevel) {
10975
- if (!topLevelByBase.has(r.baseNodeId)) topLevelByBase.set(r.baseNodeId, []);
10976
- topLevelByBase.get(r.baseNodeId).push(r);
10977
- }
10978
- for (const [, blocks] of topLevelByBase) {
10979
- const first = blocks[0];
10980
- const startIndex = Math.min(...blocks.map((b) => b.startIndex));
10981
- const endIndex = Math.max(...blocks.map((b) => b.startIndex + b.count));
10982
- const count = endIndex - startIndex;
10983
- const { parentChildren, node, baseNodeId } = first;
11206
+ if (!occByParent.has(r.parentChildren)) occByParent.set(r.parentChildren, []);
11207
+ occByParent.get(r.parentChildren).push(r);
11208
+ }
11209
+ const computeN = (baseNodeId, sampleNodeId) => {
11210
+ if (entryCountByBase.has(baseNodeId)) return entryCountByBase.get(baseNodeId);
10984
11211
  const countFromList = entryCountFromList(baseNodeId);
10985
- const countFromState = countFromList ?? (repeatableEntryCounts == null ? void 0 : repeatableEntryCounts[baseNodeId]) ?? (repeatableEntryCounts == null ? void 0 : repeatableEntryCounts[node.id]) ?? repeatableEntryCounts;
11212
+ const countFromState = countFromList ?? (repeatableEntryCounts == null ? void 0 : repeatableEntryCounts[baseNodeId]) ?? (repeatableEntryCounts == null ? void 0 : repeatableEntryCounts[sampleNodeId]) ?? repeatableEntryCounts;
10986
11213
  const N = Math.max(1, countFromState ?? getRepeatableEntryCount(baseNodeId, formValues));
10987
- const clones = [];
10988
- for (let i = 1; i <= N; i++) {
10989
- const [clone, oldToNew] = cloneNodeWithNewIds$1(node, `${baseNodeId}_e${i}`);
10990
- delete clone.repeatableSection;
10991
- clones.push(clone);
10992
- const newToOriginal = /* @__PURE__ */ new Map();
10993
- for (const [oldId, newId] of oldToNew) {
10994
- resolvedIdMap.set(`${baseNodeId}_${i}_${oldId}`, newId);
10995
- newToOriginal.set(newId, oldId);
10996
- const fieldId = elementIdToFieldId.get(oldId);
10997
- if (fieldId) resolvedIdMap.set(`${baseNodeId}_${i}_${fieldId}`, newId);
10998
- mappedNewIds.add(newId);
10999
- }
11000
- phase1NewToOriginal.set(`${baseNodeId}_${i}`, newToOriginal);
11001
- }
11002
- parentChildren.splice(startIndex, count, ...clones);
11214
+ entryCountByBase.set(baseNodeId, N);
11215
+ return N;
11216
+ };
11217
+ const occurrenceIndexByBase = /* @__PURE__ */ new Map();
11218
+ for (const r of topLevel) {
11219
+ const idx = (occurrenceIndexByBase.get(r.baseNodeId) ?? 0) + 1;
11220
+ occurrenceIndexByBase.set(r.baseNodeId, idx);
11221
+ r.__occurrenceIndex = idx;
11222
+ }
11223
+ for (const [parentChildren, blocks] of occByParent) {
11224
+ const sorted = [...blocks].sort((a, b) => b.startIndex - a.startIndex);
11225
+ for (const block of sorted) {
11226
+ const { node, baseNodeId, startIndex, count } = block;
11227
+ const occIdx = block.__occurrenceIndex ?? 1;
11228
+ const N = computeN(baseNodeId, node.id);
11229
+ const entryFilter = ((_b = node.repeatableSection) == null ? void 0 : _b.entryFilter) ?? entryFilterFromList(baseNodeId);
11230
+ let entryIndices;
11231
+ if (entryFilter && entryFilter.mode === "range" && entryFilter.range) {
11232
+ const parsed = parseEntryRange(entryFilter.range, N);
11233
+ entryIndices = parsed && parsed.length ? parsed : Array.from({ length: N }, (_, k) => k + 1);
11234
+ } else {
11235
+ entryIndices = Array.from({ length: N }, (_, k) => k + 1);
11236
+ }
11237
+ const clones = [];
11238
+ for (const i of entryIndices) {
11239
+ const [clone, oldToNew] = cloneNodeWithNewIds$1(node, `${baseNodeId}_o${occIdx}_e${i}`);
11240
+ clone.__repeatableEntryIndex = i;
11241
+ delete clone.repeatableSection;
11242
+ clones.push(clone);
11243
+ const newToOriginal = /* @__PURE__ */ new Map();
11244
+ for (const [oldId, newId] of oldToNew) {
11245
+ addResolved(`${baseNodeId}_${i}_${oldId}`, newId);
11246
+ newToOriginal.set(newId, oldId);
11247
+ const fieldId = elementIdToFieldId.get(oldId);
11248
+ if (fieldId) {
11249
+ for (const alias of getFieldKeyAliases(fieldId)) addResolved(`${baseNodeId}_${i}_${alias}`, newId);
11250
+ }
11251
+ mappedNewIds.add(newId);
11252
+ }
11253
+ phase1NewToOriginal.set(`${baseNodeId}_${i}`, newToOriginal);
11254
+ }
11255
+ parentChildren.splice(startIndex, count, ...clones);
11256
+ }
11003
11257
  }
11004
11258
  if (nestedChildToParent.size > 0) {
11005
11259
  const repeatableInfosSecond = findRepeatableByNodeIds(pages, nodeIds);
@@ -11012,25 +11266,41 @@ function applyFormDataToConfig(config, mappings, formValues, repeatableSectionsF
11012
11266
  for (const [childBaseNodeId, blocks] of byChildBase) {
11013
11267
  const parentBaseNodeId = nestedChildToParent.get(childBaseNodeId);
11014
11268
  blocks.forEach((block, parentIndex0) => {
11015
- const parentIndex1Based = parentIndex0 + 1;
11269
+ var _a2;
11270
+ const parentIndex1Based = block.parentEntryIndex ?? parentIndex0 + 1;
11016
11271
  const { parentChildren, startIndex, count, node, baseNodeId } = block;
11017
- const nestedKey = `${parentBaseNodeId}_${parentIndex1Based}_${baseNodeId}`;
11018
- const N = Math.max(
11019
- 1,
11020
- (repeatableNestedEntryCounts == null ? void 0 : repeatableNestedEntryCounts[nestedKey]) ?? getNestedRepeatableEntryCount(parentBaseNodeId, parentIndex1Based, baseNodeId, formValues)
11021
- );
11272
+ const N = getNestedCountForBasePair(parentBaseNodeId, parentIndex1Based, baseNodeId);
11022
11273
  const phase1Map = phase1NewToOriginal.get(`${parentBaseNodeId}_${parentIndex1Based}`);
11274
+ const nestedEntryFilter = ((_a2 = node.repeatableSection) == null ? void 0 : _a2.entryFilter) ?? entryFilterFromList(baseNodeId);
11275
+ let nestedEntryIndices;
11276
+ if (nestedEntryFilter && nestedEntryFilter.mode === "range" && nestedEntryFilter.range) {
11277
+ const parsed = parseEntryRange(nestedEntryFilter.range, N);
11278
+ nestedEntryIndices = parsed && parsed.length ? parsed : Array.from({ length: N }, (_, k) => k + 1);
11279
+ } else {
11280
+ nestedEntryIndices = Array.from({ length: N }, (_, k) => k + 1);
11281
+ }
11023
11282
  const clones = [];
11024
- for (let i = 1; i <= N; i++) {
11283
+ for (const i of nestedEntryIndices) {
11025
11284
  const [clone, oldToNew] = cloneNodeWithNewIds$1(node, `${parentBaseNodeId}_p${parentIndex1Based}_${baseNodeId}_e${i}`);
11026
11285
  delete clone.repeatableSection;
11027
11286
  clones.push(clone);
11028
11287
  for (const [oldId, newId] of oldToNew) {
11029
11288
  const originalId = (phase1Map == null ? void 0 : phase1Map.get(oldId)) ?? oldId;
11030
- resolvedIdMap.set(`${parentBaseNodeId}_${parentIndex1Based}_${baseNodeId}_${i}_${originalId}`, newId);
11031
- resolvedIdMap.set(`${parentBaseNodeId}_${parentIndex1Based}_${baseNodeId}_${i}_${oldId}`, newId);
11289
+ addResolved(`${parentBaseNodeId}_${parentIndex1Based}_${baseNodeId}_${i}_${originalId}`, newId);
11290
+ addResolved(`${parentBaseNodeId}_${parentIndex1Based}_${baseNodeId}_${i}_${oldId}`, newId);
11291
+ for (const { parentBaseId, childBaseId } of getNestedBasePairs(parentBaseNodeId, baseNodeId)) {
11292
+ addResolved(`${parentBaseId}_${parentIndex1Based}_${childBaseId}_${i}_${originalId}`, newId);
11293
+ addResolved(`${parentBaseId}_${parentIndex1Based}_${childBaseId}_${i}_${oldId}`, newId);
11294
+ }
11032
11295
  const fieldId = elementIdToFieldId.get(originalId) ?? elementIdToFieldId.get(oldId);
11033
- if (fieldId) resolvedIdMap.set(`${parentBaseNodeId}_${parentIndex1Based}_${baseNodeId}_${i}_${fieldId}`, newId);
11296
+ if (fieldId) {
11297
+ for (const alias of getFieldKeyAliases(fieldId)) {
11298
+ addResolved(`${parentBaseNodeId}_${parentIndex1Based}_${baseNodeId}_${i}_${alias}`, newId);
11299
+ for (const { parentBaseId, childBaseId } of getNestedBasePairs(parentBaseNodeId, baseNodeId)) {
11300
+ addResolved(`${parentBaseId}_${parentIndex1Based}_${childBaseId}_${i}_${alias}`, newId);
11301
+ }
11302
+ }
11303
+ }
11034
11304
  mappedNewIds.add(newId);
11035
11305
  }
11036
11306
  }
@@ -11038,7 +11308,9 @@ function applyFormDataToConfig(config, mappings, formValues, repeatableSectionsF
11038
11308
  });
11039
11309
  }
11040
11310
  }
11041
- cloned.__cloneIdMap = Object.fromEntries(resolvedIdMap);
11311
+ cloned.__cloneIdMap = Object.fromEntries(
11312
+ Array.from(resolvedIdMap.entries()).map(([k, v]) => [k, v.length === 1 ? v[0] : v])
11313
+ );
11042
11314
  cloned.__mappedElementIds = Array.from(mappedNewIds);
11043
11315
  const fieldLabelByKey = /* @__PURE__ */ new Map();
11044
11316
  const fieldTypeByKey = /* @__PURE__ */ new Map();
@@ -11181,10 +11453,7 @@ function applyFormDataToConfig(config, mappings, formValues, repeatableSectionsF
11181
11453
  }
11182
11454
  const byId = dynamicFields.find((f) => f.id === fieldId);
11183
11455
  if (byId) return byId;
11184
- const byElementId = dynamicFields.find((f) => {
11185
- var _a2, _b2;
11186
- return ((_b2 = (_a2 = f.mappings) == null ? void 0 : _a2[0]) == null ? void 0 : _b2.elementId) === fieldId;
11187
- });
11456
+ const byElementId = dynamicFields.find((f) => (f.mappings ?? []).some((m) => (m == null ? void 0 : m.elementId) === fieldId));
11188
11457
  if (byElementId) return byElementId;
11189
11458
  const suffixMatch = dynamicFields.find((f) => {
11190
11459
  if (f.id.endsWith(`_N_${fieldId}`)) return true;
@@ -11200,39 +11469,36 @@ function applyFormDataToConfig(config, mappings, formValues, repeatableSectionsF
11200
11469
  const [, parentId, parentIndexStr, childId, childIndexStr, fieldId] = nestedMatch;
11201
11470
  const value = formValues[key];
11202
11471
  const field = getFieldForRepeatableKey(fieldId, key);
11203
- const mapping = (_d = field == null ? void 0 : field.mappings) == null ? void 0 : _d[0];
11204
- if (!mapping) continue;
11205
- const oldElementId = mapping.elementId;
11206
- const mapKeyByElement = `${baseId(parentId)}_${parentIndexStr}_${baseId(childId)}_${childIndexStr}_${oldElementId}`;
11207
- const mapKeyByField = `${baseId(parentId)}_${parentIndexStr}_${baseId(childId)}_${childIndexStr}_${fieldId}`;
11208
- let elementId = resolvedIdMap.get(mapKeyByElement) ?? resolvedIdMap.get(mapKeyByField);
11209
- if (!elementId) {
11210
- const mapKeyByElementBase = `${baseId(parentId)}_${parentIndexStr}_${baseId(childId)}_${childIndexStr}_${baseId(oldElementId)}`;
11211
- elementId = resolvedIdMap.get(mapKeyByElementBase);
11212
- }
11213
- if (!elementId) {
11214
- elementId = findNestedRepeatableElementBySourceId(
11215
- pages,
11216
- baseId(parentId),
11217
- parseInt(parentIndexStr, 10),
11218
- baseId(childId),
11219
- parseInt(childIndexStr, 10),
11220
- oldElementId
11221
- );
11222
- }
11223
- if (!elementId) {
11224
- elementId = findNestedRepeatableElementBySourceId(
11225
- pages,
11226
- baseId(parentId),
11227
- parseInt(parentIndexStr, 10),
11228
- baseId(childId),
11229
- parseInt(childIndexStr, 10),
11230
- baseId(oldElementId)
11231
- );
11472
+ for (const mapping of (field == null ? void 0 : field.mappings) ?? []) {
11473
+ const oldElementId = mapping.elementId;
11474
+ const mapKeyByElement = `${baseId(parentId)}_${parentIndexStr}_${baseId(childId)}_${childIndexStr}_${oldElementId}`;
11475
+ let elementIds = resolvedIdMap.get(mapKeyByElement);
11476
+ if (!elementIds || elementIds.length === 0) {
11477
+ const mapKeyByElementBase = `${baseId(parentId)}_${parentIndexStr}_${baseId(childId)}_${childIndexStr}_${baseId(oldElementId)}`;
11478
+ elementIds = resolvedIdMap.get(mapKeyByElementBase);
11479
+ }
11480
+ if (!elementIds || elementIds.length === 0) {
11481
+ const fallback = findNestedRepeatableElementBySourceId(
11482
+ pages,
11483
+ baseId(parentId),
11484
+ parseInt(parentIndexStr, 10),
11485
+ baseId(childId),
11486
+ parseInt(childIndexStr, 10),
11487
+ oldElementId
11488
+ ) ?? findNestedRepeatableElementBySourceId(
11489
+ pages,
11490
+ baseId(parentId),
11491
+ parseInt(parentIndexStr, 10),
11492
+ baseId(childId),
11493
+ parseInt(childIndexStr, 10),
11494
+ baseId(oldElementId)
11495
+ );
11496
+ if (fallback) elementIds = [fallback];
11497
+ }
11498
+ if (!elementIds || elementIds.length === 0) continue;
11499
+ const targetProperty = mapping.targetProperty || "text";
11500
+ for (const elementId of elementIds) applyValue(elementId, targetProperty, value, key);
11232
11501
  }
11233
- if (!elementId) continue;
11234
- const targetProperty = mapping.targetProperty || "text";
11235
- applyValue(elementId, targetProperty, value, key);
11236
11502
  }
11237
11503
  }
11238
11504
  }
@@ -11255,18 +11521,29 @@ function applyFormDataToConfig(config, mappings, formValues, repeatableSectionsF
11255
11521
  const [, nodeId, indexStr, fieldId] = match;
11256
11522
  const value = formValues[key];
11257
11523
  const field = getFieldForRepeatableKey(fieldId);
11258
- const mapping = (_e = field == null ? void 0 : field.mappings) == null ? void 0 : _e[0];
11259
- if (!mapping) continue;
11260
- const oldElementId = mapping.elementId;
11261
- const mapKeyByElement = `${baseId(nodeId)}_${indexStr}_${oldElementId}`;
11262
- const mapKeyByField = `${baseId(nodeId)}_${indexStr}_${fieldId}`;
11263
- let elementId = resolvedIdMap.get(mapKeyByElement) ?? resolvedIdMap.get(mapKeyByField);
11264
- if (!elementId) {
11265
- elementId = findRepeatableElementBySourceId(pages, baseId(nodeId), parseInt(indexStr, 10), oldElementId);
11524
+ for (const mapping of (field == null ? void 0 : field.mappings) ?? []) {
11525
+ const oldElementId = mapping.elementId;
11526
+ const elementIds = /* @__PURE__ */ new Set();
11527
+ for (const candidateBaseId of getRepeatableBaseIdsForToken(nodeId)) {
11528
+ const mapKeyByElement = `${candidateBaseId}_${indexStr}_${oldElementId}`;
11529
+ const foundByMap = resolvedIdMap.get(mapKeyByElement);
11530
+ for (const id of foundByMap ?? []) elementIds.add(id);
11531
+ if (!(foundByMap == null ? void 0 : foundByMap.length)) {
11532
+ const N = entryCountByBase.get(candidateBaseId);
11533
+ const found = findAllRepeatableElementsBySourceId(
11534
+ pages,
11535
+ candidateBaseId,
11536
+ parseInt(indexStr, 10),
11537
+ oldElementId,
11538
+ N
11539
+ );
11540
+ for (const id of found) elementIds.add(id);
11541
+ }
11542
+ }
11543
+ if (elementIds.size === 0) continue;
11544
+ const targetProperty = mapping.targetProperty || "text";
11545
+ for (const elementId of elementIds) applyValue(elementId, targetProperty, value, key);
11266
11546
  }
11267
- if (!elementId) continue;
11268
- const targetProperty = mapping.targetProperty || "text";
11269
- applyValue(elementId, targetProperty, value, key);
11270
11547
  }
11271
11548
  }
11272
11549
  const repeatableKeySet = new Set(
@@ -11319,7 +11596,7 @@ function applyFormDataToConfig(config, mappings, formValues, repeatableSectionsF
11319
11596
  }
11320
11597
  }
11321
11598
  for (const page of pages) {
11322
- if ((_f = page.children) == null ? void 0 : _f.length) {
11599
+ if ((_c = page.children) == null ? void 0 : _c.length) {
11323
11600
  page.children = applyStackReflowToPageTree(page.children);
11324
11601
  }
11325
11602
  }
@@ -12277,7 +12554,8 @@ function applyThemeVariantToConfig(config, themeConfig, themeId) {
12277
12554
  const cloneIdMap = config.__cloneIdMap || {};
12278
12555
  const pageElements = result.pages.map((page) => flattenAll(page.children || []));
12279
12556
  for (const prop of themeConfig.properties) {
12280
- const value = variant ? (_d = variant.values) == null ? void 0 : _d[prop.id] : prop.defaultValue;
12557
+ const lookupId = prop.linkedTo || prop.id;
12558
+ const value = variant ? (_d = variant.values) == null ? void 0 : _d[lookupId] : prop.defaultValue;
12281
12559
  if (value === void 0) continue;
12282
12560
  if (prop.targetProperty === "backgroundColor" && prop.elementId === "__pageBackground__") {
12283
12561
  result.pages.forEach((p) => {
@@ -14096,6 +14374,7 @@ async function fetchTTFAsBase64(url) {
14096
14374
  if (!res.ok) return null;
14097
14375
  const buf = await res.arrayBuffer();
14098
14376
  const bytes = new Uint8Array(buf);
14377
+ if (!isJsPdfEmbeddableTrueType(bytes)) return null;
14099
14378
  let binary = "";
14100
14379
  for (let i = 0; i < bytes.length; i++) {
14101
14380
  binary += String.fromCharCode(bytes[i]);
@@ -14107,6 +14386,33 @@ async function fetchTTFAsBase64(url) {
14107
14386
  return null;
14108
14387
  }
14109
14388
  }
14389
+ function isJsPdfEmbeddableTrueType(bytes) {
14390
+ if (bytes.length < 12) return false;
14391
+ const signature = String.fromCharCode(bytes[0], bytes[1], bytes[2], bytes[3]);
14392
+ if (signature !== "\0\0\0" && signature !== "true") return false;
14393
+ const u16 = (offset) => bytes[offset] << 8 | bytes[offset + 1];
14394
+ const u32 = (offset) => (bytes[offset] << 24 | bytes[offset + 1] << 16 | bytes[offset + 2] << 8 | bytes[offset + 3]) >>> 0;
14395
+ const tableCount = u16(4);
14396
+ for (let i = 0; i < tableCount; i++) {
14397
+ const recordOffset = 12 + i * 16;
14398
+ if (recordOffset + 16 > bytes.length) return false;
14399
+ const tag = String.fromCharCode(bytes[recordOffset], bytes[recordOffset + 1], bytes[recordOffset + 2], bytes[recordOffset + 3]);
14400
+ if (tag !== "cmap") continue;
14401
+ const cmapOffset = u32(recordOffset + 8);
14402
+ const cmapLength = u32(recordOffset + 12);
14403
+ if (cmapOffset + Math.min(cmapLength, 4) > bytes.length) return false;
14404
+ const subtables = u16(cmapOffset + 2);
14405
+ for (let j = 0; j < subtables; j++) {
14406
+ const encOffset = cmapOffset + 4 + j * 8;
14407
+ if (encOffset + 8 > bytes.length) return false;
14408
+ const platform = u16(encOffset);
14409
+ const encoding = u16(encOffset + 2);
14410
+ if (platform === 0 || platform === 3 && (encoding === 1 || encoding === 10)) return true;
14411
+ }
14412
+ return false;
14413
+ }
14414
+ return false;
14415
+ }
14110
14416
  async function embedFont(pdf, fontName, weight, fontBaseUrl, isItalic = false) {
14111
14417
  const fontFiles = FONT_FILES[fontName];
14112
14418
  if (!fontFiles) return false;
@@ -15814,7 +16120,7 @@ async function assemblePdfFromSvgs(svgResults, options = {}) {
15814
16120
  }
15815
16121
  if (shouldOutlineText) {
15816
16122
  try {
15817
- const { convertAllTextToPath } = await import("./svgTextToPath-B5sT7sre.js");
16123
+ const { convertAllTextToPath } = await import("./svgTextToPath-CShDi4Ky.js");
15818
16124
  pageSvg = await convertAllTextToPath(pageSvg, fontBaseUrl, { mode: outlineSubMode });
15819
16125
  try {
15820
16126
  dumpSvgTextDiagnostics(pageSvg, i, PARITY_TAG, "STAGE-1b-after-text-to-path-raw");