@procore/ai-translations 0.5.0 → 0.6.1

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.
@@ -52,6 +52,9 @@ var Config = class _Config {
52
52
  setToolName(name) {
53
53
  this.toolName = name;
54
54
  }
55
+ isBackendTranslationStrategy() {
56
+ return this.ToolConfig.strategy === "backend_translations";
57
+ }
55
58
  getToolName() {
56
59
  return this.toolName;
57
60
  }
@@ -393,6 +396,19 @@ var _Storage = class _Storage {
393
396
  }
394
397
  }
395
398
  // ------------------------------------
399
+ // 🗑️ Clear Translation by ID
400
+ // ------------------------------------
401
+ static async deleteById(id) {
402
+ try {
403
+ const db = await _Storage.getDB();
404
+ await db.delete(_Storage.STORE_NAME, id);
405
+ return true;
406
+ } catch (error) {
407
+ console.error("[Storage] Failed to delete by id:", error);
408
+ return false;
409
+ }
410
+ }
411
+ // ------------------------------------
396
412
  // 🗑️ Clear All Translations
397
413
  // ------------------------------------
398
414
  static async clearAll() {
@@ -479,7 +495,9 @@ var _TranslationRegistry = class _TranslationRegistry {
479
495
  async removeTextsFromEnqueued(texts, targetLanguage, strategy) {
480
496
  for (const text of texts) {
481
497
  const id = await Storage.generateId(text, targetLanguage, this.tool);
482
- _TranslationRegistry.enqueuedItems.delete(`${id}:${strategy}`);
498
+ _TranslationRegistry.enqueuedItems.delete(
499
+ this.generateEnqueuedKey(id, strategy)
500
+ );
483
501
  }
484
502
  }
485
503
  static removeFromEnqueued(key) {
@@ -488,10 +506,19 @@ var _TranslationRegistry = class _TranslationRegistry {
488
506
  generateEnqueuedKey(id, strategy) {
489
507
  return `${id}:${strategy}`;
490
508
  }
491
- async get(text, targetLanguage, tool) {
509
+ async get(text, targetLanguage, tool, config2) {
492
510
  const key = await Hash.generateFromMultiple([text, targetLanguage, tool]);
493
- if (_TranslationRegistry.memoryCache.has(key)) {
494
- return _TranslationRegistry.memoryCache.get(key);
511
+ const cached = _TranslationRegistry.memoryCache.get(key);
512
+ if (cached) {
513
+ if (cached.translationStrategy === "frontend_translations" && config2.isBackendTranslationStrategy()) {
514
+ _TranslationRegistry.memoryCache.delete(key);
515
+ if (cached.translatedText) {
516
+ _TranslationRegistry.originalTextIndex.delete(cached.translatedText);
517
+ }
518
+ await Storage.deleteById(key);
519
+ return void 0;
520
+ }
521
+ return cached;
495
522
  }
496
523
  const translation = await Storage.getTranslation(
497
524
  text,
@@ -499,6 +526,10 @@ var _TranslationRegistry = class _TranslationRegistry {
499
526
  tool
500
527
  );
501
528
  if (translation !== void 0) {
529
+ if (translation.translation_strategy === "frontend_translations" && config2.isBackendTranslationStrategy()) {
530
+ await Storage.deleteById(translation.id);
531
+ return void 0;
532
+ }
502
533
  return this.toTranslationRegistryEntry(translation);
503
534
  }
504
535
  return void 0;
@@ -771,19 +802,21 @@ var TranslationManager = class {
771
802
  this.translationProgress.total = queueManager.queueSize(
772
803
  this.currentTranslatorStrategy
773
804
  );
774
- for (const batch of queueManager.generateBatches(
775
- this.translator.getConfig()
776
- )) {
777
- batch.forEach((entry) => this.mfeToBeNotified.add(entry.tool));
778
- const result = await this.translator.processTranslations(
779
- batch.map(
780
- (entry) => this.convertTranslationQueueEntryToTranslationRequest(entry)
781
- )
782
- );
783
- this.setTranslationProgress(batch.length);
784
- await this.updateDatabaseWithTranslations(result);
785
- await this.notifyTranslationCompleted();
786
- }
805
+ do {
806
+ for (const batch of queueManager.generateBatches(
807
+ this.translator.getConfig()
808
+ )) {
809
+ batch.forEach((entry) => this.mfeToBeNotified.add(entry.tool));
810
+ const result = await this.translator.processTranslations(
811
+ batch.map(
812
+ (entry) => this.convertTranslationQueueEntryToTranslationRequest(entry)
813
+ )
814
+ );
815
+ this.setTranslationProgress(batch.length);
816
+ await this.updateDatabaseWithTranslations(result);
817
+ await this.notifyTranslationCompleted();
818
+ }
819
+ } while (queueManager.queueSize(this.currentTranslatorStrategy) > 0);
787
820
  this.resetTranslationProgress();
788
821
  this.publishTranslationProgress();
789
822
  if (this.currentTranslatorStrategy === "frontend_translations") {
@@ -937,8 +970,16 @@ var Client = class {
937
970
  method: "POST",
938
971
  body: JSON.stringify(requests)
939
972
  });
973
+ const responseBody = Array.isArray(data) ? data.map((group) => ({
974
+ ...group,
975
+ translations: Array.isArray(group.translations) ? group.translations.map((t) => ({
976
+ ...t,
977
+ isTranslated: t.isTranslated ?? (!!t.translation && t.translation !== ""),
978
+ retryable: t.retryable ?? true
979
+ })) : []
980
+ })) : data;
940
981
  return {
941
- responseBody: data,
982
+ responseBody,
942
983
  success: true
943
984
  };
944
985
  } catch (error) {
@@ -1016,11 +1057,54 @@ var getModelDownloadEventHandler = () => {
1016
1057
  }
1017
1058
  return _modelDownloadEventHandler;
1018
1059
  };
1060
+ var SUPPORTED_LANGUAGES = /* @__PURE__ */ new Set([
1061
+ "ar",
1062
+ "bn",
1063
+ "bg",
1064
+ "zh",
1065
+ "hr",
1066
+ "cs",
1067
+ "da",
1068
+ "nl",
1069
+ "en",
1070
+ "fi",
1071
+ "fr",
1072
+ "de",
1073
+ "el",
1074
+ "he",
1075
+ "hi",
1076
+ "hu",
1077
+ "id",
1078
+ "it",
1079
+ "ja",
1080
+ "kn",
1081
+ "ko",
1082
+ "lt",
1083
+ "mr",
1084
+ "no",
1085
+ "pl",
1086
+ "pt",
1087
+ "ro",
1088
+ "ru",
1089
+ "sk",
1090
+ "sl",
1091
+ "es",
1092
+ "sv",
1093
+ "ta",
1094
+ "te",
1095
+ "th",
1096
+ "tr",
1097
+ "uk",
1098
+ "vi"
1099
+ ]);
1019
1100
  var _ChromeTranslator = class _ChromeTranslator {
1020
1101
  constructor(translator) {
1021
1102
  __publicField(this, "translator");
1022
1103
  this.translator = translator;
1023
1104
  }
1105
+ static isSupportedLanguage(lang) {
1106
+ return SUPPORTED_LANGUAGES.has(lang) || SUPPORTED_LANGUAGES.has(lang.split("-")[0] ?? "");
1107
+ }
1024
1108
  static ensureRegistry() {
1025
1109
  if (!globalThis.chromeTranslatorRegistry) {
1026
1110
  globalThis.chromeTranslatorRegistry = /* @__PURE__ */ new Map();
@@ -1042,30 +1126,31 @@ var _ChromeTranslator = class _ChromeTranslator {
1042
1126
  );
1043
1127
  }
1044
1128
  static async createTranslator(source, target) {
1129
+ const key = this.generateKey(source, target);
1045
1130
  let resolveReady;
1046
- this.translatorReadyPromise = new Promise((resolve) => {
1131
+ const readyPromise = new Promise((resolve) => {
1047
1132
  resolveReady = resolve;
1048
1133
  });
1134
+ this.translatorReadyPromises.set(key, readyPromise);
1049
1135
  let isDownloading = false;
1050
1136
  const translator = await Translator.create({
1051
1137
  sourceLanguage: source,
1052
1138
  targetLanguage: target,
1053
1139
  monitor(m) {
1054
- m.addEventListener(
1055
- "downloadprogress",
1056
- (e) => {
1057
- isDownloading = true;
1058
- const progress = e.total > 0 ? Math.round(e.loaded / e.total * 100) : 0;
1059
- getModelDownloadEventHandler().publishModelDownloadProgressEvent(
1060
- e.loaded,
1061
- e.total,
1062
- progress
1063
- );
1064
- if (e.loaded === e.total) {
1065
- resolveReady();
1066
- }
1140
+ m.addEventListener("downloadprogress", (e) => {
1141
+ isDownloading = true;
1142
+ const loaded = e.loaded ?? 0;
1143
+ const total = e.total ?? 0;
1144
+ const progress = total > 0 ? Math.round(loaded / total * 100) : 0;
1145
+ getModelDownloadEventHandler().publishModelDownloadProgressEvent(
1146
+ loaded,
1147
+ total,
1148
+ progress
1149
+ );
1150
+ if (total > 0 && loaded >= total) {
1151
+ resolveReady();
1067
1152
  }
1068
- );
1153
+ });
1069
1154
  }
1070
1155
  });
1071
1156
  if (!isDownloading) {
@@ -1073,8 +1158,8 @@ var _ChromeTranslator = class _ChromeTranslator {
1073
1158
  }
1074
1159
  return translator;
1075
1160
  }
1076
- static waitForReady() {
1077
- return this.translatorReadyPromise;
1161
+ static waitForReady(key) {
1162
+ return this.translatorReadyPromises.get(key) ?? Promise.resolve();
1078
1163
  }
1079
1164
  static async translate(text, targetLanguage) {
1080
1165
  var _a;
@@ -1083,8 +1168,17 @@ var _ChromeTranslator = class _ChromeTranslator {
1083
1168
  const detector = await ChromeLanguageDetector.getInstance();
1084
1169
  const sourceLanguage = await detector.detectLanguage(text);
1085
1170
  const key = this.generateKey(sourceLanguage, targetLanguage);
1086
- let instance = globalThis.chromeTranslatorRegistry.get(key);
1087
- if (!instance) {
1171
+ if (!this.isSupportedLanguage(sourceLanguage) || !this.isSupportedLanguage(targetLanguage)) {
1172
+ return {
1173
+ translation: text,
1174
+ sourceLanguage,
1175
+ success: false,
1176
+ retryable: false,
1177
+ errorMessage: `Unsupported language pair: ${sourceLanguage} \u2192 ${targetLanguage}`
1178
+ };
1179
+ }
1180
+ const existingInstance = globalThis.chromeTranslatorRegistry.get(key);
1181
+ if (!existingInstance) {
1088
1182
  const translatorCapabilities = await Translator.availability({
1089
1183
  sourceLanguage,
1090
1184
  targetLanguage
@@ -1102,10 +1196,16 @@ var _ChromeTranslator = class _ChromeTranslator {
1102
1196
  sourceLanguage,
1103
1197
  targetLanguage
1104
1198
  );
1105
- instance = new _ChromeTranslator(chromeTranslator);
1106
- globalThis.chromeTranslatorRegistry.set(key, instance);
1199
+ if (!globalThis.chromeTranslatorRegistry.has(key)) {
1200
+ globalThis.chromeTranslatorRegistry.set(
1201
+ key,
1202
+ new _ChromeTranslator(chromeTranslator)
1203
+ );
1204
+ }
1107
1205
  }
1108
- await this.waitForReady();
1206
+ const instance = globalThis.chromeTranslatorRegistry.get(key);
1207
+ await this.waitForReady(key);
1208
+ this.translatorReadyPromises.delete(key);
1109
1209
  const translation = await ((_a = instance.translator) == null ? void 0 : _a.translate(text));
1110
1210
  if (!translation) {
1111
1211
  return {
@@ -1113,7 +1213,7 @@ var _ChromeTranslator = class _ChromeTranslator {
1113
1213
  sourceLanguage,
1114
1214
  success: false,
1115
1215
  errorMessage: "Translation failed",
1116
- retryable: true
1216
+ retryable: false
1117
1217
  };
1118
1218
  }
1119
1219
  return {
@@ -1123,11 +1223,12 @@ var _ChromeTranslator = class _ChromeTranslator {
1123
1223
  retryable: true
1124
1224
  };
1125
1225
  } catch (error) {
1226
+ const message = error instanceof Error ? error.message : "Unknown error";
1126
1227
  return {
1127
1228
  translation: text,
1128
1229
  sourceLanguage: targetLanguage,
1129
1230
  success: false,
1130
- errorMessage: error instanceof Error ? error.message : "Unknown error",
1231
+ errorMessage: message,
1131
1232
  retryable: true
1132
1233
  };
1133
1234
  }
@@ -1136,7 +1237,7 @@ var _ChromeTranslator = class _ChromeTranslator {
1136
1237
  return `${sourceLanguage.toUpperCase()}-${targetLanguage.toUpperCase()}`;
1137
1238
  }
1138
1239
  };
1139
- __publicField(_ChromeTranslator, "translatorReadyPromise", Promise.resolve());
1240
+ __publicField(_ChromeTranslator, "translatorReadyPromises", /* @__PURE__ */ new Map());
1140
1241
  var ChromeTranslator = _ChromeTranslator;
1141
1242
 
1142
1243
  // src/translators/frontend_translators/chrome/client.ts
@@ -1286,7 +1387,8 @@ var aitFunction = async (text, translationRegistry, config2, tool) => {
1286
1387
  const existingByOriginal = await translationRegistry.get(
1287
1388
  text,
1288
1389
  targetLanguage,
1289
- tool
1390
+ tool,
1391
+ config2
1290
1392
  );
1291
1393
  if (existingByOriginal && existingByOriginal.isTranslated && existingByOriginal.translatedText && existingByOriginal.translatedText.trim() !== "") {
1292
1394
  return existingByOriginal.translatedText;
@@ -1347,7 +1449,12 @@ function AITranslationInnerProvider(props) {
1347
1449
  companyId,
1348
1450
  userId,
1349
1451
  projectId,
1350
- enableAIT = true
1452
+ enableAIT = true,
1453
+ companyLocale,
1454
+ projectLocale,
1455
+ onTrackAnalyticsEvent,
1456
+ page,
1457
+ scope
1351
1458
  } = props;
1352
1459
  const [translationProgress, setTranslationProgress] = useState(null);
1353
1460
  const [modelDownloadProgress, setModelDownloadProgress] = useState(null);
@@ -1403,15 +1510,15 @@ function AITranslationInnerProvider(props) {
1403
1510
  return () => unsubscribe();
1404
1511
  }, []);
1405
1512
  useEffect(() => {
1406
- if (isFetched && remoteConfig && remoteConfig[tool]) {
1407
- setConfig((prevConfig) => {
1408
- const clonedConfig = prevConfig.clone();
1409
- clonedConfig.setTargetLanguage(locale);
1410
- clonedConfig.setToolConfig(remoteConfig[tool]);
1411
- translator.current.updateConfig(clonedConfig);
1412
- return clonedConfig;
1413
- });
1414
- }
1513
+ if (!isFetched || !remoteConfig) return;
1514
+ const toolConfig = remoteConfig[tool] ?? remoteConfig;
1515
+ setConfig((prevConfig) => {
1516
+ const clonedConfig = prevConfig.clone();
1517
+ clonedConfig.setTargetLanguage(locale);
1518
+ clonedConfig.setToolConfig(toolConfig);
1519
+ translator.current.updateConfig(clonedConfig);
1520
+ return clonedConfig;
1521
+ });
1415
1522
  }, [tool, remoteConfig, isFetched, locale]);
1416
1523
  config2.setTargetLanguage(locale);
1417
1524
  config2.setToolName(tool);
@@ -1424,10 +1531,15 @@ function AITranslationInnerProvider(props) {
1424
1531
  const contextValue = {
1425
1532
  ait,
1426
1533
  locale,
1534
+ companyLocale,
1535
+ projectLocale,
1427
1536
  renderVersion: renderVersionManager.getVersion(),
1428
1537
  translationProgress,
1429
1538
  modelDownloadProgress,
1430
- tool
1539
+ tool,
1540
+ onTrackAnalyticsEvent,
1541
+ page,
1542
+ scope
1431
1543
  };
1432
1544
  return /* @__PURE__ */ jsx(AITranslationContext.Provider, { value: contextValue, children });
1433
1545
  }
@@ -1447,12 +1559,140 @@ function useAITranslation() {
1447
1559
  return ctx;
1448
1560
  }
1449
1561
 
1562
+ // src/hooks/useAIAnalytics.ts
1563
+ import { useContext as useContext2, useCallback as useCallback2 } from "react";
1564
+
1565
+ // src/analytics/events.ts
1566
+ var BUTTON_TYPE = {
1567
+ TRANSLATE: "translate",
1568
+ HIGHLIGHT: "highlight"
1569
+ };
1570
+ var ACTION = {
1571
+ CLICKED: "clicked"
1572
+ };
1573
+ function buildObject(pageContext, buttonType) {
1574
+ return `${pageContext}_${buttonType}_button`;
1575
+ }
1576
+ function buildEventKey(parts) {
1577
+ const { scope, tool, object, action } = parts;
1578
+ return `ux.web.feature.${scope}.${tool}.${object}.${action}`;
1579
+ }
1580
+ function buildAnalyticEvent(params) {
1581
+ const {
1582
+ scope,
1583
+ tool,
1584
+ pageContext,
1585
+ buttonType,
1586
+ baseProperties,
1587
+ action,
1588
+ additionalProperties
1589
+ } = params;
1590
+ const resolvedAction = action ?? ACTION.CLICKED;
1591
+ const object = buildObject(pageContext, buttonType);
1592
+ const key = buildEventKey({
1593
+ scope,
1594
+ tool,
1595
+ object,
1596
+ action: resolvedAction
1597
+ });
1598
+ const properties = {
1599
+ ...baseProperties,
1600
+ ...additionalProperties
1601
+ };
1602
+ return { key, properties };
1603
+ }
1604
+
1605
+ // src/hooks/useAIAnalytics.ts
1606
+ function useAIAnalytics() {
1607
+ const ctx = useContext2(AITranslationContext);
1608
+ if (!ctx) {
1609
+ throw new Error(
1610
+ "useAIAnalytics must be used inside an AITranslationProvider"
1611
+ );
1612
+ }
1613
+ const {
1614
+ locale,
1615
+ companyLocale,
1616
+ projectLocale,
1617
+ tool,
1618
+ page,
1619
+ scope,
1620
+ onTrackAnalyticsEvent
1621
+ } = ctx;
1622
+ const isTrackingEnabled = Boolean(onTrackAnalyticsEvent);
1623
+ const buildBaseProperties = useCallback2(() => {
1624
+ const props = {
1625
+ user_locale: locale,
1626
+ tool,
1627
+ page: page ?? ""
1628
+ };
1629
+ if (companyLocale) props.company_locale = companyLocale;
1630
+ if (projectLocale) props.project_locale = projectLocale;
1631
+ return props;
1632
+ }, [locale, tool, page, companyLocale, projectLocale]);
1633
+ const trackTranslateButtonClicked = useCallback2(
1634
+ (additionalProperties) => {
1635
+ if (!onTrackAnalyticsEvent || !page || !scope) return;
1636
+ onTrackAnalyticsEvent(
1637
+ buildAnalyticEvent({
1638
+ scope,
1639
+ tool,
1640
+ pageContext: page,
1641
+ buttonType: BUTTON_TYPE.TRANSLATE,
1642
+ baseProperties: buildBaseProperties(),
1643
+ additionalProperties
1644
+ })
1645
+ );
1646
+ },
1647
+ [onTrackAnalyticsEvent, tool, page, scope, buildBaseProperties]
1648
+ );
1649
+ const trackHighlightButtonClicked = useCallback2(
1650
+ (additionalProperties) => {
1651
+ if (!onTrackAnalyticsEvent || !page || !scope) return;
1652
+ onTrackAnalyticsEvent(
1653
+ buildAnalyticEvent({
1654
+ scope,
1655
+ tool,
1656
+ pageContext: page,
1657
+ buttonType: BUTTON_TYPE.HIGHLIGHT,
1658
+ baseProperties: buildBaseProperties(),
1659
+ additionalProperties
1660
+ })
1661
+ );
1662
+ },
1663
+ [onTrackAnalyticsEvent, tool, page, scope, buildBaseProperties]
1664
+ );
1665
+ const trackCustomEvent = useCallback2(
1666
+ (buttonType, action, additionalProperties) => {
1667
+ if (!onTrackAnalyticsEvent || !page || !scope) return;
1668
+ onTrackAnalyticsEvent(
1669
+ buildAnalyticEvent({
1670
+ scope,
1671
+ tool,
1672
+ pageContext: page,
1673
+ buttonType,
1674
+ baseProperties: buildBaseProperties(),
1675
+ action,
1676
+ additionalProperties
1677
+ })
1678
+ );
1679
+ },
1680
+ [onTrackAnalyticsEvent, tool, page, scope, buildBaseProperties]
1681
+ );
1682
+ return {
1683
+ trackTranslateButtonClicked,
1684
+ trackHighlightButtonClicked,
1685
+ trackCustomEvent,
1686
+ isTrackingEnabled
1687
+ };
1688
+ }
1689
+
1450
1690
  // src/components/AITranslateText.tsx
1451
1691
  import {
1452
1692
  useState as useState2,
1453
1693
  useEffect as useEffect2,
1454
- useContext as useContext2,
1455
- useCallback as useCallback2,
1694
+ useContext as useContext3,
1695
+ useCallback as useCallback3,
1456
1696
  useRef as useRef2
1457
1697
  } from "react";
1458
1698
 
@@ -1460,8 +1700,8 @@ import {
1460
1700
  import "react";
1461
1701
  import { jsx as jsx2 } from "react/jsx-runtime";
1462
1702
  var TranslatedIcon = ({
1463
- width = 14,
1464
- height = 14,
1703
+ width = 24,
1704
+ height = 24,
1465
1705
  className,
1466
1706
  color = "#000000"
1467
1707
  }) => {
@@ -1474,11 +1714,12 @@ var TranslatedIcon = ({
1474
1714
  className,
1475
1715
  xmlns: "http://www.w3.org/2000/svg",
1476
1716
  "aria-hidden": "true",
1717
+ style: { marginRight: "10px", flexShrink: 0 },
1477
1718
  children: /* @__PURE__ */ jsx2(
1478
1719
  "path",
1479
1720
  {
1480
1721
  fill: color,
1481
- d: "M12.87,15.07l-2.54,-2.51 0.03,-0.03c1.74,-1.94 2.98,-4.17 3.71,-6.53L17,6L17,4h-7L10,2L8,2v2L1,4v1.99h11.17C11.5,7.92 10.44,9.75 9,11.35 8.07,10.32 7.3,9.19 6.69,8h-2c0.73,1.63 1.73,3.17 2.98,4.56l-5.09,5.02L4,19l5,-5 3.11,3.11 0.76,-2.04zM18.5,10h-2L12,22h2l1.12,-3h4.75L21,22h2l-4.5,-12zM15.88,17l1.62,-4.33L19.12,17h-3.24z"
1722
+ d: "M11.99 2C6.47 2 2 6.48 2 12C2 17.52 6.47 22 11.99 22C17.52 22 22 17.52 22 12C22 6.48 17.52 2 11.99 2ZM18.92 8H15.97C15.65 6.75 15.19 5.55 14.59 4.44C16.43 5.07 17.96 6.35 18.92 8ZM12 4.04C12.83 5.24 13.48 6.57 13.91 8H10.09C10.52 6.57 11.17 5.24 12 4.04ZM4.26 14C4.1 13.36 4 12.69 4 12C4 11.31 4.1 10.64 4.26 10H7.64C7.56 10.66 7.5 11.32 7.5 12C7.5 12.68 7.56 13.34 7.64 14H4.26ZM5.08 16H8.03C8.35 17.25 8.81 18.45 9.41 19.56C7.57 18.93 6.04 17.66 5.08 16ZM8.03 8H5.08C6.04 6.34 7.57 5.07 9.41 4.44C8.81 5.55 8.35 6.75 8.03 8ZM12 19.96C11.17 18.76 10.52 17.43 10.09 16H13.91C13.48 17.43 12.83 18.76 12 19.96ZM14.34 14H9.66C9.57 13.34 9.5 12.68 9.5 12C9.5 11.32 9.57 10.65 9.66 10H14.34C14.43 10.65 14.5 11.32 14.5 12C14.5 12.68 14.43 13.34 14.34 14ZM14.59 19.56C15.19 18.45 15.65 17.25 15.97 16H18.92C17.96 17.65 16.43 18.93 14.59 19.56ZM16.36 14C16.44 13.34 16.5 12.68 16.5 12C16.5 11.32 16.44 10.66 16.36 10H19.74C19.9 10.64 20 11.31 20 12C20 12.69 19.9 13.36 19.74 14H16.36Z"
1482
1723
  }
1483
1724
  )
1484
1725
  }
@@ -1493,7 +1734,7 @@ var AITranslateText = ({
1493
1734
  showHighlight = false,
1494
1735
  translatedIconProps
1495
1736
  }) => {
1496
- const context = useContext2(AITranslationContext);
1737
+ const context = useContext3(AITranslationContext);
1497
1738
  const [displayText, setDisplayText] = useState2(text ?? "");
1498
1739
  const [showHighlightState, setShowHighlightState] = useState2(showHighlight);
1499
1740
  const eventHandlerRef = useRef2(null);
@@ -1516,7 +1757,7 @@ var AITranslateText = ({
1516
1757
  );
1517
1758
  return () => unsubscribe();
1518
1759
  }, [context, text, showHighlight]);
1519
- const reset = useCallback2(
1760
+ const reset = useCallback3(
1520
1761
  (displayValue = text) => {
1521
1762
  setDisplayText(displayValue);
1522
1763
  setShowHighlightState(false);
@@ -1550,8 +1791,8 @@ var AITranslateText = ({
1550
1791
  };
1551
1792
  }, [text, shouldTranslate, context, showHighlight, reset]);
1552
1793
  return /* @__PURE__ */ jsxs(Fragment, { children: [
1553
- displayText,
1554
- showHighlightState && /* @__PURE__ */ jsx3(TranslatedIcon, { ...translatedIconProps })
1794
+ showHighlightState && /* @__PURE__ */ jsx3(TranslatedIcon, { ...translatedIconProps }),
1795
+ displayText
1555
1796
  ] });
1556
1797
  };
1557
1798
 
@@ -1574,10 +1815,16 @@ var getAITranslationLDId = (domain) => {
1574
1815
  }
1575
1816
  };
1576
1817
  export {
1818
+ ACTION,
1577
1819
  AITranslateText,
1578
1820
  AITranslationProvider,
1579
1821
  AI_TRANSLATION_FEATURE_FLAG_KEY,
1822
+ BUTTON_TYPE,
1823
+ buildAnalyticEvent,
1824
+ buildEventKey,
1825
+ buildObject,
1580
1826
  getAITranslationLDId,
1827
+ useAIAnalytics,
1581
1828
  useAITranslation,
1582
1829
  useConfig
1583
1830
  };