@claritylabs/cl-sdk 3.0.8 → 3.0.9

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
@@ -9448,6 +9448,12 @@ function looksLikeEndorsementStart(node) {
9448
9448
  if (/^endorsement\s+(?:no\.?|number|#)\s*[A-Z0-9][A-Z0-9.-]*\b/i.test(start)) return true;
9449
9449
  return /^endorsement\s+(?:no\.?|number|#)\s*[A-Z0-9][A-Z0-9.-]*\b/i.test(title) && /\bthis endorsement changes the policy\b/i.test(body);
9450
9450
  }
9451
+ function looksLikeEndorsementContinuation(node) {
9452
+ if (looksLikeEndorsementStart(node)) return false;
9453
+ const title = cleanText(node.title, "");
9454
+ const text = sourceNodeText(node);
9455
+ return /\bendorsement\b/i.test(text) || /\bcontinuation\b/i.test(title) || /\ball\s+other\s+terms\s+and\s+conditions\b/i.test(text);
9456
+ }
9451
9457
  function endorsementStartTitle(node) {
9452
9458
  return looksLikeEndorsementStart(node) ? endorsementTitle(sourceNodeText(node)) : void 0;
9453
9459
  }
@@ -9608,6 +9614,124 @@ function endorsementGroupNodeId(documentId, parentId) {
9608
9614
  parentId?.replace(/[^a-zA-Z0-9_.:-]/g, "_").slice(0, 48) ?? "root"
9609
9615
  ].join(":");
9610
9616
  }
9617
+ function isPolicyFormNode(node) {
9618
+ return node.title === "Policy Form" && (node.kind === "form" || node.kind === "page_group");
9619
+ }
9620
+ function isDeclarationsNode(node) {
9621
+ return node.kind === "page_group" && node.title === "Declarations";
9622
+ }
9623
+ function normalizePolicyFormStructure(sourceTree) {
9624
+ let nextTree = sourceTree;
9625
+ const byParent = nodesByParent(nextTree);
9626
+ const nodesToRemove = /* @__PURE__ */ new Set();
9627
+ for (const form of nextTree.filter((node) => node.kind === "form" && node.title === "Policy Form")) {
9628
+ const children = byParent.get(form.id) ?? [];
9629
+ const declarationsChildren = children.filter(isDeclarationsNode);
9630
+ const nestedPolicyForm = children.find((child) => child.id !== form.id && isPolicyFormNode(child));
9631
+ if (declarationsChildren.length === 0 && !nestedPolicyForm) continue;
9632
+ const declarationIds = new Set(declarationsChildren.map((child) => child.id));
9633
+ nextTree = nextTree.map((node) => {
9634
+ if (declarationIds.has(node.id)) {
9635
+ return {
9636
+ ...node,
9637
+ parentId: form.parentId,
9638
+ metadata: {
9639
+ ...node.metadata,
9640
+ organizerRepair: "promote_declarations_from_policy_form"
9641
+ }
9642
+ };
9643
+ }
9644
+ if (nestedPolicyForm && node.parentId === nestedPolicyForm.id) {
9645
+ return {
9646
+ ...node,
9647
+ parentId: form.id,
9648
+ metadata: {
9649
+ ...node.metadata,
9650
+ organizerRepair: "collapse_nested_policy_form"
9651
+ }
9652
+ };
9653
+ }
9654
+ return node;
9655
+ });
9656
+ if (nestedPolicyForm) nodesToRemove.add(nestedPolicyForm.id);
9657
+ }
9658
+ if (nodesToRemove.size > 0) {
9659
+ nextTree = nextTree.filter((node) => !nodesToRemove.has(node.id));
9660
+ }
9661
+ return nextTree;
9662
+ }
9663
+ function nestEndorsementContinuationPages(sourceTree) {
9664
+ const byParent = nodesByParent(sourceTree);
9665
+ const continuationParentById = /* @__PURE__ */ new Map();
9666
+ for (const group of sourceTree.filter(isEndorsementGroup)) {
9667
+ const children = byParent.get(group.id) ?? [];
9668
+ let currentEndorsement;
9669
+ for (const child of children) {
9670
+ if (child.kind === "endorsement" && endorsementStartTitle(child)) {
9671
+ currentEndorsement = child;
9672
+ continue;
9673
+ }
9674
+ if (!currentEndorsement || child.kind !== "page") continue;
9675
+ continuationParentById.set(child.id, currentEndorsement.id);
9676
+ }
9677
+ }
9678
+ if (continuationParentById.size === 0) return sourceTree;
9679
+ return sourceTree.map((node) => {
9680
+ const parentId = continuationParentById.get(node.id);
9681
+ if (!parentId) return node;
9682
+ return {
9683
+ ...node,
9684
+ parentId,
9685
+ metadata: {
9686
+ ...node.metadata,
9687
+ organizerRepair: "nest_endorsement_continuation"
9688
+ }
9689
+ };
9690
+ });
9691
+ }
9692
+ function nodeDepth(node) {
9693
+ return node.path ? node.path.split("/").filter(Boolean).length : 0;
9694
+ }
9695
+ function shouldUseOwnEvidenceForContainer(node) {
9696
+ return node.kind === "endorsement" || node.kind === "page" || node.kind === "table" || node.kind === "table_row" || node.kind === "table_cell" || node.kind === "text";
9697
+ }
9698
+ function normalizeContainerEvidenceFromChildren(sourceTree) {
9699
+ const byParent = nodesByParent(sourceTree);
9700
+ const byId = new Map(sourceTree.map((node) => [node.id, node]));
9701
+ const sorted = [...sourceTree].sort((left, right) => nodeDepth(right) - nodeDepth(left));
9702
+ for (const originalNode of sorted) {
9703
+ const children = (byParent.get(originalNode.id) ?? []).map((child) => byId.get(child.id)).filter((child) => Boolean(child));
9704
+ if (children.length === 0) continue;
9705
+ const currentNode = byId.get(originalNode.id) ?? originalNode;
9706
+ const evidenceNodes = shouldUseOwnEvidenceForContainer(currentNode) ? [currentNode, ...children] : children;
9707
+ const pageStarts = evidenceNodes.map((node) => node.pageStart).filter((page) => typeof page === "number");
9708
+ const pageEnds = evidenceNodes.map((node) => node.pageEnd ?? node.pageStart).filter((page) => typeof page === "number");
9709
+ const sourceSpanIds = [...new Set(evidenceNodes.flatMap((node) => node.sourceSpanIds))];
9710
+ const bbox = evidenceNodes.flatMap((node) => node.bbox ?? []).slice(0, 12);
9711
+ const childText = children.map((child) => child.textExcerpt ?? child.description).filter(Boolean).join("\n\n").slice(0, 1600);
9712
+ byId.set(currentNode.id, {
9713
+ ...currentNode,
9714
+ sourceSpanIds,
9715
+ pageStart: pageStarts.length ? Math.min(...pageStarts) : currentNode.pageStart,
9716
+ pageEnd: pageEnds.length ? Math.max(...pageEnds) : currentNode.pageEnd,
9717
+ bbox,
9718
+ order: Math.min(currentNode.order, ...children.map((child) => child.order)),
9719
+ textExcerpt: shouldUseOwnEvidenceForContainer(currentNode) ? currentNode.textExcerpt : childText || currentNode.textExcerpt
9720
+ });
9721
+ }
9722
+ return sourceTree.map((node) => byId.get(node.id) ?? node);
9723
+ }
9724
+ function normalizeSemanticHierarchy(sourceTree) {
9725
+ return normalizeDocumentSourceTreePaths(
9726
+ normalizeContainerEvidenceFromChildren(
9727
+ nestEndorsementContinuationPages(
9728
+ normalizePolicyFormStructure(
9729
+ normalizeDocumentSourceTreePaths(sourceTree)
9730
+ )
9731
+ )
9732
+ )
9733
+ );
9734
+ }
9611
9735
  function applyEndorsementGrouping(sourceTree) {
9612
9736
  const relabeledTree = sourceTree.map((node) => {
9613
9737
  if (node.kind === "document" || isEndorsementGroup(node)) return node;
@@ -9682,9 +9806,21 @@ function applyEndorsementGrouping(sourceTree) {
9682
9806
  if (endorsementGroupIds.has(parentId ?? "")) continue;
9683
9807
  const endorsementChildren = children.filter((child) => child.kind === "endorsement" && !isEndorsementGroup(child));
9684
9808
  if (endorsementChildren.length < 2) continue;
9809
+ const endorsementGroupChildren = [];
9810
+ let hasSeenEndorsementStart = false;
9811
+ for (const child of children) {
9812
+ if (child.kind === "endorsement" && !isEndorsementGroup(child)) {
9813
+ hasSeenEndorsementStart = true;
9814
+ endorsementGroupChildren.push(child);
9815
+ continue;
9816
+ }
9817
+ if (hasSeenEndorsementStart && child.kind === "page" && looksLikeEndorsementContinuation(child)) {
9818
+ endorsementGroupChildren.push(child);
9819
+ }
9820
+ }
9685
9821
  const documentId = endorsementChildren[0].documentId;
9686
- const pageStarts = endorsementChildren.map((child) => child.pageStart).filter((page) => typeof page === "number");
9687
- const pageEnds = endorsementChildren.map((child) => child.pageEnd ?? child.pageStart).filter((page) => typeof page === "number");
9822
+ const pageStarts = endorsementGroupChildren.map((child) => child.pageStart).filter((page) => typeof page === "number");
9823
+ const pageEnds = endorsementGroupChildren.map((child) => child.pageEnd ?? child.pageStart).filter((page) => typeof page === "number");
9688
9824
  const order = Math.min(...endorsementChildren.map((child) => child.order));
9689
9825
  const existingGroup = groupsByParent.get(parentId);
9690
9826
  const groupId = existingGroup?.id ?? endorsementGroupNodeId(documentId, parentId);
@@ -9699,12 +9835,12 @@ function applyEndorsementGrouping(sourceTree) {
9699
9835
  sourceSpanIds: [],
9700
9836
  pageStart: pageStarts.length ? Math.min(...pageStarts) : void 0,
9701
9837
  pageEnd: pageEnds.length ? Math.max(...pageEnds) : void 0,
9702
- bbox: endorsementChildren.flatMap((child) => child.bbox ?? []).slice(0, 12),
9838
+ bbox: endorsementGroupChildren.flatMap((child) => child.bbox ?? []).slice(0, 12),
9703
9839
  order,
9704
9840
  path: "",
9705
9841
  metadata: { sourceTreeVersion: "v3", organizer: "endorsement_grouping" }
9706
9842
  };
9707
- const childSpanIds = [...new Set(endorsementChildren.flatMap((child) => child.sourceSpanIds))];
9843
+ const childSpanIds = [...new Set(endorsementGroupChildren.flatMap((child) => child.sourceSpanIds))];
9708
9844
  const normalizedGroup = {
9709
9845
  ...groupNode,
9710
9846
  sourceSpanIds: groupNode.sourceSpanIds.length ? groupNode.sourceSpanIds : childSpanIds,
@@ -9715,11 +9851,12 @@ function applyEndorsementGrouping(sourceTree) {
9715
9851
  groupsByParent.set(parentId, normalizedGroup);
9716
9852
  if (!existingGroup) nextTree.push(normalizedGroup);
9717
9853
  else nextTree = nextTree.map((node) => node.id === normalizedGroup.id ? normalizedGroup : node);
9854
+ const endorsementGroupChildIds = new Set(endorsementGroupChildren.map((child) => child.id));
9718
9855
  nextTree = nextTree.map(
9719
- (node) => endorsementChildren.some((child) => child.id === node.id) ? { ...node, parentId: groupId, order: node.order + 1e-3 } : node
9856
+ (node) => endorsementGroupChildIds.has(node.id) ? { ...node, parentId: groupId, order: node.order + 1e-3 } : node
9720
9857
  );
9721
9858
  }
9722
- return normalizeDocumentSourceTreePaths(nextTree);
9859
+ return normalizeSemanticHierarchy(nextTree);
9723
9860
  }
9724
9861
  function compactNode(node, maxText = 700) {
9725
9862
  return {