@oxy.so/core 7.9.0 → 7.9.2

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.
Files changed (86) hide show
  1. package/dist/cjs/HttpService.js +113 -12
  2. package/dist/cjs/i18n/compactLocale.js +36 -0
  3. package/dist/cjs/i18n/compactLocaleValues.generated.js +4 -0
  4. package/dist/cjs/i18n/index.js +15 -15
  5. package/dist/cjs/i18n/locales/compact/ar-SA.generated.js +5 -0
  6. package/dist/cjs/i18n/locales/compact/bn-BD.generated.js +5 -0
  7. package/dist/cjs/i18n/locales/compact/ca-ES.generated.js +5 -0
  8. package/dist/cjs/i18n/locales/compact/de-DE.generated.js +5 -0
  9. package/dist/cjs/i18n/locales/compact/es-ES.generated.js +5 -0
  10. package/dist/cjs/i18n/locales/compact/fr-FR.generated.js +5 -0
  11. package/dist/cjs/i18n/locales/compact/hi-IN.generated.js +5 -0
  12. package/dist/cjs/i18n/locales/compact/id-ID.generated.js +5 -0
  13. package/dist/cjs/i18n/locales/compact/it-IT.generated.js +5 -0
  14. package/dist/cjs/i18n/locales/compact/ja-JP.generated.js +5 -0
  15. package/dist/cjs/i18n/locales/compact/ko-KR.generated.js +5 -0
  16. package/dist/cjs/i18n/locales/compact/pt-PT.generated.js +5 -0
  17. package/dist/cjs/i18n/locales/compact/ru-RU.generated.js +5 -0
  18. package/dist/cjs/i18n/locales/compact/tr-TR.generated.js +5 -0
  19. package/dist/cjs/i18n/locales/compact/zh-CN.generated.js +5 -0
  20. package/dist/cjs/shared/utils/errorUtils.js +5 -2
  21. package/dist/cjs/utils/asyncUtils.js +6 -0
  22. package/dist/cjs/utils/authHelpers.js +3 -0
  23. package/dist/esm/HttpService.js +113 -12
  24. package/dist/esm/i18n/compactLocale.js +30 -0
  25. package/dist/esm/i18n/compactLocaleValues.generated.js +2 -0
  26. package/dist/esm/i18n/index.js +15 -15
  27. package/dist/esm/i18n/locales/compact/ar-SA.generated.js +3 -0
  28. package/dist/esm/i18n/locales/compact/bn-BD.generated.js +3 -0
  29. package/dist/esm/i18n/locales/compact/ca-ES.generated.js +3 -0
  30. package/dist/esm/i18n/locales/compact/de-DE.generated.js +3 -0
  31. package/dist/esm/i18n/locales/compact/es-ES.generated.js +3 -0
  32. package/dist/esm/i18n/locales/compact/fr-FR.generated.js +3 -0
  33. package/dist/esm/i18n/locales/compact/hi-IN.generated.js +3 -0
  34. package/dist/esm/i18n/locales/compact/id-ID.generated.js +3 -0
  35. package/dist/esm/i18n/locales/compact/it-IT.generated.js +3 -0
  36. package/dist/esm/i18n/locales/compact/ja-JP.generated.js +3 -0
  37. package/dist/esm/i18n/locales/compact/ko-KR.generated.js +3 -0
  38. package/dist/esm/i18n/locales/compact/pt-PT.generated.js +3 -0
  39. package/dist/esm/i18n/locales/compact/ru-RU.generated.js +3 -0
  40. package/dist/esm/i18n/locales/compact/tr-TR.generated.js +3 -0
  41. package/dist/esm/i18n/locales/compact/zh-CN.generated.js +3 -0
  42. package/dist/esm/shared/utils/errorUtils.js +3 -1
  43. package/dist/esm/utils/asyncUtils.js +6 -0
  44. package/dist/esm/utils/authHelpers.js +3 -0
  45. package/dist/types/i18n/compactLocale.d.ts +2 -0
  46. package/dist/types/i18n/compactLocaleValues.generated.d.ts +2 -0
  47. package/dist/types/i18n/locales/compact/ar-SA.generated.d.ts +3 -0
  48. package/dist/types/i18n/locales/compact/bn-BD.generated.d.ts +3 -0
  49. package/dist/types/i18n/locales/compact/ca-ES.generated.d.ts +3 -0
  50. package/dist/types/i18n/locales/compact/de-DE.generated.d.ts +3 -0
  51. package/dist/types/i18n/locales/compact/es-ES.generated.d.ts +3 -0
  52. package/dist/types/i18n/locales/compact/fr-FR.generated.d.ts +3 -0
  53. package/dist/types/i18n/locales/compact/hi-IN.generated.d.ts +3 -0
  54. package/dist/types/i18n/locales/compact/id-ID.generated.d.ts +3 -0
  55. package/dist/types/i18n/locales/compact/it-IT.generated.d.ts +3 -0
  56. package/dist/types/i18n/locales/compact/ja-JP.generated.d.ts +3 -0
  57. package/dist/types/i18n/locales/compact/ko-KR.generated.d.ts +3 -0
  58. package/dist/types/i18n/locales/compact/pt-PT.generated.d.ts +3 -0
  59. package/dist/types/i18n/locales/compact/ru-RU.generated.d.ts +3 -0
  60. package/dist/types/i18n/locales/compact/tr-TR.generated.d.ts +3 -0
  61. package/dist/types/i18n/locales/compact/zh-CN.generated.d.ts +3 -0
  62. package/dist/types/shared/utils/errorUtils.d.ts +2 -0
  63. package/package.json +5 -3
  64. package/src/HttpService.ts +122 -12
  65. package/src/i18n/README.md +11 -0
  66. package/src/i18n/compactLocale.ts +32 -0
  67. package/src/i18n/compactLocaleValues.generated.ts +2 -0
  68. package/src/i18n/index.ts +15 -15
  69. package/src/i18n/locales/compact/ar-SA.generated.ts +4 -0
  70. package/src/i18n/locales/compact/bn-BD.generated.ts +4 -0
  71. package/src/i18n/locales/compact/ca-ES.generated.ts +4 -0
  72. package/src/i18n/locales/compact/de-DE.generated.ts +4 -0
  73. package/src/i18n/locales/compact/es-ES.generated.ts +4 -0
  74. package/src/i18n/locales/compact/fr-FR.generated.ts +4 -0
  75. package/src/i18n/locales/compact/hi-IN.generated.ts +4 -0
  76. package/src/i18n/locales/compact/id-ID.generated.ts +4 -0
  77. package/src/i18n/locales/compact/it-IT.generated.ts +4 -0
  78. package/src/i18n/locales/compact/ja-JP.generated.ts +4 -0
  79. package/src/i18n/locales/compact/ko-KR.generated.ts +4 -0
  80. package/src/i18n/locales/compact/pt-PT.generated.ts +4 -0
  81. package/src/i18n/locales/compact/ru-RU.generated.ts +4 -0
  82. package/src/i18n/locales/compact/tr-TR.generated.ts +4 -0
  83. package/src/i18n/locales/compact/zh-CN.generated.ts +4 -0
  84. package/src/shared/utils/errorUtils.ts +5 -1
  85. package/src/utils/asyncUtils.ts +7 -0
  86. package/src/utils/authHelpers.ts +2 -0
@@ -71,6 +71,18 @@ function sameTokenSession(left, right) {
71
71
  'authMethodId',
72
72
  ].every((key) => (a[key] === undefined || typeof a[key] === 'string') && a[key] === b[key]);
73
73
  }
74
+ /** Discard an unused body even when a platform's stream shim lacks cancel. */
75
+ function discardResponseBody(response) {
76
+ try {
77
+ const body = response.body;
78
+ if (typeof body?.cancel !== 'function')
79
+ return Promise.resolve();
80
+ return Promise.resolve(body.cancel()).catch(() => { });
81
+ }
82
+ catch {
83
+ return Promise.resolve();
84
+ }
85
+ }
74
86
  /**
75
87
  * The keys whose presence beside `data` makes a body a PAGE rather than a
76
88
  * payload — see {@link HttpService.unwrapResponse} for why this list is narrow.
@@ -463,6 +475,13 @@ class HttpService {
463
475
  * {@link ResponsePayload}, which makes reading the envelope a compile error.
464
476
  */
