@semiont/api-client 0.2.28-build.37 → 0.2.28-build.38

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.
@@ -3507,6 +3507,45 @@ interface ResourceCreationDetails {
3507
3507
  */
3508
3508
  declare function getResourceCreationDetails(event: StoredEvent): ResourceCreationDetails | null;
3509
3509
 
3510
+ /**
3511
+ * Fuzzy Anchoring for W3C Web Annotation TextQuoteSelector
3512
+ *
3513
+ * Uses prefix/suffix context to disambiguate when the same text appears multiple times.
3514
+ * Implements fuzzy matching as specified in the W3C Web Annotation Data Model.
3515
+ *
3516
+ * @see https://www.w3.org/TR/annotation-model/#text-quote-selector
3517
+ */
3518
+ interface TextPosition {
3519
+ start: number;
3520
+ end: number;
3521
+ }
3522
+ /**
3523
+ * Find text using exact match with optional prefix/suffix context
3524
+ *
3525
+ * When the exact text appears multiple times in the content, prefix and suffix
3526
+ * are used to disambiguate and find the correct occurrence.
3527
+ *
3528
+ * @param content - Full text content to search within
3529
+ * @param exact - The exact text to find
3530
+ * @param prefix - Optional text that should appear immediately before the match
3531
+ * @param suffix - Optional text that should appear immediately after the match
3532
+ * @returns Position of the matched text, or null if not found
3533
+ *
3534
+ * @example
3535
+ * ```typescript
3536
+ * const content = "The cat sat. The cat ran.";
3537
+ * // Find second "The cat" occurrence
3538
+ * const pos = findTextWithContext(content, "The cat", "sat. ", " ran");
3539
+ * // Returns { start: 13, end: 20 }
3540
+ * ```
3541
+ */
3542
+ declare function findTextWithContext(content: string, exact: string, prefix?: string, suffix?: string): TextPosition | null;
3543
+ /**
3544
+ * Verify that a position correctly points to the exact text
3545
+ * Useful for debugging and validation
3546
+ */
3547
+ declare function verifyPosition(content: string, position: TextPosition, expectedExact: string): boolean;
3548
+
3510
3549
  /**
3511
3550
  * Locale information
3512
3551
  * Copied from SDK for frontend use
@@ -3571,6 +3610,84 @@ declare function getChecksum(resource: ResourceDescriptor | undefined): string |
3571
3610
  */
3572
3611
  declare function getLanguage(resource: ResourceDescriptor | undefined): string | undefined;
3573
3612
 
3613
+ /**
3614
+ * SVG Utility Functions
3615
+ *
3616
+ * Utilities for creating, parsing, and manipulating W3C-compliant SVG selectors
3617
+ * for image annotation.
3618
+ */
3619
+ interface Point {
3620
+ x: number;
3621
+ y: number;
3622
+ }
3623
+ interface BoundingBox {
3624
+ x: number;
3625
+ y: number;
3626
+ width: number;
3627
+ height: number;
3628
+ }
3629
+ /**
3630
+ * Create W3C-compliant SVG rectangle selector
3631
+ */
3632
+ declare function createRectangleSvg(start: Point, end: Point): string;
3633
+ /**
3634
+ * Create W3C-compliant SVG polygon selector
3635
+ */
3636
+ declare function createPolygonSvg(points: Point[]): string;
3637
+ /**
3638
+ * Create W3C-compliant SVG circle selector
3639
+ */
3640
+ declare function createCircleSvg(center: Point, radius: number): string;
3641
+ /**
3642
+ * Parse SVG selector to extract shape type and data
3643
+ */
3644
+ declare function parseSvgSelector(svg: string): {
3645
+ type: 'rect' | 'polygon' | 'circle' | 'path';
3646
+ data: any;
3647
+ } | null;
3648
+ /**
3649
+ * Normalize coordinates from display space to image native resolution
3650
+ */
3651
+ declare function normalizeCoordinates(point: Point, displayWidth: number, displayHeight: number, imageWidth: number, imageHeight: number): Point;
3652
+ /**
3653
+ * Scale entire SVG selector from display space to image native resolution
3654
+ */
3655
+ declare function scaleSvgToNative(svg: string, displayWidth: number, displayHeight: number, imageWidth: number, imageHeight: number): string;
3656
+
3657
+ /**
3658
+ * Text encoding utilities for consistent charset handling
3659
+ *
3660
+ * Ensures frontend decoding matches backend decoding by respecting
3661
+ * charset parameters in mediaType (e.g., "text/plain; charset=iso-8859-1")
3662
+ */
3663
+ /**
3664
+ * Extract charset from mediaType parameter
3665
+ *
3666
+ * @param mediaType - Media type with optional charset (e.g., "text/plain; charset=utf-8")
3667
+ * @returns Charset name in lowercase (defaults to "utf-8")
3668
+ *
3669
+ * @example
3670
+ * extractCharset("text/plain; charset=iso-8859-1") // "iso-8859-1"
3671
+ * extractCharset("text/plain") // "utf-8"
3672
+ */
3673
+ declare function extractCharset(mediaType: string): string;
3674
+ /**
3675
+ * Decode ArrayBuffer to string using charset from mediaType
3676
+ *
3677
+ * Uses TextDecoder with the charset extracted from mediaType parameter.
3678
+ * This ensures the same character space is used for both annotation creation
3679
+ * (backend) and rendering (frontend).
3680
+ *
3681
+ * @param buffer - Binary data to decode
3682
+ * @param mediaType - Media type with optional charset parameter
3683
+ * @returns Decoded string in the original character space
3684
+ *
3685
+ * @example
3686
+ * const buffer = new Uint8Array([...]);
3687
+ * const text = decodeWithCharset(buffer, "text/plain; charset=iso-8859-1");
3688
+ */
3689
+ declare function decodeWithCharset(buffer: ArrayBuffer, mediaType: string): string;
3690
+
3574
3691
  /**
3575
3692
  * Generic validation utilities for @semiont/api-client
3576
3693
  *
@@ -3628,4 +3745,4 @@ declare function validateData<T>(schema: {
3628
3745
  */
3629
3746
  declare function isValidEmail(email: string): boolean;
3630
3747
 
3631
- export { type $defs as $, type AccessToken as A, type BaseUrl as B, type ContentFormat as C, getTagSchemaId as D, type EntityType as E, isStubReference as F, type GoogleCredential as G, isResolvedReference as H, getExactText as I, type JobId as J, getAnnotationExactText as K, getPrimarySelector as L, type Motivation as M, getTextPositionSelector as N, getTextQuoteSelector as O, getSvgSelector as P, validateSvgMarkup as Q, type ResourceUri as R, type SearchQuery as S, type TextPositionSelector as T, type UserDID as U, extractBoundingBox as V, type StoredEvent as W, type EventMetadata as X, type ResourceEventType as Y, getAnnotationUriFromEvent as Z, isEventRelatedToAnnotation as _, type AnnotationUri as a, isResourceEvent as a0, formatEventType as a1, getEventEmoji as a2, formatRelativeTime as a3, getEventDisplayContent as a4, getEventEntityTypes as a5, type ResourceCreationDetails as a6, getResourceCreationDetails as a7, type LocaleInfo as a8, LOCALES as a9, userDID as aA, entityType as aB, searchQuery as aC, baseUrl as aD, resourceUri as aE, annotationUri as aF, resourceAnnotationUri as aG, type ResourceEvent as aH, getLocaleInfo as aa, getLocaleNativeName as ab, getLocaleEnglishName as ac, formatLocaleDisplay as ad, getAllLocaleCodes as ae, getResourceId as af, getPrimaryRepresentation as ag, getPrimaryMediaType as ah, getChecksum as ai, getLanguage as aj, type ValidationSuccess as ak, type ValidationFailure as al, type ValidationResult as am, JWTTokenSchema as an, validateData as ao, isValidEmail as ap, type AuthCode as aq, type MCPToken as ar, email as as, authCode as at, googleCredential as au, accessToken as av, refreshToken as aw, mcpToken as ax, cloneToken as ay, jobId as az, type Email as b, type components as c, type RefreshToken as d, type CloneToken as e, type ResourceAnnotationUri as f, type TextQuoteSelector as g, type SvgSelector as h, type Selector as i, getBodySource as j, getBodyType as k, isBodyResolved as l, getTargetSource as m, getTargetSelector as n, type operations as o, type paths as p, hasTargetSelector as q, getEntityTypes as r, isHighlight as s, isReference as t, isAssessment as u, isComment as v, type webhooks as w, isTag as x, getCommentText as y, getTagCategory as z };
3748
+ export { type $defs as $, type AccessToken as A, type BaseUrl as B, type ContentFormat as C, getTagSchemaId as D, type EntityType as E, isStubReference as F, type GoogleCredential as G, isResolvedReference as H, getExactText as I, type JobId as J, getAnnotationExactText as K, getPrimarySelector as L, type Motivation as M, getTextPositionSelector as N, getTextQuoteSelector as O, getSvgSelector as P, validateSvgMarkup as Q, type ResourceUri as R, type SearchQuery as S, type TextPositionSelector as T, type UserDID as U, extractBoundingBox as V, type StoredEvent as W, type EventMetadata as X, type ResourceEventType as Y, getAnnotationUriFromEvent as Z, isEventRelatedToAnnotation as _, type AnnotationUri as a, isResourceEvent as a0, formatEventType as a1, getEventEmoji as a2, formatRelativeTime as a3, getEventDisplayContent as a4, getEventEntityTypes as a5, type ResourceCreationDetails as a6, getResourceCreationDetails as a7, type TextPosition as a8, findTextWithContext as a9, JWTTokenSchema as aA, validateData as aB, isValidEmail as aC, type AuthCode as aD, type MCPToken as aE, email as aF, authCode as aG, googleCredential as aH, accessToken as aI, refreshToken as aJ, mcpToken as aK, cloneToken as aL, jobId as aM, userDID as aN, entityType as aO, searchQuery as aP, baseUrl as aQ, resourceUri as aR, annotationUri as aS, resourceAnnotationUri as aT, type ResourceEvent as aU, verifyPosition as aa, type LocaleInfo as ab, LOCALES as ac, getLocaleInfo as ad, getLocaleNativeName as ae, getLocaleEnglishName as af, formatLocaleDisplay as ag, getAllLocaleCodes as ah, getResourceId as ai, getPrimaryRepresentation as aj, getPrimaryMediaType as ak, getChecksum as al, getLanguage as am, type Point as an, type BoundingBox as ao, createRectangleSvg as ap, createPolygonSvg as aq, createCircleSvg as ar, parseSvgSelector as as, normalizeCoordinates as at, scaleSvgToNative as au, extractCharset as av, decodeWithCharset as aw, type ValidationSuccess as ax, type ValidationFailure as ay, type ValidationResult as az, type Email as b, type components as c, type RefreshToken as d, type CloneToken as e, type ResourceAnnotationUri as f, type TextQuoteSelector as g, type SvgSelector as h, type Selector as i, getBodySource as j, getBodyType as k, isBodyResolved as l, getTargetSource as m, getTargetSelector as n, type operations as o, type paths as p, hasTargetSelector as q, getEntityTypes as r, isHighlight as s, isReference as t, isAssessment as u, isComment as v, type webhooks as w, isTag as x, getCommentText as y, getTagCategory as z };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { B as BaseUrl, A as AccessToken, R as ResourceUri, E as EntityType, a as AnnotationUri, c as components, b as Email, p as paths, d as RefreshToken, G as GoogleCredential, C as ContentFormat, S as SearchQuery, e as CloneToken, f as ResourceAnnotationUri, M as Motivation, U as UserDID, J as JobId } from './index-DHh0ToZB.js';
2
- export { $ as $defs, aq as AuthCode, X as EventMetadata, an as JWTTokenSchema, a9 as LOCALES, a8 as LocaleInfo, ar as MCPToken, a6 as ResourceCreationDetails, Y as ResourceEventType, i as Selector, W as StoredEvent, h as SvgSelector, T as TextPositionSelector, g as TextQuoteSelector, al as ValidationFailure, am as ValidationResult, ak as ValidationSuccess, av as accessToken, aF as annotationUri, at as authCode, aD as baseUrl, ay as cloneToken, as as email, aB as entityType, V as extractBoundingBox, a1 as formatEventType, ad as formatLocaleDisplay, a3 as formatRelativeTime, ae as getAllLocaleCodes, K as getAnnotationExactText, Z as getAnnotationUriFromEvent, j as getBodySource, k as getBodyType, ai as getChecksum, y as getCommentText, r as getEntityTypes, a4 as getEventDisplayContent, a2 as getEventEmoji, a5 as getEventEntityTypes, I as getExactText, aj as getLanguage, ac as getLocaleEnglishName, aa as getLocaleInfo, ab as getLocaleNativeName, ah as getPrimaryMediaType, ag as getPrimaryRepresentation, L as getPrimarySelector, a7 as getResourceCreationDetails, af as getResourceId, P as getSvgSelector, z as getTagCategory, D as getTagSchemaId, n as getTargetSelector, m as getTargetSource, N as getTextPositionSelector, O as getTextQuoteSelector, au as googleCredential, q as hasTargetSelector, u as isAssessment, l as isBodyResolved, v as isComment, _ as isEventRelatedToAnnotation, s as isHighlight, t as isReference, H as isResolvedReference, a0 as isResourceEvent, F as isStubReference, x as isTag, ap as isValidEmail, az as jobId, ax as mcpToken, o as operations, aw as refreshToken, aG as resourceAnnotationUri, aE as resourceUri, aC as searchQuery, aA as userDID, ao as validateData, Q as validateSvgMarkup, w as webhooks } from './index-DHh0ToZB.js';
1
+ import { B as BaseUrl, A as AccessToken, R as ResourceUri, E as EntityType, a as AnnotationUri, c as components, b as Email, p as paths, d as RefreshToken, G as GoogleCredential, C as ContentFormat, S as SearchQuery, e as CloneToken, f as ResourceAnnotationUri, M as Motivation, U as UserDID, J as JobId } from './index-CBMGI-nS.js';
2
+ export { $ as $defs, aD as AuthCode, ao as BoundingBox, X as EventMetadata, aA as JWTTokenSchema, ac as LOCALES, ab as LocaleInfo, aE as MCPToken, an as Point, a6 as ResourceCreationDetails, Y as ResourceEventType, i as Selector, W as StoredEvent, h as SvgSelector, a8 as TextPosition, T as TextPositionSelector, g as TextQuoteSelector, ay as ValidationFailure, az as ValidationResult, ax as ValidationSuccess, aI as accessToken, aS as annotationUri, aG as authCode, aQ as baseUrl, aL as cloneToken, ar as createCircleSvg, aq as createPolygonSvg, ap as createRectangleSvg, aw as decodeWithCharset, aF as email, aO as entityType, V as extractBoundingBox, av as extractCharset, a9 as findTextWithContext, a1 as formatEventType, ag as formatLocaleDisplay, a3 as formatRelativeTime, ah as getAllLocaleCodes, K as getAnnotationExactText, Z as getAnnotationUriFromEvent, j as getBodySource, k as getBodyType, al as getChecksum, y as getCommentText, r as getEntityTypes, a4 as getEventDisplayContent, a2 as getEventEmoji, a5 as getEventEntityTypes, I as getExactText, am as getLanguage, af as getLocaleEnglishName, ad as getLocaleInfo, ae as getLocaleNativeName, ak as getPrimaryMediaType, aj as getPrimaryRepresentation, L as getPrimarySelector, a7 as getResourceCreationDetails, ai as getResourceId, P as getSvgSelector, z as getTagCategory, D as getTagSchemaId, n as getTargetSelector, m as getTargetSource, N as getTextPositionSelector, O as getTextQuoteSelector, aH as googleCredential, q as hasTargetSelector, u as isAssessment, l as isBodyResolved, v as isComment, _ as isEventRelatedToAnnotation, s as isHighlight, t as isReference, H as isResolvedReference, a0 as isResourceEvent, F as isStubReference, x as isTag, aC as isValidEmail, aM as jobId, aK as mcpToken, at as normalizeCoordinates, o as operations, as as parseSvgSelector, aJ as refreshToken, aT as resourceAnnotationUri, aR as resourceUri, au as scaleSvgToNative, aP as searchQuery, aN as userDID, aB as validateData, Q as validateSvgMarkup, aa as verifyPosition, w as webhooks } from './index-CBMGI-nS.js';
3
3
 
4
4
  /**
5
5
  * TypeScript types for Server-Sent Events (SSE) streaming
package/dist/index.js CHANGED
@@ -1537,6 +1537,60 @@ function getResourceCreationDetails(event) {
1537
1537
  return null;
1538
1538
  }
1539
1539
 
1540
+ // src/utils/fuzzy-anchor.ts
1541
+ function findTextWithContext(content, exact, prefix, suffix) {
1542
+ if (!exact) return null;
1543
+ const occurrences = [];
1544
+ let index = content.indexOf(exact);
1545
+ while (index !== -1) {
1546
+ occurrences.push(index);
1547
+ index = content.indexOf(exact, index + 1);
1548
+ }
1549
+ if (occurrences.length === 0) {
1550
+ console.warn(`[FuzzyAnchor] Text not found: "${exact.substring(0, 50)}..."`);
1551
+ return null;
1552
+ }
1553
+ if (occurrences.length === 1) {
1554
+ const pos2 = occurrences[0];
1555
+ return { start: pos2, end: pos2 + exact.length };
1556
+ }
1557
+ if (prefix || suffix) {
1558
+ for (const pos2 of occurrences) {
1559
+ const actualPrefixStart = Math.max(0, pos2 - (prefix?.length || 0));
1560
+ const actualPrefix = content.substring(actualPrefixStart, pos2);
1561
+ const actualSuffixEnd = Math.min(content.length, pos2 + exact.length + (suffix?.length || 0));
1562
+ const actualSuffix = content.substring(pos2 + exact.length, actualSuffixEnd);
1563
+ const prefixMatch = !prefix || actualPrefix.endsWith(prefix);
1564
+ const suffixMatch = !suffix || actualSuffix.startsWith(suffix);
1565
+ if (prefixMatch && suffixMatch) {
1566
+ return { start: pos2, end: pos2 + exact.length };
1567
+ }
1568
+ }
1569
+ console.warn(
1570
+ `[FuzzyAnchor] Multiple matches found but none match prefix/suffix exactly. Exact: "${exact.substring(0, 30)}...", Prefix: "${prefix?.substring(0, 20) || "none"}", Suffix: "${suffix?.substring(0, 20) || "none"}"`
1571
+ );
1572
+ for (const pos2 of occurrences) {
1573
+ const actualPrefix = content.substring(Math.max(0, pos2 - (prefix?.length || 0)), pos2);
1574
+ const actualSuffix = content.substring(pos2 + exact.length, pos2 + exact.length + (suffix?.length || 0));
1575
+ const fuzzyPrefixMatch = !prefix || actualPrefix.includes(prefix.trim());
1576
+ const fuzzySuffixMatch = !suffix || actualSuffix.includes(suffix.trim());
1577
+ if (fuzzyPrefixMatch && fuzzySuffixMatch) {
1578
+ console.warn(`[FuzzyAnchor] Using fuzzy match at position ${pos2}`);
1579
+ return { start: pos2, end: pos2 + exact.length };
1580
+ }
1581
+ }
1582
+ }
1583
+ console.warn(
1584
+ `[FuzzyAnchor] Multiple matches but no context match. Using first occurrence. Exact: "${exact.substring(0, 30)}..."`
1585
+ );
1586
+ const pos = occurrences[0];
1587
+ return { start: pos, end: pos + exact.length };
1588
+ }
1589
+ function verifyPosition(content, position, expectedExact) {
1590
+ const actualText = content.substring(position.start, position.end);
1591
+ return actualText === expectedExact;
1592
+ }
1593
+
1540
1594
  // src/utils/locales.ts
1541
1595
  var LOCALES = [
1542
1596
  { code: "ar", nativeName: "\u0627\u0644\u0639\u0631\u0628\u064A\u0629", englishName: "Arabic" },
@@ -1618,6 +1672,113 @@ function getLanguage(resource) {
1618
1672
  return getPrimaryRepresentation(resource)?.language;
1619
1673
  }
1620
1674
 
1675
+ // src/utils/svg-utils.ts
1676
+ function createRectangleSvg(start, end) {
1677
+ const x = Math.min(start.x, end.x);
1678
+ const y = Math.min(start.y, end.y);
1679
+ const width = Math.abs(end.x - start.x);
1680
+ const height = Math.abs(end.y - start.y);
1681
+ return `<svg xmlns="http://www.w3.org/2000/svg"><rect x="${x}" y="${y}" width="${width}" height="${height}"/></svg>`;
1682
+ }
1683
+ function createPolygonSvg(points) {
1684
+ if (points.length < 3) {
1685
+ throw new Error("Polygon requires at least 3 points");
1686
+ }
1687
+ const pointsStr = points.map((p) => `${p.x},${p.y}`).join(" ");
1688
+ return `<svg xmlns="http://www.w3.org/2000/svg"><polygon points="${pointsStr}"/></svg>`;
1689
+ }
1690
+ function createCircleSvg(center, radius) {
1691
+ if (radius <= 0) {
1692
+ throw new Error("Circle radius must be positive");
1693
+ }
1694
+ return `<svg xmlns="http://www.w3.org/2000/svg"><circle cx="${center.x}" cy="${center.y}" r="${radius}"/></svg>`;
1695
+ }
1696
+ function parseSvgSelector(svg) {
1697
+ const rectMatch = svg.match(/<rect\s+([^>]+)\/>/);
1698
+ if (rectMatch && rectMatch[1]) {
1699
+ const attrs = rectMatch[1];
1700
+ const x = parseFloat(attrs.match(/x="([^"]+)"/)?.[1] || "0");
1701
+ const y = parseFloat(attrs.match(/y="([^"]+)"/)?.[1] || "0");
1702
+ const width = parseFloat(attrs.match(/width="([^"]+)"/)?.[1] || "0");
1703
+ const height = parseFloat(attrs.match(/height="([^"]+)"/)?.[1] || "0");
1704
+ return {
1705
+ type: "rect",
1706
+ data: { x, y, width, height }
1707
+ };
1708
+ }
1709
+ const polygonMatch = svg.match(/<polygon\s+points="([^"]+)"/);
1710
+ if (polygonMatch && polygonMatch[1]) {
1711
+ const pointsStr = polygonMatch[1];
1712
+ const points = pointsStr.split(/\s+/).map((pair) => {
1713
+ const [x, y] = pair.split(",").map(parseFloat);
1714
+ return { x, y };
1715
+ });
1716
+ return {
1717
+ type: "polygon",
1718
+ data: { points }
1719
+ };
1720
+ }
1721
+ const circleMatch = svg.match(/<circle\s+([^>]+)\/>/);
1722
+ if (circleMatch && circleMatch[1]) {
1723
+ const attrs = circleMatch[1];
1724
+ const cx = parseFloat(attrs.match(/cx="([^"]+)"/)?.[1] || "0");
1725
+ const cy = parseFloat(attrs.match(/cy="([^"]+)"/)?.[1] || "0");
1726
+ const r = parseFloat(attrs.match(/r="([^"]+)"/)?.[1] || "0");
1727
+ return {
1728
+ type: "circle",
1729
+ data: { cx, cy, r }
1730
+ };
1731
+ }
1732
+ return null;
1733
+ }
1734
+ function normalizeCoordinates(point, displayWidth, displayHeight, imageWidth, imageHeight) {
1735
+ return {
1736
+ x: point.x / displayWidth * imageWidth,
1737
+ y: point.y / displayHeight * imageHeight
1738
+ };
1739
+ }
1740
+ function scaleSvgToNative(svg, displayWidth, displayHeight, imageWidth, imageHeight) {
1741
+ const parsed = parseSvgSelector(svg);
1742
+ if (!parsed) return svg;
1743
+ const scaleX = imageWidth / displayWidth;
1744
+ const scaleY = imageHeight / displayHeight;
1745
+ switch (parsed.type) {
1746
+ case "rect": {
1747
+ const { x, y, width, height } = parsed.data;
1748
+ return createRectangleSvg(
1749
+ { x: x * scaleX, y: y * scaleY },
1750
+ { x: (x + width) * scaleX, y: (y + height) * scaleY }
1751
+ );
1752
+ }
1753
+ case "circle": {
1754
+ const { cx, cy, r } = parsed.data;
1755
+ return createCircleSvg(
1756
+ { x: cx * scaleX, y: cy * scaleY },
1757
+ r * Math.min(scaleX, scaleY)
1758
+ );
1759
+ }
1760
+ case "polygon": {
1761
+ const points = parsed.data.points.map((p) => ({
1762
+ x: p.x * scaleX,
1763
+ y: p.y * scaleY
1764
+ }));
1765
+ return createPolygonSvg(points);
1766
+ }
1767
+ }
1768
+ return svg;
1769
+ }
1770
+
1771
+ // src/utils/text-encoding.ts
1772
+ function extractCharset(mediaType) {
1773
+ const charsetMatch = mediaType.match(/charset=([^\s;]+)/i);
1774
+ return (charsetMatch?.[1] || "utf-8").toLowerCase();
1775
+ }
1776
+ function decodeWithCharset(buffer, mediaType) {
1777
+ const charset = extractCharset(mediaType);
1778
+ const decoder = new TextDecoder(charset);
1779
+ return decoder.decode(buffer);
1780
+ }
1781
+
1621
1782
  // src/utils/validation.ts
1622
1783
  var JWTTokenSchema = {
1623
1784
  parse(token) {
@@ -1690,6 +1851,6 @@ function getMimeCategory(mimeType) {
1690
1851
  return "unsupported";
1691
1852
  }
1692
1853
 
1693
- export { APIError, JWTTokenSchema, LOCALES, SSEClient, SemiontApiClient, accessToken, annotationUri, authCode, baseUrl, cloneToken, email, entityType, extractBoundingBox, formatEventType, formatLocaleDisplay, formatRelativeTime, getAllLocaleCodes, getAnnotationExactText, getAnnotationUriFromEvent, getBodySource, getBodyType, getChecksum, getCommentText, getEntityTypes, getEventDisplayContent, getEventEmoji, getEventEntityTypes, getExactText, getExtensionForMimeType, getLanguage, getLocaleEnglishName, getLocaleInfo, getLocaleNativeName, getMimeCategory, getPrimaryMediaType, getPrimaryRepresentation, getPrimarySelector, getResourceCreationDetails, getResourceId, getSvgSelector, getTagCategory, getTagSchemaId, getTargetSelector, getTargetSource, getTextPositionSelector, getTextQuoteSelector, googleCredential, hasTargetSelector, isAssessment, isBodyResolved, isComment, isEventRelatedToAnnotation, isHighlight, isImageMimeType, isReference, isResolvedReference, isResourceEvent, isStubReference, isTag, isTextMimeType, isValidEmail, jobId, mcpToken, refreshToken, resourceAnnotationUri, resourceUri, searchQuery, userDID, validateData, validateSvgMarkup };
1854
+ export { APIError, JWTTokenSchema, LOCALES, SSEClient, SemiontApiClient, accessToken, annotationUri, authCode, baseUrl, cloneToken, createCircleSvg, createPolygonSvg, createRectangleSvg, decodeWithCharset, email, entityType, extractBoundingBox, extractCharset, findTextWithContext, formatEventType, formatLocaleDisplay, formatRelativeTime, getAllLocaleCodes, getAnnotationExactText, getAnnotationUriFromEvent, getBodySource, getBodyType, getChecksum, getCommentText, getEntityTypes, getEventDisplayContent, getEventEmoji, getEventEntityTypes, getExactText, getExtensionForMimeType, getLanguage, getLocaleEnglishName, getLocaleInfo, getLocaleNativeName, getMimeCategory, getPrimaryMediaType, getPrimaryRepresentation, getPrimarySelector, getResourceCreationDetails, getResourceId, getSvgSelector, getTagCategory, getTagSchemaId, getTargetSelector, getTargetSource, getTextPositionSelector, getTextQuoteSelector, googleCredential, hasTargetSelector, isAssessment, isBodyResolved, isComment, isEventRelatedToAnnotation, isHighlight, isImageMimeType, isReference, isResolvedReference, isResourceEvent, isStubReference, isTag, isTextMimeType, isValidEmail, jobId, mcpToken, normalizeCoordinates, parseSvgSelector, refreshToken, resourceAnnotationUri, resourceUri, scaleSvgToNative, searchQuery, userDID, validateData, validateSvgMarkup, verifyPosition };
1694
1855
  //# sourceMappingURL=index.js.map
1695
1856
  //# sourceMappingURL=index.js.map