{"version":3,"file":"planActions.mjs","names":[],"sources":["../../../src/docReview/planActions.ts"],"sourcesContent":["import type { AlignmentPair, AlignmentPlan, PlannedAction } from './types';\n\n/**\n * Turn raw alignment pairs into an ordered list of merge actions.\n *\n * A block aligned in both documents is reused when its base counterpart is not\n * marked as changed, and reviewed otherwise. Blocks present only in the base are\n * inserted, blocks present only in the target are deleted.\n *\n * @param alignment - The alignment pairs produced by the aligner.\n * @param changedBaseBlockIndexes - Indexes of base blocks reported as changed.\n * @returns The plan of actions to merge the documents.\n */\nexport const planAlignmentActions = (\n  alignment: AlignmentPair[],\n  changedBaseBlockIndexes: Set<number>\n): AlignmentPlan => {\n  const actions: PlannedAction[] = [];\n  const seenTarget = new Set<number>();\n\n  alignment.forEach((pair) => {\n    const baseIndex = pair.baseIndex;\n    const targetIndex = pair.targetIndex;\n\n    // Case 1: Deletion (Exists in target, not in base)\n    if (baseIndex === -1 && targetIndex !== null) {\n      if (!seenTarget.has(targetIndex)) {\n        actions.push({ kind: 'delete', targetIndex });\n        seenTarget.add(targetIndex);\n      }\n      return;\n    }\n\n    // Case 2: New Insertion (Exists in base, not in target)\n    if (baseIndex >= 0 && targetIndex === null) {\n      actions.push({ kind: 'insert_new', baseIndex });\n      return;\n    }\n\n    // Case 3: Alignment (Exists in both)\n    if (baseIndex >= 0 && targetIndex !== null) {\n      const isChanged = changedBaseBlockIndexes.has(baseIndex);\n\n      // If the block is NOT marked as changed, we REUSE it. We assume the existing\n      // translation is correct because the source hasn't been touched. We ignore\n      // 'similarityScore' here because base vs target text will always have low\n      // similarity.\n      if (!isChanged) {\n        actions.push({ kind: 'reuse', baseIndex, targetIndex });\n      } else {\n        // If the block IS changed, we Review it.\n        actions.push({ kind: 'review', baseIndex, targetIndex });\n      }\n\n      seenTarget.add(targetIndex);\n      return;\n    }\n  });\n\n  return { actions };\n};\n"],"mappings":";;;;;;;;;;;;AAaA,MAAa,wBACX,WACA,4BACkB;CAClB,MAAM,UAA2B,CAAC;CAClC,MAAM,6BAAa,IAAI,IAAY;CAEnC,UAAU,SAAS,SAAS;EAC1B,MAAM,YAAY,KAAK;EACvB,MAAM,cAAc,KAAK;EAGzB,IAAI,cAAc,MAAM,gBAAgB,MAAM;GAC5C,IAAI,CAAC,WAAW,IAAI,WAAW,GAAG;IAChC,QAAQ,KAAK;KAAE,MAAM;KAAU;IAAY,CAAC;IAC5C,WAAW,IAAI,WAAW;GAC5B;GACA;EACF;EAGA,IAAI,aAAa,KAAK,gBAAgB,MAAM;GAC1C,QAAQ,KAAK;IAAE,MAAM;IAAc;GAAU,CAAC;GAC9C;EACF;EAGA,IAAI,aAAa,KAAK,gBAAgB,MAAM;GAO1C,IAAI,CANc,wBAAwB,IAAI,SAMjC,GACX,QAAQ,KAAK;IAAE,MAAM;IAAS;IAAW;GAAY,CAAC;QAGtD,QAAQ,KAAK;IAAE,MAAM;IAAU;IAAW;GAAY,CAAC;GAGzD,WAAW,IAAI,WAAW;GAC1B;EACF;CACF,CAAC;CAED,OAAO,EAAE,QAAQ;AACnB"}