465
477
  async request(config) {
478
+ if (config.signal?.aborted)
479
+ throw (0, errorUtils_1.createCancelledError)('Request cancelled before it was sent');
480
+ // The provider can change independently of the last request. Synchronize
481
+ // before deriving the cache and deduplication identity, including hits.
482
+ const explicitAuthorization = Object.keys(config.headers ?? {}).some((key) => key.toLowerCase() === 'authorization');
483
+ if (!config.skipAuth && !explicitAuthorization)
484
+ this.syncAccessTokenFromProvider();
466
485
  // Per-call authority is not represented by the instance's session cache
467
486
  // key. Never share or retain responses authenticated by explicit headers.
468
487
  if (Object.keys(config.headers ?? {}).some((key) => ['authorization', 'x-oxy-user-id'].includes(key.toLowerCase()) ||
@@ -484,7 +503,8 @@ class HttpService {
484
503
  valid: true,
485
504
  });
486
505
  }
487
- const key = this.generateCacheKey(config.method, config.url, config.data || config.params);
506
+ const key = this.generateCacheKey(config.method, config.url, config.data || config.params) +
507
+ (config.skipAuth ? ' auth=none' : '');
488
508
  let lease = this.readLeases.get(key);
489
509
  if (!lease) {
490
510
  lease = { key, id: ++this.nextReadLeaseId, valid: true, readers: 0 };
@@ -514,6 +534,7 @@ class HttpService {
514
534
  // overrides any per-request `cache:true`: nothing is read from nor written
515
535
  // to the response cache. Request deduplication below is unaffected.
516
536
  const cache = cacheRequested && !this.cacheDisabled;
537
+ const cacheSessionEpoch = this.sessionEpoch;
517
538
  // Generate cache key (optimized for large objects)
518
539
  const cacheKey = cache ? lease.key : null;
519
540
  // Check cache first
@@ -538,7 +559,33 @@ class HttpService {
538
559
  // and skip the near-expiry preflight — see RequestOptions.skipAuth. The
539
560
  // 401 retry re-enters request() with a fresh config, so it re-resolves
540
561
  // this here with the refreshed token.
541
- const authHeader = config.skipAuth ? null : await this.getAuthHeader();
562
+ const explicitAuth = Object.keys(config.headers ?? {}).some((key) => key.toLowerCase() === 'authorization');
563
+ const usesSessionAuth = !config.skipAuth && !explicitAuth;
564
+ const contextToken = usesSessionAuth ? this.syncAccessTokenFromProvider() : null;
565
+ const contextEpoch = this.sessionEpoch;
566
+ const authHeader = usesSessionAuth
567
+ ? await (0, requestSignal_1.awaitRequestSignal)(this.getAuthHeader(), signal)
568
+ : null;
569
+ const isOriginalSession = () => this.sessionEpoch === contextEpoch &&
570
+ sameTokenSession(contextToken, this.syncAccessTokenFromProvider());
571
+ const newerRequestToken = () => {
572
+ if (!contextToken || !authHeader?.startsWith('Bearer '))
573
+ return null;
574
+ const requestToken = authHeader.slice('Bearer '.length);
575
+ const current = this.syncAccessTokenFromProvider();
576
+ return current && current !== requestToken && sameTokenSession(requestToken, current)
577
+ ? current
578
+ : null;
579
+ };
580
+ // The provider can change between cache-key selection and auth preflight.
581
+ // Refuse to attach a response to a lease belonging to another identity.
582
+ if (usesSessionAuth &&
583
+ (!isOriginalSession() ||
584
+ (lease.key &&
585
+ (cacheSessionEpoch !== this.sessionEpoch ||
586
+ lease.key !== this.generateCacheKey(method, url, data || params))))) {
587
+ throw new OxyServices_errors_1.OxyAuthenticationError('The request session changed', 'AUTH_SESSION_CHANGED');
588
+ }
542
589
  // Never awaited: the PoP is a hint, and waiting on its trace fetch put up
543
590
  // to a second in front of requests.
544
591
  const edgeRegionHeader = (0, edgeRegion_1.peekBrowserEdgeRegionHeader)();
@@ -561,6 +608,9 @@ class HttpService {
561
608
  if (domain.aborted) {
562
609
  throw (0, errorUtils_1.createCancelledError)('Request cancelled');
563
610
  }
611
+ if (usesSessionAuth && !isOriginalSession()) {
612
+ throw new OxyServices_errors_1.OxyAuthenticationError('The request session changed', 'AUTH_SESSION_CHANGED');
613
+ }
564
614
  /**
565
615
  * Whether OUR timer fired, so a timeout can be told apart from a
566
616
  * cancellation. Both reach us from `fetch` as an indistinguishable
@@ -568,6 +618,7 @@ class HttpService {
568
618
  * an abandoned request as a transient failure.
569
619
  */
570
620
  let timedOut = false;
621
+ let selfClearedEpoch = null;
571
622
  // This attempt's controller carries its own timeout and inherits the
572
623
  // call-wide abort domain. Declared OUTSIDE the `try` so the `finally`
573
624
  // that releases them can see them — the timer and the listener are
@@ -670,14 +721,27 @@ class HttpService {
670
721
  // it, including on every throw between here and there.
671
722
  if (timeoutId)
672
723
  clearTimeout(timeoutId);
724
+ if (usesSessionAuth && !isOriginalSession()) {
725
+ void discardResponseBody(response);
726
+ throw new OxyServices_errors_1.OxyAuthenticationError('The request session changed', 'AUTH_SESSION_CHANGED');
727
+ }
673
728
  // Handle response
674
729
  if (!response.ok) {
675
730
  // On 401, delegate to the installed auth refresh handler and retry
676
731
  // once before giving up. HttpService deliberately does not know any
677
732
  // session routes; the refresh handler owns session rotation.
678
- if (response.status === 401 && !config._isAuthRetry && !config.skipAuth) {
679
- const refreshed = await this.refreshAccessToken('response-401');
680
- if (refreshed) {
733
+ if (response.status === 401 &&
734
+ !config._isAuthRetry &&
735
+ usesSessionAuth &&
736
+ isOriginalSession()) {
737
+ let refreshed = newerRequestToken();
738
+ if (!refreshed) {
739
+ if (domain.aborted)
740
+ throw (0, errorUtils_1.createCancelledError)();
741
+ refreshed = await (0, requestSignal_1.awaitRequestSignal)(this.refreshAccessToken('response-401'), domain);
742
+ }
743
+ refreshed || (refreshed = newerRequestToken());
744
+ if (refreshed && isOriginalSession()) {
681
745
  // `deduplicate: false` is REQUIRED on the retry. This re-issue runs
682
746
  // while the ORIGINAL request is still in-flight under its dedupe
683
747
  // key; the refreshed token is
@@ -696,11 +760,19 @@ class HttpService {
696
760
  retry: false,
697
761
  deduplicate: false,
698
762
  bypassQueue: true,
763
+ // The original caller's signal may be aborted while another
764
+ // deduplicated caller still owns this shared request.
765
+ signal: domain,
699
766
  });
700
767
  }
701
768
  // Refresh failed or no token — clear tokens
702
- this.tokenStore.clearTokens();
703
- this.notifyTokenChange();
769
+ if (isOriginalSession()) {
770
+ if (this.tokenStore.getAccessToken())
771
+ this.sessionEpoch += 1;
772
+ this.tokenStore.clearTokens();
773
+ selfClearedEpoch = this.sessionEpoch;
774
+ this.notifyTokenChange();
775
+ }
704
776
  }
705
777
  // Read the error body (may be absent, non-JSON, empty or malformed).
706
778
  // Anything unreadable leaves `errorBody` undefined and degrades to the
@@ -787,6 +859,9 @@ class HttpService {
787
859
  const text = await response.text();
788
860
  responseData = text || null;
789
861
  }
862
+ if (usesSessionAuth && !isOriginalSession()) {
863
+ throw new OxyServices_errors_1.OxyAuthenticationError('The request session changed', 'AUTH_SESSION_CHANGED');
864
+ }
790
865
  const duration = Date.now() - startTime;
791
866
  this.updateMetrics(true, duration);
792
867
  this.config.onRequestEnd?.(url, method, duration, true);
@@ -795,6 +870,21 @@ class HttpService {
795
870
  catch (error) {
796
871
  const duration = Date.now() - startTime;
797
872
  this.updateMetrics(false, duration);
873
+ // A body reader can reject or finish parsing an error after the viewer
874
+ // changed. Do not surface that previous viewer's error or callbacks.
875
+ // An explicit abort/timeout retains its existing classification.
876
+ const providerToken = selfClearedEpoch !== null ? this.accessTokenProvider?.() : null;
877
+ const originalClearStillCurrent = selfClearedEpoch !== null &&
878
+ selfClearedEpoch === this.sessionEpoch &&
879
+ this.tokenStore.getAccessToken() === null &&
880
+ (!providerToken || sameTokenSession(contextToken, providerToken));
881
+ if (usesSessionAuth &&
882
+ !originalClearStillCurrent &&
883
+ !isOriginalSession() &&
884
+ !isAbortLike(error) &&
885
+ !controller.signal.aborted) {
886
+ throw new OxyServices_errors_1.OxyAuthenticationError('The request session changed', 'AUTH_SESSION_CHANGED');
887
+ }
798
888
  this.config.onRequestEnd?.(url, method, duration, false);
799
889
  this.config.onRequestError?.(url, method, error instanceof Error ? error : new Error(String(error)));
800
890
  // An abort is the one failure whose CAUSE the error cannot carry on its
@@ -886,6 +976,9 @@ class HttpService {
886
976
  disposeCallerLink?.();
887
977
  }
888
978
  }
979
+ if (usesSessionAuth && !isOriginalSession()) {
980
+ throw new OxyServices_errors_1.OxyAuthenticationError('The request session changed', 'AUTH_SESSION_CHANGED');
981
+ }
889
982
  // Cache the result if caching is enabled
890
983
  if (cache && cacheKey && lease.valid && result) {
891
984
  this.cache.set(cacheKey, result, cacheTTL);
@@ -1049,7 +1142,7 @@ class HttpService {
1049
1142
  * in `clearCacheEntry`.
1050
1143
  */
1051
1144
  generateCacheKey(method, url, data) {
1052
- return `${this.generateBaseCacheKey(method, url, data)}${HttpService.CACHE_IDENTITY_DELIM}${this.computeIdentityTag()}`;
1145
+ return `${this.generateBaseCacheKey(method, url, data)}${HttpService.CACHE_IDENTITY_DELIM}${this.computeIdentityTag()} epoch=${this.sessionEpoch}`;
1053
1146
  }
1054
1147
  /**
1055
1148
  * Build the identity-agnostic portion of a cache key (`method:url[:data]`).
@@ -1173,6 +1266,7 @@ class HttpService {
1173
1266
  // on the way out would discard the flag it just set.
1174
1267
  this.lastRefreshWasRateLimited = false;
1175
1268
  const epoch = this.sessionEpoch;
1269
+ const tokenAtStart = this.tokenStore.getAccessToken();
1176
1270
  this.tokenRefreshPromise = this.authRefreshHandler(reason)
1177
1271
  .then((newToken) => {
1178
1272
  if (epoch !== this.sessionEpoch) {
@@ -1185,6 +1279,12 @@ class HttpService {
1185
1279
  this.logger.debug('Discarded a token refresh that outlived its session');
1186
1280
  return null;
1187
1281
  }
1282
+ const installed = this.tokenStore.getAccessToken();
1283
+ if (installed !== tokenAtStart && installed !== newToken) {
1284
+ // Another operation installed a token while this refresh was in
1285
+ // flight. Never overwrite it with this older completion.
1286
+ return installed && sameTokenSession(tokenAtStart, installed) ? installed : null;
1287
+ }
1188
1288
  if (!newToken) {
1189
1289
  this.lastRefreshFailureAt = Date.now();
1190
1290
  return null;
@@ -1482,7 +1582,7 @@ class HttpService {
1482
1582
  assertCurrent();
1483
1583
  }
1484
1584
  catch (error) {
1485
- await response.body?.cancel();
1585
+ await discardResponseBody(response);
1486
1586
  throw error;
1487
1587
  }
1488
1588
  const replayable = Boolean(config.bodyFactory) || body === undefined || typeof body === 'string';
@@ -1496,18 +1596,18 @@ class HttpService {
1496
1596
  refreshed = await (0, requestSignal_1.awaitRequestSignal)(this.refreshAccessToken('response-401'), config.signal);
1497
1597
  }
1498
1598
  catch (error) {
1499
- void response.body?.cancel().catch(() => undefined);
1599
+ void discardResponseBody(response);
1500
1600
  throw error;
1501
1601
  }
1502
1602
  try {
1503
1603
  assertCurrent();
1504
1604
  }
1505
1605
  catch (error) {
1506
- await response.body?.cancel();
1606
+ await discardResponseBody(response);
1507
1607
  throw error;
1508
1608
  }
1509
1609
  if (refreshed) {
1510
- await response.body?.cancel();
1610
+ await discardResponseBody(response);
1511
1611
  if (config.signal?.aborted)
1512
1612
  throw (0, errorUtils_1.createCancelledError)();
1513
1613
  return this.requestResponseAttempt(config, fullUrl, `Bearer ${refreshed}`, true, epoch, contextToken);
@@ -1673,6 +1773,7 @@ class HttpService {
1673
1773
  peekCachedGet(url, params) {
1674
1774
  if (this.cacheDisabled)
1675
1775
  return null;
1776
+ this.syncAccessTokenFromProvider();
1676
1777
  return this.cache.get(this.generateCacheKey('GET', url, params));
1677
1778
  }
1678
1779
  clearCache() {
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.restoreCompactLocale = restoreCompactLocale;
7
+ const compactLocaleValues_generated_1 = __importDefault(require("./compactLocaleValues.generated"));
8
+ function isRecord(value) {
9
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
10
+ }
11
+ function clone(value) {
12
+ if (Array.isArray(value))
13
+ return value.map(clone);
14
+ if (isRecord(value))
15
+ return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, clone(child)]));
16
+ return value;
17
+ }
18
+ /** Reconstruct a complete independent dictionary from generated data. */
19
+ function restoreCompactLocale(value) {
20
+ if (Array.isArray(value)) {
21
+ if (value[0] === -1)
22
+ return clone(value[1]);
23
+ const index = value[0];
24
+ if (typeof index !== 'number' || !Number.isInteger(index) || index < 0) {
25
+ throw new Error('Invalid compact locale reference');
26
+ }
27
+ const literal = compactLocaleValues_generated_1.default[index];
28
+ if (typeof literal !== 'string')
29
+ throw new Error('Invalid compact locale reference');
30
+ return literal;
31
+ }
32
+ if (isRecord(value)) {
33
+ return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, restoreCompactLocale(child)]));
34
+ }
35
+ return value;
36
+ }
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ // Generated by scripts/generateCompactLocales.ts; do not edit.
4
+ exports.default = ["Language", "Commons", "you@example.com", "Email", "Marketing", "About preferences", "Alerts", "Appearance", "Apps you authorize to sign in with your Oxy account will appear here", "Channels", "Connected apps", "Dark", "Email digest", "Failed to revoke access", "Failed to update notification preferences", "Following system: reduce motion is on", "Last used {{relative}}", "Light", "Manage push, email, and security alerts", "Manage third-party app access", "Marketing emails", "Minimise animations across Oxy apps", "No connected apps", "Notifications", "Periodic summary of your account activity", "Preferences", "Preferences sync across every Oxy app you sign into", "Product news and occasional offers", "Push notifications", "Real-time alerts on your devices", "Reduce motion", "Region", "Revoke", "Revoke access", "Revoke {{name}}'s access to your Oxy account?", "Revoked access for {{name}}", "Security alerts", "Sign-ins, recovery codes, and key changes", "System default", "Theme", "Theme, motion, and regional settings", "Timezone", "Unable to detect timezone", "yourname"];
@@ -51,21 +51,21 @@ const FALLBACK = 'en-US';
51
51
  * is the fallback for every missing key, so it is always present.
52
52
  */
53
53
  const LOADERS = {
54
- 'es-ES': () => Promise.resolve().then(() => __importStar(require('./locales/es-ES'))),
55
- 'ca-ES': () => Promise.resolve().then(() => __importStar(require('./locales/ca-ES'))),
56
- 'fr-FR': () => Promise.resolve().then(() => __importStar(require('./locales/fr-FR'))),
57
- 'de-DE': () => Promise.resolve().then(() => __importStar(require('./locales/de-DE'))),
58
- 'it-IT': () => Promise.resolve().then(() => __importStar(require('./locales/it-IT'))),
59
- 'pt-PT': () => Promise.resolve().then(() => __importStar(require('./locales/pt-PT'))),
60
- 'ja-JP': () => Promise.resolve().then(() => __importStar(require('./locales/ja-JP'))),
61
- 'ko-KR': () => Promise.resolve().then(() => __importStar(require('./locales/ko-KR'))),
62
- 'zh-CN': () => Promise.resolve().then(() => __importStar(require('./locales/zh-CN'))),
63
- 'ar-SA': () => Promise.resolve().then(() => __importStar(require('./locales/ar-SA'))),
64
- 'bn-BD': () => Promise.resolve().then(() => __importStar(require('./locales/bn-BD'))),
65
- 'hi-IN': () => Promise.resolve().then(() => __importStar(require('./locales/hi-IN'))),
66
- 'id-ID': () => Promise.resolve().then(() => __importStar(require('./locales/id-ID'))),
67
- 'ru-RU': () => Promise.resolve().then(() => __importStar(require('./locales/ru-RU'))),
68
- 'tr-TR': () => Promise.resolve().then(() => __importStar(require('./locales/tr-TR'))),
54
+ 'es-ES': () => Promise.resolve().then(() => __importStar(require('./locales/compact/es-ES.generated'))),
55
+ 'ca-ES': () => Promise.resolve().then(() => __importStar(require('./locales/compact/ca-ES.generated'))),
56
+ 'fr-FR': () => Promise.resolve().then(() => __importStar(require('./locales/compact/fr-FR.generated'))),
57
+ 'de-DE': () => Promise.resolve().then(() => __importStar(require('./locales/compact/de-DE.generated'))),
58
+ 'it-IT': () => Promise.resolve().then(() => __importStar(require('./locales/compact/it-IT.generated'))),
59
+ 'pt-PT': () => Promise.resolve().then(() => __importStar(require('./locales/compact/pt-PT.generated'))),
60
+ 'ja-JP': () => Promise.resolve().then(() => __importStar(require('./locales/compact/ja-JP.generated'))),
61
+ 'ko-KR': () => Promise.resolve().then(() => __importStar(require('./locales/compact/ko-KR.generated'))),
62
+ 'zh-CN': () => Promise.resolve().then(() => __importStar(require('./locales/compact/zh-CN.generated'))),
63
+ 'ar-SA': () => Promise.resolve().then(() => __importStar(require('./locales/compact/ar-SA.generated'))),
64
+ 'bn-BD': () => Promise.resolve().then(() => __importStar(require('./locales/compact/bn-BD.generated'))),
65
+ 'hi-IN': () => Promise.resolve().then(() => __importStar(require('./locales/compact/hi-IN.generated'))),
66
+ 'id-ID': () => Promise.resolve().then(() => __importStar(require('./locales/compact/id-ID.generated'))),
67
+ 'ru-RU': () => Promise.resolve().then(() => __importStar(require('./locales/compact/ru-RU.generated'))),
68
+ 'tr-TR': () => Promise.resolve().then(() => __importStar(require('./locales/compact/tr-TR.generated'))),
69
69
  };
70
70
  /** Base subtag → the dictionary that serves it. */
71
71
  const ALIASES = {
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ // Generated by scripts/generateCompactLocales.ts; do not edit.
4
+ const compactLocale_1 = require("../../compactLocale");
5
+ exports.default = (0, compactLocale_1.restoreCompactLocale)({ "signin": { "title": "تسجيل الدخول", "subtitle": "استخدم حسابك في Oxy", "addAccountTitle": "إضافة حساب آخر", "addAccountSubtitle": "تسجيل الدخول بحساب آخر", "actions": { "continue": "متابعة", "back": "رجوع" }, "createAccountLink": "جديد على Oxy؟ أنشئ حسابًا", "status": { "signingIn": "جارٍ تسجيل الدخول…" }, "subtitleToApp": "للمتابعة إلى {{app}}", "orContinueWith": "أو تابع باستخدام", "qr": { "caption": "امسح باستخدام Commons لتسجيل الدخول", "renew": "عرض رمز جديد" }, "device": { "codeHint": "تأكد من أن هاتفك يعرض هذا الرمز" }, "errors": { "rateLimited": "محاولات كثيرة جدًا. حاول مرة أخرى بعد {{seconds}} ث.", "invalidCredentials": "اسم المستخدم أو البريد الإلكتروني أو كلمة المرور غير صحيح. إذا كانت عدة حسابات تستخدم هذا البريد الإلكتروني، فسجّل الدخول باسم المستخدم.", "emailAccountsFull": "هذا البريد الإلكتروني لديه بالفعل الحد الأقصى من الحسابات.", "codeInvalid": "الرمز غير صحيح أو انتهت صلاحيته.", "requestExpired": "انتهت صلاحية تسجيل الدخول هذا. أرسل رسالة جديدة.", "secondFactorInvalid": "الرمز غير صحيح. جرّب الرمز الحالي.", "originNotAllowed": "تسجيل الدخول غير متاح هنا.", "generic": "حدث خطأ ما. يُرجى المحاولة مرة أخرى.", "notConfigured": "تسجيل الدخول غير متاح", "notConfiguredDescription": "لم يُعدّ {{app}} لتسجيل الدخول بعد. تواصل مع مطوّر التطبيق.", "failed": "تعذّر بدء تسجيل الدخول", "failedDescription": "حدث خطأ ما. يُرجى المحاولة مرة أخرى." }, "emailAccounts": { "title": "اختر حسابًا", "description": "لدى {{identifier}} عدة حسابات. اختر الحساب الذي تريد تسجيل الدخول به." }, "chooser": { "subtitleToApp": "للمتابعة إلى {{app}}", "title": "اختر حسابًا", "subtitle": "تابع بأحد الحسابات أدناه، أو استخدم حسابًا آخر.", "useAnother": "استخدم حسابًا آخر", "continueAs": "المتابعة باسم {{name}}" }, "terms": { "before": "بالمتابعة، أنت توافق على", "termsLink": "شروط الخدمة", "and": "و", "privacyLink": "سياسة الخصوصية" }, "noAccount": "ليس لديك حساب؟", "createAccount": "إنشاء حساب", "identifier": { "label": "البريد الإلكتروني أو اسم المستخدم", "placeholder": [2], "required": "أدخل بريدك الإلكتروني أو اسم المستخدم." }, "checkEmail": { "title": "تحقق من بريدك", "description": "إذا كان هناك حساب يطابق {{identifier}}، فقد أرسلنا إليه رمزًا ورابطًا لتسجيل الدخول.", "codeLabel": "الرمز", "codeHint": "اكتب الرمز الوارد في الرسالة، أو افتح رابطها في هذا المتصفح.", "codeHasLetters": "هل يحتوي رمزك على أحرف؟", "codeDigitsOnly": "هل يتكون رمزك من أرقام فقط؟", "resend": "أرسل رسالة جديدة", "resendIn": "أرسل رسالة جديدة بعد {{seconds}} ث", "resent": "أرسلنا رسالة جديدة.", "retryLater": "أرسلنا عدة رسائل بالفعل. انتظر بضع دقائق ثم حاول مرة أخرى.", "usePassword": "استخدم كلمة المرور بدلًا من ذلك", "differentAccount": "استخدم حسابًا آخر" }, "password": { "title": "أدخل كلمة المرور", "label": "كلمة المرور", "required": "أدخل كلمة المرور.", "forgot": "نسيتها؟ احصل على رمز عبر البريد" }, "secondFactor": { "title": "التحقق بخطوتين", "description": "أدخل الرمز من تطبيق المصادقة.", "backupDescription": "أدخل أحد رموزك الاحتياطية. يعمل كل رمز مرة واحدة فقط.", "label": "رمز المصادقة", "backupLabel": "رمز احتياطي", "useBackup": "استخدم رمزًا احتياطيًا", "useAuthenticator": "استخدم تطبيق المصادقة" }, "link": { "approvedTitle": "سجّلت الدخول", "approvedDescription": "ارجع إلى التطبيق الذي طلبت منه تسجيل الدخول: سيتابع تلقائيًا. يمكنك إغلاق علامة التبويب هذه.", "otherDeviceTitle": "افتح الرابط في المتصفح نفسه", "otherDeviceDescription": "يعمل هذا الرابط فقط في المتصفح الذي طلبت منه تسجيل الدخول. افتحه هناك، أو اكتب الرمز الوارد في الرسالة داخل التطبيق.", "invalidTitle": "لا يمكن استخدام هذا الرابط", "invalidDescription": "انتهت صلاحيته أو استُخدم من قبل. اطلب رسالة جديدة من التطبيق، أو اكتب الرمز الوارد في أحدث رسالة." } }, "signup": { "title": "أنشئ حسابك", "subtitle": "اختر اسم المستخدم. ثم نؤكد بريدك الإلكتروني.", "createInCommons": "أنشئها في Commons بدلًا من ذلك", "backToSignInLink": "لديك حساب بالفعل؟ سجّل الدخول", "username": { "label": "اسم المستخدم", "placeholder": [43], "required": "اختر اسم مستخدم.", "taken": "اسم المستخدم هذا مستخدم بالفعل." }, "email": { "title": "ما بريدك الإلكتروني؟", "subtitle": "تسجّل الدخول به: نرسل إليك رمزًا في كل مرة. لا يراه أحد غيرك.", "label": "البريد الإلكتروني", "placeholder": [2], "invalid": "أدخل بريدًا إلكترونيًا صالحًا." }, "commonsSubtitle": "أو أنشئ هويتك في Commons واحتفظ بمفتاحك بنفسك.", "laterNote": "يمكنك لاحقًا إضافة كلمة مرور أو تطبيق مصادقة من إعدادات الأمان في حسابك." }, "accountSwitcher": { "loading": "جارٍ تحميل الحسابات...", "qrHeadline": "سجّل الدخول بهوية Oxy الخاصة بك", "signInWithOxy": "تسجيل الدخول باستخدام Oxy", "signUpWithOxy": "التسجيل باستخدام Oxy", "getCommons": "احصل على Commons", "commonsNotInstalled": "لا تملك Commons؟ احصل على التطبيق لتسجيل الدخول بمعرّف Oxy الخاص بك.", "showQrAnyway": "لدي Commons على جهاز آخر", "switchWhileSignedInAs": "تبديل الحساب، مسجّل الدخول باسم {{name}}", "manageOnDevice": "إدارة الحسابات على هذا الجهاز", "continueWithOxy": "المتابعة باستخدام Oxy", "havingTrouble": "هل تواجه مشكلة؟", "progress": { "preparing": "جارٍ تحضير الطلب", "awaitingApproval": "في انتظار الموافقة", "scanWithCommons": "امسح الرمز باستخدام Commons على هاتفك", "continueInCommons": "تابع في Commons", "checkCommons": "تحقّق من Commons على هاتفك", "openedInCommons": "تم الفتح في Commons", "confirming": "جارٍ تأكيد الهوية", "confirmed": "تم تأكيد الهوية" }, "signInFailures": { "denied": "تم رفض تسجيل الدخول في Commons.", "expired": "انتهت صلاحية طلب تسجيل الدخول. يُرجى المحاولة مرة أخرى.", "network": "تعذّر الاتصال بـ Oxy. تحقّق من اتصالك وحاول مرة أخرى.", "notConfigured": "هذا التطبيق غير مُعدّ لتسجيل الدخول بعد.", "unsupportedFlow": "لا يمكن إكمال تسجيل الدخول هنا.", "claimFailed": "تمت الموافقة على تسجيل الدخول، لكن تعذّر إكماله. يُرجى المحاولة مرة أخرى.", "generic": "تعذّر تسجيل الدخول. يُرجى المحاولة مرة أخرى." }, "linkOpenFailed": "تعذّر فتح الرابط. يُرجى المحاولة مرة أخرى." }, "common": { "stepOf": "الخطوة {{step}} من {{total}}", "actions": { "back": "رجوع", "continue": "متابعة", "next": "التالي", "getStarted": "ابدأ", "createAccount": "إنشاء حساب", "signIn": "تسجيل الدخول", "verify": "التحقق", "resetPassword": "إعادة تعيين كلمة المرور", "signedOut": "تم تسجيل الخروج", "close": "إغلاق", "tryAgain": "حاول مرة أخرى" }, "links": { "recoverAccount": "استعادة حسابك", "signUp": "التسجيل" }, "labels": { "username": "اسم المستخدم", "email": "البريد الإلكتروني", "password": "كلمة المرور", "confirmPassword": "تأكيد كلمة المرور" }, "revoke": [32], "errors": { "signOutAllFailed": "حدثت مشكلة أثناء تسجيل الخروج من جميع الحسابات. يرجى المحاولة مرة أخرى." } }, "notifications": { "title": [23], "subtitle": [18], "updateError": [14], "sections": { "channels": [9], "alerts": [6], "marketing": [4] }, "items": { "push": { "title": [28], "subtitle": [29] }, "emailDigest": { "title": [12], "subtitle": [24] }, "securityAlerts": { "title": [36], "subtitle": [37] }, "marketingEmails": { "title": [20], "subtitle": [27] } } }, "preferences": { "title": [25], "subtitle": [40], "sections": { "appearance": [7], "language": [0], "region": [31] }, "theme": { "light": [17], "dark": [11], "system": [38] }, "items": { "theme": { "title": [39] }, "reduceMotion": { "title": [30], "subtitle": [21], "systemOn": [15] }, "language": { "title": [0] }, "timezone": { "title": [41], "unknown": [42] }, "about": { "title": [5], "subtitle": [26] } } }, "connectedApps": { "title": [10], "subtitle": [19], "empty": { "title": [22], "subtitle": [8] }, "item": { "granted": "ممنوح {{relative}}", "lastUsed": [16] }, "confirm": { "title": [33], "message": [34] }, "toasts": { "revoked": [35], "revokeFailed": [13] } }, "accountMenu": { "label": "قائمة الحساب", "manage": "إدارة حساب Oxy الخاص بك", "viewProfile": "عرض الملف الشخصي", "addAnother": "إضافة حساب آخر", "signOutAll": "تسجيل الخروج من جميع الحسابات", "open": "قائمة الحساب", "openHint": "يفتح قائمة الحساب", "openWithUser": "قائمة حساب {{name}}", "switching": "جارٍ تبديل الحساب…", "signOutAccount": "تسجيل خروج {{name}}", "greeting": "مرحبًا، {{name}}!", "switchAccount": "تبديل الحساب", "storage": { "title": "تخزين Oxy", "usage": "{{used}} من {{total}} مستخدم", "used": "مستخدم", "free": "متاح", "unavailable": "تفاصيل الاستخدام غير متاحة", "upgrade": "ترقية الخطة", "manage": "إدارة التخزين" }, "data": "بياناتك في Oxy", "settings": "إعدادات Oxy", "help": "المساعدة والملاحظات", "signOut": "تسجيل الخروج", "privacy": "سياسة الخصوصية", "terms": "شروط الخدمة" }, "emailCode": { "title": "تحقق من بريدك", "sentTo": "أرسلنا رمزًا من 6 أرقام إلى {{email}}.", "label": "الرمز", "resend": "أرسل رمزًا جديدًا", "resent": "أرسلنا رمزًا جديدًا.", "changeEmail": "استخدم بريدًا آخر", "errors": { "codeInvalid": "الرمز غير صحيح أو انتهت صلاحيته.", "tooManyAttempts": "رموز خاطئة كثيرة. اطلب رمزًا جديدًا.", "expired": "استغرق الأمر وقتًا طويلًا. ابدأ من جديد.", "unavailable": "لا يستطيع Oxy إرسال البريد الآن. حاول لاحقًا.", "rateLimited": "رموز كثيرة. حاول لاحقًا." } }, "deleteAccount": { "keyless": { "subtitle": "سيُحذف @{{username}} وكل ما فيه نهائيًا. اكتب اسم المستخدم، ثم أكّد برمز نرسله إلى بريدك.", "action": "حذف الحساب", "done": "حُذف حسابك.", "doneDescription": "سُجّل خروجك.", "keyed": "يستخدم هذا الحساب Commons: احذفه في Oxy Commons من الإعدادات > حذف الحساب، بمفتاحه." }, "handoff": { "elsewhereMessage": "حذف حسابك يتطلب مفتاح هويتك، وهو غير موجود على هذا الجهاز. افتح Oxy Commons على الجهاز الذي يحتفظ به وانتقل إلى الإعدادات > حذف الحساب." } }, "linkCommons": { "title": "اربط Commons", "subtitle": "احتفظ بمفتاحك: اربط Commons ليصبح هذا الحساب لك وحدك. يُحذف بريده الإلكتروني، وتصبح عبارة الاسترداد في Commons طريقك للعودة.", "scan": "على هاتفك، افتح Commons واختر «لدي حساب Oxy على الويب» ثم امسح هذا الرمز.", "waiting": "بانتظار Commons…", "compareTitle": "تحقق من الرمز", "compare": "يعرض Commons الرمز نفسه. إن لم يكن كذلك، ألغِ العملية.", "confirm": "نعم، اربط Commons", "cancel": "إلغاء", "doneTitle": "تم ربط Commons", "done": "أصبح هذا الحساب ذاتي الحفظ. حُذف بريده الإلكتروني: عبارة الاسترداد في Commons هي طريقك للعودة.", "already": "يستخدم هذا الحساب Commons بالفعل.", "expired": "انتهت صلاحية هذا الرمز.", "renew": "اعرض رمزًا جديدًا", "failed": "تعذّر ربط Commons. حاول مجددًا.", "confirmTitle": "أكّد الربط", "confirmDescription": "للإنهاء، أكّد أنك أنت برمز نرسله إلى بريدك.", "confirmPasswordDescription": "للإنهاء، أكّد أنك أنت بكلمة المرور.", "row": "احتفظ بمفتاحك بنفسك مع Commons" }, "reauth": { "title": "أكّد أنك أنت", "emailDescription": "سنرسل رمزًا إلى بريدك لتأكيد هذا التغيير.", "sendCode": "أرسل الرمز", "codeSent": "أرسلنا رمزًا من 6 أرقام إلى بريدك.", "codeLabel": "الرمز من الرسالة", "passwordLabel": "كلمة المرور الحالية", "usePassword": "استخدم كلمة المرور بدلًا من ذلك", "useEmail": "احصل على رمز عبر البريد بدلًا من ذلك", "errors": { "invalid": "لم ينجح ذلك. تحقق مما كتبته وحاول مرة أخرى.", "totpRequired": "أدخل أيضًا الرمز من تطبيق المصادقة." } }, "signInSecurity": { "title": "تسجيل الدخول والأمان", "subtitle": "البريد الإلكتروني وكلمة المرور وتطبيق المصادقة والأماكن التي سجّلت الدخول فيها", "methodsTitle": "كيف تسجّل الدخول", "notPersonal": "الحساب الشخصي وحده يسجّل الدخول ببريد إلكتروني أو كلمة مرور أو تطبيق مصادقة.", "loadFailed": "تعذّر تحميل طرق تسجيل الدخول لهذا الحساب.", "retry": "حاول مجددًا", "noEmailWarning": "لا يوجد بريد إلكتروني لهذا الحساب. تسجّل الدخول بكلمة المرور فقط، وإذا نسيتها فلا توجد طريقة لاستعادة الحساب.", "status": { "on": "مفعّل", "off": "متوقف" }, "commons": { "title": [1] }, "errors": { "lastSignInMethod": "هذه طريقتك الوحيدة لتسجيل الدخول. أضف طريقة أخرى أولًا.", "passwordRequired": "عيّن كلمة مرور أولًا، ثم أكّد بها.", "emailUnchanged": "هذا بريدك الإلكتروني بالفعل." }, "email": { "title": "البريد الإلكتروني", "none": "لا يوجد بريد إلكتروني", "description": "تصل رموز تسجيل الدخول وروابطه وتنبيهات الأمان إلى هذا العنوان.", "noneDescription": "أضف بريدًا إلكترونيًا لتسجّل الدخول برمز أو رابط، ولتستعيد حسابك إذا نسيت كلمة المرور.", "change": "غيّر البريد الإلكتروني", "add": "أضف بريدًا إلكترونيًا", "remove": "أزل البريد الإلكتروني", "removeNeedsPassword": "لإزالة بريدك الإلكتروني، عيّن كلمة مرور أولًا: ستكون طريقتك الوحيدة لتسجيل الدخول.", "newLabel": "عنوان البريد الإلكتروني الجديد", "newDescription": "سنرسل رمزًا إلى العنوان الجديد للتحقق من أنه لك.", "invalid": "أدخل عنوان بريد إلكتروني صالحًا.", "sendCode": "أرسل الرمز", "confirmTitle": "أكّد البريد الإلكتروني الجديد", "confirmDescription": "أدخل الرمز الذي أرسلناه إلى {{email}}، ثم أكّد أنك أنت.", "codeLabel": "الرمز المرسل إلى البريد الجديد", "save": "احفظ البريد الإلكتروني", "saved": "حُدّث بريدك الإلكتروني. سُجّل الخروج من الأجهزة الأخرى.", "removeTitle": "أزل بريدك الإلكتروني", "removeDescription": "ستسجّل الدخول بكلمة المرور فقط. إذا نسيتها، فلا توجد طريقة لاستعادة الحساب. أكّد بكلمة المرور.", "removed": "أُزيل بريدك الإلكتروني. سُجّل الخروج من الأجهزة الأخرى." }, "password": { "title": "كلمة المرور", "setTitle": "عيّن كلمة مرور", "changeTitle": "غيّر كلمة المرور", "description": "سجّل الدخول بكلمة المرور بدلًا من رمز عبر البريد. استخدم {{min}} أحرف على الأقل.", "newLabel": "كلمة المرور الجديدة", "repeatLabel": "كرّر كلمة المرور", "tooShort": "استخدم {{min}} أحرف على الأقل.", "mismatch": "كلمتا المرور غير متطابقتين.", "signOutOthers": "سجّل الخروج من كل مكان آخر", "save": "احفظ كلمة المرور", "saved": "حُفظت كلمة المرور.", "row": "اختياري: سجّل الدخول بكلمة مرور", "remove": "أزل كلمة المرور", "removeTitle": "أزل كلمة مرورك", "removeDescription": "ستسجّل الدخول برمز أو رابط يُرسل إلى بريدك.", "removed": "أُزيلت كلمة المرور. سُجّل الخروج من الأجهزة الأخرى." }, "totp": { "title": "تطبيق المصادقة", "description": "بعد رمز البريد أو كلمة المرور، يطلب Oxy أيضًا رمزًا من تطبيق مثل Google Authenticator أو 1Password.", "setUp": "إعداد", "scan": "امسح رمز QR هذا بتطبيق المصادقة، أو أدخل مفتاح الإعداد.", "secretLabel": "مفتاح الإعداد", "codeLabel": "الرمز من التطبيق", "enable": "تشغيل", "enabled": "تطبيق المصادقة مفعّل.", "disable": "أوقف تطبيق المصادقة", "disabled": "تطبيق المصادقة متوقف.", "on": "مفعّل", "off": "متوقف", "backupTitle": "احفظ رموزك الاحتياطية", "backupDescription": "إذا فقدت هاتفك، فكل رمز يتيح لك تسجيل الدخول مرة واحدة. احفظها في مكان آمن: لن تُعرض مرة أخرى.", "copy": "انسخ الرموز", "copied": "نُسخت الرموز الاحتياطية.", "savedThem": "حفظتها", "regenerate": "احصل على رموز احتياطية جديدة", "regenerateDescription": "ستتوقف رموزك الاحتياطية القديمة عن العمل.", "remaining": "تبقّى {{count}} من الرموز الاحتياطية", "row": "خطوة ثانية عند تسجيل الدخول", "onWithCodes": "مفعّل · تبقّى {{count}} من الرموز الاحتياطية" } }, "fileManagement": { "deleteFile": "حذف الملف", "confirm": "تأكيد", "retry": "أعد المحاولة", "loadError": { "description": "حدث خطأ ما. تحقّق من اتصالك ثم أعد المحاولة." }, "moveToTrash": "نقل إلى سلة المهملات", "moveToTrashCount": "نقل إلى سلة المهملات ({{count}})", "appAccess": { "title": "التطبيقات التي لديها وصول", "description": "يمكن لهذه التطبيقات فتح هذا الملف بنفسها. ألغِ وصول أي تطبيق لسحب هذه الإمكانية منه.", "empty": "لا يمكن لأي تطبيق فتح هذا الملف بنفسه.", "loadError": "تعذّر تحميل التطبيقات التي يمكنها فتح هذا الملف", "via": { "upload": "حفظ هذا الملف نيابةً عنك", "link": "أنت من شاركه" }, "revoke": "إلغاء الوصول", "confirm": { "title": "إلغاء وصول {{name}}؟", "message": "لن يتمكن {{name}} من فتح هذا الملف بعد الآن، وسيتوقف أي تشغيل بدأه فورًا." }, "toasts": { "revoked": "لم يعد بإمكان {{name}} فتح هذا الملف", "revokeFailed": "تعذّر إلغاء وصول {{name}}" }, "a11y": { "revoke": "إلغاء وصول {{name}} إلى هذا الملف" } }, "trashView": { "title": "سلة المهملات", "subtitle": "استعد الملفات أو احذفها نهائيًا", "notice": "تبقى الملفات في سلة المهملات حتى تستعيدها أو تحذفها، وتظل محسوبة ضمن مساحة التخزين لديك.", "emptyTitle": "سلة المهملات فارغة", "emptyDescription": "تظهر هنا الملفات التي تنقلها إلى سلة المهملات. يمكنك استعادتها أو حذفها نهائيًا.", "trashedOn": "نُقل إلى سلة المهملات في {{date}}", "deleteForever": "حذف نهائيًا", "loadError": "تعذّر تحميل سلة المهملات", "a11y": { "restore": "استعادة {{name}}", "deleteForever": "حذف {{name}} نهائيًا" } }, "a11y": { "moveToTrash": "نقل {{name}} إلى سلة المهملات", "deleteFile": "حذف {{name}}", "openTrash": "فتح سلة المهملات" }, "toasts": { "movedToTrash": "نُقل إلى سلة المهملات. يمكنك استعادته منها.", "bulkMovedToTrash": "نُقل {{count}} ملف إلى سلة المهملات", "moveToTrashFailed": "تعذّر نقل الملف إلى سلة المهملات", "restored": "تمت استعادة الملف", "notInTrash": "لم يعد هذا الملف في سلة المهملات.", "restoreFailed": "تعذّرت استعادة الملف", "deletedForever": "حُذف الملف نهائيًا", "deleteSuccess": "حُذف الملف", "deleteFailed": "تعذّر حذف الملف", "fileNotFound": "لم يُعثر على الملف. ربما حُذف بالفعل.", "noPermission": "ليس لديك إذن بحذف هذا الملف.", "bulkDeleteSuccess": "حُذف {{count}} ملف", "bulkDeleteFailed": "تعذّر حذف {{count}} ملف", "bulkDeleteError": "تعذّر حذف الملفات" }, "confirms": { "deleteFile": "هل تريد حذف «{{filename}}»؟ لا يمكن التراجع عن هذا الإجراء.", "moveToTrash": "هل تريد نقل «{{filename}}» إلى سلة المهملات؟ لن يُعرض في أي مكان بعد الآن، ويمكنك استعادته من سلة المهملات.", "moveFilesToTrash": "هل تريد نقل {{count}} ملف إلى سلة المهملات؟ لن تُعرض في أي مكان بعد الآن، ويمكنك استعادتها من سلة المهملات.", "deleteForever": "هل تريد حذف «{{filename}}» نهائيًا؟ لا يمكن التراجع عن هذا الإجراء.", "deleteForeverInUse": "لا يزال «{{filename}}» مستخدمًا في {{count}} موضع في تطبيقاتك. حذفه يزيله من هناك أيضًا. هل تريد حذفه نهائيًا؟" } }, "follow": { "pending": "تم الطلب", "disabled": "متوقفة هنا", "named": "{{label}}: {{name}}", "verbs": { "follow": { "idle": "متابعة", "active": "تتم المتابعة", "everywhere": "إلغاء المتابعة في كل مكان", "undo": "يلغي متابعة هذا الحساب", "undoNamed": "يلغي متابعة {{name}}", "checking": "جارٍ التحقق من حالة المتابعة", "checkingNamed": "جارٍ التحقق مما إذا كنت تتابع {{name}}" }, "subscribe": { "idle": "اشتراك", "active": "مشترك", "everywhere": "إلغاء الاشتراك في كل مكان", "undo": "يلغي الاشتراك", "undoNamed": "يلغي الاشتراك في {{name}}", "checking": "جارٍ التحقق من الاشتراك", "checkingNamed": "جارٍ التحقق مما إذا كنت مشتركًا في {{name}}" }, "join": { "idle": "انضمام", "active": "منضم", "everywhere": "المغادرة من كل مكان", "undo": "يغادر", "undoNamed": "يغادر {{name}}", "checking": "جارٍ التحقق من العضوية", "checkingNamed": "جارٍ التحقق مما إذا كنت عضوًا في {{name}}" }, "watch": { "idle": "مراقبة", "active": "تتم المراقبة", "everywhere": "إيقاف المراقبة في كل مكان", "undo": "يوقف المراقبة", "undoNamed": "يوقف مراقبة {{name}}", "checking": "جارٍ التحقق من حالة المراقبة", "checkingNamed": "جارٍ التحقق مما إذا كنت تراقب {{name}}" } }, "all": { "idle": "متابعة الكل", "hint": "يتابع جميع الحسابات ({{count}})", "hintOne": "يتابع الحساب ({{count}})", "undoHint": "يلغي متابعة جميع الحسابات ({{count}})", "undoHintOne": "يلغي متابعة الحساب ({{count}})" }, "menu": { "forDuration": "{{label}} لمدة {{duration}}", "showIn": "إظهار في {{app}}", "hideIn": "عدم الإظهار في {{app}}", "thisApp": "هذا التطبيق", "options": "خيارات {{label}}", "optionsHint": "يفتح خيارات إضافية" }, "durations": { "day": "24 ساعة", "threeDays": "72 ساعة", "week": "أسبوع" }, "errors": { "update": "تعذّر تحديث الحالة", "read": "تعذّر التحقق من الحالة", "mode": "تعذّر تغيير إعداد هذا التطبيق", "offline": "أنت غير متصل. تحقّق من الاتصال وحاول مجددًا.", "signedOut": "سجّل الدخول مرة أخرى للاستمرار", "forbidden": "لا يُسمح لهذا التطبيق بذلك", "notFound": "لم يعد هذا متاحًا", "rateLimited": "محاولات كثيرة جدًا. حاول مجددًا بعد قليل." } }, "accounts": { "accountCategory": { "news": "أخبار", "politics": "سياسة", "business": "أعمال", "startup": "الشركات الناشئة وريادة الأعمال", "finance": "المال والاستثمار", "crypto": "العملات المشفرة والويب 3", "marketplace": "سوق وإعلانات مبوبة", "retail": "التجزئة والتجارة الإلكترونية", "real_estate": "عقارات", "agency": "وكالة عقارية", "landlord": "الملاك وإدارة العقارات", "cooperative": "تعاونية سكنية", "architecture": "العمارة والبناء", "technology": "التقنية", "software": "البرمجيات والتطوير", "ai": "الذكاء الاصطناعي وتعلّم الآلة", "security": "الأمان والخصوصية", "automation": "الأتمتة والأدوات", "science": "العلوم والبحث", "education": "التعليم والتدريب", "books": "الكتب والكتابة", "health": "الصحة والطب", "fitness": "اللياقة والعافية", "sports": "رياضة", "gaming": "الألعاب والرياضات الإلكترونية", "music": "موسيقى", "film": "أفلام وتلفزيون", "podcast": "بودكاست وصوتيات", "art": "الفن والتصميم", "photography": "تصوير", "comedy": "كوميديا", "food": "طعام وشراب", "travel": "السفر والأماكن", "fashion": "الموضة والجمال", "home_garden": "المنزل والحديقة", "diy": "اصنعها بنفسك", "automotive": "السيارات", "animals": "الحيوانات الأليفة", "family": "الأسرة والتربية", "nonprofit": "غير ربحي وخيري", "government": "الحكومة والقطاع العام", "community": "المجتمع المحلي", "activism": "النشاط والمناصرة", "environment": "البيئة والاستدامة", "religion": "الدين والروحانية", "other": "أخرى" }, "members": { "title": "الأعضاء" }, "settings": { "title": "إعدادات الحساب", "subtitle": "أدِر الملف الشخصي لهذا الحساب وأعضاءه والوصول إليه.", "save": "حفظ التغييرات", "displayName": { "label": "الاسم المعروض", "invalidChars": "استخدم الحروف والمسافات والفواصل العليا وفواصل الأسماء فقط", "invalidTitle": "استخدم نصًا عاديًا بدون < أو > (حتى 300 حرف)" }, "bio": { "label": "نبذة (اختياري)" }, "picture": { "change": "تغيير الصورة" }, "categories": { "title": "الفئات", "footer": "الفئة الأولى هي الفئة الرئيسية المعروضة في الملف الشخصي. حتى {{max}}.", "primary": "رئيسية", "makePrimary": "اجعلها رئيسية", "remove": "إزالة {{category}}", "add": "إضافة فئة", "atCap": "حتى {{max}}. أزِل واحدة لإضافة أخرى.", "unavailable": "فئة غير متاحة" }, "sections": { "access": "الوصول", "dangerZone": "منطقة الخطر" }, "members": { "subtitle": "ادعُ أشخاصًا وأدِر الأدوار" }, "archive": { "title": "أرشفة الحساب", "subtitle": "إلغاء تنشيط هذا الحساب", "confirmTitle": "أرشفة الحساب", "confirmDescription": "هل تريد أرشفة هذا الحساب؟ سيتم إلغاء تنشيطه وسيفقد أعضاؤه الوصول." }, "errors": { "missingAccount": "لم يتم تحديد أي حساب." }, "toasts": { "saved": "تم تحديث الحساب", "saveFailed": "تعذر تحديث الحساب", "archived": "تمت أرشفة الحساب", "archiveFailed": "تعذرت أرشفة الحساب" } } } });
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ // Generated by scripts/generateCompactLocales.ts; do not edit.
4
+ const compactLocale_1 = require("../../compactLocale");
5
+ exports.default = (0, compactLocale_1.restoreCompactLocale)({ "signin": { "title": "সাইন ইন", "subtitle": "আপনার Oxy অ্যাকাউন্ট ব্যবহার করুন", "addAccountTitle": "আরেকটি অ্যাকাউন্ট যোগ করুন", "addAccountSubtitle": "অন্য অ্যাকাউন্ট দিয়ে সাইন ইন করুন", "actions": { "continue": "চালিয়ে যান", "back": "পিছনে" }, "createAccountLink": "Oxy-তে নতুন? একটি অ্যাকাউন্ট তৈরি করুন", "status": { "signingIn": "সাইন ইন হচ্ছে…" }, "subtitleToApp": "{{app}}-এ যেতে", "orContinueWith": "অথবা এর মাধ্যমে চালিয়ে যান", "qr": { "caption": "সাইন ইন করতে Commons দিয়ে স্ক্যান করুন", "renew": "নতুন কোড দেখান" }, "device": { "codeHint": "দেখে নিন আপনার ফোনে এই কোডটিই দেখাচ্ছে" }, "errors": { "rateLimited": "অনেকবার চেষ্টা করা হয়েছে। {{seconds}} সেকেন্ড পরে আবার চেষ্টা করুন।", "invalidCredentials": "ইউজারনেম, ইমেইল বা পাসওয়ার্ড সঠিক নয়। এই ইমেইলে একাধিক অ্যাকাউন্ট থাকলে ইউজারনেম দিয়ে সাইন ইন করুন।", "emailAccountsFull": "এই ইমেইলে সর্বোচ্চ সংখ্যক অ্যাকাউন্ট আগেই আছে।", "codeInvalid": "কোডটি সঠিক নয়, অথবা এর মেয়াদ শেষ হয়ে গেছে।", "requestExpired": "এই সাইন-ইনের মেয়াদ শেষ। নতুন ইমেইল পাঠান।", "secondFactorInvalid": "কোডটি সঠিক নয়। বর্তমান কোডটি দিন।", "originNotAllowed": "এখানে সাইন ইন করা যাবে না।", "generic": "কিছু একটা সমস্যা হয়েছে। অনুগ্রহ করে আবার চেষ্টা করুন।", "notConfigured": "সাইন ইন উপলভ্য নয়", "notConfiguredDescription": "{{app}}-এ এখনও সাইন-ইন চালু করা হয়নি। অ্যাপের ডেভেলপারের সাথে যোগাযোগ করুন।", "failed": "সাইন ইন শুরু করা যায়নি", "failedDescription": "কিছু একটা সমস্যা হয়েছে। অনুগ্রহ করে আবার চেষ্টা করুন।" }, "emailAccounts": { "title": "একটি অ্যাকাউন্ট বেছে নিন", "description": "{{identifier}}-এর একাধিক অ্যাকাউন্ট আছে। কোনটি দিয়ে সাইন ইন করবেন, বেছে নিন।" }, "chooser": { "subtitleToApp": "{{app}}-এ যেতে", "title": "একটি অ্যাকাউন্ট বেছে নিন", "subtitle": "নিচের একটি অ্যাকাউন্ট দিয়ে চালিয়ে যান, অথবা অন্যটি ব্যবহার করুন।", "useAnother": "অন্য অ্যাকাউন্ট ব্যবহার করুন", "continueAs": "{{name}} হিসেবে চালিয়ে যান" }, "terms": { "before": "চালিয়ে যাওয়ার মাধ্যমে আপনি আমাদের", "termsLink": "পরিষেবার শর্তাবলি", "and": "এবং", "privacyLink": "গোপনীয়তা নীতিতে সম্মত হচ্ছেন" }, "noAccount": "অ্যাকাউন্ট নেই?", "createAccount": "অ্যাকাউন্ট তৈরি করুন", "identifier": { "label": "ইমেইল বা ইউজারনেম", "placeholder": [2], "required": "আপনার ইমেইল বা ইউজারনেম লিখুন।" }, "checkEmail": { "title": "আপনার ইমেইল দেখুন", "description": "{{identifier}}-এর সাথে কোনো অ্যাকাউন্ট মিললে আমরা সেখানে একটি কোড ও সাইন-ইন লিংক পাঠিয়েছি।", "codeLabel": "কোড", "codeHint": "ইমেইলের কোডটি লিখুন, অথবা এর লিংকটি এই ব্রাউজারে খুলুন।", "codeHasLetters": "আপনার কোডে কি অক্ষর আছে?", "codeDigitsOnly": "আপনার কোড কি শুধু সংখ্যা?", "resend": "নতুন ইমেইল পাঠান", "resendIn": "{{seconds}} সেকেন্ড পরে নতুন ইমেইল পাঠান", "resent": "আমরা একটি নতুন ইমেইল পাঠিয়েছি।", "retryLater": "আমরা ইতিমধ্যে কয়েকটি ইমেইল পাঠিয়েছি। কয়েক মিনিট অপেক্ষা করে আবার চেষ্টা করুন।", "usePassword": "এর বদলে পাসওয়ার্ড ব্যবহার করুন", "differentAccount": "অন্য অ্যাকাউন্ট ব্যবহার করুন" }, "password": { "title": "আপনার পাসওয়ার্ড লিখুন", "label": "পাসওয়ার্ড", "required": "আপনার পাসওয়ার্ড লিখুন।", "forgot": "ভুলে গেছেন? ইমেইলে কোড নিন" }, "secondFactor": { "title": "দুই-ধাপের যাচাইকরণ", "description": "আপনার অথেনটিকেটর অ্যাপের কোডটি লিখুন।", "backupDescription": "আপনার একটি ব্যাকআপ কোড লিখুন। প্রতিটি কোড একবারই কাজ করে।", "label": "অথেনটিকেটর কোড", "backupLabel": "ব্যাকআপ কোড", "useBackup": "ব্যাকআপ কোড ব্যবহার করুন", "useAuthenticator": "অথেনটিকেটর অ্যাপ ব্যবহার করুন" }, "link": { "approvedTitle": "আপনি সাইন ইন করেছেন", "approvedDescription": "যে অ্যাপে সাইন ইন করতে চেয়েছিলেন সেখানে ফিরে যান: সেটি নিজে থেকেই চালু হবে। আপনি এই ট্যাবটি বন্ধ করতে পারেন।", "otherDeviceTitle": "একই ব্রাউজারে লিংকটি খুলুন", "otherDeviceDescription": "এই লিংক শুধু সেই ব্রাউজারে কাজ করে যেখানে আপনি সাইন ইন করতে চেয়েছিলেন। সেখানে খুলুন, অথবা ইমেইলের কোডটি অ্যাপে লিখুন।", "invalidTitle": "এই লিংকটি ব্যবহার করা যাবে না", "invalidDescription": "এর মেয়াদ শেষ হয়েছে বা এটি আগেই ব্যবহার করা হয়েছে। অ্যাপে নতুন ইমেইল চান, অথবা সর্বশেষ ইমেইলের কোডটি লিখুন।" } }, "signup": { "title": "আপনার অ্যাকাউন্ট তৈরি করুন", "subtitle": "আপনার ইউজারনেম বেছে নিন। তারপর আমরা আপনার ইমেইল নিশ্চিত করব।", "createInCommons": "এর বদলে Commons-এ তৈরি করুন", "backToSignInLink": "আগে থেকেই অ্যাকাউন্ট আছে? সাইন ইন করুন", "username": { "label": "ইউজারনেম", "placeholder": [43], "required": "একটি ইউজারনেম বেছে নিন।", "taken": "এই ইউজারনেমটি আগেই নেওয়া হয়েছে।" }, "email": { "title": "আপনার ইমেইল কী?", "subtitle": "এটি দিয়েই আপনি সাইন ইন করবেন: প্রতিবার আমরা একটি কোড পাঠাব। অন্য কেউ এটি দেখতে পাবে না।", "label": "ইমেইল", "placeholder": [2], "invalid": "একটি সঠিক ইমেইল ঠিকানা লিখুন।" }, "commonsSubtitle": "অথবা Commons-এ আপনার পরিচয় তৈরি করুন এবং নিজের কী নিজের কাছে রাখুন।", "laterNote": "পরে আপনার অ্যাকাউন্টের নিরাপত্তা সেটিংসে পাসওয়ার্ড বা অথেনটিকেটর অ্যাপ যোগ করতে পারবেন।" }, "accountSwitcher": { "loading": "অ্যাকাউন্ট লোড হচ্ছে...", "qrHeadline": "আপনার Oxy পরিচয় দিয়ে সাইন ইন করুন", "signInWithOxy": "Oxy দিয়ে সাইন ইন করুন", "signUpWithOxy": "Oxy দিয়ে সাইন আপ করুন", "getCommons": "Commons নিন", "commonsNotInstalled": "Commons নেই? আপনার Oxy ID দিয়ে সাইন ইন করতে অ্যাপটি নিন।", "showQrAnyway": "অন্য ডিভাইসে আমার Commons আছে", "switchWhileSignedInAs": "অ্যাকাউন্ট বদলান, {{name}} হিসেবে সাইন ইন করা আছে", "manageOnDevice": "এই ডিভাইসের অ্যাকাউন্টগুলো পরিচালনা করুন", "continueWithOxy": "Oxy দিয়ে চালিয়ে যান", "havingTrouble": "সমস্যা হচ্ছে?", "progress": { "preparing": "অনুরোধ তৈরি হচ্ছে", "awaitingApproval": "অনুমোদনের অপেক্ষায়", "scanWithCommons": "আপনার ফোনের Commons দিয়ে স্ক্যান করুন", "continueInCommons": "Commons-এ চালিয়ে যান", "checkCommons": "আপনার ফোনে Commons দেখুন", "openedInCommons": "Commons-এ খোলা হয়েছে", "confirming": "পরিচয় নিশ্চিত করা হচ্ছে", "confirmed": "পরিচয় নিশ্চিত হয়েছে" }, "signInFailures": { "denied": "Commons-এ সাইন-ইন প্রত্যাখ্যান করা হয়েছে।", "expired": "এই সাইন-ইন অনুরোধের মেয়াদ শেষ। অনুগ্রহ করে আবার চেষ্টা করুন।", "network": "Oxy-তে সংযোগ করা যায়নি। আপনার সংযোগ পরীক্ষা করে আবার চেষ্টা করুন।", "notConfigured": "এই অ্যাপে এখনও সাইন-ইন চালু করা হয়নি।", "unsupportedFlow": "এই সাইন-ইন এখানে সম্পন্ন করা যাবে না।", "claimFailed": "সাইন-ইন অনুমোদিত হয়েছে, কিন্তু আমরা তা শেষ করতে পারিনি। অনুগ্রহ করে আবার চেষ্টা করুন।", "generic": "সাইন ইন ব্যর্থ হয়েছে। অনুগ্রহ করে আবার চেষ্টা করুন।" }, "linkOpenFailed": "লিংকটি খোলা যায়নি। অনুগ্রহ করে আবার চেষ্টা করুন।" }, "common": { "stepOf": "ধাপ {{step}}/{{total}}", "actions": { "back": "পিছনে", "continue": "চালিয়ে যান", "next": "পরবর্তী", "getStarted": "শুরু করুন", "createAccount": "অ্যাকাউন্ট তৈরি করুন", "signIn": "সাইন ইন", "verify": "যাচাই করুন", "resetPassword": "পাসওয়ার্ড রিসেট করুন", "signedOut": "সাইন আউট হয়েছে", "close": "বন্ধ করুন", "tryAgain": "আবার চেষ্টা করুন" }, "links": { "recoverAccount": "আপনার অ্যাকাউন্ট পুনরুদ্ধার করুন", "signUp": "সাইন আপ" }, "labels": { "username": "ইউজারনেম", "email": "ইমেইল", "password": "পাসওয়ার্ড", "confirmPassword": "পাসওয়ার্ড নিশ্চিত করুন" }, "revoke": "প্রত্যাহার করুন", "errors": { "signOutAllFailed": "সব অ্যাকাউন্ট থেকে সাইন আউট করতে সমস্যা হয়েছে। অনুগ্রহ করে আবার চেষ্টা করুন।" } }, "notifications": { "title": "নোটিফিকেশন", "subtitle": "পুশ, ইমেইল ও নিরাপত্তা সতর্কতা পরিচালনা করুন", "updateError": "নোটিফিকেশন পছন্দ আপডেট করা যায়নি", "sections": { "channels": "চ্যানেল", "alerts": "সতর্কতা", "marketing": "মার্কেটিং" }, "items": { "push": { "title": "পুশ নোটিফিকেশন", "subtitle": "আপনার ডিভাইসে তাৎক্ষণিক সতর্কতা" }, "emailDigest": { "title": "ইমেইল সারসংক্ষেপ", "subtitle": "আপনার অ্যাকাউন্টের কার্যকলাপের নিয়মিত সারসংক্ষেপ" }, "securityAlerts": { "title": "নিরাপত্তা সতর্কতা", "subtitle": "সাইন-ইন, পুনরুদ্ধার কোড ও কী পরিবর্তন" }, "marketingEmails": { "title": "মার্কেটিং ইমেইল", "subtitle": "পণ্যের খবর ও মাঝেমধ্যে অফার" } } }, "preferences": { "title": "পছন্দসমূহ", "subtitle": "থিম, মোশন ও আঞ্চলিক সেটিংস", "sections": { "appearance": "চেহারা", "language": "ভাষা", "region": "অঞ্চল" }, "theme": { "light": "লাইট", "dark": "ডার্ক", "system": "সিস্টেম ডিফল্ট" }, "items": { "theme": { "title": "থিম" }, "reduceMotion": { "title": "মোশন কমান", "subtitle": "Oxy অ্যাপগুলোতে অ্যানিমেশন কমিয়ে রাখুন", "systemOn": "সিস্টেম অনুসরণ করছে: মোশন কমানো চালু আছে" }, "language": { "title": "ভাষা" }, "timezone": { "title": "টাইমজোন", "unknown": "টাইমজোন শনাক্ত করা যায়নি" }, "about": { "title": "পছন্দসমূহ সম্পর্কে", "subtitle": "আপনি যেসব Oxy অ্যাপে সাইন ইন করেন, সবগুলোতে পছন্দসমূহ সিঙ্ক হয়" } } }, "connectedApps": { "title": "সংযুক্ত অ্যাপ", "subtitle": "তৃতীয় পক্ষের অ্যাপের অ্যাক্সেস পরিচালনা করুন", "empty": { "title": "কোনো সংযুক্ত অ্যাপ নেই", "subtitle": "যেসব অ্যাপকে আপনার Oxy অ্যাকাউন্ট দিয়ে সাইন ইন করার অনুমতি দেবেন, সেগুলো এখানে দেখা যাবে" }, "item": { "granted": "অনুমতি দেওয়া হয়েছে {{relative}}", "lastUsed": "শেষ ব্যবহার {{relative}}" }, "confirm": { "title": "অ্যাক্সেস প্রত্যাহার করুন", "message": "আপনার Oxy অ্যাকাউন্টে {{name}}-এর অ্যাক্সেস প্রত্যাহার করবেন?" }, "toasts": { "revoked": "{{name}}-এর অ্যাক্সেস প্রত্যাহার করা হয়েছে", "revokeFailed": "অ্যাক্সেস প্রত্যাহার করা যায়নি" } }, "accountMenu": { "label": "অ্যাকাউন্ট মেনু", "manage": "আপনার Oxy অ্যাকাউন্ট পরিচালনা করুন", "viewProfile": "প্রোফাইল দেখুন", "addAnother": "আরেকটি অ্যাকাউন্ট যোগ করুন", "signOutAll": "সব অ্যাকাউন্ট থেকে সাইন আউট করুন", "open": "অ্যাকাউন্ট মেনু", "openHint": "অ্যাকাউন্ট মেনু খোলে", "openWithUser": "{{name}}-এর অ্যাকাউন্ট মেনু", "switching": "অ্যাকাউন্ট বদলানো হচ্ছে…", "signOutAccount": "{{name}} সাইন আউট করুন", "greeting": "হাই, {{name}}!", "switchAccount": "অ্যাকাউন্ট বদলান", "storage": { "title": "Oxy স্টোরেজ", "usage": "{{total}}-এর মধ্যে {{used}} ব্যবহৃত", "used": "ব্যবহৃত", "free": "খালি", "unavailable": "ব্যবহারের বিবরণ পাওয়া যাচ্ছে না", "upgrade": "প্ল্যান আপগ্রেড করুন", "manage": "স্টোরেজ পরিচালনা করুন" }, "data": "Oxy-তে আপনার ডেটা", "settings": "Oxy সেটিংস", "help": "সাহায্য ও মতামত", "signOut": "সাইন আউট", "privacy": "গোপনীয়তা নীতি", "terms": "পরিষেবার শর্তাবলি" }, "emailCode": { "title": "আপনার ইমেইল দেখুন", "sentTo": "আমরা {{email}}-এ একটি ৬-সংখ্যার কোড পাঠিয়েছি।", "label": "কোড", "resend": "নতুন কোড পাঠান", "resent": "আমরা একটি নতুন কোড পাঠিয়েছি।", "changeEmail": "অন্য ইমেইল ব্যবহার করুন", "errors": { "codeInvalid": "কোডটি সঠিক নয়, অথবা এর মেয়াদ শেষ হয়ে গেছে।", "tooManyAttempts": "অনেকবার ভুল কোড দেওয়া হয়েছে। নতুন কোড চান।", "expired": "অনেক সময় লেগে গেছে। আবার শুরু করুন।", "unavailable": "Oxy এখন ইমেইল পাঠাতে পারছে না। পরে আবার চেষ্টা করুন।", "rateLimited": "অনেকগুলো কোড চাওয়া হয়েছে। পরে আবার চেষ্টা করুন।" } }, "deleteAccount": { "keyless": { "subtitle": "@{{username}} এবং এর সবকিছু চিরতরে মুছে যাবে। আপনার ইউজারনেম লিখুন, তারপর আমাদের ইমেইল করা কোড দিয়ে নিশ্চিত করুন।", "action": "অ্যাকাউন্ট মুছুন", "done": "আপনার অ্যাকাউন্ট মুছে ফেলা হয়েছে।", "doneDescription": "আপনাকে সাইন আউট করা হয়েছে।", "keyed": "এই অ্যাকাউন্টটি Commons ব্যবহার করে: এর কী দিয়ে Oxy Commons-এ, সেটিংস > অ্যাকাউন্ট মুছুন-এ গিয়ে মুছুন।" }, "handoff": { "elsewhereMessage": "অ্যাকাউন্ট মুছতে আপনার পরিচয় কী লাগবে, আর সেটি এই ডিভাইসে নেই। যে ডিভাইসে কী আছে সেখানে Oxy Commons খুলে সেটিংস > অ্যাকাউন্ট মুছুন-এ যান।" } }, "linkCommons": { "title": "Commons লিংক করুন", "subtitle": "নিজের কী নিজের কাছে রাখুন: Commons লিংক করলে এই অ্যাকাউন্ট শুধু আপনার। এর ইমেইল মুছে যাবে, আর Commons-এ থাকা আপনার রিকভারি ফ্রেজ দিয়েই আবার প্রবেশ করবেন।", "scan": "আপনার ফোনে Commons খুলুন, “ওয়েবে আমার Oxy অ্যাকাউন্ট আছে” বেছে নিন এবং এই কোডটি স্ক্যান করুন।", "waiting": "Commons-এর অপেক্ষায়…", "compareTitle": "কোডটি মিলিয়ে দেখুন", "compare": "Commons-এ একই কোড দেখাবে। না দেখালে বাতিল করুন।", "confirm": "হ্যাঁ, Commons লিংক করুন", "cancel": "বাতিল", "doneTitle": "Commons লিংক হয়েছে", "done": "এই অ্যাকাউন্ট এখন নিজের হেফাজতে। এর ইমেইল মুছে ফেলা হয়েছে: Commons-এ থাকা আপনার রিকভারি ফ্রেজ দিয়েই আবার প্রবেশ করবেন।", "already": "এই অ্যাকাউন্ট আগে থেকেই Commons ব্যবহার করে।", "expired": "এই কোডের মেয়াদ শেষ।", "renew": "নতুন কোড দেখান", "failed": "Commons লিংক করা যায়নি। আবার চেষ্টা করুন।", "confirmTitle": "লিংক নিশ্চিত করুন", "confirmDescription": "শেষ করতে, আমাদের ইমেইল করা কোড দিয়ে নিশ্চিত করুন যে এটি আপনি।", "confirmPasswordDescription": "শেষ করতে, আপনার পাসওয়ার্ড দিয়ে নিশ্চিত করুন যে এটি আপনি।", "row": "Commons দিয়ে নিজের কী নিজের কাছে রাখুন" }, "reauth": { "title": "নিশ্চিত করুন যে এটি আপনি", "emailDescription": "এই পরিবর্তন নিশ্চিত করতে আমরা আপনার ইমেইলে একটি কোড পাঠাব।", "sendCode": "কোড পাঠান", "codeSent": "আমরা আপনার ইমেইলে একটি ৬-সংখ্যার কোড পাঠিয়েছি।", "codeLabel": "ইমেইলের কোড", "passwordLabel": "বর্তমান পাসওয়ার্ড", "usePassword": "এর বদলে পাসওয়ার্ড ব্যবহার করুন", "useEmail": "এর বদলে ইমেইলে কোড নিন", "errors": { "invalid": "কাজ হয়নি। যা লিখেছেন তা পরীক্ষা করে আবার চেষ্টা করুন।", "totpRequired": "আপনার অথেনটিকেটর অ্যাপের কোডটিও লিখুন।" } }, "signInSecurity": { "title": "সাইন-ইন ও নিরাপত্তা", "subtitle": "ইমেইল, পাসওয়ার্ড, অথেনটিকেটর অ্যাপ এবং কোথায় সাইন ইন করা আছে", "methodsTitle": "আপনি যেভাবে সাইন ইন করেন", "notPersonal": "শুধু ব্যক্তিগত অ্যাকাউন্ট ইমেইল, পাসওয়ার্ড বা অথেনটিকেটর অ্যাপ দিয়ে সাইন ইন করে।", "loadFailed": "এই অ্যাকাউন্ট কীভাবে সাইন ইন করে তা লোড করা যায়নি।", "retry": "আবার চেষ্টা করুন", "noEmailWarning": "এই অ্যাকাউন্টে কোনো ইমেইল নেই। আপনি শুধু পাসওয়ার্ড দিয়ে সাইন ইন করেন, আর সেটি ভুলে গেলে অ্যাকাউন্ট ফিরে পাওয়ার কোনো উপায় নেই।", "status": { "on": "চালু", "off": "বন্ধ" }, "commons": { "title": [1] }, "errors": { "lastSignInMethod": "সাইন ইন করার এটিই আপনার একমাত্র উপায়। আগে আরেকটি উপায় যোগ করুন।", "passwordRequired": "আগে একটি পাসওয়ার্ড সেট করুন, এবং সেটি দিয়ে নিশ্চিত করুন।", "emailUnchanged": "এটি আগে থেকেই আপনার ইমেইল।" }, "email": { "title": "ইমেইল", "none": "কোনো ইমেইল নেই", "description": "সাইন-ইন কোড, সাইন-ইন লিংক ও নিরাপত্তা বিজ্ঞপ্তি এই ঠিকানায় যায়।", "noneDescription": "কোড বা লিংক দিয়ে সাইন ইন করতে, এবং পাসওয়ার্ড ভুলে গেলে অ্যাকাউন্ট ফিরে পেতে একটি ইমেইল যোগ করুন।", "change": "ইমেইল বদলান", "add": "একটি ইমেইল যোগ করুন", "remove": "ইমেইল সরান", "removeNeedsPassword": "ইমেইল সরাতে আগে একটি পাসওয়ার্ড সেট করুন: সেটিই হবে সাইন ইন করার একমাত্র উপায়।", "newLabel": "নতুন ইমেইল ঠিকানা", "newDescription": "ঠিকানাটি আপনার কিনা যাচাই করতে আমরা নতুন ঠিকানায় একটি কোড পাঠাব।", "invalid": "একটি সঠিক ইমেইল ঠিকানা লিখুন।", "sendCode": "কোড পাঠান", "confirmTitle": "নতুন ইমেইল নিশ্চিত করুন", "confirmDescription": "{{email}}-এ পাঠানো কোডটি লিখুন, তারপর নিশ্চিত করুন যে এটি আপনি।", "codeLabel": "নতুন ইমেইলে পাঠানো কোড", "save": "ইমেইল সংরক্ষণ করুন", "saved": "আপনার ইমেইল আপডেট হয়েছে। অন্য ডিভাইসগুলো থেকে সাইন আউট করা হয়েছে।", "removeTitle": "আপনার ইমেইল সরান", "removeDescription": "আপনি শুধু পাসওয়ার্ড দিয়ে সাইন ইন করবেন। সেটি ভুলে গেলে অ্যাকাউন্ট ফিরে পাওয়ার কোনো উপায় নেই। আপনার পাসওয়ার্ড দিয়ে নিশ্চিত করুন।", "removed": "আপনার ইমেইল সরানো হয়েছে। অন্য ডিভাইসগুলো থেকে সাইন আউট করা হয়েছে।" }, "password": { "title": "পাসওয়ার্ড", "setTitle": "পাসওয়ার্ড সেট করুন", "changeTitle": "আপনার পাসওয়ার্ড বদলান", "description": "ইমেইলের কোডের বদলে পাসওয়ার্ড দিয়ে সাইন ইন করুন। কমপক্ষে {{min}}টি অক্ষর ব্যবহার করুন।", "newLabel": "নতুন পাসওয়ার্ড", "repeatLabel": "পাসওয়ার্ডটি আবার লিখুন", "tooShort": "কমপক্ষে {{min}}টি অক্ষর ব্যবহার করুন।", "mismatch": "পাসওয়ার্ড দুটি মিলছে না।", "signOutOthers": "অন্য সব জায়গা থেকে সাইন আউট করুন", "save": "পাসওয়ার্ড সংরক্ষণ করুন", "saved": "আপনার পাসওয়ার্ড সংরক্ষিত হয়েছে।", "row": "ঐচ্ছিক: পাসওয়ার্ড দিয়ে সাইন ইন", "remove": "পাসওয়ার্ড সরান", "removeTitle": "আপনার পাসওয়ার্ড সরান", "removeDescription": "আপনি ইমেইলে পাঠানো কোড বা লিংক দিয়ে সাইন ইন করবেন।", "removed": "আপনার পাসওয়ার্ড সরানো হয়েছে। অন্য ডিভাইসগুলো থেকে সাইন আউট করা হয়েছে।" }, "totp": { "title": "অথেনটিকেটর অ্যাপ", "description": "ইমেইল কোড বা পাসওয়ার্ডের পরে Oxy আরও একটি কোড চাইবে, যা Google Authenticator বা 1Password-এর মতো অ্যাপ থেকে আসবে।", "setUp": "সেট আপ করুন", "scan": "আপনার অথেনটিকেটর অ্যাপ দিয়ে এই QR কোডটি স্ক্যান করুন, অথবা সেটআপ কী লিখুন।", "secretLabel": "সেটআপ কী", "codeLabel": "অ্যাপের কোড", "enable": "চালু করুন", "enabled": "অথেনটিকেটর অ্যাপ চালু আছে।", "disable": "অথেনটিকেটর অ্যাপ বন্ধ করুন", "disabled": "অথেনটিকেটর অ্যাপ বন্ধ আছে।", "on": "চালু", "off": "বন্ধ", "backupTitle": "আপনার ব্যাকআপ কোড সংরক্ষণ করুন", "backupDescription": "ফোন হারালে প্রতিটি কোড দিয়ে একবার সাইন ইন করা যাবে। কোডগুলো নিরাপদ কোথাও রাখুন: এগুলো আর দেখানো হবে না।", "copy": "কোড কপি করুন", "copied": "ব্যাকআপ কোড কপি হয়েছে।", "savedThem": "আমি সংরক্ষণ করেছি", "regenerate": "নতুন ব্যাকআপ কোড নিন", "regenerateDescription": "আপনার পুরোনো ব্যাকআপ কোডগুলো আর কাজ করবে না।", "remaining": "{{count}}টি ব্যাকআপ কোড বাকি", "row": "সাইন ইন করার সময় একটি দ্বিতীয় ধাপ", "onWithCodes": "চালু · {{count}}টি ব্যাকআপ কোড বাকি" } }, "fileManagement": { "deleteFile": "ফাইল মুছুন", "confirm": "নিশ্চিত করুন", "retry": "আবার চেষ্টা করুন", "loadError": { "description": "কিছু একটা সমস্যা হয়েছে। আপনার সংযোগ পরীক্ষা করে আবার চেষ্টা করুন।" }, "moveToTrash": "ট্র্যাশে সরান", "moveToTrashCount": "ট্র্যাশে সরান ({{count}})", "appAccess": { "title": "যেসব অ্যাপের অ্যাক্সেস আছে", "description": "এই অ্যাপগুলো নিজে থেকেই এই ফাইলটি খুলতে পারে। অ্যাক্সেস সরাতে কোনো অ্যাপ প্রত্যাহার করুন।", "empty": "কোনো অ্যাপ নিজে থেকে এই ফাইলটি খুলতে পারে না।", "loadError": "যেসব অ্যাপ এই ফাইলটি খুলতে পারে সেগুলো লোড করা যায়নি", "via": { "upload": "আপনার জন্য এই ফাইলটি সংরক্ষণ করেছে", "link": "আপনি শেয়ার করেছেন" }, "revoke": "প্রত্যাহার করুন", "confirm": { "title": "{{name}} প্রত্যাহার করবেন?", "message": "{{name}} আর এই ফাইলটি খুলতে পারবে না, এবং এটি যে প্লেব্যাক শুরু করেছে তা এখনই থেমে যাবে।" }, "toasts": { "revoked": "{{name}} আর এই ফাইলটি খুলতে পারবে না", "revokeFailed": "{{name}}-এর অ্যাক্সেস প্রত্যাহার করা যায়নি" }, "a11y": { "revoke": "এই ফাইলে {{name}}-এর অ্যাক্সেস প্রত্যাহার করুন" } }, "trashView": { "title": "ট্র্যাশ", "subtitle": "ফাইল পুনরুদ্ধার করুন বা স্থায়ীভাবে মুছুন", "notice": "পুনরুদ্ধার বা মুছে না ফেলা পর্যন্ত ফাইলগুলো ট্র্যাশে থাকে, এবং এগুলো আপনার স্টোরেজেও গণ্য হয়।", "emptyTitle": "ট্র্যাশ খালি", "emptyDescription": "ট্র্যাশে সরানো ফাইলগুলো এখানে দেখা যাবে। আপনি সেগুলো পুনরুদ্ধার করতে বা স্থায়ীভাবে মুছতে পারবেন।", "trashedOn": "ট্র্যাশে সরানো হয়েছে {{date}}", "deleteForever": "স্থায়ীভাবে মুছুন", "loadError": "আপনার ট্র্যাশ লোড করা যায়নি", "a11y": { "restore": "{{name}} পুনরুদ্ধার করুন", "deleteForever": "{{name}} স্থায়ীভাবে মুছুন" } }, "a11y": { "moveToTrash": "{{name}} ট্র্যাশে সরান", "deleteFile": "{{name}} মুছুন", "openTrash": "ট্র্যাশ খুলুন" }, "toasts": { "movedToTrash": "ট্র্যাশে সরানো হয়েছে। ট্র্যাশ থেকে এটি পুনরুদ্ধার করতে পারবেন।", "bulkMovedToTrash": "{{count}}টি ফাইল ট্র্যাশে সরানো হয়েছে", "moveToTrashFailed": "ফাইলটি ট্র্যাশে সরানো যায়নি", "restored": "ফাইল পুনরুদ্ধার করা হয়েছে", "notInTrash": "এই ফাইলটি আর ট্র্যাশে নেই।", "restoreFailed": "ফাইলটি পুনরুদ্ধার করা যায়নি", "deletedForever": "ফাইল স্থায়ীভাবে মুছে ফেলা হয়েছে", "deleteSuccess": "ফাইল সফলভাবে মুছে ফেলা হয়েছে", "deleteFailed": "ফাইল মোছা যায়নি", "fileNotFound": "ফাইল পাওয়া যায়নি। হয়তো এটি আগেই মুছে ফেলা হয়েছে।", "noPermission": "এই ফাইলটি মোছার অনুমতি আপনার নেই।", "bulkDeleteSuccess": "{{count}}টি ফাইল সফলভাবে মুছে ফেলা হয়েছে", "bulkDeleteFailed": "{{count}}টি ফাইল মোছা যায়নি", "bulkDeleteError": "ফাইলগুলো মোছা যায়নি" }, "confirms": { "deleteFile": "আপনি কি নিশ্চিত যে \"{{filename}}\" মুছতে চান? এটি আর ফেরানো যাবে না।", "moveToTrash": "\"{{filename}}\" ট্র্যাশে সরাবেন? এটি আর কোথাও দেখানো হবে না, এবং ট্র্যাশ থেকে পুনরুদ্ধার করতে পারবেন।", "moveFilesToTrash": "{{count}}টি ফাইল ট্র্যাশে সরাবেন? এগুলো আর কোথাও দেখানো হবে না, এবং ট্র্যাশ থেকে পুনরুদ্ধার করতে পারবেন।", "deleteForever": "\"{{filename}}\" স্থায়ীভাবে মুছবেন? এটি আর ফেরানো যাবে না।", "deleteForeverInUse": "\"{{filename}}\" এখনও আপনার অ্যাপগুলোর {{count}}টি জায়গায় ব্যবহৃত হচ্ছে। মুছলে সেখান থেকেও সরে যাবে। স্থায়ীভাবে মুছবেন?" } }, "follow": { "pending": "অনুরোধ পাঠানো হয়েছে", "disabled": "এখানে বন্ধ", "named": "{{label}} {{name}}", "verbs": { "follow": { "idle": "ফলো করুন", "active": "ফলো করছেন", "everywhere": "সব জায়গায় আনফলো করুন", "undo": "এই অ্যাকাউন্টটি আনফলো করে", "undoNamed": "{{name}}-কে আনফলো করে", "checking": "ফলো স্ট্যাটাস দেখা হচ্ছে", "checkingNamed": "আপনি {{name}}-কে ফলো করেন কিনা দেখা হচ্ছে" }, "subscribe": { "idle": "সাবস্ক্রাইব করুন", "active": "সাবস্ক্রাইব করা হয়েছে", "everywhere": "সব জায়গায় আনসাবস্ক্রাইব করুন", "undo": "আনসাবস্ক্রাইব করে", "undoNamed": "{{name}} থেকে আনসাবস্ক্রাইব করে", "checking": "সাবস্ক্রিপশন স্ট্যাটাস দেখা হচ্ছে", "checkingNamed": "আপনি {{name}}-এ সাবস্ক্রাইব করেছেন কিনা দেখা হচ্ছে" }, "join": { "idle": "যোগ দিন", "active": "যোগ দিয়েছেন", "everywhere": "সব জায়গা থেকে বেরিয়ে যান", "undo": "বেরিয়ে যায়", "undoNamed": "{{name}} থেকে বেরিয়ে যায়", "checking": "সদস্যপদ দেখা হচ্ছে", "checkingNamed": "আপনি {{name}}-এর সদস্য কিনা দেখা হচ্ছে" }, "watch": { "idle": "নজর রাখুন", "active": "নজর রাখছেন", "everywhere": "সব জায়গায় নজর রাখা বন্ধ করুন", "undo": "নজর রাখা বন্ধ করে", "undoNamed": "{{name}}-এর ওপর নজর রাখা বন্ধ করে", "checking": "নজর রাখার স্ট্যাটাস দেখা হচ্ছে", "checkingNamed": "আপনি {{name}}-এর ওপর নজর রাখছেন কিনা দেখা হচ্ছে" } }, "all": { "idle": "সবাইকে ফলো করুন", "hint": "{{count}}টি অ্যাকাউন্টের সবগুলোকে ফলো করে", "hintOne": "{{count}}টি অ্যাকাউন্ট ফলো করে", "undoHint": "{{count}}টি অ্যাকাউন্টের সবগুলোকে আনফলো করে", "undoHintOne": "{{count}}টি অ্যাকাউন্ট আনফলো করে" }, "menu": { "forDuration": "{{duration}}-এর জন্য {{label}}", "showIn": "{{app}}-এ দেখান", "hideIn": "{{app}}-এ দেখাবেন না", "thisApp": "এই অ্যাপ", "options": "{{label}} অপশন", "optionsHint": "আরও অপশন খোলে" }, "durations": { "day": "২৪ ঘণ্টা", "threeDays": "৭২ ঘণ্টা", "week": "এক সপ্তাহ" }, "errors": { "update": "ফলো স্ট্যাটাস আপডেট করা যায়নি", "read": "ফলো স্ট্যাটাস দেখা যায়নি", "mode": "এই ফলোর জন্য এই অ্যাপের সেটিং বদলানো যায়নি", "offline": "আপনি অফলাইনে আছেন। আপনার সংযোগ পরীক্ষা করে আবার চেষ্টা করুন।", "signedOut": "চালিয়ে যেতে আবার সাইন ইন করুন", "forbidden": "এই অ্যাপের এটি করার অনুমতি নেই", "notFound": "এটি আর পাওয়া যাচ্ছে না", "rateLimited": "অনেকবার চেষ্টা করা হয়েছে। একটু পরে আবার চেষ্টা করুন।" } }, "accounts": { "accountCategory": { "news": "সংবাদ", "politics": "রাজনীতি ও নীতি", "business": "ব্যবসা", "startup": "স্টার্টআপ ও উদ্যোক্তা", "finance": "অর্থ ও বিনিয়োগ", "crypto": "ক্রিপ্টো ও ওয়েব৩", "marketplace": "মার্কেটপ্লেস ও শ্রেণিবদ্ধ বিজ্ঞাপন", "retail": "খুচরা ও ই-কমার্স", "real_estate": "রিয়েল এস্টেট", "agency": "রিয়েল এস্টেট এজেন্সি", "landlord": "বাড়িওয়ালা ও সম্পত্তি ব্যবস্থাপনা", "cooperative": "আবাসন সমবায়", "architecture": "স্থাপত্য ও নির্মাণ", "technology": "প্রযুক্তি", "software": "সফটওয়্যার ও ডেভেলপমেন্ট", "ai": "এআই ও মেশিন লার্নিং", "security": "নিরাপত্তা ও গোপনীয়তা", "automation": "অটোমেশন ও টুলস", "science": "বিজ্ঞান ও গবেষণা", "education": "শিক্ষা ও প্রশিক্ষণ", "books": "বই ও লেখালেখি", "health": "স্বাস্থ্য ও চিকিৎসা", "fitness": "ফিটনেস ও সুস্থতা", "sports": "খেলাধুলা", "gaming": "গেমিং ও ই-স্পোর্টস", "music": "সংগীত", "film": "চলচ্চিত্র ও টিভি", "podcast": "পডকাস্ট ও অডিও", "art": "শিল্প ও ডিজাইন", "photography": "ফটোগ্রাফি", "comedy": "কমেডি", "food": "খাবার ও পানীয়", "travel": "ভ্রমণ ও স্থান", "fashion": "ফ্যাশন ও সৌন্দর্য", "home_garden": "বাড়ি ও বাগান", "diy": "DIY ও হাতের কাজ", "automotive": "গাড়ি ও মোটরিং", "animals": "প্রাণী ও পোষা প্রাণী", "family": "পরিবার ও প্যারেন্টিং", "nonprofit": "অলাভজনক ও দাতব্য", "government": "সরকার ও সরকারি খাত", "community": "স্থানীয় কমিউনিটি", "activism": "অ্যাক্টিভিজম ও অ্যাডভোকেসি", "environment": "পরিবেশ ও টেকসই উন্নয়ন", "religion": "ধর্ম ও আধ্যাত্মিকতা", "other": "অন্যান্য" }, "members": { "title": "সদস্য" }, "settings": { "title": "অ্যাকাউন্ট সেটিংস", "subtitle": "এই অ্যাকাউন্টের প্রোফাইল, সদস্য ও অ্যাক্সেস পরিচালনা করুন।", "save": "পরিবর্তন সংরক্ষণ করুন", "displayName": { "label": "প্রদর্শিত নাম", "invalidChars": "শুধু অক্ষর, স্পেস, অ্যাপোস্ট্রফি ও নাম বিভাজক ব্যবহার করুন", "invalidTitle": "< বা > ছাড়া সাধারণ লেখা ব্যবহার করুন (সর্বোচ্চ ৩০০ অক্ষর)" }, "bio": { "label": "বায়ো (ঐচ্ছিক)" }, "picture": { "change": "ছবি বদলান" }, "categories": { "title": "ক্যাটাগরি", "footer": "প্রথম ক্যাটাগরিটি প্রোফাইলে প্রধান হিসেবে দেখানো হয়। সর্বোচ্চ {{max}}টি।", "primary": "প্রধান", "makePrimary": "প্রধান করুন", "remove": "{{category}} সরান", "add": "একটি ক্যাটাগরি যোগ করুন", "atCap": "সর্বোচ্চ {{max}}টি। আরেকটি যোগ করতে একটি সরান।", "unavailable": "অনুপলভ্য ক্যাটাগরি" }, "sections": { "access": "অ্যাক্সেস", "dangerZone": "বিপজ্জনক এলাকা" }, "members": { "subtitle": "মানুষকে আমন্ত্রণ জানান ও ভূমিকা পরিচালনা করুন" }, "archive": { "title": "অ্যাকাউন্ট আর্কাইভ করুন", "subtitle": "এই অ্যাকাউন্ট নিষ্ক্রিয় করুন", "confirmTitle": "অ্যাকাউন্ট আর্কাইভ করুন", "confirmDescription": "এই অ্যাকাউন্ট আর্কাইভ করবেন? এটি নিষ্ক্রিয় হয়ে যাবে এবং এর সদস্যরা অ্যাক্সেস হারাবেন।" }, "errors": { "missingAccount": "কোনো অ্যাকাউন্ট বেছে নেওয়া হয়নি।" }, "toasts": { "saved": "অ্যাকাউন্ট আপডেট হয়েছে", "saveFailed": "অ্যাকাউন্ট আপডেট করা যায়নি", "archived": "অ্যাকাউন্ট আর্কাইভ করা হয়েছে", "archiveFailed": "অ্যাকাউন্ট আর্কাইভ করা যায়নি" } } } });