dytools-capture-engine 1.1.2 → 1.2.0

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.cjs CHANGED
@@ -504,11 +504,8 @@ var SimpleZone = class extends CaptureZoneBase {
504
504
  let isFirstMatch = true;
505
505
  for (const match of ocrMatches) {
506
506
  if (match.templateZoneId != this.id) continue;
507
- if (isFirstMatch) {
508
- this.example = match.processedText;
509
- }
510
507
  if (!this.hidden) {
511
- this.ocrOverlayIds.push(this.canvasManager?.addPolygon(match.polygonAbsolute.points, "rgba(0, 255, 0, 0.25)", false));
508
+ this.ocrOverlayIds.push(this.canvasManager?.addPolygon(match.polygonAbsolute.points, "rgba(0, 255, 255, 0.25)", false));
512
509
  }
513
510
  break;
514
511
  }
@@ -528,7 +525,7 @@ var SimpleZone = class extends CaptureZoneBase {
528
525
  const captureOcrMatchesLoadedPayload = payload;
529
526
  let ocrMatches = captureOcrMatchesLoadedPayload.ocrMatches;
530
527
  let thisOcrMatches = ocrMatches?.filter((e) => e.templateZoneId == this.id) ?? [];
531
- let matchHash = this.hidden + "|" + thisOcrMatches.map((e) => `${e.ocrTextResultId}*${e.anchorPointPercent}`).join(",");
528
+ let matchHash = this.hidden + "|" + thisOcrMatches.map((e) => `${e.ocrTextResultIds.sort().join(",")}*${e.anchorPointPercent}`).join(",");
532
529
  if (matchHash !== this.lastMatchHash) {
533
530
  this.lastMatchHash = matchHash;
534
531
  this.emitZoneEvent(CaptureZoneEventType.ZoneOcrMatchesChanged, { matches: ocrMatches });
@@ -550,7 +547,7 @@ var SimpleZone = class extends CaptureZoneBase {
550
547
  return;
551
548
  }
552
549
  let thisOcrMatches = ocrMatches?.filter((e) => e.templateZoneId == this.id) ?? [];
553
- let matchHash = this.hidden + "|" + thisOcrMatches.map((e) => `${e.ocrTextResultId}`).join(",");
550
+ let matchHash = this.hidden + "|" + thisOcrMatches.map((e) => `${e.ocrTextResultIds.sort().join(",")}`).join(",");
554
551
  if (matchHash === this.lastMatchHash) {
555
552
  return;
556
553
  }
@@ -558,9 +555,6 @@ var SimpleZone = class extends CaptureZoneBase {
558
555
  this.lastMatchHash = matchHash;
559
556
  let isFirstMatch = true;
560
557
  for (const match of thisOcrMatches) {
561
- if (isFirstMatch) {
562
- this.example = match.processedText;
563
- }
564
558
  if (!this.hidden) {
565
559
  this.ocrOverlayIds.push(canvas.addPolygon(match.polygonAbsolute.points, "rgba(0, 255, 0, 0.25)", false));
566
560
  }
@@ -568,7 +562,6 @@ var SimpleZone = class extends CaptureZoneBase {
568
562
  }
569
563
  }
570
564
  toExternal(docWidth, docHeight) {
571
- console.log(`Sim x:${this.rect.origin.x}, y:${this.rect.origin.y}, w:${this.rect.size.width}, h:${this.rect.size.height}`);
572
565
  return {
573
566
  TemplateZoneId: this.id,
574
567
  Name: this.name,
@@ -598,6 +591,7 @@ var AnchorChildZone = class extends SimpleZone {
598
591
  }
599
592
  toExternalChild(docWidth, docHeight, parentAnchor) {
600
593
  let external = this.toExternal(docWidth, docHeight);
594
+ if (!external) return null;
601
595
  external.Type = "TemplateAnchorZoneChild";
602
596
  const parentAnchorPercent = new import_dytools_geometry.Point(parentAnchor.x / docWidth, parentAnchor.y / docHeight);
603
597
  external.X = this.rect.origin.x / docWidth - parentAnchorPercent.x;
@@ -734,9 +728,6 @@ var AnchorZone = class extends CaptureZoneBase {
734
728
  let cycle = this.cycle;
735
729
  for (const match of ocrMatches) {
736
730
  if (match.templateZoneId != this.id) continue;
737
- if (isFirstMatch) {
738
- this.example = match.processedText;
739
- }
740
731
  if (!this.hidden) {
741
732
  this.ocrOverlayIds.push(this.canvasManager?.addPolygon(match.polygonAbsolute.points, "rgba(0, 255, 0, 0.25)", false));
742
733
  }
@@ -795,7 +786,7 @@ var AnchorZone = class extends CaptureZoneBase {
795
786
  const captureOcrMatchesLoadedPayload = payload;
796
787
  let ocrMatches = captureOcrMatchesLoadedPayload.ocrMatches;
797
788
  let thisOcrMatches = ocrMatches?.filter((e) => e.templateZoneId == this.id) ?? [];
798
- let matchHash = this.groupChildren + "|" + this.anchorLocation + "|" + this.hidden + "|" + thisOcrMatches.map((e) => `${e.ocrTextResultId}*${e.anchorPointPercent?.x}*${e.anchorPointPercent?.y}`).join(",") + "|" + this.children.map((e) => `${e.id}*${e.hidden}*${e.rect?.origin.x}*${e.rect?.origin.y}*${e.rect?.size.width}*${e.rect?.size.height}`).join(",");
789
+ let matchHash = this.groupChildren + "|" + this.anchorLocation + "|" + this.hidden + "|" + thisOcrMatches.map((e) => `${e.ocrTextResultIds.sort().join(",")}*${e.anchorPointPercent?.x}*${e.anchorPointPercent?.y}`).join(",") + "|" + this.children.map((e) => `${e.id}*${e.hidden}*${e.rect?.origin.x}*${e.rect?.origin.y}*${e.rect?.size.width}*${e.rect?.size.height}`).join(",");
799
790
  if (matchHash !== this.lastMatchHash) {
800
791
  this.lastMatchHash = matchHash;
801
792
  this.emitZoneEvent(CaptureZoneEventType.ZoneOcrMatchesChanged, { matches: ocrMatches });
@@ -803,53 +794,6 @@ var AnchorZone = class extends CaptureZoneBase {
803
794
  }
804
795
  }
805
796
  }
806
- update(ocrRead, ocrMatches, canvas, flags) {
807
- if (!this.primaryCanvasRectangleId) {
808
- this.primaryCanvasRectangleId = canvas.addRectangle(this.rect, this.name, "green", true, true);
809
- } else {
810
- canvas.setName(this.primaryCanvasRectangleId, this.name);
811
- canvas.setColor(this.primaryCanvasRectangleId, "green");
812
- canvas.setVisibility(this.primaryCanvasRectangleId, !this.hidden);
813
- canvas.setSelectable(this.primaryCanvasRectangleId, true);
814
- canvas.setResizable(this.primaryCanvasRectangleId, true);
815
- canvas.setRectangleSize(this.primaryCanvasRectangleId, this.rect);
816
- }
817
- let thisOcrMatches = ocrMatches?.filter((e) => e.templateZoneId == this.id) ?? [];
818
- let matchHash = this.hidden + "|" + thisOcrMatches.map((e) => `${e.ocrTextResultId}`).join(",") + "|" + this.children.map((e) => `${e.id}*${e.hidden}`).join(",");
819
- if (matchHash === this.lastMatchHash) {
820
- return;
821
- }
822
- this.ocrOverlayIds.forEach((id) => canvas.removeObject(id));
823
- this.lastMatchHash = matchHash;
824
- let isFirstMatch = true;
825
- for (const match of thisOcrMatches) {
826
- if (isFirstMatch) {
827
- this.example = match.processedText;
828
- }
829
- if (!this.hidden) {
830
- this.ocrOverlayIds.push(canvas.addPolygon(match.polygonAbsolute.points, "rgba(0, 255, 0, 0.25)", false));
831
- }
832
- if (match.anchorPointAbsolute) {
833
- if (!this.hidden) {
834
- this.ocrOverlayIds.push(canvas.addCircle(match.anchorPointAbsolute, 2, "rgba(0, 0, 255, 0.25)", false, false));
835
- }
836
- if (!isFirstMatch) {
837
- for (const child of this.children) {
838
- if (child.hidden == false) {
839
- let vector = this.currentAnchorPoint ? match.anchorPointAbsolute.getDeltaFromPoint(this.currentAnchorPoint) : new import_dytools_geometry.Vector(0, 0);
840
- let color = "rgba(128, 128, 255, 0.5)";
841
- const polygon = child.rect.move(vector).toPolygon().points;
842
- this.ocrOverlayIds.push(canvas.addPolygon(polygon, color, false));
843
- }
844
- }
845
- }
846
- if (this.currentAnchorPoint === null || isFirstMatch) {
847
- this.currentAnchorPoint = match.anchorPointAbsolute;
848
- }
849
- }
850
- isFirstMatch = false;
851
- }
852
- }
853
797
  onChildZoneAdded(childZone) {
854
798
  this.emitToEngine(CaptureToEngineEventType.ZoneChildZoneAdded, { parentZone: this, newChildZone: childZone });
855
799
  }
@@ -880,7 +824,7 @@ var AnchorZone = class extends CaptureZoneBase {
880
824
  AnchorLocationXAbsoluteHint: this.currentAnchorPoint?.x,
881
825
  AnchorLocationYAbsoluteHint: this.currentAnchorPoint?.y,
882
826
  GroupChildrenInSubRecord: this.groupChildren,
883
- ChildZones: this.children.map((e) => e instanceof AnchorChildZone ? e.toExternalChild(docWidth, docHeight, this.currentAnchorPoint || this.rect.origin) : e.toExternal(docWidth, docHeight))
827
+ ChildZones: this.children.map((e) => e instanceof AnchorChildZone ? e.toExternalChild(docWidth, docHeight, this.currentAnchorPoint || this.rect.origin) ?? null : e.toExternal(docWidth, docHeight) ?? null).filter((e) => e !== null)
884
828
  };
885
829
  }
886
830
  };
@@ -1338,15 +1282,6 @@ var CaptureEngine = class {
1338
1282
  const docWidth = this.width;
1339
1283
  const docHeight = this.height;
1340
1284
  this.getOcrMatchesSnapshot();
1341
- console.log(this.zones.filter((e) => e.name == "Anchor 1").map((e) => {
1342
- let extParent = e.toExternal(docWidth, docHeight);
1343
- if (extParent.ChildZones && extParent.ChildZones.length > 0) {
1344
- let ext = extParent.ChildZones[0];
1345
- return { x: ext.X, y: ext.Y, width: ext.Width, height: ext.Height };
1346
- } else {
1347
- return "no child";
1348
- }
1349
- }));
1350
1285
  return {
1351
1286
  Name: this._name ?? "Untitled",
1352
1287
  DocumentWidth: docWidth,
@@ -1680,6 +1615,22 @@ var CaptureEngine = class {
1680
1615
  get mode() {
1681
1616
  return this.engine.mode;
1682
1617
  }
1618
+ /* --- EXAMPLES --- */
1619
+ setZoneExamples(zoneExamples, setMissingExamplesToNull = true) {
1620
+ for (const zone of this.allZonesFlattened) {
1621
+ let wasSet = false;
1622
+ for (const example of zoneExamples ?? []) {
1623
+ if (example.templateZoneId === zone.id) {
1624
+ zone.example = example.exampleText;
1625
+ wasSet = true;
1626
+ break;
1627
+ }
1628
+ }
1629
+ if (!wasSet && setMissingExamplesToNull) {
1630
+ zone.example = null;
1631
+ }
1632
+ }
1633
+ }
1683
1634
  /* --- OCR --- */
1684
1635
  /**
1685
1636
  * Render the current OCR snapshot as non-interactive polygons on the canvas.
@@ -1749,7 +1700,7 @@ var CaptureEngine = class {
1749
1700
  setOcrMatchesSnapshot(matches) {
1750
1701
  const absoluteMatches = matches.map((m) => ({
1751
1702
  templateZoneId: m.templateZoneId,
1752
- ocrTextResultId: m.ocrTextResultId,
1703
+ ocrTextResultIds: m.ocrTextResultIds,
1753
1704
  originalText: m.originalText,
1754
1705
  processedText: m.processedText,
1755
1706
  polygonPercent: m.polygonPercent,
package/dist/index.d.cts CHANGED
@@ -415,7 +415,7 @@ interface TemplateZoneBase {
415
415
  children?: TemplateZoneBase[];
416
416
  handleEvent?<T extends CaptureEngineToZoneEventType>(id: string, type: T, payload: CaptureEngineToZoneEventPayloads[T]): void;
417
417
  setCanvasManager?(cm?: ZoneCanvasManager): void;
418
- toExternal(docWidth: number, docHeight: number): ExternalTemplateZone;
418
+ toExternal(docWidth: number, docHeight: number): ExternalTemplateZone | null;
419
419
  setEngineEventSink?(callback?: (type: CaptureToEngineEventType, payload?: CaptureToEngineEventPayloads[CaptureToEngineEventType]) => void): void;
420
420
  }
421
421
  interface ZoneCanvasManager {
@@ -505,6 +505,7 @@ declare class CaptureEngine {
505
505
  setBackgroundImage(imageOrUrl: string | File | Blob): Promise<void>;
506
506
  switchMode(name: string): void;
507
507
  get mode(): string;
508
+ setZoneExamples(zoneExamples: ZoneExample[] | null, setMissingExamplesToNull?: boolean): void;
508
509
  /**
509
510
  * Render the current OCR snapshot as non-interactive polygons on the canvas.
510
511
  */
@@ -537,7 +538,7 @@ interface OcrWord {
537
538
  }
538
539
  interface ZoneOcrMatch {
539
540
  templateZoneId: string;
540
- ocrTextResultId: number;
541
+ ocrTextResultIds: number[];
541
542
  originalText: string;
542
543
  processedText: string;
543
544
  polygonPercent: Polygon;
@@ -545,7 +546,7 @@ interface ZoneOcrMatch {
545
546
  }
546
547
  interface InternalZoneOcrMatch {
547
548
  templateZoneId: string;
548
- ocrTextResultId: number;
549
+ ocrTextResultIds: number[];
549
550
  originalText: string;
550
551
  processedText: string;
551
552
  polygonPercent: Polygon;
@@ -553,6 +554,10 @@ interface InternalZoneOcrMatch {
553
554
  anchorPointPercent?: Point | null;
554
555
  anchorPointAbsolute?: Point | null;
555
556
  }
557
+ interface ZoneExample {
558
+ templateZoneId: string;
559
+ exampleText: string;
560
+ }
556
561
  interface CaptureEngineServerApi {
557
562
  /** 1) /api/v1/ocr/readimage */
558
563
  readImage(file: File | Blob): Promise<Result<OcrRead>>;
@@ -563,4 +568,4 @@ interface CaptureEngineServerApi {
563
568
  }): Promise<Result<ZoneOcrMatch[]>>;
564
569
  }
565
570
 
566
- export { CaptureEngine, type CaptureEngineServerApi, type CaptureEngineToZoneEventPayloads, CaptureEngineToZoneEventType, type CapturePublicEventPayloads, CapturePublicEventType, type CaptureToEngineEventPayloads, CaptureToEngineEventType, type CaptureZoneEventPayloads, type ExternalTemplate, type ExternalTemplateZone, type ExternalZoneType, type OcrRead, type OcrWord, type TemplateZoneBase, type ZoneCanvasManager, type ZoneKind, type ZoneOcrMatch };
571
+ export { CaptureEngine, type CaptureEngineServerApi, type CaptureEngineToZoneEventPayloads, CaptureEngineToZoneEventType, type CapturePublicEventPayloads, CapturePublicEventType, type CaptureToEngineEventPayloads, CaptureToEngineEventType, type CaptureZoneEventPayloads, type ExternalTemplate, type ExternalTemplateZone, type ExternalZoneType, type OcrRead, type OcrWord, type TemplateZoneBase, type ZoneCanvasManager, type ZoneExample, type ZoneKind, type ZoneOcrMatch };
package/dist/index.d.ts CHANGED
@@ -415,7 +415,7 @@ interface TemplateZoneBase {
415
415
  children?: TemplateZoneBase[];
416
416
  handleEvent?<T extends CaptureEngineToZoneEventType>(id: string, type: T, payload: CaptureEngineToZoneEventPayloads[T]): void;
417
417
  setCanvasManager?(cm?: ZoneCanvasManager): void;
418
- toExternal(docWidth: number, docHeight: number): ExternalTemplateZone;
418
+ toExternal(docWidth: number, docHeight: number): ExternalTemplateZone | null;
419
419
  setEngineEventSink?(callback?: (type: CaptureToEngineEventType, payload?: CaptureToEngineEventPayloads[CaptureToEngineEventType]) => void): void;
420
420
  }
421
421
  interface ZoneCanvasManager {
@@ -505,6 +505,7 @@ declare class CaptureEngine {
505
505
  setBackgroundImage(imageOrUrl: string | File | Blob): Promise<void>;
506
506
  switchMode(name: string): void;
507
507
  get mode(): string;
508
+ setZoneExamples(zoneExamples: ZoneExample[] | null, setMissingExamplesToNull?: boolean): void;
508
509
  /**
509
510
  * Render the current OCR snapshot as non-interactive polygons on the canvas.
510
511
  */
@@ -537,7 +538,7 @@ interface OcrWord {
537
538
  }
538
539
  interface ZoneOcrMatch {
539
540
  templateZoneId: string;
540
- ocrTextResultId: number;
541
+ ocrTextResultIds: number[];
541
542
  originalText: string;
542
543
  processedText: string;
543
544
  polygonPercent: Polygon;
@@ -545,7 +546,7 @@ interface ZoneOcrMatch {
545
546
  }
546
547
  interface InternalZoneOcrMatch {
547
548
  templateZoneId: string;
548
- ocrTextResultId: number;
549
+ ocrTextResultIds: number[];
549
550
  originalText: string;
550
551
  processedText: string;
551
552
  polygonPercent: Polygon;
@@ -553,6 +554,10 @@ interface InternalZoneOcrMatch {
553
554
  anchorPointPercent?: Point | null;
554
555
  anchorPointAbsolute?: Point | null;
555
556
  }
557
+ interface ZoneExample {
558
+ templateZoneId: string;
559
+ exampleText: string;
560
+ }
556
561
  interface CaptureEngineServerApi {
557
562
  /** 1) /api/v1/ocr/readimage */
558
563
  readImage(file: File | Blob): Promise<Result<OcrRead>>;
@@ -563,4 +568,4 @@ interface CaptureEngineServerApi {
563
568
  }): Promise<Result<ZoneOcrMatch[]>>;
564
569
  }
565
570
 
566
- export { CaptureEngine, type CaptureEngineServerApi, type CaptureEngineToZoneEventPayloads, CaptureEngineToZoneEventType, type CapturePublicEventPayloads, CapturePublicEventType, type CaptureToEngineEventPayloads, CaptureToEngineEventType, type CaptureZoneEventPayloads, type ExternalTemplate, type ExternalTemplateZone, type ExternalZoneType, type OcrRead, type OcrWord, type TemplateZoneBase, type ZoneCanvasManager, type ZoneKind, type ZoneOcrMatch };
571
+ export { CaptureEngine, type CaptureEngineServerApi, type CaptureEngineToZoneEventPayloads, CaptureEngineToZoneEventType, type CapturePublicEventPayloads, CapturePublicEventType, type CaptureToEngineEventPayloads, CaptureToEngineEventType, type CaptureZoneEventPayloads, type ExternalTemplate, type ExternalTemplateZone, type ExternalZoneType, type OcrRead, type OcrWord, type TemplateZoneBase, type ZoneCanvasManager, type ZoneExample, type ZoneKind, type ZoneOcrMatch };
package/dist/index.js CHANGED
@@ -488,11 +488,8 @@ var SimpleZone = class extends CaptureZoneBase {
488
488
  let isFirstMatch = true;
489
489
  for (const match of ocrMatches) {
490
490
  if (match.templateZoneId != this.id) continue;
491
- if (isFirstMatch) {
492
- this.example = match.processedText;
493
- }
494
491
  if (!this.hidden) {
495
- this.ocrOverlayIds.push(this.canvasManager?.addPolygon(match.polygonAbsolute.points, "rgba(0, 255, 0, 0.25)", false));
492
+ this.ocrOverlayIds.push(this.canvasManager?.addPolygon(match.polygonAbsolute.points, "rgba(0, 255, 255, 0.25)", false));
496
493
  }
497
494
  break;
498
495
  }
@@ -512,7 +509,7 @@ var SimpleZone = class extends CaptureZoneBase {
512
509
  const captureOcrMatchesLoadedPayload = payload;
513
510
  let ocrMatches = captureOcrMatchesLoadedPayload.ocrMatches;
514
511
  let thisOcrMatches = ocrMatches?.filter((e) => e.templateZoneId == this.id) ?? [];
515
- let matchHash = this.hidden + "|" + thisOcrMatches.map((e) => `${e.ocrTextResultId}*${e.anchorPointPercent}`).join(",");
512
+ let matchHash = this.hidden + "|" + thisOcrMatches.map((e) => `${e.ocrTextResultIds.sort().join(",")}*${e.anchorPointPercent}`).join(",");
516
513
  if (matchHash !== this.lastMatchHash) {
517
514
  this.lastMatchHash = matchHash;
518
515
  this.emitZoneEvent(CaptureZoneEventType.ZoneOcrMatchesChanged, { matches: ocrMatches });
@@ -534,7 +531,7 @@ var SimpleZone = class extends CaptureZoneBase {
534
531
  return;
535
532
  }
536
533
  let thisOcrMatches = ocrMatches?.filter((e) => e.templateZoneId == this.id) ?? [];
537
- let matchHash = this.hidden + "|" + thisOcrMatches.map((e) => `${e.ocrTextResultId}`).join(",");
534
+ let matchHash = this.hidden + "|" + thisOcrMatches.map((e) => `${e.ocrTextResultIds.sort().join(",")}`).join(",");
538
535
  if (matchHash === this.lastMatchHash) {
539
536
  return;
540
537
  }
@@ -542,9 +539,6 @@ var SimpleZone = class extends CaptureZoneBase {
542
539
  this.lastMatchHash = matchHash;
543
540
  let isFirstMatch = true;
544
541
  for (const match of thisOcrMatches) {
545
- if (isFirstMatch) {
546
- this.example = match.processedText;
547
- }
548
542
  if (!this.hidden) {
549
543
  this.ocrOverlayIds.push(canvas.addPolygon(match.polygonAbsolute.points, "rgba(0, 255, 0, 0.25)", false));
550
544
  }
@@ -552,7 +546,6 @@ var SimpleZone = class extends CaptureZoneBase {
552
546
  }
553
547
  }
554
548
  toExternal(docWidth, docHeight) {
555
- console.log(`Sim x:${this.rect.origin.x}, y:${this.rect.origin.y}, w:${this.rect.size.width}, h:${this.rect.size.height}`);
556
549
  return {
557
550
  TemplateZoneId: this.id,
558
551
  Name: this.name,
@@ -582,6 +575,7 @@ var AnchorChildZone = class extends SimpleZone {
582
575
  }
583
576
  toExternalChild(docWidth, docHeight, parentAnchor) {
584
577
  let external = this.toExternal(docWidth, docHeight);
578
+ if (!external) return null;
585
579
  external.Type = "TemplateAnchorZoneChild";
586
580
  const parentAnchorPercent = new Point(parentAnchor.x / docWidth, parentAnchor.y / docHeight);
587
581
  external.X = this.rect.origin.x / docWidth - parentAnchorPercent.x;
@@ -718,9 +712,6 @@ var AnchorZone = class extends CaptureZoneBase {
718
712
  let cycle = this.cycle;
719
713
  for (const match of ocrMatches) {
720
714
  if (match.templateZoneId != this.id) continue;
721
- if (isFirstMatch) {
722
- this.example = match.processedText;
723
- }
724
715
  if (!this.hidden) {
725
716
  this.ocrOverlayIds.push(this.canvasManager?.addPolygon(match.polygonAbsolute.points, "rgba(0, 255, 0, 0.25)", false));
726
717
  }
@@ -779,7 +770,7 @@ var AnchorZone = class extends CaptureZoneBase {
779
770
  const captureOcrMatchesLoadedPayload = payload;
780
771
  let ocrMatches = captureOcrMatchesLoadedPayload.ocrMatches;
781
772
  let thisOcrMatches = ocrMatches?.filter((e) => e.templateZoneId == this.id) ?? [];
782
- let matchHash = this.groupChildren + "|" + this.anchorLocation + "|" + this.hidden + "|" + thisOcrMatches.map((e) => `${e.ocrTextResultId}*${e.anchorPointPercent?.x}*${e.anchorPointPercent?.y}`).join(",") + "|" + this.children.map((e) => `${e.id}*${e.hidden}*${e.rect?.origin.x}*${e.rect?.origin.y}*${e.rect?.size.width}*${e.rect?.size.height}`).join(",");
773
+ let matchHash = this.groupChildren + "|" + this.anchorLocation + "|" + this.hidden + "|" + thisOcrMatches.map((e) => `${e.ocrTextResultIds.sort().join(",")}*${e.anchorPointPercent?.x}*${e.anchorPointPercent?.y}`).join(",") + "|" + this.children.map((e) => `${e.id}*${e.hidden}*${e.rect?.origin.x}*${e.rect?.origin.y}*${e.rect?.size.width}*${e.rect?.size.height}`).join(",");
783
774
  if (matchHash !== this.lastMatchHash) {
784
775
  this.lastMatchHash = matchHash;
785
776
  this.emitZoneEvent(CaptureZoneEventType.ZoneOcrMatchesChanged, { matches: ocrMatches });
@@ -787,53 +778,6 @@ var AnchorZone = class extends CaptureZoneBase {
787
778
  }
788
779
  }
789
780
  }
790
- update(ocrRead, ocrMatches, canvas, flags) {
791
- if (!this.primaryCanvasRectangleId) {
792
- this.primaryCanvasRectangleId = canvas.addRectangle(this.rect, this.name, "green", true, true);
793
- } else {
794
- canvas.setName(this.primaryCanvasRectangleId, this.name);
795
- canvas.setColor(this.primaryCanvasRectangleId, "green");
796
- canvas.setVisibility(this.primaryCanvasRectangleId, !this.hidden);
797
- canvas.setSelectable(this.primaryCanvasRectangleId, true);
798
- canvas.setResizable(this.primaryCanvasRectangleId, true);
799
- canvas.setRectangleSize(this.primaryCanvasRectangleId, this.rect);
800
- }
801
- let thisOcrMatches = ocrMatches?.filter((e) => e.templateZoneId == this.id) ?? [];
802
- let matchHash = this.hidden + "|" + thisOcrMatches.map((e) => `${e.ocrTextResultId}`).join(",") + "|" + this.children.map((e) => `${e.id}*${e.hidden}`).join(",");
803
- if (matchHash === this.lastMatchHash) {
804
- return;
805
- }
806
- this.ocrOverlayIds.forEach((id) => canvas.removeObject(id));
807
- this.lastMatchHash = matchHash;
808
- let isFirstMatch = true;
809
- for (const match of thisOcrMatches) {
810
- if (isFirstMatch) {
811
- this.example = match.processedText;
812
- }
813
- if (!this.hidden) {
814
- this.ocrOverlayIds.push(canvas.addPolygon(match.polygonAbsolute.points, "rgba(0, 255, 0, 0.25)", false));
815
- }
816
- if (match.anchorPointAbsolute) {
817
- if (!this.hidden) {
818
- this.ocrOverlayIds.push(canvas.addCircle(match.anchorPointAbsolute, 2, "rgba(0, 0, 255, 0.25)", false, false));
819
- }
820
- if (!isFirstMatch) {
821
- for (const child of this.children) {
822
- if (child.hidden == false) {
823
- let vector = this.currentAnchorPoint ? match.anchorPointAbsolute.getDeltaFromPoint(this.currentAnchorPoint) : new Vector(0, 0);
824
- let color = "rgba(128, 128, 255, 0.5)";
825
- const polygon = child.rect.move(vector).toPolygon().points;
826
- this.ocrOverlayIds.push(canvas.addPolygon(polygon, color, false));
827
- }
828
- }
829
- }
830
- if (this.currentAnchorPoint === null || isFirstMatch) {
831
- this.currentAnchorPoint = match.anchorPointAbsolute;
832
- }
833
- }
834
- isFirstMatch = false;
835
- }
836
- }
837
781
  onChildZoneAdded(childZone) {
838
782
  this.emitToEngine(CaptureToEngineEventType.ZoneChildZoneAdded, { parentZone: this, newChildZone: childZone });
839
783
  }
@@ -864,7 +808,7 @@ var AnchorZone = class extends CaptureZoneBase {
864
808
  AnchorLocationXAbsoluteHint: this.currentAnchorPoint?.x,
865
809
  AnchorLocationYAbsoluteHint: this.currentAnchorPoint?.y,
866
810
  GroupChildrenInSubRecord: this.groupChildren,
867
- ChildZones: this.children.map((e) => e instanceof AnchorChildZone ? e.toExternalChild(docWidth, docHeight, this.currentAnchorPoint || this.rect.origin) : e.toExternal(docWidth, docHeight))
811
+ ChildZones: this.children.map((e) => e instanceof AnchorChildZone ? e.toExternalChild(docWidth, docHeight, this.currentAnchorPoint || this.rect.origin) ?? null : e.toExternal(docWidth, docHeight) ?? null).filter((e) => e !== null)
868
812
  };
869
813
  }
870
814
  };
@@ -1322,15 +1266,6 @@ var CaptureEngine = class {
1322
1266
  const docWidth = this.width;
1323
1267
  const docHeight = this.height;
1324
1268
  this.getOcrMatchesSnapshot();
1325
- console.log(this.zones.filter((e) => e.name == "Anchor 1").map((e) => {
1326
- let extParent = e.toExternal(docWidth, docHeight);
1327
- if (extParent.ChildZones && extParent.ChildZones.length > 0) {
1328
- let ext = extParent.ChildZones[0];
1329
- return { x: ext.X, y: ext.Y, width: ext.Width, height: ext.Height };
1330
- } else {
1331
- return "no child";
1332
- }
1333
- }));
1334
1269
  return {
1335
1270
  Name: this._name ?? "Untitled",
1336
1271
  DocumentWidth: docWidth,
@@ -1664,6 +1599,22 @@ var CaptureEngine = class {
1664
1599
  get mode() {
1665
1600
  return this.engine.mode;
1666
1601
  }
1602
+ /* --- EXAMPLES --- */
1603
+ setZoneExamples(zoneExamples, setMissingExamplesToNull = true) {
1604
+ for (const zone of this.allZonesFlattened) {
1605
+ let wasSet = false;
1606
+ for (const example of zoneExamples ?? []) {
1607
+ if (example.templateZoneId === zone.id) {
1608
+ zone.example = example.exampleText;
1609
+ wasSet = true;
1610
+ break;
1611
+ }
1612
+ }
1613
+ if (!wasSet && setMissingExamplesToNull) {
1614
+ zone.example = null;
1615
+ }
1616
+ }
1617
+ }
1667
1618
  /* --- OCR --- */
1668
1619
  /**
1669
1620
  * Render the current OCR snapshot as non-interactive polygons on the canvas.
@@ -1733,7 +1684,7 @@ var CaptureEngine = class {
1733
1684
  setOcrMatchesSnapshot(matches) {
1734
1685
  const absoluteMatches = matches.map((m) => ({
1735
1686
  templateZoneId: m.templateZoneId,
1736
- ocrTextResultId: m.ocrTextResultId,
1687
+ ocrTextResultIds: m.ocrTextResultIds,
1737
1688
  originalText: m.originalText,
1738
1689
  processedText: m.processedText,
1739
1690
  polygonPercent: m.polygonPercent,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dytools-capture-engine",
3
- "version": "1.1.2",
3
+ "version": "1.2.0",
4
4
  "description": "An editor allowing the creation of templates for ocr capture.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",