@solana/connector 0.1.2 → 0.1.4

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 (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +460 -1082
  3. package/dist/{chunk-RIBOPAOD.js → chunk-CLXM6UEE.js} +149 -121
  4. package/dist/chunk-CLXM6UEE.js.map +1 -0
  5. package/dist/{chunk-JS4KJ2KK.js → chunk-D6PZY5G6.js} +71 -93
  6. package/dist/chunk-D6PZY5G6.js.map +1 -0
  7. package/dist/chunk-LUZWUZ5N.js +2012 -0
  8. package/dist/chunk-LUZWUZ5N.js.map +1 -0
  9. package/dist/{chunk-WXYUUCSD.mjs → chunk-N3Q2J2FG.mjs} +53 -71
  10. package/dist/chunk-N3Q2J2FG.mjs.map +1 -0
  11. package/dist/chunk-P5MWBDFG.mjs +298 -0
  12. package/dist/chunk-P5MWBDFG.mjs.map +1 -0
  13. package/dist/chunk-RIQH5W7D.js +311 -0
  14. package/dist/chunk-RIQH5W7D.js.map +1 -0
  15. package/dist/chunk-U64YZRJL.mjs +1984 -0
  16. package/dist/chunk-U64YZRJL.mjs.map +1 -0
  17. package/dist/{chunk-4K6QY4HR.mjs → chunk-YTCSTE3Q.mjs} +64 -37
  18. package/dist/chunk-YTCSTE3Q.mjs.map +1 -0
  19. package/dist/compat.d.mts +4 -2
  20. package/dist/compat.d.ts +4 -2
  21. package/dist/compat.js +3 -3
  22. package/dist/compat.mjs +1 -1
  23. package/dist/headless.d.mts +146 -18
  24. package/dist/headless.d.ts +146 -18
  25. package/dist/headless.js +144 -111
  26. package/dist/headless.mjs +3 -2
  27. package/dist/index.d.mts +6 -5
  28. package/dist/index.d.ts +6 -5
  29. package/dist/index.js +207 -126
  30. package/dist/index.mjs +4 -3
  31. package/dist/react.d.mts +707 -67
  32. package/dist/react.d.ts +707 -67
  33. package/dist/react.js +64 -16
  34. package/dist/react.mjs +2 -2
  35. package/dist/{transaction-signer-D3csM_Mf.d.ts → transaction-signer-D9d8nxwb.d.mts} +3 -1
  36. package/dist/{transaction-signer-D3csM_Mf.d.mts → transaction-signer-D9d8nxwb.d.ts} +3 -1
  37. package/dist/{wallet-standard-shim-Cg0GVGwu.d.mts → wallet-standard-shim-Cp4vF4oo.d.mts} +133 -6
  38. package/dist/{wallet-standard-shim-C1tisl9S.d.ts → wallet-standard-shim-DC_Z7DS-.d.ts} +133 -6
  39. package/package.json +16 -12
  40. package/dist/chunk-4K6QY4HR.mjs.map +0 -1
  41. package/dist/chunk-5ZUVZZWU.mjs +0 -180
  42. package/dist/chunk-5ZUVZZWU.mjs.map +0 -1
  43. package/dist/chunk-F2QJH5ED.mjs +0 -298
  44. package/dist/chunk-F2QJH5ED.mjs.map +0 -1
  45. package/dist/chunk-JS4KJ2KK.js.map +0 -1
  46. package/dist/chunk-RIBOPAOD.js.map +0 -1
  47. package/dist/chunk-SJEZHNYF.js +0 -314
  48. package/dist/chunk-SJEZHNYF.js.map +0 -1
  49. package/dist/chunk-SMUUAKC3.js +0 -186
  50. package/dist/chunk-SMUUAKC3.js.map +0 -1
  51. package/dist/chunk-WXYUUCSD.mjs.map +0 -1
@@ -1,24 +1,19 @@
1
1
  'use strict';
2
2
 
3
- var chunkRIBOPAOD_js = require('./chunk-RIBOPAOD.js');
4
- var chunkSMUUAKC3_js = require('./chunk-SMUUAKC3.js');
3
+ var chunkCLXM6UEE_js = require('./chunk-CLXM6UEE.js');
4
+ var chunkRIQH5W7D_js = require('./chunk-RIQH5W7D.js');
5
5
  var core = require('@wallet-ui/core');
6
- var gill = require('gill');
7
- var bs58 = require('bs58');
8
6
  var addresses = require('@solana/addresses');
7
+ var codecs = require('@solana/codecs');
9
8
  var signers = require('@solana/signers');
10
9
 
11
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
12
-
13
- var bs58__default = /*#__PURE__*/_interopDefault(bs58);
14
-
15
- var logger = chunkSMUUAKC3_js.createLogger("EnhancedStorage"), STORAGE_VERSION = "v1", EnhancedStorage = class extends core.Storage {
10
+ var logger = chunkRIQH5W7D_js.createLogger("EnhancedStorage"), STORAGE_VERSION = "v1", EnhancedStorage = class extends core.Storage {
16
11
  constructor(key, initial, options) {
17
12
  super(key, initial);
18
13
  this.options = options;
19
- chunkSMUUAKC3_js.__publicField(this, "errorHandlers", /* @__PURE__ */ new Set());
20
- chunkSMUUAKC3_js.__publicField(this, "validators", []);
21
- chunkSMUUAKC3_js.__publicField(this, "memoryFallback");
14
+ chunkRIQH5W7D_js.__publicField(this, "errorHandlers", /* @__PURE__ */ new Set());
15
+ chunkRIQH5W7D_js.__publicField(this, "validators", []);
16
+ chunkRIQH5W7D_js.__publicField(this, "memoryFallback");
22
17
  this.memoryFallback = initial, options?.onError && this.errorHandlers.add(options.onError), options?.validator && this.validators.push(options.validator);
23
18
  }
24
19
  set(value) {
@@ -147,7 +142,7 @@ var EnhancedStorageAdapter = class {
147
142
  return this.storage.onError(handler), this;
148
143
  }
149
144
  };
150
- var logger2 = chunkSMUUAKC3_js.createLogger("DefaultConfig");
145
+ var logger2 = chunkRIQH5W7D_js.createLogger("DefaultConfig");
151
146
  function getDefaultConfig(options) {
152
147
  let {
153
148
  appName,
@@ -162,7 +157,7 @@ function getDefaultConfig(options) {
162
157
  persistClusterSelection = true,
163
158
  clusterStorageKey,
164
159
  enableErrorBoundary = true,
165
- maxRetries = chunkRIBOPAOD_js.DEFAULT_MAX_RETRIES,
160
+ maxRetries = chunkCLXM6UEE_js.DEFAULT_MAX_RETRIES,
166
161
  onError
167
162
  } = options, defaultClusters = clusters ?? [
168
163
  core.createSolanaMainnet(),
@@ -171,7 +166,7 @@ function getDefaultConfig(options) {
171
166
  ...network === "localnet" ? [core.createSolanaLocalnet()] : [],
172
167
  ...customClusters || []
173
168
  ], validClusterIds = defaultClusters.map((c) => c.id), accountStorage = createEnhancedStorageAccount({
174
- validator: (address3) => address3 ? gill.isAddress(address3) : true,
169
+ validator: (address3) => address3 ? addresses.isAddress(address3) : true,
175
170
  onError: (error) => {
176
171
  debug && logger2.error("Account Storage error", { error }), onError && onError(error, {
177
172
  componentStack: "account-storage"
@@ -223,7 +218,7 @@ function getDefaultConfig(options) {
223
218
  };
224
219
  }
225
220
  function getInitialCluster(network = "mainnet-beta") {
226
- return chunkRIBOPAOD_js.toClusterId(network);
221
+ return chunkCLXM6UEE_js.toClusterId(network);
227
222
  }
228
223
  function getDefaultMobileConfig(options) {
229
224
  let baseUrl = options.appUrl || (typeof window < "u" ? window.location.origin : "https://localhost:3000");
@@ -239,7 +234,7 @@ function getDefaultMobileConfig(options) {
239
234
 
240
235
  // src/config/unified-config.ts
241
236
  function createConfig(options) {
242
- let { network = "mainnet-beta", rpcUrl: customRpcUrl, ...connectorOptions } = options, normalizedNetwork = chunkRIBOPAOD_js.normalizeNetwork(typeof network == "string" ? network : "mainnet-beta"), rpcUrl = customRpcUrl || chunkRIBOPAOD_js.getDefaultRpcUrl(normalizedNetwork), rpcNetwork = normalizedNetwork === "mainnet" ? "mainnet-beta" : normalizedNetwork, connectorConfig = getDefaultConfig({
237
+ let { network = "mainnet-beta", rpcUrl: customRpcUrl, ...connectorOptions } = options, normalizedNetwork = chunkCLXM6UEE_js.normalizeNetwork(typeof network == "string" ? network : "mainnet-beta"), rpcUrl = customRpcUrl || chunkCLXM6UEE_js.getDefaultRpcUrl(normalizedNetwork), rpcNetwork = normalizedNetwork === "mainnet" ? "mainnet-beta" : normalizedNetwork, connectorConfig = getDefaultConfig({
243
238
  ...connectorOptions,
244
239
  network: rpcNetwork
245
240
  }), mobile = options.enableMobile !== false && normalizedNetwork !== "localnet" ? getDefaultMobileConfig({
@@ -289,10 +284,10 @@ function freezeSigner(signer) {
289
284
  }
290
285
  function base58ToSignatureBytes(signature) {
291
286
  try {
292
- let bytes = bs58__default.default.decode(signature);
287
+ let bytes = codecs.getBase58Encoder().encode(signature);
293
288
  if (bytes.length !== 64)
294
289
  throw new Error(`Invalid signature length: expected 64 bytes, got ${bytes.length}`);
295
- return new Uint8Array(bytes);
290
+ return bytes;
296
291
  } catch (error) {
297
292
  throw new Error(`Failed to decode base58 signature: ${error instanceof Error ? error.message : String(error)}`);
298
293
  }
@@ -301,9 +296,11 @@ function signatureBytesToBase58(bytes) {
301
296
  try {
302
297
  if (bytes.length !== 64)
303
298
  throw new Error(`Invalid signature length: expected 64 bytes, got ${bytes.length}`);
304
- return bs58__default.default.encode(bytes);
299
+ return codecs.getBase58Decoder().decode(bytes);
305
300
  } catch (error) {
306
- throw new Error(`Failed to encode signature to base58: ${error instanceof Error ? error.message : String(error)}`);
301
+ throw new Error(
302
+ `Failed to encode signature to base58: ${error instanceof Error ? error.message : String(error)}`
303
+ );
307
304
  }
308
305
  }
309
306
 
@@ -313,21 +310,15 @@ function createMessageSignerFromWallet(walletAddress, signMessageFn) {
313
310
  address: walletAddress,
314
311
  async modifyAndSignMessages(messages, config) {
315
312
  if (messages.length !== 1)
316
- throw new chunkRIBOPAOD_js.ValidationError("INVALID_FORMAT", "Wallets only support signing one message at a time", {
313
+ throw new chunkCLXM6UEE_js.ValidationError("INVALID_FORMAT", "Wallets only support signing one message at a time", {
317
314
  receivedCount: messages.length,
318
315
  expectedCount: 1
319
316
  });
320
317
  let [message] = messages, { content, signatures: originalSignatures } = message;
321
318
  if (config?.abortSignal?.aborted)
322
- throw chunkRIBOPAOD_js.Errors.userRejected("message signing");
319
+ throw chunkCLXM6UEE_js.Errors.userRejected("message signing");
323
320
  try {
324
- let signature = await signMessageFn(content);
325
- console.log("Signature received from wallet:", {
326
- signatureLength: signature?.length,
327
- signatureType: signature?.constructor?.name,
328
- walletAddress
329
- });
330
- let signatures = updateSignatureDictionary(
321
+ let signature = await signMessageFn(content), signatures = updateSignatureDictionary(
331
322
  content,
332
323
  content,
333
324
  // Message content doesn't change in signMessage
@@ -335,10 +326,7 @@ function createMessageSignerFromWallet(walletAddress, signMessageFn) {
335
326
  walletAddress,
336
327
  signature
337
328
  );
338
- return console.log("Signatures after update:", {
339
- signaturesKeys: Object.keys(signatures),
340
- signaturesValues: Object.values(signatures).map((s) => ({ length: s?.length, type: s?.constructor?.name }))
341
- }), [
329
+ return [
342
330
  {
343
331
  content,
344
332
  signatures
@@ -347,9 +335,9 @@ function createMessageSignerFromWallet(walletAddress, signMessageFn) {
347
335
  } catch (error) {
348
336
  if (error instanceof Error) {
349
337
  let message2 = error.message.toLowerCase();
350
- throw message2.includes("user rejected") || message2.includes("user denied") ? chunkRIBOPAOD_js.Errors.userRejected("message signing") : new chunkRIBOPAOD_js.TransactionError("SIGNING_FAILED", "Failed to sign message", void 0, error);
338
+ throw message2.includes("user rejected") || message2.includes("user denied") ? chunkCLXM6UEE_js.Errors.userRejected("message signing") : new chunkCLXM6UEE_js.TransactionError("SIGNING_FAILED", "Failed to sign message", void 0, error);
351
339
  }
352
- throw new chunkRIBOPAOD_js.TransactionError("SIGNING_FAILED", "Failed to sign message", {
340
+ throw new chunkCLXM6UEE_js.TransactionError("SIGNING_FAILED", "Failed to sign message", {
353
341
  originalError: String(error)
354
342
  });
355
343
  }
@@ -361,22 +349,22 @@ function createTransactionSendingSignerFromWallet(walletAddress, chain, sendTran
361
349
  address: walletAddress,
362
350
  async signAndSendTransactions(transactions, config) {
363
351
  if (transactions.length !== 1)
364
- throw new chunkRIBOPAOD_js.ValidationError("INVALID_FORMAT", "Wallets only support sending one transaction at a time", {
352
+ throw new chunkCLXM6UEE_js.ValidationError("INVALID_FORMAT", "Wallets only support sending one transaction at a time", {
365
353
  receivedCount: transactions.length,
366
354
  expectedCount: 1
367
355
  });
368
356
  let [transaction] = transactions;
369
357
  if (config?.abortSignal?.aborted)
370
- throw chunkRIBOPAOD_js.Errors.userRejected("transaction sending");
358
+ throw chunkCLXM6UEE_js.Errors.userRejected("transaction sending");
371
359
  try {
372
360
  let signatureString = await sendTransactionFn(transaction);
373
361
  return [base58ToSignatureBytes(signatureString)];
374
362
  } catch (error) {
375
363
  if (error instanceof Error) {
376
364
  let message = error.message.toLowerCase();
377
- throw message.includes("user rejected") || message.includes("user denied") ? chunkRIBOPAOD_js.Errors.userRejected("transaction sending") : message.includes("network") || message.includes("rpc") ? new chunkRIBOPAOD_js.TransactionError("SEND_FAILED", "Failed to send transaction", void 0, error) : new chunkRIBOPAOD_js.TransactionError("SEND_FAILED", "Failed to send transaction", void 0, error);
365
+ throw message.includes("user rejected") || message.includes("user denied") ? chunkCLXM6UEE_js.Errors.userRejected("transaction sending") : message.includes("network") || message.includes("rpc") ? new chunkCLXM6UEE_js.TransactionError("SEND_FAILED", "Failed to send transaction", void 0, error) : new chunkCLXM6UEE_js.TransactionError("SEND_FAILED", "Failed to send transaction", void 0, error);
378
366
  }
379
- throw new chunkRIBOPAOD_js.TransactionError("SEND_FAILED", "Failed to send transaction", {
367
+ throw new chunkCLXM6UEE_js.TransactionError("SEND_FAILED", "Failed to send transaction", {
380
368
  originalError: String(error)
381
369
  });
382
370
  }
@@ -413,60 +401,48 @@ function createKitSignersFromWallet(wallet, account, connection, network) {
413
401
  let rpcUrl = connection.rpcEndpoint || "";
414
402
  rpcUrl.includes("mainnet") || rpcUrl.includes("api.mainnet-beta") ? chain = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp" : rpcUrl.includes("testnet") ? chain = "solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z" : chain = "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1";
415
403
  }
416
- let features = wallet.features, hasSignMessage = !!features["solana:signMessage"], hasSignAndSendTransaction = !!features["solana:signAndSendTransaction"], hasSendTransaction = !!features["solana:sendTransaction"], messageSigner = hasSignMessage ? createMessageSignerFromWallet(
417
- walletAddress,
418
- async (message) => {
419
- if (!hasSignMessage)
420
- throw chunkRIBOPAOD_js.Errors.featureNotSupported("message signing");
404
+ let features = wallet.features, hasSignMessage = !!features["solana:signMessage"], hasSignAndSendTransaction = !!features["solana:signAndSendTransaction"], hasSendTransaction = !!features["solana:sendTransaction"], messageSigner = hasSignMessage ? createMessageSignerFromWallet(walletAddress, async (message) => {
405
+ if (!hasSignMessage)
406
+ throw chunkCLXM6UEE_js.Errors.featureNotSupported("message signing");
407
+ try {
408
+ let signFeature = features["solana:signMessage"], messageBytes = message instanceof Uint8Array ? message : new Uint8Array(message), results = await signFeature.signMessage({
409
+ account,
410
+ message: messageBytes,
411
+ ...chain ? { chain } : {}
412
+ });
413
+ if (!Array.isArray(results) || results.length === 0)
414
+ throw new Error("Wallet returned empty results array");
415
+ let firstResult = results[0];
416
+ if (!firstResult?.signature)
417
+ throw new Error("Wallet returned no signature in first result");
418
+ return firstResult.signature;
419
+ } catch (error) {
420
+ throw console.error("signMessage error:", error), error instanceof Error ? error : new Error(String(error));
421
+ }
422
+ }) : null, transactionSigner = hasSignAndSendTransaction || hasSendTransaction ? createTransactionSendingSignerFromWallet(walletAddress, chain, async (transaction) => {
423
+ if (hasSignAndSendTransaction)
421
424
  try {
422
- let results = await features["solana:signMessage"].signMessage({
425
+ return (await features["solana:signAndSendTransaction"].signAndSendTransaction({
423
426
  account,
424
- message,
427
+ transactions: [transaction],
428
+ ...chain ? { chain } : {},
429
+ ...connection ? { connection } : {}
430
+ })).signatures[0] || "";
431
+ } catch (error) {
432
+ throw error instanceof Error ? error : new Error(String(error));
433
+ }
434
+ if (hasSendTransaction)
435
+ try {
436
+ return (await features["solana:sendTransaction"].sendTransaction({
437
+ account,
438
+ transactions: [transaction],
425
439
  ...chain ? { chain } : {}
426
- });
427
- if (console.log("Wallet signMessage result:", {
428
- isArray: Array.isArray(results),
429
- length: results?.length,
430
- firstResult: results?.[0],
431
- firstSignature: results?.[0]?.signature
432
- }), !Array.isArray(results) || results.length === 0)
433
- throw new Error("Wallet returned empty results array");
434
- let firstResult = results[0];
435
- if (!firstResult?.signature)
436
- throw new Error("Wallet returned no signature in first result");
437
- return firstResult.signature;
440
+ })).signatures[0] || "";
438
441
  } catch (error) {
439
- throw console.error("signMessage error:", error), error instanceof Error ? error : new Error(String(error));
442
+ throw error instanceof Error ? error : new Error(String(error));
440
443
  }
441
- }
442
- ) : null, transactionSigner = hasSignAndSendTransaction || hasSendTransaction ? createTransactionSendingSignerFromWallet(
443
- walletAddress,
444
- chain,
445
- async (transaction) => {
446
- if (hasSignAndSendTransaction)
447
- try {
448
- return (await features["solana:signAndSendTransaction"].signAndSendTransaction({
449
- account,
450
- transactions: [transaction],
451
- ...chain ? { chain } : {},
452
- ...connection ? { chain } : {}
453
- })).signatures[0] || "";
454
- } catch (error) {
455
- throw error instanceof Error ? error : new Error(String(error));
456
- }
457
- if (hasSendTransaction)
458
- try {
459
- return (await features["solana:sendTransaction"].sendTransaction({
460
- account,
461
- transactions: [transaction],
462
- ...chain ? { chain } : {}
463
- })).signatures[0] || "";
464
- } catch (error) {
465
- throw error instanceof Error ? error : new Error(String(error));
466
- }
467
- throw chunkRIBOPAOD_js.Errors.featureNotSupported("transaction sending");
468
- }
469
- ) : null;
444
+ throw chunkCLXM6UEE_js.Errors.featureNotSupported("transaction sending");
445
+ }) : null;
470
446
  return {
471
447
  address: walletAddress,
472
448
  addressString: walletAddressString,
@@ -524,7 +500,7 @@ var SOLANA_CHAIN_IDS = {
524
500
  "solana:testnet": SOLANA_CHAIN_IDS.testnet
525
501
  };
526
502
  function getChainIdFromCluster(cluster) {
527
- let clusterType = chunkRIBOPAOD_js.getClusterType(cluster);
503
+ let clusterType = chunkCLXM6UEE_js.getClusterType(cluster);
528
504
  return clusterType === "localnet" || clusterType === "custom" ? null : getChainIdFromClusterType(clusterType);
529
505
  }
530
506
  function getChainIdFromClusterId(clusterId) {
@@ -594,12 +570,14 @@ function chainIdToClusterType(chainId) {
594
570
  function chainIdToClusterId(chainId) {
595
571
  return getClusterIdFromChainId(chainId);
596
572
  }
573
+
574
+ // src/lib/utils/explorer-urls.ts
597
575
  function getSolanaExplorerUrl(signature, options = {}) {
598
576
  let { cluster = "mainnet", customUrl } = options, normalizedCluster = cluster === "mainnet-beta" ? "mainnet" : cluster;
599
577
  if (normalizedCluster === "localnet")
600
578
  return `https://explorer.solana.com/tx/${signature}?cluster=custom&customUrl=${encodeURIComponent(customUrl || "http://localhost:8899")}`;
601
579
  let explorerCluster = ["mainnet", "devnet", "testnet"].includes(normalizedCluster) ? normalizedCluster : "devnet";
602
- return gill.getExplorerLink({
580
+ return chunkRIQH5W7D_js.getExplorerLink({
603
581
  transaction: signature,
604
582
  cluster: explorerCluster
605
583
  });
@@ -702,5 +680,5 @@ exports.sendRawTransaction = sendRawTransaction;
702
680
  exports.signatureBytesToBase58 = signatureBytesToBase58;
703
681
  exports.updateSignatureDictionary = updateSignatureDictionary;
704
682
  exports.validateKnownSolanaChain = validateKnownSolanaChain;
705
- //# sourceMappingURL=chunk-JS4KJ2KK.js.map
706
- //# sourceMappingURL=chunk-JS4KJ2KK.js.map
683
+ //# sourceMappingURL=chunk-D6PZY5G6.js.map
684
+ //# sourceMappingURL=chunk-D6PZY5G6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/adapters/enhanced-storage.ts","../src/config/default-config.ts","../src/config/unified-config.ts","../src/types/wallets.ts","../src/lib/kit-signers/utils.ts","../src/lib/kit-signers/factories.ts","../src/lib/kit-signers/integration.ts","../src/lib/connection/types.ts","../src/lib/connection/helpers.ts","../src/utils/chain.ts","../src/lib/utils/explorer-urls.ts"],"names":["createLogger","WalletUiStorage","__publicField","logger","DEFAULT_MAX_RETRIES","createSolanaMainnet","createSolanaDevnet","createSolanaTestnet","createSolanaLocalnet","address","isAddress","toClusterId","normalizeNetwork","getDefaultRpcUrl","getBase58Encoder","getBase58Decoder","ValidationError","Errors","message","TransactionError","getClusterType","getExplorerLink"],"mappings":";;;;;;;;;AAeA,IAAM,MAAA,GAASA,8BAAa,iBAAiB,CAAA,CAAA,CAMhC,kBAAkB,IAAA,CAAA,CAMlB,eAAA,GAAN,cAAiCC,YAAA,CAAmB;AAAA,EAKvD,WAAA,CACI,GAAA,EACA,OAAA,EACQ,OAAA,EACV;AACE,IAAA,KAAA,CAAM,KAAK,OAAO,CAAA;AAFV,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAPZ,IAAAC,8BAAA,CAAA,IAAA,EAAQ,eAAA,sBAAiD,GAAA,EAAI,CAAA;AAC7D,IAAAA,8BAAA,CAAA,IAAA,EAAQ,cAAwC,EAAC,CAAA;AACjD,IAAAA,8BAAA,CAAA,IAAA,EAAQ,gBAAA,CAAA;AAQJ,IAAA,IAAA,CAAK,iBAAiB,OAAA,EAElB,OAAA,EAAS,OAAA,IACT,IAAA,CAAK,cAAc,GAAA,CAAI,OAAA,CAAQ,OAAO,CAAA,EAEtC,SAAS,SAAA,IACT,IAAA,CAAK,UAAA,CAAW,IAAA,CAAK,QAAQ,SAAS,CAAA;AAAA,EAE9C;AAAA,EAES,IAAI,KAAA,EAAmB;AAC5B,IAAA,IAAI;AACA,MAAA,OAAK,IAAA,CAAK,SAAS,KAAK,CAAA,IAKxB,MAAM,GAAA,CAAI,KAAK,GAEf,IAAA,CAAK,cAAA,GAAiB,OACf,IAAA,KAPH,MAAA,CAAO,KAAK,mBAAA,EAAqB,EAAE,KAAK,IAAA,CAAK,GAAA,EAAK,CAAA,EAC3C,KAAA,CAAA;AAAA,IAOf,SAAS,KAAA,EAAO;AAGZ,MAAA,OAFA,IAAA,CAAK,WAAA,CAAY,KAAc,CAAA,EAE3B,IAAA,CAAK,SAAS,iBAAA,IACd,IAAA,CAAK,cAAA,GAAiB,KAAA,EACf,IAAA,IAGJ,KAAA;AAAA,IACX;AAAA,EACJ;AAAA,EAES,GAAA,GAAS;AACd,IAAA,IAAI;AACA,MAAA,OAAO,MAAM,GAAA,EAAI;AAAA,IACrB,SAAS,KAAA,EAAO;AAGZ,MAAA,OAFA,IAAA,CAAK,YAAY,KAAc,CAAA,EAE3B,KAAK,OAAA,EAAS,iBAAA,GACP,IAAA,CAAK,cAAA,GAGT,IAAA,CAAK,OAAA;AAAA,IAChB;AAAA,EACJ;AAAA,EAEA,SAAS,KAAA,EAAmB;AACxB,IAAA,OAAO,KAAK,UAAA,CAAW,KAAA,CAAM,CAAA,SAAA,KAAa,SAAA,CAAU,KAAK,CAAC,CAAA;AAAA,EAC9D;AAAA,EAEA,aAAa,SAAA,EAAwC;AACjD,IAAA,OAAA,IAAA,CAAK,UAAA,CAAW,IAAA,CAAK,SAAS,CAAA,EACvB,IAAA;AAAA,EACX;AAAA,EAEA,QAAQ,OAAA,EAAuC;AAC3C,IAAA,OAAA,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,OAAO,CAAA,EACvB,IAAA;AAAA,EACX;AAAA,EAEA,UAAa,WAAA,EAAiC;AAC1C,IAAA,OAAO,WAAA,CAAY,IAAA,CAAK,GAAA,EAAK,CAAA;AAAA,EACjC;AAAA,EAEA,KAAA,GAAc;AACV,IAAA,IAAA,CAAK,GAAA,CAAI,KAAK,OAAO,CAAA;AAAA,EACzB;AAAA,EAEA,KAAA,GAAc;AACV,IAAA,IAAI;AACA,MAAI,OAAO,MAAA,GAAW,GAAA,IAAe,MAAA,CAAO,YAAA,IACxC,MAAA,CAAO,YAAA,CAAa,UAAA,CAAW,IAAA,CAAK,GAAG,CAAA,EAE3C,IAAA,CAAK,KAAA,EAAM;AAAA,IACf,SAAS,KAAA,EAAO;AACZ,MAAA,IAAA,CAAK,YAAY,KAAc,CAAA;AAAA,IACnC;AAAA,EACJ;AAAA,EAEA,WAAA,GAAuB;AACnB,IAAA,IAAI;AACA,MAAA,IAAI,OAAO,MAAA,GAAW,GAAA,EAAa,OAAO,KAAA;AAC1C,MAAA,IAAM,OAAA,GAAU,CAAA,eAAA,EAAkB,IAAA,CAAK,GAAG,CAAA,EAAA,CAAA;AAC1C,MAAA,OAAA,MAAA,CAAO,YAAA,CAAa,QAAQ,OAAA,EAAS,MAAM,GAC3C,MAAA,CAAO,YAAA,CAAa,UAAA,CAAW,OAAO,CAAA,EAC/B,IAAA;AAAA,IACX,CAAA,CAAA,MAAQ;AACJ,MAAA,OAAO,KAAA;AAAA,IACX;AAAA,EACJ;AAAA,EAEA,OAAO,OAAA,CAAW,MAAA,EAAgB,UAAA,EAAyC;AACvE,IAAA,IAAI;AACA,MAAA,IAAI,OAAO,MAAA,GAAW,GAAA,EAAa,OAAO,KAAA;AAE1C,MAAA,IAAM,QAAA,GAAW,MAAA,CAAO,YAAA,CAAa,OAAA,CAAQ,MAAM,CAAA;AACnD,MAAA,IAAI,QAAA,EAAU;AACV,QAAA,IAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,QAAQ,CAAA;AAClC,QAAA,OAAA,UAAA,CAAW,IAAI,MAAM,CAAA,EACrB,OAAO,YAAA,CAAa,UAAA,CAAW,MAAM,CAAA,EAC9B,IAAA;AAAA,MACX;AACA,MAAA,OAAO,KAAA;AAAA,IACX,CAAA,CAAA,MAAQ;AACJ,MAAA,OAAO,KAAA;AAAA,IACX;AAAA,EACJ;AAAA,EAEQ,YAAY,KAAA,EAAoB;AACpC,IAAA,MAAA,CAAO,KAAA,CAAM,eAAA,EAAiB,EAAE,GAAA,EAAK,IAAA,CAAK,GAAA,EAAK,KAAA,EAAO,CAAA,EACtD,IAAA,CAAK,aAAA,CAAc,OAAA,CAAQ,CAAA,OAAA,KAAW;AAClC,MAAA,IAAI;AACA,QAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,MACjB,SAAS,GAAA,EAAK;AACV,QAAA,MAAA,CAAO,KAAA,CAAM,wBAAA,EAA0B,EAAE,KAAA,EAAO,KAAK,CAAA;AAAA,MACzD;AAAA,IACJ,CAAC,CAAA;AAAA,EACL;AACJ;AAEO,SAAS,6BACZ,OAAA,EACmC;AACnC,EAAA,IAAM,GAAA,GAAM,OAAA,EAAS,GAAA,IAAO,CAAA,cAAA,EAAiB,eAAe,CAAA,QAAA,CAAA;AAC5D,EAAA,OAAO,IAAI,eAAA,CAAgB,GAAA,EAAK,OAAA,EAAS,OAAA,EAAS;AAAA,IAC9C,WAAW,OAAA,EAAS,SAAA;AAAA,IACpB,SAAS,OAAA,EAAS,OAAA;AAAA,IAClB,iBAAA,EAAmB;AAAA;AAAA,GACtB,CAAA;AACL;AAEO,SAAS,6BACZ,OAAA,EACgC;AAChC,EAAA,IAAM,GAAA,GAAM,OAAA,EAAS,GAAA,IAAO,CAAA,cAAA,EAAiB,eAAe,CAAA,QAAA,CAAA,EACtD,OAAA,GAAU,IAAI,eAAA,CAAgB,GAAA,EAAK,OAAA,EAAS,OAAA,IAAW,gBAAA,EAAkB;AAAA,IAC3E,SAAS,OAAA,EAAS,OAAA;AAAA,IAClB,iBAAA,EAAmB;AAAA,GACtB,CAAA;AAED,EAAA,OAAI,OAAA,EAAS,aAAA,IACT,OAAA,CAAQ,YAAA,CAAa,CAAA,SAAA,KAAa,QAAQ,aAAA,CAAe,QAAA,CAAS,SAAS,CAAC,CAAA,EAGzE,OAAA;AACX;AAEO,SAAS,4BACZ,OAAA,EACmC;AACnC,EAAA,IAAM,GAAA,GAAM,OAAA,EAAS,GAAA,IAAO,CAAA,cAAA,EAAiB,eAAe,CAAA,OAAA,CAAA;AAC5D,EAAA,OAAO,IAAI,eAAA,CAAgB,GAAA,EAAK,OAAA,EAAS,OAAA,EAAS;AAAA,IAC9C,SAAS,OAAA,EAAS,OAAA;AAAA,IAClB,iBAAA,EAAmB;AAAA,GACtB,CAAA;AACL;AAEO,IAAM,yBAAN,MAA6D;AAAA,EAChE,YAAoB,OAAA,EAA6B;AAA7B,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAAA,EAA8B;AAAA,EAElD,GAAA,GAAS;AACL,IAAA,OAAO,IAAA,CAAK,QAAQ,GAAA,EAAI;AAAA,EAC5B;AAAA,EAEA,IAAI,KAAA,EAAgB;AAChB,IAAA,IAAA,CAAK,OAAA,CAAQ,IAAI,KAAK,CAAA;AAAA,EAC1B;AAAA,EAEA,UAAU,QAAA,EAA0C;AAChD,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,KAAA,CAAM,SAAA,CAAU,QAAQ,CAAA;AAAA,EAChD;AAAA,EAEA,SAAS,KAAA,EAAmB;AACxB,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,QAAA,CAAS,KAAK,CAAA;AAAA,EACtC;AAAA,EAEA,KAAA,GAAc;AACV,IAAA,IAAA,CAAK,QAAQ,KAAA,EAAM;AAAA,EACvB;AAAA,EAEA,KAAA,GAAc;AACV,IAAA,IAAA,CAAK,QAAQ,KAAA,EAAM;AAAA,EACvB;AAAA,EAEA,WAAA,GAAuB;AACnB,IAAA,OAAO,IAAA,CAAK,QAAQ,WAAA,EAAY;AAAA,EACpC;AAAA,EAEA,UAAa,WAAA,EAAiC;AAC1C,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,SAAA,CAAU,WAAW,CAAA;AAAA,EAC7C;AAAA,EAEA,aAAa,SAAA,EAAwC;AACjD,IAAA,OAAA,IAAA,CAAK,OAAA,CAAQ,YAAA,CAAa,SAAS,CAAA,EAC5B,IAAA;AAAA,EACX;AAAA,EAEA,QAAQ,OAAA,EAAuC;AAC3C,IAAA,OAAA,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,OAAO,CAAA,EACrB,IAAA;AAAA,EACX;AACJ;AChOA,IAAMC,OAAAA,GAASH,8BAAa,eAAe,CAAA;AA2DpC,SAAS,iBAAiB,OAAA,EAAwD;AACrF,EAAA,IAAM;AAAA,IACF,OAAA;AAAA,IACA,MAAA;AAAA,IACA,WAAA,GAAc,IAAA;AAAA,IACd,KAAA;AAAA,IACA,OAAA,GAAU,cAAA;AAAA,IACV,YAAA,GAAe,IAAA;AAAA,IACf,OAAA;AAAA,IACA,QAAA;AAAA,IACA,iBAAiB,EAAC;AAAA,IAClB,uBAAA,GAA0B,IAAA;AAAA,IAC1B,iBAAA;AAAA,IACA,mBAAA,GAAsB,IAAA;AAAA,IACtB,UAAA,GAAaI,oCAAA;AAAA,IACb;AAAA,GACJ,GAAI,OAAA,EAEE,eAAA,GAAmC,QAAA,IAAY;AAAA,IACjDC,wBAAA,EAAoB;AAAA,IACpBC,uBAAA,EAAmB;AAAA,IACnBC,wBAAA,EAAoB;AAAA,IACpB,GAAI,OAAA,KAAY,UAAA,GAAa,CAACC,yBAAA,EAAsB,IAAI,EAAC;AAAA,IACzD,GAAI,kBAAkB;AAAC,GAC3B,EAEM,kBAAkB,eAAA,CAAgB,GAAA,CAAI,OAAK,CAAA,CAAE,EAAE,CAAA,EAE/C,cAAA,GAAiB,4BAAA,CAA6B;AAAA,IAChD,WAAW,CAAAC,QAAAA,KACFA,QAAAA,GACEC,mBAAA,CAAUD,QAAO,CAAA,GADH,IAAA;AAAA,IAGzB,SAAS,CAAA,KAAA,KAAS;AACd,MAAI,KAAA,IACAN,OAAAA,CAAO,KAAA,CAAM,uBAAA,EAAyB,EAAE,OAAO,CAAA,EAE/C,OAAA,IACA,OAAA,CAAQ,KAAA,EAAO;AAAA,QACX,cAAA,EAAgB;AAAA,OACnB,CAAA;AAAA,IAET;AAAA,GACH,CAAA,EAEK,cAAA,GAAiB,4BAAA,CAA6B;AAAA,IAChD,GAAA,EAAK,iBAAA;AAAA,IACL,OAAA,EAAS,kBAAkB,OAAO,CAAA;AAAA,IAClC,aAAA,EAAe,0BAA0B,eAAA,GAAkB,MAAA;AAAA,IAC3D,SAAS,CAAA,KAAA,KAAS;AACd,MAAI,KAAA,IACAA,OAAAA,CAAO,KAAA,CAAM,uBAAA,EAAyB,EAAE,OAAO,CAAA,EAE/C,OAAA,IACA,OAAA,CAAQ,KAAA,EAAO;AAAA,QACX,cAAA,EAAgB;AAAA,OACnB,CAAA;AAAA,IAET;AAAA,GACH,CAAA,EAEK,aAAA,GAAgB,2BAAA,CAA4B;AAAA,IAC9C,SAAS,CAAA,KAAA,KAAS;AACd,MAAI,KAAA,IACAA,OAAAA,CAAO,KAAA,CAAM,sBAAA,EAAwB,EAAE,OAAO,CAAA,EAE9C,OAAA,IACA,OAAA,CAAQ,KAAA,EAAO;AAAA,QACX,cAAA,EAAgB;AAAA,OACnB,CAAA;AAAA,IAET;AAAA,GACH,CAAA;AAID,EAAA,IAAI,OAAO,SAAW,GAAA,EAAa;AAG/B,IAAA,IAAM,aAAA,GAAgB,uBAAA,EAChB,YAAA,GAAe,sBAAA,EACf,gBAAgB,iBAAA,IAAqB,uBAAA;AAE3C,IAAA,eAAA,CAAgB,OAAA,CAAQ,aAAA,EAAe,cAAc,CAAA,EACrD,eAAA,CAAgB,OAAA,CAAQ,YAAA,EAAc,aAAa,CAAA,EACnD,eAAA,CAAgB,OAAA,CAAQ,aAAA,EAAe,cAAc,CAAA;AAAA,EACzD;AAEA,EAAA,IAAM,iBAA6C,OAAA,IAAW;AAAA,IAC1D,OAAA,EAAS,IAAI,sBAAA,CAAuB,cAAc,CAAA;AAAA,IAClD,OAAA,EAAS,IAAI,sBAAA,CAAuB,cAAc,CAAA;AAAA,IAClD,MAAA,EAAQ,IAAI,sBAAA,CAAuB,aAAa;AAAA,GACpD;AAsBA,EAAA,OApBwC;AAAA,IACpC,WAAA;AAAA,IACA,KAAA,EAAO,KAAA,IAAS,OAAA,CAAQ,GAAA,CAAI,QAAA,KAAa,aAAA;AAAA,IACzC,OAAA,EAAS,cAAA;AAAA,IACT,OAAA;AAAA,IACA,MAAA;AAAA,IACA,YAAA;AAAA,IACA,OAAA;AAAA,IACA,OAAA,EAAS;AAAA,MACL,QAAA,EAAU,eAAA;AAAA,MACV,gBAAA,EAAkB,uBAAA;AAAA,MAClB,cAAA,EAAgB,kBAAkB,OAAO;AAAA,KAC7C;AAAA,IACA,aAAA,EAAe;AAAA,MACX,OAAA,EAAS,mBAAA;AAAA,MACT,UAAA;AAAA,MACA;AAAA;AACJ,GACJ;AAGJ;AAMA,SAAS,iBAAA,CACL,UAA0E,cAAA,EAC3D;AACf,EAAA,OAAOQ,6BAAY,OAAO,CAAA;AAC9B;AAKO,SAAS,uBAAuB,OAAA,EAIpC;AACC,EAAA,IAAM,OAAA,GACF,QAAQ,MAAA,KAAW,OAAO,SAAW,GAAA,GAAc,MAAA,CAAO,SAAS,MAAA,GAAS,wBAAA,CAAA;AAEhF,EAAA,OAAO;AAAA,IACH,WAAA,EAAa;AAAA,MACT,MAAM,OAAA,CAAQ,OAAA;AAAA,MACd,GAAA,EAAK,OAAA;AAAA,MACL,IAAA,EAAM,GAAG,OAAO,CAAA,YAAA;AAAA,KACpB;AAAA,IACA,OAAA,EAAS,QAAQ,OAAA,IAAW;AAAA,GAChC;AACJ;;;AC5FO,SAAS,aAAa,OAAA,EAA8C;AAEvE,EAAA,IAAM,EAAE,OAAA,GAAU,cAAA,EAAgB,MAAA,EAAQ,YAAA,EAAc,GAAG,gBAAA,EAAiB,GAAI,OAAA,EAG1E,iBAAA,GAAoBC,iCAAA,CAAiB,OAAO,OAAA,IAAY,QAAA,GAAW,OAAA,GAAU,cAAc,CAAA,EAG3F,MAAA,GAAS,YAAA,IAAgBC,iCAAA,CAAiB,iBAAiB,CAAA,EAG3D,UAAA,GAAa,iBAAA,KAAsB,SAAA,GAAY,cAAA,GAAiB,iBAAA,EAGhE,eAAA,GAAkB,gBAAA,CAAiB;AAAA,IACrC,GAAG,gBAAA;AAAA,IACH,OAAA,EAAS;AAAA,GACZ,GAGK,MAAA,GACF,OAAA,CAAQ,iBAAiB,KAAA,IAAS,iBAAA,KAAsB,aAClD,sBAAA,CAAuB;AAAA,IACnB,SAAS,OAAA,CAAQ,OAAA;AAAA,IACjB,QAAQ,eAAA,CAAgB,MAAA;AAAA,IACxB,OAAA,EAAS;AAAA,GACZ,CAAA,GACD,MAAA;AAEV,EAAA,OAAO;AAAA,IACH,eAAA;AAAA,IACA,MAAA;AAAA,IACA,OAAA,EAAS,iBAAA;AAAA,IACT,MAAA;AAAA,IACA,GAAA,EAAK;AAAA,MACD,MAAM,OAAA,CAAQ,OAAA;AAAA,MACd,GAAA,EACI,gBAAgB,MAAA,KACf,OAAO,SAAW,GAAA,GAAc,MAAA,CAAO,SAAS,MAAA,GAAS,wBAAA;AAAA;AAClE,GACJ;AACJ;AAaO,SAAS,gBAAgB,MAAA,EAA0C;AACtE,EAAA,OAAO,CAAA,EACH,MAAA,IACI,OAAO,MAAA,IAAW,QAAA,IAClB,iBAAA,IAAqB,MAAA,IACrB,SAAA,IAAa,MAAA,IACb,QAAA,IAAY,MAAA,IACZ,KAAA,IAAS,MAAA,CAAA;AAErB;;;ACrKO,SAAS,aAAa,KAAA,EAAoC;AAC7D,EAAA,OAAO,OAAO,KAAA,IAAU,QAAA,IAAY,KAAA,CAAM,MAAA,GAAS,CAAA;AACvD;AAOO,SAAS,iBAAiB,KAAA,EAAwC;AAErE,EAAA,OAAO,OAAO,KAAA,IAAU,QAAA,IAAY,MAAM,MAAA,IAAU,EAAA,IAAM,MAAM,MAAA,IAAU,EAAA;AAC9E;AC9BO,SAAS,yBAAA,CAA0B,UAAsB,QAAA,EAA+B;AAC3F,EAAA,IAAI,QAAA,CAAS,WAAW,QAAA,CAAS,MAAA;AAC7B,IAAA,OAAO,IAAA;AAGX,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,QAAA,CAAS,MAAA,EAAQ,CAAA,EAAA;AACjC,IAAA,IAAI,QAAA,CAAS,CAAC,CAAA,KAAM,QAAA,CAAS,CAAC,CAAA;AAC1B,MAAA,OAAO,IAAA;AAIf,EAAA,OAAO,KAAA;AACX;AAEO,SAAS,yBAAA,CACZ,QAAA,EACA,MAAA,EACA,kBAAA,EACAJ,UACA,SAAA,EACmB;AACnB,EAAA,IAAM,WAAA,GAAc,0BAA0B,QAAA,EAAU,MAAM,GAExD,cAAA,GAAiB,SAAA,EAEjB,gBAAgB,EAAC;AAGvB,EAAA,OAFA,aAAA,CAAcA,QAAiB,CAAA,GAAI,cAAA,EAE/B,cACO,aAAA,GAGI;AAAA,IACX,GAAG,kBAAA;AAAA,IACH,GAAG;AAAA,GACP;AAGJ;AAEO,SAAS,aAA+B,MAAA,EAAwB;AACnE,EAAA,OAAO,MAAA,CAAO,OAAO,MAAM,CAAA;AAC/B;AAEO,SAAS,uBAAuB,SAAA,EAAmC;AACtE,EAAA,IAAI;AACA,IAAA,IAAM,KAAA,GAAQK,uBAAA,EAAiB,CAAE,MAAA,CAAO,SAAS,CAAA;AACjD,IAAA,IAAI,MAAM,MAAA,KAAW,EAAA;AACjB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,iDAAA,EAAoD,KAAA,CAAM,MAAM,CAAA,CAAE,CAAA;AAEtF,IAAA,OAAO,KAAA;AAAA,EACX,SAAS,KAAA,EAAO;AACZ,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,mCAAA,EAAsC,KAAA,YAAiB,KAAA,GAAQ,MAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CAAC,CAAA,CAAE,CAAA;AAAA,EAClH;AACJ;AAEO,SAAS,uBAAuB,KAAA,EAA+B;AAClE,EAAA,IAAI;AACA,IAAA,IAAI,MAAM,MAAA,KAAW,EAAA;AACjB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,iDAAA,EAAoD,KAAA,CAAM,MAAM,CAAA,CAAE,CAAA;AAEtF,IAAA,OAAOC,uBAAA,EAAiB,CAAE,MAAA,CAAO,KAAK,CAAA;AAAA,EAC1C,SAAS,KAAA,EAAO;AACZ,IAAA,MAAM,IAAI,KAAA;AAAA,MACN,yCAAyC,KAAA,YAAiB,KAAA,GAAQ,MAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,KACnG;AAAA,EACJ;AACJ;;;AChCO,SAAS,6BAAA,CACZ,eACA,aAAA,EAC8B;AA6D9B,EAAA,OAAO,YAAA,CA5DwC;AAAA,IAC3C,OAAA,EAAS,aAAA;AAAA,IAET,MAAM,qBAAA,CACF,QAAA,EACA,MAAA,EACmC;AAEnC,MAAA,IAAI,SAAS,MAAA,KAAW,CAAA;AACpB,QAAA,MAAM,IAAIC,gCAAA,CAAgB,gBAAA,EAAkB,oDAAA,EAAsD;AAAA,UAC9F,eAAe,QAAA,CAAS,MAAA;AAAA,UACxB,aAAA,EAAe;AAAA,SAClB,CAAA;AAGL,MAAA,IAAM,CAAC,OAAO,CAAA,GAAI,QAAA,EACZ,EAAE,OAAA,EAAS,UAAA,EAAY,oBAAmB,GAAI,OAAA;AAGpD,MAAA,IAAI,QAAQ,WAAA,EAAa,OAAA;AACrB,QAAA,MAAMC,uBAAA,CAAO,aAAa,iBAAiB,CAAA;AAG/C,MAAA,IAAI;AAEA,QAAA,IAAM,SAAA,GAAY,MAAM,aAAA,CAAc,OAAO,GAIvC,UAAA,GAAa,yBAAA;AAAA,UACf,OAAA;AAAA,UACA,OAAA;AAAA;AAAA,UACA,kBAAA;AAAA,UACA,aAAA;AAAA,UACA;AAAA,SACJ;AAGA,QAAA,OAAO;AAAA,UACH;AAAA,YACI,OAAA;AAAA,YACA;AAAA;AACJ,SACJ;AAAA,MACJ,SAAS,KAAA,EAAO;AAEZ,QAAA,IAAI,iBAAiB,KAAA,EAAO;AACxB,UAAA,IAAMC,QAAAA,GAAU,KAAA,CAAM,OAAA,CAAQ,WAAA,EAAY;AAC1C,UAAA,MAAIA,SAAQ,QAAA,CAAS,eAAe,CAAA,IAAKA,QAAAA,CAAQ,SAAS,aAAa,CAAA,GAC7DD,uBAAA,CAAO,YAAA,CAAa,iBAAiB,CAAA,GAEzC,IAAIE,kCAAiB,gBAAA,EAAkB,wBAAA,EAA0B,QAAW,KAAK,CAAA;AAAA,QAC3F;AACA,QAAA,MAAM,IAAIA,iCAAA,CAAiB,gBAAA,EAAkB,wBAAA,EAA0B;AAAA,UACnE,aAAA,EAAe,OAAO,KAAK;AAAA,SAC9B,CAAA;AAAA,MACL;AAAA,IACJ;AAAA,GAGsB,CAAA;AAC9B;AA4BO,SAAS,wCAAA,CACZ,aAAA,EACA,KAAA,EACA,iBAAA,EACgC;AAkDhC,EAAA,OAAO,YAAA,CAjD0C;AAAA,IAC7C,OAAA,EAAS,aAAA;AAAA,IAET,MAAM,uBAAA,CACF,YAAA,EACA,MAAA,EACkC;AAElC,MAAA,IAAI,aAAa,MAAA,KAAW,CAAA;AACxB,QAAA,MAAM,IAAIH,gCAAA,CAAgB,gBAAA,EAAkB,wDAAA,EAA0D;AAAA,UAClG,eAAe,YAAA,CAAa,MAAA;AAAA,UAC5B,aAAA,EAAe;AAAA,SAClB,CAAA;AAGL,MAAA,IAAM,CAAC,WAAW,CAAA,GAAI,YAAA;AAGtB,MAAA,IAAI,QAAQ,WAAA,EAAa,OAAA;AACrB,QAAA,MAAMC,uBAAA,CAAO,aAAa,qBAAqB,CAAA;AAGnD,MAAA,IAAI;AAEA,QAAA,IAAM,eAAA,GAAkB,MAAM,iBAAA,CAAkB,WAAW,CAAA;AAK3D,QAAA,OAAO,CAFgB,sBAAA,CAAuB,eAAe,CAEvC,CAAA;AAAA,MAC1B,SAAS,KAAA,EAAO;AAEZ,QAAA,IAAI,iBAAiB,KAAA,EAAO;AACxB,UAAA,IAAM,OAAA,GAAU,KAAA,CAAM,OAAA,CAAQ,WAAA,EAAY;AAC1C,UAAA,MAAI,OAAA,CAAQ,QAAA,CAAS,eAAe,CAAA,IAAK,QAAQ,QAAA,CAAS,aAAa,CAAA,GAC7DA,uBAAA,CAAO,YAAA,CAAa,qBAAqB,CAAA,GAE/C,OAAA,CAAQ,SAAS,SAAS,CAAA,IAAK,OAAA,CAAQ,QAAA,CAAS,KAAK,CAAA,GAC/C,IAAIE,iCAAA,CAAiB,eAAe,4BAAA,EAA8B,MAAA,EAAW,KAAK,CAAA,GAEtF,IAAIA,iCAAA,CAAiB,aAAA,EAAe,4BAAA,EAA8B,QAAW,KAAK,CAAA;AAAA,QAC5F;AACA,QAAA,MAAM,IAAIA,iCAAA,CAAiB,aAAA,EAAe,4BAAA,EAA8B;AAAA,UACpE,aAAA,EAAe,OAAO,KAAK;AAAA,SAC9B,CAAA;AAAA,MACL;AAAA,IACJ;AAAA,GAGsB,CAAA;AAC9B;ACpIO,SAAS,0BAAA,CACZ,MAAA,EACA,OAAA,EACA,UAAA,EACA,OAAA,EACoB;AAEpB,EAAA,IAAI,CAAC,UAAU,CAAC,OAAA;AACZ,IAAA,OAAO;AAAA,MACH,OAAA,EAAS,IAAA;AAAA,MACT,aAAA,EAAe,IAAA;AAAA,MACf,aAAA,EAAe,IAAA;AAAA,MACf,iBAAA,EAAmB;AAAA,KACvB;AAIJ,EAAA,IAAI,aAAA,GAAwC,MACxC,mBAAA,GAAqC,IAAA;AAEzC,EAAA,IAAI;AACA,IAAA,aAAA,GAAgBV,iBAAA,CAAQ,OAAA,CAAQ,OAAO,CAAA,EACvC,sBAAsB,OAAA,CAAQ,OAAA;AAAA,EAClC,CAAA,CAAA,MAAgB;AAEZ,IAAA,OAAO;AAAA,MACH,OAAA,EAAS,IAAA;AAAA,MACT,aAAA,EAAe,IAAA;AAAA,MACf,aAAA,EAAe,IAAA;AAAA,MACf,iBAAA,EAAmB;AAAA,KACvB;AAAA,EACJ;AAIA,EAAA,IAAI,KAAA,GAA4B,yCAAA;AAEhC,EAAA,IAAI,OAAA;AAOA,IAAA,KAAA,GALqD;AAAA,MACjD,OAAA,EAAS,yCAAA;AAAA,MACT,MAAA,EAAQ,yCAAA;AAAA,MACR,OAAA,EAAS;AAAA,KACb,CACiB,OAAO,CAAA,IAAK,KAAA;AAAA,OAAA,IACtB,UAAA,EAAY;AAEnB,IAAA,IAAM,MAAA,GAAS,WAAW,WAAA,IAAe,EAAA;AACzC,IAAI,OAAO,QAAA,CAAS,SAAS,CAAA,IAAK,MAAA,CAAO,SAAS,kBAAkB,CAAA,GAChE,KAAA,GAAQ,yCAAA,GACD,OAAO,QAAA,CAAS,SAAS,CAAA,GAChC,KAAA,GAAQ,4CAGR,KAAA,GAAQ,yCAAA;AAAA,EAEhB;AAGA,EAAA,IAAM,QAAA,GAAW,OAAO,QAAA,EAClB,cAAA,GAAiB,EAAQ,QAAA,CAAS,oBAAoB,CAAA,EACtD,yBAAA,GAA4B,CAAA,CAAQ,QAAA,CAAS,+BAA+B,CAAA,EAC5E,kBAAA,GAAqB,CAAA,CAAQ,QAAA,CAAS,wBAAwB,CAAA,EAG9D,gBAAuD,cAAA,GACvD,6BAAA,CAA8B,aAAA,EAAe,OAAO,OAAA,KAAwB;AACxE,IAAA,IAAI,CAAC,cAAA;AACD,MAAA,MAAMQ,uBAAA,CAAO,oBAAoB,iBAAiB,CAAA;AAGtD,IAAA,IAAI;AACA,MAAA,IAAM,WAAA,GAAc,QAAA,CAAS,oBAAoB,CAAA,EAG3C,eAAe,OAAA,YAAmB,UAAA,GAAa,OAAA,GAAU,IAAI,WAAW,OAAO,CAAA,EAG/E,OAAA,GAAW,MAAM,YAAY,WAAA,CAAY;AAAA,QAC3C,OAAA;AAAA,QACA,OAAA,EAAS,YAAA;AAAA,QACT,GAAI,KAAA,GAAQ,EAAE,KAAA,KAAU;AAAC,OAC5B,CAAA;AAED,MAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,OAAO,CAAA,IAAK,QAAQ,MAAA,KAAW,CAAA;AAC9C,QAAA,MAAM,IAAI,MAAM,qCAAqC,CAAA;AAGzD,MAAA,IAAM,WAAA,GAAc,QAAQ,CAAC,CAAA;AAC7B,MAAA,IAAI,CAAC,WAAA,EAAa,SAAA;AACd,QAAA,MAAM,IAAI,MAAM,8CAA8C,CAAA;AAGlE,MAAA,OAAO,WAAA,CAAY,SAAA;AAAA,IACvB,SAAS,KAAA,EAAO;AACZ,MAAA,MAAA,OAAA,CAAQ,KAAA,CAAM,oBAAA,EAAsB,KAAK,CAAA,EACnC,KAAA,YAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,KAAA,CAAM,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,IAClE;AAAA,EACJ,CAAC,CAAA,GACD,IAAA,EAIA,iBAAA,GACF,yBAAA,IAA6B,qBACvB,wCAAA,CAAyC,aAAA,EAAe,KAAA,EAAO,OAAO,WAAA,KAAqB;AAEvF,IAAA,IAAI,yBAAA;AACA,MAAA,IAAI;AAUA,QAAA,OAAA,CARgB,MADW,QAAA,CAAS,+BAA+B,CAAA,CAC1B,sBAAA,CAAuB;AAAA,UAC5D,OAAA;AAAA,UACA,YAAA,EAAc,CAAC,WAAW,CAAA;AAAA,UAC1B,GAAI,KAAA,GAAQ,EAAE,KAAA,KAAU,EAAC;AAAA,UACzB,GAAI,UAAA,GAAa,EAAE,UAAA,KAAe;AAAC,SACtC,CAAA,EAGa,UAAA,CAAW,CAAC,CAAA,IAAK,EAAA;AAAA,MACnC,SAAS,KAAA,EAAO;AACZ,QAAA,MAAM,iBAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,KAAA,CAAM,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,MAClE;AAMJ,IAAA,IAAI,kBAAA;AACA,MAAA,IAAI;AAUA,QAAA,OAAA,CARgB,MADI,QAAA,CAAS,wBAAwB,CAAA,CACnB,eAAA,CAAgB;AAAA,UAC9C,OAAA;AAAA,UACA,YAAA,EAAc,CAAC,WAAW,CAAA;AAAA,UAC1B,GAAI,KAAA,GAAQ,EAAE,KAAA,KAAU;AAAC,SAC5B,CAAA,EAIa,UAAA,CAAW,CAAC,CAAA,IAAK,EAAA;AAAA,MACnC,SAAS,KAAA,EAAO;AACZ,QAAA,MAAM,iBAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,KAAA,CAAM,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,MAClE;AAGJ,IAAA,MAAMA,uBAAA,CAAO,oBAAoB,qBAAqB,CAAA;AAAA,EAC1D,CAAC,CAAA,GACD,IAAA;AAEV,EAAA,OAAO;AAAA,IACH,OAAA,EAAS,aAAA;AAAA,IACT,aAAA,EAAe,mBAAA;AAAA,IACf,aAAA;AAAA,IACA;AAAA,GACJ;AACJ;;;ACnMO,SAAS,mBAAmB,IAAA,EAA0C;AACzE,EAAA,OAAO,aAAA,IAAiB,IAAA,IAAQ,OAAQ,IAAA,CAAoB,WAAA,IAAgB,QAAA;AAChF;AAEO,SAAS,gBAAgB,IAAA,EAAsC;AAClE,EAAA,IAAI,aAAA,IAAiB,IAAA;AACjB,IAAA,OAAO,KAAA;AAGX,EAAA,IAAM,QAAA,GAAW,IAAA;AACjB,EAAA,OAAO,OAAO,QAAA,CAAS,kBAAA,IAAuB,UAAA,IAAc,OAAO,SAAS,eAAA,IAAoB,UAAA;AACpG;;;ACJA,eAAsB,kBAAA,CAClB,UAAA,EACA,UAAA,GAAyB,WAAA,EACmC;AAC5D,EAAA,IAAI,mBAAmB,UAAU,CAAA;AAE7B,IAAA,OAAO,MAAM,UAAA,CAAW,kBAAA,CAAmB,UAAU,CAAA;AAGzD,EAAA,IAAI,gBAAgB,UAAU,CAAA;AAI1B,IAAA,OAAA,CADe,MADH,WACa,kBAAA,CAAmB,EAAE,YAAY,CAAA,CAAE,MAAK,EACnD,KAAA;AAGlB,EAAA,MAAM,IAAI,MAAM,6BAA6B,CAAA;AACjD;AAqBA,eAAsB,kBAAA,CAClB,UAAA,EACA,KAAA,EACA,OAAA,EACe;AACf,EAAA,IAAI,mBAAmB,UAAU,CAAA;AAE7B,IAAA,OAAO,MAAM,UAAA,CAAW,kBAAA,CAAmB,KAAA,EAAO,OAAO,CAAA;AAG7D,EAAA,IAAI,eAAA,CAAgB,UAAU,CAAA,EAAG;AAG7B,IAAA,IAAM,GAAA,GAAM,YAEN,YAAA,GAAe,MAAA,CAAO,KAAK,KAAK,CAAA,CAAE,SAAS,QAAQ,CAAA;AAUzD,IAAA,OATe,MAAM,GAAA,CAChB,eAAA,CAAgB,YAAA,EAAqC;AAAA,MAClD,GAAI,SAAS,UAAA,GAAa,EAAE,YAAY,OAAA,CAAQ,UAAA,KAAe,EAAC;AAAA,MAChE,GAAI,SAAS,aAAA,KAAkB,MAAA,GAAY,EAAE,aAAA,EAAe,OAAA,CAAQ,aAAA,EAAc,GAAI,EAAC;AAAA,MACvF,GAAI,SAAS,UAAA,KAAe,MAAA,GAAY,EAAE,UAAA,EAAY,OAAA,CAAQ,UAAA,EAAW,GAAI;AAAC,KACjF,EACA,IAAA,EAAK;AAAA,EAId;AAEA,EAAA,MAAM,IAAI,MAAM,6BAA6B,CAAA;AACjD;;;ACxFO,IAAM,gBAAA,GAAmB;AAAA,EAC5B,OAAA,EAAS,yCAAA;AAAA,EACT,MAAA,EAAQ,yCAAA;AAAA,EACR,OAAA,EAAS;AACb,CAAA,CAAA,CAEM,wBAAA,GAAwD;AAAA,EAC1D,CAAC,gBAAA,CAAiB,OAAO,GAAG,SAAA;AAAA,EAC5B,CAAC,gBAAA,CAAiB,MAAM,GAAG,QAAA;AAAA,EAC3B,CAAC,gBAAA,CAAiB,OAAO,GAAG;AAChC,CAAA,CAAA,CAEM,sBAAA,GAAmE;AAAA,EACrE,kBAAkB,gBAAA,CAAiB,OAAA;AAAA,EACnC,uBAAuB,gBAAA,CAAiB,OAAA;AAAA,EACxC,iBAAiB,gBAAA,CAAiB,MAAA;AAAA,EAClC,kBAAkB,gBAAA,CAAiB;AACvC;AAEO,SAAS,sBAAsB,OAAA,EAAmD;AACrF,EAAA,IAAM,WAAA,GAAcG,gCAAe,OAAO,CAAA;AAE1C,EAAA,OAAI,gBAAgB,UAAA,IAAc,WAAA,KAAgB,QAAA,GACvC,IAAA,GAGJ,0BAA0B,WAAW,CAAA;AAChD;AAEO,SAAS,wBAAwB,SAAA,EAAuD;AAC3F,EAAA,OAAQ,sBAAA,CAAuB,SAAS,CAAA,IAAwC,IAAA;AACpF;AAEO,SAAS,0BAA0B,IAAA,EAA8C;AACpF,EAAA,QAAQ,IAAA;AAAM,IACV,KAAK,SAAA;AACD,MAAA,OAAO,gBAAA,CAAiB,OAAA;AAAA,IAC5B,KAAK,QAAA;AACD,MAAA,OAAO,gBAAA,CAAiB,MAAA;AAAA,IAC5B,KAAK,SAAA;AACD,MAAA,OAAO,gBAAA,CAAiB,OAAA;AAAA,IAC5B,KAAK,UAAA;AAAA,IACL,KAAK,QAAA;AACD,MAAA,OAAO,IAAA;AAAA;AAEnB;AAEO,SAAS,0BAA0B,OAAA,EAAqC;AAC3E,EAAA,OAAO,wBAAA,CAAyB,OAAO,CAAA,IAAK,IAAA;AAChD;AAEO,SAAS,wBAAwB,OAAA,EAAyC;AAC7E,EAAA,IAAM,WAAA,GAAc,0BAA0B,OAAO,CAAA;AACrD,EAAA,IAAI,CAAC,WAAA;AACD,IAAA,OAAO,IAAA;AAGX,EAAA,QAAQ,WAAA;AAAa,IACjB,KAAK,SAAA;AACD,MAAA,OAAO,gBAAA;AAAA,IACX,KAAK,QAAA;AACD,MAAA,OAAO,eAAA;AAAA,IACX,KAAK,SAAA;AACD,MAAA,OAAO,gBAAA;AAAA,IACX;AACI,MAAA,OAAO,IAAA;AAAA;AAEnB;AAEO,SAAS,cAAc,KAAA,EAA4C;AACtE,EAAA,OAAO,KAAA,CAAM,WAAW,SAAS,CAAA;AACrC;AAEO,SAAS,mBAAmB,KAAA,EAAwB;AACvD,EAAA,OACI,UAAU,gBAAA,CAAiB,OAAA,IAAW,UAAU,gBAAA,CAAiB,MAAA,IAAU,UAAU,gBAAA,CAAiB,OAAA;AAE9G;AAEO,SAAS,yBAAyB,KAAA,EAAoD;AACzF,EAAA,IAAI,CAAC,cAAc,KAAK,CAAA;AACpB,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,kDAAA,EAAqD,KAAK,CAAA,CAAA,CAAG,CAAA;AAGjF,EAAA,IAAI,CAAC,mBAAmB,KAAK,CAAA;AACzB,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,sBAAA,EAAyB,KAAK,CAAA,gBAAA,EAAmB,MAAA,CAAO,MAAA,CAAO,gBAAgB,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,CAAE,CAAA;AAErH;AAEO,SAAS,6BAA6B,UAAA,EAAmD;AAC5F,EAAA,IAAI,CAAC,UAAA;AACD,IAAA,OAAO,IAAA;AAGX,EAAA,IAAM,MAAA,GAAS,WAAW,WAAA,IAAe,EAAA;AAEzC,EAAA,OAAI,MAAA,CAAO,QAAA,CAAS,SAAS,CAAA,IAAK,MAAA,CAAO,QAAA,CAAS,kBAAkB,CAAA,GACzD,SAAA,GAGP,MAAA,CAAO,QAAA,CAAS,SAAS,CAAA,GAClB,SAAA,GAGP,MAAA,CAAO,QAAA,CAAS,QAAQ,CAAA,GACjB,QAAA,GAGP,MAAA,CAAO,QAAA,CAAS,WAAW,CAAA,IAAK,MAAA,CAAO,QAAA,CAAS,WAAW,CAAA,GACpD,UAAA,GAGJ,QAAA;AACX;AAEO,SAAS,wBAAA,CACZ,YACA,OAAA,EACyB;AACzB,EAAA,IAAI,OAAA;AACA,IAAA,OAAO,0BAA0B,OAAO,CAAA;AAG5C,EAAA,IAAM,WAAA,GAAc,6BAA6B,UAAU,CAAA;AAC3D,EAAA,OAAK,WAAA,GAIE,yBAAA,CAA0B,WAAW,CAAA,GAHjC,IAAA;AAIf;AAEO,SAAS,iBAAiB,OAAA,EAAmD;AAChF,EAAA,OAAO,sBAAsB,OAAO,CAAA;AACxC;AAEO,SAAS,qBAAqB,OAAA,EAAqC;AACtE,EAAA,OAAO,0BAA0B,OAAO,CAAA;AAC5C;AAEO,SAAS,mBAAmB,OAAA,EAAyC;AACxE,EAAA,OAAO,wBAAwB,OAAO,CAAA;AAC1C;;;AC7HO,SAAS,oBAAA,CAAqB,SAAA,EAAmB,OAAA,GAA2B,EAAC,EAAW;AAC3F,EAAA,IAAM,EAAE,UAAU,SAAA,EAAW,SAAA,KAAc,OAAA,EACrC,iBAAA,GAAoB,OAAA,KAAY,cAAA,GAAiB,SAAA,GAAY,OAAA;AAGnE,EAAA,IAAI,iBAAA,KAAsB,UAAA;AAEtB,IAAA,OAAO,kCAAkC,SAAS,CAAA,0BAAA,EAA6B,kBAAA,CADnE,SAAA,IAAa,uBAC4E,CAAC,CAAA,CAAA;AAK1G,EAAA,IAAM,eAAA,GADgB,CAAC,SAAA,EAAW,QAAA,EAAU,SAAS,CAAA,CACf,QAAA,CAAS,iBAAqD,CAAA,GAC7F,iBAAA,GACD,QAAA;AAGN,EAAA,OAAOC,gCAAA,CAAgB;AAAA,IACnB,WAAA,EAAa,SAAA;AAAA,IACb,OAAA,EAAS;AAAA,GACZ,CAAA;AACL;AAKO,SAAS,aAAA,CAAc,SAAA,EAAmB,OAAA,GAA2B,EAAC,EAAW;AACpF,EAAA,IAAM,EAAE,UAAU,SAAA,EAAU,GAAI,SAC1B,iBAAA,GAAoB,OAAA,KAAY,iBAAiB,SAAA,GAAY,OAAA;AAEnE,EAAA,OAAI,iBAAA,KAAsB,SAAA,GACf,CAAA,sBAAA,EAAyB,SAAS,CAAA,CAAA,GAGzC,iBAAA,KAAsB,UAAA,GACf,CAAA,sBAAA,EAAyB,SAAS,CAAA,eAAA,CAAA,GAGtC,CAAA,sBAAA,EAAyB,SAAS,YAAY,iBAAiB,CAAA,CAAA;AAC1E;AAMO,SAAS,WAAW,SAAA,EAA2B;AAClD,EAAA,OAAO,8BAA8B,SAAS,CAAA,CAAA;AAClD;AAKO,SAAS,cAAA,CAAe,SAAA,EAAmB,OAAA,GAA2B,EAAC,EAAW;AACrF,EAAA,IAAM,EAAE,UAAU,SAAA,EAAU,GAAI,SAC1B,iBAAA,GAAoB,OAAA,KAAY,iBAAiB,SAAA,GAAY,OAAA;AAEnE,EAAA,OAAI,iBAAA,KAAsB,YACf,CAAA,qBAAA,EAAwB,SAAS,KAGrC,CAAA,qBAAA,EAAwB,SAAS,YAAY,iBAAiB,CAAA,CAAA;AACzE;AAKO,SAAS,kBAAA,CAAmB,SAAA,EAAmB,OAAA,GAA2B,EAAC,EAAiC;AAC/G,EAAA,OAAO;AAAA,IACH,iBAAA,EAAmB,oBAAA,CAAqB,SAAA,EAAW,OAAO,CAAA;AAAA,IAC1D,OAAA,EAAS,aAAA,CAAc,SAAA,EAAW,OAAO,CAAA;AAAA,IACzC,IAAA,EAAM,WAAW,SAAS,CAAA;AAAA,IAC1B,WAAA,EAAa,cAAA,CAAe,SAAA,EAAW,OAAO;AAAA,GAClD;AACJ;AAKO,SAAS,eAAA,CAAgB,SAAA,EAAmB,KAAA,GAAQ,CAAA,EAAW;AAClE,EAAA,OAAI,UAAU,MAAA,IAAU,KAAA,GAAQ,CAAA,GAAU,SAAA,GACnC,GAAG,SAAA,CAAU,KAAA,CAAM,CAAA,EAAG,KAAK,CAAC,CAAA,GAAA,EAAM,SAAA,CAAU,KAAA,CAAM,CAAC,KAAK,CAAC,CAAA,CAAA;AACpE;AAQA,eAAsB,cAAc,SAAA,EAAqC;AACrE,EAAA,IAAI;AACA,IAAA,OAAA,MAAM,SAAA,CAAU,SAAA,CAAU,SAAA,CAAU,SAAS,CAAA,EACtC,IAAA;AAAA,EACX,CAAA,CAAA,MAAQ;AACJ,IAAA,OAAO,KAAA;AAAA,EACX;AACJ","file":"chunk-D6PZY5G6.js","sourcesContent":["/**\n * Enhanced Storage\n */\n\nimport { Storage as WalletUiStorage } from '@wallet-ui/core';\nimport type { SolanaClusterId } from '@wallet-ui/core';\nimport type {\n StorageOptions,\n StorageAdapter,\n EnhancedStorageAccountOptions,\n EnhancedStorageClusterOptions,\n EnhancedStorageWalletOptions,\n} from '../../types/storage';\nimport { createLogger } from '../utils/secure-logger';\n\nconst logger = createLogger('EnhancedStorage');\n\n/**\n * Storage version for migration support\n * Increment when making breaking changes to storage format\n */\nexport const STORAGE_VERSION = 'v1';\n\n/**\n * Enhanced version of wallet-ui's Storage class\n * Extends the base Storage with validation, error handling, and SSR support\n */\nexport class EnhancedStorage<T> extends WalletUiStorage<T> {\n private errorHandlers: Set<(error: Error) => void> = new Set();\n private validators: ((value: T) => boolean)[] = [];\n private memoryFallback: T;\n\n constructor(\n key: string,\n initial: T,\n private options?: StorageOptions<T>,\n ) {\n super(key, initial);\n this.memoryFallback = initial;\n\n if (options?.onError) {\n this.errorHandlers.add(options.onError);\n }\n if (options?.validator) {\n this.validators.push(options.validator);\n }\n }\n\n override set(value: T): boolean {\n try {\n if (!this.validate(value)) {\n logger.warn('Validation failed', { key: this.key });\n return false;\n }\n\n super.set(value);\n\n this.memoryFallback = value;\n return true;\n } catch (error) {\n this.handleError(error as Error);\n\n if (this.options?.useMemoryFallback) {\n this.memoryFallback = value;\n return true;\n }\n\n return false;\n }\n }\n\n override get(): T {\n try {\n return super.get();\n } catch (error) {\n this.handleError(error as Error);\n\n if (this.options?.useMemoryFallback) {\n return this.memoryFallback;\n }\n\n return this.initial;\n }\n }\n\n validate(value: T): boolean {\n return this.validators.every(validator => validator(value));\n }\n\n addValidator(validator: (value: T) => boolean): this {\n this.validators.push(validator);\n return this;\n }\n\n onError(handler: (error: Error) => void): this {\n this.errorHandlers.add(handler);\n return this;\n }\n\n transform<U>(transformer: (value: T) => U): U {\n return transformer(this.get());\n }\n\n reset(): void {\n this.set(this.initial);\n }\n\n clear(): void {\n try {\n if (typeof window !== 'undefined' && window.localStorage) {\n window.localStorage.removeItem(this.key);\n }\n this.reset();\n } catch (error) {\n this.handleError(error as Error);\n }\n }\n\n isAvailable(): boolean {\n try {\n if (typeof window === 'undefined') return false;\n const testKey = `__storage_test_${this.key}__`;\n window.localStorage.setItem(testKey, 'test');\n window.localStorage.removeItem(testKey);\n return true;\n } catch {\n return false;\n }\n }\n\n static migrate<T>(oldKey: string, newStorage: EnhancedStorage<T>): boolean {\n try {\n if (typeof window === 'undefined') return false;\n\n const oldValue = window.localStorage.getItem(oldKey);\n if (oldValue) {\n const parsed = JSON.parse(oldValue) as T;\n newStorage.set(parsed);\n window.localStorage.removeItem(oldKey);\n return true;\n }\n return false;\n } catch {\n return false;\n }\n }\n\n private handleError(error: Error): void {\n logger.error('Storage error', { key: this.key, error });\n this.errorHandlers.forEach(handler => {\n try {\n handler(error);\n } catch (err) {\n logger.error('Error in error handler', { error: err });\n }\n });\n }\n}\n\nexport function createEnhancedStorageAccount(\n options?: EnhancedStorageAccountOptions,\n): EnhancedStorage<string | undefined> {\n const key = options?.key ?? `connector-kit:${STORAGE_VERSION}:account`;\n return new EnhancedStorage(key, options?.initial, {\n validator: options?.validator,\n onError: options?.onError,\n useMemoryFallback: true, // Always fallback for SSR\n });\n}\n\nexport function createEnhancedStorageCluster(\n options?: EnhancedStorageClusterOptions,\n): EnhancedStorage<SolanaClusterId> {\n const key = options?.key ?? `connector-kit:${STORAGE_VERSION}:cluster`;\n const storage = new EnhancedStorage(key, options?.initial ?? 'solana:mainnet', {\n onError: options?.onError,\n useMemoryFallback: true,\n });\n\n if (options?.validClusters) {\n storage.addValidator(clusterId => options.validClusters!.includes(clusterId));\n }\n\n return storage;\n}\n\nexport function createEnhancedStorageWallet(\n options?: EnhancedStorageWalletOptions,\n): EnhancedStorage<string | undefined> {\n const key = options?.key ?? `connector-kit:${STORAGE_VERSION}:wallet`;\n return new EnhancedStorage(key, options?.initial, {\n onError: options?.onError,\n useMemoryFallback: true,\n });\n}\n\nexport class EnhancedStorageAdapter<T> implements StorageAdapter<T> {\n constructor(private storage: EnhancedStorage<T>) {}\n\n get(): T {\n return this.storage.get();\n }\n\n set(value: T): void {\n this.storage.set(value);\n }\n\n subscribe(callback: (value: T) => void): () => void {\n return this.storage.value.subscribe(callback);\n }\n\n validate(value: T): boolean {\n return this.storage.validate(value);\n }\n\n reset(): void {\n this.storage.reset();\n }\n\n clear(): void {\n this.storage.clear();\n }\n\n isAvailable(): boolean {\n return this.storage.isAvailable();\n }\n\n transform<U>(transformer: (value: T) => U): U {\n return this.storage.transform(transformer);\n }\n\n addValidator(validator: (value: T) => boolean): this {\n this.storage.addValidator(validator);\n return this;\n }\n\n onError(handler: (error: Error) => void): this {\n this.storage.onError(handler);\n return this;\n }\n}\n","import type { ConnectorConfig } from '../types/connector';\nimport type { SolanaCluster, SolanaClusterId } from '@wallet-ui/core';\nimport { createSolanaMainnet, createSolanaDevnet, createSolanaTestnet, createSolanaLocalnet } from '@wallet-ui/core';\nimport {\n createEnhancedStorageAccount,\n createEnhancedStorageCluster,\n createEnhancedStorageWallet,\n EnhancedStorageAdapter,\n EnhancedStorage,\n} from '../lib/adapters/enhanced-storage';\nimport { toClusterId } from '../utils/network';\nimport type React from 'react';\nimport { isAddress } from '@solana/addresses';\nimport { DEFAULT_MAX_RETRIES } from '../lib/constants';\nimport { createLogger } from '../lib/utils/secure-logger';\n\nconst logger = createLogger('DefaultConfig');\n\nexport interface DefaultConfigOptions {\n /** Application name shown in wallet connection prompts */\n appName: string;\n /** Application URL for wallet connection metadata */\n appUrl?: string;\n /** Enable automatic wallet reconnection on page load */\n autoConnect?: boolean;\n /** Enable debug logging */\n debug?: boolean;\n /** Solana network to connect to (accepts both 'mainnet' and 'mainnet-beta' conventions) */\n network?: 'mainnet' | 'mainnet-beta' | 'devnet' | 'testnet' | 'localnet';\n /** Enable Mobile Wallet Adapter support */\n enableMobile?: boolean;\n /** Custom storage implementation */\n storage?: ConnectorConfig['storage'];\n /** Custom cluster configuration - overrides network if provided */\n clusters?: SolanaCluster[];\n /** Additional custom clusters to add to the default list */\n customClusters?: SolanaCluster[];\n /** Persist cluster selection across sessions */\n persistClusterSelection?: boolean;\n /** Custom storage key for cluster persistence */\n clusterStorageKey?: string;\n /** Enable error boundaries for automatic error handling (default: true) */\n enableErrorBoundary?: boolean;\n /** Maximum retry attempts for error recovery (default: 3) */\n maxRetries?: number;\n /** Custom error handler */\n onError?: (error: Error, errorInfo: React.ErrorInfo) => void;\n}\n\n/** Extended ConnectorConfig with app metadata */\nexport interface ExtendedConnectorConfig extends ConnectorConfig {\n /** Application name for display and metadata */\n appName?: string;\n /** Application URL for metadata */\n appUrl?: string;\n /** Whether mobile wallet adapter is enabled */\n enableMobile?: boolean;\n /** Selected network for convenience (accepts both 'mainnet' and 'mainnet-beta' conventions) */\n network?: 'mainnet' | 'mainnet-beta' | 'devnet' | 'testnet' | 'localnet';\n /** Error boundary configuration */\n errorBoundary?: {\n /** Enable error boundaries (default: true) */\n enabled?: boolean;\n /** Maximum retry attempts (default: 3) */\n maxRetries?: number;\n /** Custom error handler */\n onError?: (error: Error, errorInfo: React.ErrorInfo) => void;\n /** Custom fallback component */\n fallback?: (error: Error, retry: () => void) => React.ReactNode;\n };\n}\n\n/**\n * Creates a default connector configuration with sensible defaults for Solana applications\n */\nexport function getDefaultConfig(options: DefaultConfigOptions): ExtendedConnectorConfig {\n const {\n appName,\n appUrl,\n autoConnect = true,\n debug,\n network = 'mainnet-beta',\n enableMobile = true,\n storage,\n clusters,\n customClusters = [],\n persistClusterSelection = true,\n clusterStorageKey,\n enableErrorBoundary = true,\n maxRetries = DEFAULT_MAX_RETRIES,\n onError,\n } = options;\n\n const defaultClusters: SolanaCluster[] = clusters ?? [\n createSolanaMainnet(),\n createSolanaDevnet(),\n createSolanaTestnet(),\n ...(network === 'localnet' ? [createSolanaLocalnet()] : []),\n ...(customClusters || []),\n ];\n\n const validClusterIds = defaultClusters.map(c => c.id);\n\n const accountStorage = createEnhancedStorageAccount({\n validator: address => {\n if (!address) return true;\n return isAddress(address);\n },\n onError: error => {\n if (debug) {\n logger.error('Account Storage error', { error });\n }\n if (onError) {\n onError(error, {\n componentStack: 'account-storage',\n });\n }\n },\n });\n\n const clusterStorage = createEnhancedStorageCluster({\n key: clusterStorageKey,\n initial: getInitialCluster(network),\n validClusters: persistClusterSelection ? validClusterIds : undefined,\n onError: error => {\n if (debug) {\n logger.error('Cluster Storage error', { error });\n }\n if (onError) {\n onError(error, {\n componentStack: 'cluster-storage',\n });\n }\n },\n });\n\n const walletStorage = createEnhancedStorageWallet({\n onError: error => {\n if (debug) {\n logger.error('Wallet Storage error', { error });\n }\n if (onError) {\n onError(error, {\n componentStack: 'wallet-storage',\n });\n }\n },\n });\n\n // Migrate old storage keys to new versioned format (v1)\n // This allows seamless upgrades from old versions without losing user data\n if (typeof window !== 'undefined') {\n // Old keys (pre-v1): 'connector-kit:account', 'connector-kit:wallet', 'connector-kit:cluster'\n // New keys (v1): 'connector-kit:v1:account', 'connector-kit:v1:wallet', 'connector-kit:v1:cluster'\n const oldAccountKey = 'connector-kit:account';\n const oldWalletKey = 'connector-kit:wallet';\n const oldClusterKey = clusterStorageKey || 'connector-kit:cluster';\n\n EnhancedStorage.migrate(oldAccountKey, accountStorage);\n EnhancedStorage.migrate(oldWalletKey, walletStorage);\n EnhancedStorage.migrate(oldClusterKey, clusterStorage);\n }\n\n const defaultStorage: ConnectorConfig['storage'] = storage ?? {\n account: new EnhancedStorageAdapter(accountStorage),\n cluster: new EnhancedStorageAdapter(clusterStorage),\n wallet: new EnhancedStorageAdapter(walletStorage),\n };\n\n const config: ExtendedConnectorConfig = {\n autoConnect,\n debug: debug ?? process.env.NODE_ENV === 'development',\n storage: defaultStorage,\n appName,\n appUrl,\n enableMobile,\n network,\n cluster: {\n clusters: defaultClusters,\n persistSelection: persistClusterSelection,\n initialCluster: getInitialCluster(network),\n },\n errorBoundary: {\n enabled: enableErrorBoundary,\n maxRetries,\n onError,\n },\n };\n\n return config;\n}\n\n/**\n * Helper to convert network string to cluster ID\n * Uses network utility for consistent translation\n */\nfunction getInitialCluster(\n network: 'mainnet' | 'mainnet-beta' | 'devnet' | 'testnet' | 'localnet' = 'mainnet-beta',\n): SolanaClusterId {\n return toClusterId(network);\n}\n\n/**\n * Default Mobile Wallet Adapter configuration for Solana applications\n */\nexport function getDefaultMobileConfig(options: {\n appName: string;\n appUrl?: string;\n network?: 'mainnet' | 'mainnet-beta' | 'devnet' | 'testnet';\n}) {\n const baseUrl =\n options.appUrl || (typeof window !== 'undefined' ? window.location.origin : 'https://localhost:3000');\n\n return {\n appIdentity: {\n name: options.appName,\n uri: baseUrl,\n icon: `${baseUrl}/favicon.ico`,\n },\n cluster: options.network || 'mainnet-beta',\n };\n}\n","/**\n * @solana/connector - Unified configuration\n *\n * Simplified configuration for apps using ConnectorKit\n * Eliminates config duplication and provides a single source of truth\n */\n\nimport type { ExtendedConnectorConfig, DefaultConfigOptions } from './default-config';\nimport type { MobileWalletAdapterConfig } from '../ui/connector-provider';\nimport { getDefaultConfig, getDefaultMobileConfig } from './default-config';\nimport { normalizeNetwork, getDefaultRpcUrl, type SolanaNetwork } from '../utils/network';\n\n/**\n * Options for creating a unified configuration\n * Maintains type safety while providing flexibility\n */\nexport interface UnifiedConfigOptions extends DefaultConfigOptions {\n /**\n * Custom RPC URL (optional - overrides default for network)\n * Note: For production apps, use environment variables to avoid exposing API keys\n * @see packages/connector/src/utils/cluster.ts for secure RPC URL patterns\n */\n rpcUrl?: string;\n}\n\n/**\n * Unified configuration output\n * Contains all configs needed for ConnectorKit and integrations\n *\n * Important: The `rpcUrl` property is intended for:\n * 1. Server-side rendering (SSR) setup\n * 2. Passing to external libraries that need RPC configuration\n * 3. Development/testing environments\n *\n * For production client-side code, use the connector client's `getRpcUrl()` method\n * which supports environment variable patterns and proxy configurations.\n */\nexport interface UnifiedConfig {\n /** ConnectorKit configuration */\n connectorConfig: ExtendedConnectorConfig;\n /** Mobile Wallet Adapter configuration (optional) */\n mobile?: MobileWalletAdapterConfig;\n /** Normalized network name ('mainnet', 'devnet', 'testnet', 'localnet') */\n network: SolanaNetwork;\n /**\n * RPC endpoint URL\n * For external library integration only - client code should use connector client\n * @deprecated in client components - use `useConnectorClient().getRpcUrl()` instead\n */\n rpcUrl: string;\n /** Application metadata */\n app: {\n name: string;\n url: string;\n };\n}\n\n/**\n * Create a unified configuration for ConnectorKit\n *\n * This helper eliminates configuration duplication by creating all necessary\n * configs from a single source of truth. It automatically handles network\n * name translation between different conventions.\n *\n * @example Basic usage\n * ```tsx\n * import { createConfig, AppProvider } from '@solana/connector';\n *\n * const config = createConfig({\n * appName: 'My App',\n * network: 'mainnet', // Works with 'mainnet' or 'mainnet-beta'\n * enableMobile: true\n * });\n *\n * <AppProvider config={config}>\n * {children}\n * </AppProvider>\n * ```\n *\n * @example Integration with external libraries\n * ```tsx\n * import { createConfig, AppProvider } from '@solana/connector';\n * import { ArmaProvider } from '@armadura/sdk';\n *\n * const config = createConfig({\n * appName: 'My App',\n * network: 'mainnet',\n * });\n *\n * <AppProvider config={config}>\n * <ArmaProvider\n * config={{\n * network: config.network,\n * rpcUrl: config.rpcUrl, // Safe - for external library initialization\n * providers: [...]\n * }}\n * useConnector=\"auto\"\n * >\n * {children}\n * </ArmaProvider>\n * </AppProvider>\n * ```\n *\n * @example Production with environment variables\n * ```tsx\n * // Use environment variables to avoid exposing API keys\n * const config = createConfig({\n * appName: 'My App',\n * network: 'mainnet',\n * // RPC URL comes from process.env on server\n * // Client-side code should use connector client's getRpcUrl()\n * });\n * ```\n *\n * @example Custom clusters\n * ```tsx\n * const config = createConfig({\n * appName: 'My App',\n * network: 'mainnet',\n * customClusters: [\n * {\n * id: 'solana:custom',\n * label: 'Custom RPC',\n * url: process.env.CUSTOM_RPC_URL || 'https://...'\n * }\n * ]\n * });\n * ```\n */\nexport function createConfig(options: UnifiedConfigOptions): UnifiedConfig {\n // Extract network and rpcUrl, use remaining options for connector config\n const { network = 'mainnet-beta', rpcUrl: customRpcUrl, ...connectorOptions } = options;\n\n // Normalize network name for consistency\n const normalizedNetwork = normalizeNetwork(typeof network === 'string' ? network : 'mainnet-beta');\n\n // Get RPC URL (custom or default)\n const rpcUrl = customRpcUrl || getDefaultRpcUrl(normalizedNetwork);\n\n // Convert normalized network to RPC format (mainnet -> mainnet-beta)\n const rpcNetwork = normalizedNetwork === 'mainnet' ? 'mainnet-beta' : normalizedNetwork;\n\n // Create connector configuration\n const connectorConfig = getDefaultConfig({\n ...connectorOptions,\n network: rpcNetwork,\n });\n\n // Create mobile configuration (if enabled)\n const mobile =\n options.enableMobile !== false && normalizedNetwork !== 'localnet'\n ? getDefaultMobileConfig({\n appName: options.appName,\n appUrl: connectorConfig.appUrl,\n network: rpcNetwork as 'mainnet-beta' | 'devnet' | 'testnet',\n })\n : undefined;\n\n return {\n connectorConfig,\n mobile,\n network: normalizedNetwork,\n rpcUrl,\n app: {\n name: options.appName,\n url:\n connectorConfig.appUrl ||\n (typeof window !== 'undefined' ? window.location.origin : 'https://localhost:3000'),\n },\n };\n}\n\n/**\n * Type guard to check if a config is a unified config\n *\n * @example\n * ```ts\n * if (isUnifiedConfig(someConfig)) {\n * // TypeScript knows this is UnifiedConfig\n * console.log(someConfig.network, someConfig.rpcUrl);\n * }\n * ```\n */\nexport function isUnifiedConfig(config: unknown): config is UnifiedConfig {\n return Boolean(\n config &&\n typeof config === 'object' &&\n 'connectorConfig' in config &&\n 'network' in config &&\n 'rpcUrl' in config &&\n 'app' in config,\n );\n}\n","/**\n * Wallet-related types\n * Re-exports from @wallet-standard/base and custom wallet types\n */\n\nimport type { Wallet, WalletAccount } from '@wallet-standard/base';\n\n// Re-export standard types\nexport type { Wallet, WalletAccount };\n\n/**\n * Wallet name as a branded string for type safety\n * Represents the unique identifier for a wallet (e.g., \"Phantom\", \"Solflare\")\n */\nexport type WalletName = string & { readonly __brand: 'WalletName' };\n\n/**\n * Account address as a branded string for type safety\n * Represents a Solana address (base58-encoded public key)\n *\n * @deprecated Use `Address` from '@solana/addresses' instead for consistent address typing\n */\nexport type AccountAddress = string & { readonly __brand: 'AccountAddress' };\n\n/**\n * Type guard to check if a string is a valid wallet name\n */\nexport function isWalletName(value: string): value is WalletName {\n return typeof value === 'string' && value.length > 0;\n}\n\n/**\n * Type guard to check if a string is a valid account address\n *\n * @deprecated Use `isAddress` from '@solana/addresses' instead for proper address validation\n */\nexport function isAccountAddress(value: string): value is AccountAddress {\n // Basic validation: Solana addresses are typically 32-44 characters\n return typeof value === 'string' && value.length >= 32 && value.length <= 44;\n}\n\n/**\n * Extended wallet information with capability metadata\n */\nexport interface WalletInfo {\n /** The Wallet Standard wallet object */\n wallet: Wallet;\n /** Whether the wallet extension is installed */\n installed: boolean;\n /** Precomputed capability flag for UI convenience */\n connectable?: boolean;\n}\n","import type { Address } from '@solana/addresses';\nimport { getBase58Decoder, getBase58Encoder } from '@solana/codecs';\nimport type { SignatureBytes } from '@solana/keys';\nimport type { SignatureDictionary } from '@solana/signers';\n\nfunction toSignatureBytes(bytes: Uint8Array): SignatureBytes {\n return bytes as SignatureBytes;\n}\n\nexport function detectMessageModification(original: Uint8Array, modified: Uint8Array): boolean {\n if (original.length !== modified.length) {\n return true;\n }\n\n for (let i = 0; i < original.length; i++) {\n if (original[i] !== modified[i]) {\n return true;\n }\n }\n\n return false;\n}\n\nexport function updateSignatureDictionary(\n original: Uint8Array,\n signed: Uint8Array,\n originalSignatures: SignatureDictionary,\n address: Address<string>,\n signature: Uint8Array,\n): SignatureDictionary {\n const wasModified = detectMessageModification(original, signed);\n\n const signatureBytes = signature as unknown as SignatureBytes;\n\n const newSignatures = {} as Record<string, SignatureBytes>;\n newSignatures[address as string] = signatureBytes;\n\n if (wasModified) {\n return newSignatures as SignatureDictionary;\n }\n\n const merged = {\n ...originalSignatures,\n ...newSignatures,\n };\n\n return merged as SignatureDictionary;\n}\n\nexport function freezeSigner<T extends object>(signer: T): Readonly<T> {\n return Object.freeze(signer);\n}\n\nexport function base58ToSignatureBytes(signature: string): SignatureBytes {\n try {\n const bytes = getBase58Encoder().encode(signature);\n if (bytes.length !== 64) {\n throw new Error(`Invalid signature length: expected 64 bytes, got ${bytes.length}`);\n }\n return bytes as SignatureBytes;\n } catch (error) {\n throw new Error(`Failed to decode base58 signature: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\nexport function signatureBytesToBase58(bytes: SignatureBytes): string {\n try {\n if (bytes.length !== 64) {\n throw new Error(`Invalid signature length: expected 64 bytes, got ${bytes.length}`);\n }\n return getBase58Decoder().decode(bytes);\n } catch (error) {\n throw new Error(\n `Failed to encode signature to base58: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n","/**\n * @solana/connector - Kit Signer Factories\n *\n * Framework-agnostic factory functions to create Kit-compatible signers from wallet functions.\n * These factories enable pure Kit integration without React or framework dependencies.\n */\n\nimport type { Address } from '@solana/addresses';\nimport type {\n MessageModifyingSigner,\n TransactionSendingSigner,\n SignableMessage,\n MessageModifyingSignerConfig,\n TransactionSendingSignerConfig,\n} from '@solana/signers';\nimport type { SignatureBytes } from '@solana/keys';\nimport { ValidationError, TransactionError, Errors } from '../errors';\nimport { updateSignatureDictionary, freezeSigner, base58ToSignatureBytes } from './utils';\n\n/**\n * Create a MessageModifyingSigner from a wallet's sign message function\n *\n * This is a pure, framework-agnostic factory function that can be used anywhere.\n * Enables message signing (SIWS, auth) without React.\n *\n * @param walletAddress - The address of the wallet\n * @param signMessageFn - Function to sign a message (from wallet adapter)\n * @returns A frozen MessageModifyingSigner object\n *\n * @example\n * ```typescript\n * import { address } from '@solana/addresses';\n * import { createMessageSignerFromWallet } from '@solana/connector/headless';\n *\n * const signer = createMessageSignerFromWallet(\n * address('...'),\n * async (msg) => await wallet.signMessage(msg)\n * );\n *\n * // Use with Kit message signing\n * import { createSignableMessage } from '@solana/signers';\n * const signed = await signer.modifyAndSignMessages([createSignableMessage(messageBytes)]);\n * ```\n */\nexport function createMessageSignerFromWallet(\n walletAddress: Address<string>,\n signMessageFn: (message: Uint8Array) => Promise<Uint8Array>,\n): MessageModifyingSigner<string> {\n const signer: MessageModifyingSigner<string> = {\n address: walletAddress,\n\n async modifyAndSignMessages(\n messages: readonly SignableMessage[],\n config?: MessageModifyingSignerConfig,\n ): Promise<readonly SignableMessage[]> {\n // Most wallets only support signing one message at a time\n if (messages.length !== 1) {\n throw new ValidationError('INVALID_FORMAT', 'Wallets only support signing one message at a time', {\n receivedCount: messages.length,\n expectedCount: 1,\n });\n }\n\n const [message] = messages;\n const { content, signatures: originalSignatures } = message;\n\n // Handle abort signal if provided\n if (config?.abortSignal?.aborted) {\n throw Errors.userRejected('message signing');\n }\n\n try {\n // Sign the message\n const signature = await signMessageFn(content);\n\n // Update signatures (handle potential message modification)\n // Note: Message content doesn't change in signMessage operations\n const signatures = updateSignatureDictionary(\n content,\n content, // Message content doesn't change in signMessage\n originalSignatures,\n walletAddress,\n signature,\n );\n\n // Return signed message\n return [\n {\n content,\n signatures,\n },\n ];\n } catch (error) {\n // Convert wallet errors to ConnectorKit errors\n if (error instanceof Error) {\n const message = error.message.toLowerCase();\n if (message.includes('user rejected') || message.includes('user denied')) {\n throw Errors.userRejected('message signing');\n }\n throw new TransactionError('SIGNING_FAILED', 'Failed to sign message', undefined, error);\n }\n throw new TransactionError('SIGNING_FAILED', 'Failed to sign message', {\n originalError: String(error),\n });\n }\n },\n };\n\n return freezeSigner(signer);\n}\n\n/**\n * Create a TransactionSendingSigner from a wallet's send transaction function\n *\n * This is a pure, framework-agnostic factory function that can be used anywhere.\n * Enables sign + send in one operation (wallets like Phantom support this).\n *\n * @param walletAddress - The address of the wallet\n * @param chain - The Solana chain identifier (e.g., 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1')\n * @param sendTransactionFn - Function to send a transaction (from wallet adapter)\n * @returns A frozen TransactionSendingSigner object\n *\n * @example\n * ```typescript\n * import { address } from '@solana/addresses';\n * import { createTransactionSendingSignerFromWallet } from '@solana/connector/headless';\n *\n * const signer = createTransactionSendingSignerFromWallet(\n * address('...'),\n * 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1',\n * async (tx) => await wallet.sendTransaction(tx, connection)\n * );\n *\n * // Use with Kit transaction sending\n * const signatures = await signer.signAndSendTransactions([transaction]);\n * ```\n */\nexport function createTransactionSendingSignerFromWallet(\n walletAddress: Address<string>,\n chain: `solana:${string}`,\n sendTransactionFn: (transaction: any) => Promise<string>,\n): TransactionSendingSigner<string> {\n const signer: TransactionSendingSigner<string> = {\n address: walletAddress,\n\n async signAndSendTransactions(\n transactions: readonly any[],\n config?: TransactionSendingSignerConfig,\n ): Promise<readonly SignatureBytes[]> {\n // Most wallets only support signing one transaction at a time\n if (transactions.length !== 1) {\n throw new ValidationError('INVALID_FORMAT', 'Wallets only support sending one transaction at a time', {\n receivedCount: transactions.length,\n expectedCount: 1,\n });\n }\n\n const [transaction] = transactions;\n\n // Handle abort signal if provided\n if (config?.abortSignal?.aborted) {\n throw Errors.userRejected('transaction sending');\n }\n\n try {\n // Send the transaction and get signature string (base58)\n const signatureString = await sendTransactionFn(transaction);\n\n // Convert base58 signature string to SignatureBytes\n const signatureBytes = base58ToSignatureBytes(signatureString);\n\n return [signatureBytes];\n } catch (error) {\n // Convert wallet errors to ConnectorKit errors\n if (error instanceof Error) {\n const message = error.message.toLowerCase();\n if (message.includes('user rejected') || message.includes('user denied')) {\n throw Errors.userRejected('transaction sending');\n }\n if (message.includes('network') || message.includes('rpc')) {\n throw new TransactionError('SEND_FAILED', 'Failed to send transaction', undefined, error);\n }\n throw new TransactionError('SEND_FAILED', 'Failed to send transaction', undefined, error);\n }\n throw new TransactionError('SEND_FAILED', 'Failed to send transaction', {\n originalError: String(error),\n });\n }\n },\n };\n\n return freezeSigner(signer);\n}\n","/**\n * @solana/connector - Kit Integration Helper\n *\n * High-level helper to create Kit signers from Wallet Standard wallets.\n * Framework-agnostic and works in any JavaScript environment.\n */\n\nimport type { Wallet, WalletAccount } from '@wallet-standard/base';\nimport type { Address } from '@solana/addresses';\nimport type { MessageModifyingSigner, TransactionSendingSigner } from '@solana/signers';\nimport { address } from '@solana/addresses';\nimport type { Connection } from '@solana/web3.js';\nimport { createMessageSignerFromWallet, createTransactionSendingSignerFromWallet } from './factories';\nimport { Errors } from '../errors';\n\n/**\n * Result of creating Kit signers from a Wallet Standard wallet\n */\nexport interface KitSignersFromWallet {\n /** Kit Address type (null if wallet not connected) */\n address: Address<string> | null;\n\n /** Plain address string (null if wallet not connected) */\n addressString: string | null;\n\n /** Message signer (null if wallet doesn't support signing or not connected) */\n messageSigner: MessageModifyingSigner<string> | null;\n\n /** Transaction sending signer (null if wallet doesn't support or not connected) */\n transactionSigner: TransactionSendingSigner<string> | null;\n}\n\n/**\n * Create Kit-compatible signers from a Wallet Standard wallet\n *\n * This function bridges Wallet Standard wallets with modern Kit architecture.\n * It's framework-agnostic and can be used in any JavaScript environment.\n *\n * The network is automatically detected from the connection's RPC endpoint.\n * For custom RPC URLs, you can override detection with the optional `network` parameter.\n *\n * @param wallet - The Wallet Standard wallet instance\n * @param account - The wallet account to use (first account if not provided)\n * @param connection - Optional connection for network detection and transaction sending\n * @param network - Optional network override ('mainnet' | 'devnet' | 'testnet')\n * @returns Kit signers object with address and signer instances\n *\n * @example\n * ```typescript\n * import { Connection } from '@solana/web3.js';\n * import { createKitSignersFromWallet } from '@solana/connector/headless';\n *\n * const connection = new Connection('https://api.devnet.solana.com');\n * const { address, messageSigner, transactionSigner } = createKitSignersFromWallet(\n * wallet,\n * account,\n * connection\n * );\n * ```\n */\nexport function createKitSignersFromWallet(\n wallet: Wallet | null,\n account?: WalletAccount | null,\n connection?: Connection | null,\n network?: 'mainnet' | 'devnet' | 'testnet',\n): KitSignersFromWallet {\n // If no wallet or account, return null values\n if (!wallet || !account) {\n return {\n address: null,\n addressString: null,\n messageSigner: null,\n transactionSigner: null,\n };\n }\n\n // Convert account address to Kit Address type\n let walletAddress: Address<string> | null = null;\n let walletAddressString: string | null = null;\n\n try {\n walletAddress = address(account.address) as Address<string>;\n walletAddressString = account.address;\n } catch (error) {\n // Invalid address format\n return {\n address: null,\n addressString: null,\n messageSigner: null,\n transactionSigner: null,\n };\n }\n\n // Detect network from connection or use provided override\n // Note: Will be enhanced in Phase 2 with chain utilities\n let chain: `solana:${string}` = 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1'; // Default to devnet\n\n if (network) {\n // Map network to Wallet Standard chain ID\n const chainMap: Record<string, `solana:${string}`> = {\n mainnet: 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp',\n devnet: 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1',\n testnet: 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z',\n };\n chain = chainMap[network] || chain;\n } else if (connection) {\n // Detect from connection RPC URL\n const rpcUrl = connection.rpcEndpoint || '';\n if (rpcUrl.includes('mainnet') || rpcUrl.includes('api.mainnet-beta')) {\n chain = 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp';\n } else if (rpcUrl.includes('testnet')) {\n chain = 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z';\n } else {\n // Default to devnet\n chain = 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1';\n }\n }\n\n // Check wallet features for capabilities\n const features = wallet.features as Record<string, Record<string, (...args: unknown[]) => unknown>>;\n const hasSignMessage = Boolean(features['solana:signMessage']);\n const hasSignAndSendTransaction = Boolean(features['solana:signAndSendTransaction']);\n const hasSendTransaction = Boolean(features['solana:sendTransaction']);\n\n // Create message signer if wallet supports message signing\n const messageSigner: MessageModifyingSigner<string> | null = hasSignMessage\n ? createMessageSignerFromWallet(walletAddress, async (message: Uint8Array) => {\n if (!hasSignMessage) {\n throw Errors.featureNotSupported('message signing');\n }\n\n try {\n const signFeature = features['solana:signMessage'];\n\n // Ensure message is a Uint8Array\n const messageBytes = message instanceof Uint8Array ? message : new Uint8Array(message);\n\n // Wallet Standard returns an array of signed messages\n const results = (await signFeature.signMessage({\n account,\n message: messageBytes,\n ...(chain ? { chain } : {}),\n })) as Array<{ signature: Uint8Array; signedMessage?: Uint8Array }>;\n\n if (!Array.isArray(results) || results.length === 0) {\n throw new Error('Wallet returned empty results array');\n }\n\n const firstResult = results[0];\n if (!firstResult?.signature) {\n throw new Error('Wallet returned no signature in first result');\n }\n\n return firstResult.signature;\n } catch (error) {\n console.error('signMessage error:', error);\n throw error instanceof Error ? error : new Error(String(error));\n }\n })\n : null;\n\n // Create transaction sending signer if wallet supports sending transactions\n // Prefer signAndSendTransaction over sendTransaction as it's more efficient\n const transactionSigner: TransactionSendingSigner<string> | null =\n hasSignAndSendTransaction || hasSendTransaction\n ? createTransactionSendingSignerFromWallet(walletAddress, chain, async (transaction: any) => {\n // Prefer signAndSendTransaction (sign + send in one call)\n if (hasSignAndSendTransaction) {\n try {\n const signAndSendFeature = features['solana:signAndSendTransaction'];\n const result = (await signAndSendFeature.signAndSendTransaction({\n account,\n transactions: [transaction],\n ...(chain ? { chain } : {}),\n ...(connection ? { connection } : {}),\n })) as { signatures: string[] };\n\n // Return first signature (wallet limitation: single transaction)\n return result.signatures[0] || '';\n } catch (error) {\n throw error instanceof Error ? error : new Error(String(error));\n }\n }\n\n // Fallback to sendTransaction (if wallet supports it but not signAndSendTransaction)\n // Note: sendTransaction in Wallet Standard typically just signs, but some wallets\n // may implement it to also send if connection is available\n if (hasSendTransaction) {\n try {\n const sendFeature = features['solana:sendTransaction'];\n const result = (await sendFeature.sendTransaction({\n account,\n transactions: [transaction],\n ...(chain ? { chain } : {}),\n })) as { signatures: string[] };\n\n // Return first signature\n // Note: Actual sending should be handled by the caller or wallet implementation\n return result.signatures[0] || '';\n } catch (error) {\n throw error instanceof Error ? error : new Error(String(error));\n }\n }\n\n throw Errors.featureNotSupported('transaction sending');\n })\n : null;\n\n return {\n address: walletAddress,\n addressString: walletAddressString,\n messageSigner,\n transactionSigner,\n };\n}\n","import type { Connection } from '@solana/web3.js';\n\nexport type Commitment = 'processed' | 'confirmed' | 'finalized';\n\nexport type KitRpc = {\n getLatestBlockhash(options?: { commitment?: Commitment }): {\n send(): Promise<{ value: { blockhash: string; lastValidBlockHeight: number } }>;\n };\n sendTransaction(\n bytes: Uint8Array | string,\n options?: any,\n ): {\n send(): Promise<string>;\n };\n send?: () => unknown;\n};\n\nexport type DualConnection = Connection | KitRpc;\n\nexport function isLegacyConnection(conn: DualConnection): conn is Connection {\n return 'rpcEndpoint' in conn && typeof (conn as Connection).rpcEndpoint === 'string';\n}\n\nexport function isKitConnection(conn: DualConnection): conn is KitRpc {\n if ('rpcEndpoint' in conn) {\n return false;\n }\n\n const asKitRpc = conn as KitRpc;\n return typeof asKitRpc.getLatestBlockhash === 'function' && typeof asKitRpc.sendTransaction === 'function';\n}\n","/**\n * @solana/connector - Connection Helpers\n *\n * Abstraction layer for working with both legacy @solana/web3.js Connection\n * and modern Kit/gill Rpc objects.\n */\n\nimport type { SendOptions } from '@solana/web3.js';\nimport type { DualConnection, Commitment, KitRpc } from './types';\nimport { isLegacyConnection, isKitConnection } from './types';\n\n/**\n * Get latest blockhash from either legacy Connection or Kit Rpc\n *\n * Abstracts the differences between web3.js 1.x and Kit/gill APIs.\n *\n * @param connection - Legacy Connection or Kit Rpc\n * @param commitment - Optional commitment level (default: 'confirmed')\n * @returns Latest blockhash and last valid block height\n *\n * @example\n * ```typescript\n * // Works with both Connection and Rpc\n * const { blockhash, lastValidBlockHeight } = await getLatestBlockhash(connection);\n * ```\n */\nexport async function getLatestBlockhash(\n connection: DualConnection,\n commitment: Commitment = 'confirmed',\n): Promise<{ blockhash: string; lastValidBlockHeight: number }> {\n if (isLegacyConnection(connection)) {\n // Legacy Connection API\n return await connection.getLatestBlockhash(commitment);\n }\n\n if (isKitConnection(connection)) {\n // Kit/gill Rpc API - returns { value: { blockhash, lastValidBlockHeight } }\n const rpc = connection as KitRpc;\n const result = await rpc.getLatestBlockhash({ commitment }).send();\n return result.value;\n }\n\n throw new Error('Unsupported connection type');\n}\n\n/**\n * Send raw transaction bytes to either legacy Connection or Kit Rpc\n *\n * Abstracts the differences between web3.js 1.x and Kit/gill APIs.\n *\n * @param connection - Legacy Connection or Kit Rpc\n * @param bytes - Raw transaction bytes\n * @param options - Optional send options (skipPreflight, maxRetries, etc.)\n * @returns Transaction signature string\n *\n * @example\n * ```typescript\n * // Works with both Connection and Rpc\n * const signature = await sendRawTransaction(connection, transactionBytes, {\n * skipPreflight: false,\n * maxRetries: 3\n * });\n * ```\n */\nexport async function sendRawTransaction(\n connection: DualConnection,\n bytes: Uint8Array,\n options?: SendOptions & { commitment?: Commitment },\n): Promise<string> {\n if (isLegacyConnection(connection)) {\n // Legacy Connection API\n return await connection.sendRawTransaction(bytes, options);\n }\n\n if (isKitConnection(connection)) {\n // Kit/gill Rpc API\n // Note: gill's sendTransaction expects different options format\n const rpc = connection as KitRpc;\n // Convert Uint8Array to base64 string\n const base64String = Buffer.from(bytes).toString('base64');\n const result = await rpc\n .sendTransaction(base64String as Uint8Array | string, {\n ...(options?.commitment ? { commitment: options.commitment } : {}),\n ...(options?.skipPreflight !== undefined ? { skipPreflight: options.skipPreflight } : {}),\n ...(options?.maxRetries !== undefined ? { maxRetries: options.maxRetries } : {}),\n })\n .send();\n\n // Kit Rpc returns signature string directly\n return result;\n }\n\n throw new Error('Unsupported connection type');\n}\n","import type { SolanaCluster, SolanaClusterId } from '@wallet-ui/core';\nimport type { Connection } from '@solana/web3.js';\nimport type { ClusterType } from './cluster';\nimport { getClusterType, isMainnetCluster, isDevnetCluster, isTestnetCluster } from './cluster';\n\nexport const SOLANA_CHAIN_IDS = {\n mainnet: 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp',\n devnet: 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1',\n testnet: 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z',\n} as const;\n\nconst CHAIN_ID_TO_CLUSTER_TYPE: Record<string, ClusterType> = {\n [SOLANA_CHAIN_IDS.mainnet]: 'mainnet',\n [SOLANA_CHAIN_IDS.devnet]: 'devnet',\n [SOLANA_CHAIN_IDS.testnet]: 'testnet',\n};\n\nconst CLUSTER_ID_TO_CHAIN_ID: Partial<Record<SolanaClusterId, string>> = {\n 'solana:mainnet': SOLANA_CHAIN_IDS.mainnet,\n 'solana:mainnet-beta': SOLANA_CHAIN_IDS.mainnet,\n 'solana:devnet': SOLANA_CHAIN_IDS.devnet,\n 'solana:testnet': SOLANA_CHAIN_IDS.testnet,\n};\n\nexport function getChainIdFromCluster(cluster: SolanaCluster): `solana:${string}` | null {\n const clusterType = getClusterType(cluster);\n\n if (clusterType === 'localnet' || clusterType === 'custom') {\n return null;\n }\n\n return getChainIdFromClusterType(clusterType);\n}\n\nexport function getChainIdFromClusterId(clusterId: SolanaClusterId): `solana:${string}` | null {\n return (CLUSTER_ID_TO_CHAIN_ID[clusterId] as `solana:${string}` | undefined) || null;\n}\n\nexport function getChainIdFromClusterType(type: ClusterType): `solana:${string}` | null {\n switch (type) {\n case 'mainnet':\n return SOLANA_CHAIN_IDS.mainnet;\n case 'devnet':\n return SOLANA_CHAIN_IDS.devnet;\n case 'testnet':\n return SOLANA_CHAIN_IDS.testnet;\n case 'localnet':\n case 'custom':\n return null;\n }\n}\n\nexport function getClusterTypeFromChainId(chainId: string): ClusterType | null {\n return CHAIN_ID_TO_CLUSTER_TYPE[chainId] || null;\n}\n\nexport function getClusterIdFromChainId(chainId: string): SolanaClusterId | null {\n const clusterType = getClusterTypeFromChainId(chainId);\n if (!clusterType) {\n return null;\n }\n\n switch (clusterType) {\n case 'mainnet':\n return 'solana:mainnet';\n case 'devnet':\n return 'solana:devnet';\n case 'testnet':\n return 'solana:testnet';\n default:\n return null;\n }\n}\n\nexport function isSolanaChain(chain: string): chain is `solana:${string}` {\n return chain.startsWith('solana:');\n}\n\nexport function isKnownSolanaChain(chain: string): boolean {\n return (\n chain === SOLANA_CHAIN_IDS.mainnet || chain === SOLANA_CHAIN_IDS.devnet || chain === SOLANA_CHAIN_IDS.testnet\n );\n}\n\nexport function validateKnownSolanaChain(chain: string): asserts chain is `solana:${string}` {\n if (!isSolanaChain(chain)) {\n throw new Error(`Invalid chain format: expected 'solana:...', got '${chain}'`);\n }\n\n if (!isKnownSolanaChain(chain)) {\n throw new Error(`Unknown Solana chain: ${chain}. Known chains: ${Object.values(SOLANA_CHAIN_IDS).join(', ')}`);\n }\n}\n\nexport function getClusterTypeFromConnection(connection: Connection | null): ClusterType | null {\n if (!connection) {\n return null;\n }\n\n const rpcUrl = connection.rpcEndpoint || '';\n\n if (rpcUrl.includes('mainnet') || rpcUrl.includes('api.mainnet-beta')) {\n return 'mainnet';\n }\n\n if (rpcUrl.includes('testnet')) {\n return 'testnet';\n }\n\n if (rpcUrl.includes('devnet')) {\n return 'devnet';\n }\n\n if (rpcUrl.includes('localhost') || rpcUrl.includes('127.0.0.1')) {\n return 'localnet';\n }\n\n return 'custom';\n}\n\nexport function getChainIdFromConnection(\n connection: Connection | null,\n network?: 'mainnet' | 'devnet' | 'testnet',\n): `solana:${string}` | null {\n if (network) {\n return getChainIdFromClusterType(network);\n }\n\n const clusterType = getClusterTypeFromConnection(connection);\n if (!clusterType) {\n return null;\n }\n\n return getChainIdFromClusterType(clusterType);\n}\n\nexport function clusterToChainId(cluster: SolanaCluster): `solana:${string}` | null {\n return getChainIdFromCluster(cluster);\n}\n\nexport function chainIdToClusterType(chainId: string): ClusterType | null {\n return getClusterTypeFromChainId(chainId);\n}\n\nexport function chainIdToClusterId(chainId: string): SolanaClusterId | null {\n return getClusterIdFromChainId(chainId);\n}\n","/**\n * @solana/connector - Explorer URL Utilities\n *\n * Generate URLs for various Solana block explorers to view transactions,\n * accounts, and other on-chain data.\n */\n\nimport { getExplorerLink } from '../kit-utils';\n\nexport type ExplorerType = 'solana-explorer' | 'solscan' | 'xray' | 'solana-fm';\n\nexport interface ExplorerOptions {\n /** Cluster to use for the explorer link */\n cluster?: string;\n /** Custom RPC URL for localnet */\n customUrl?: string;\n}\n\n/**\n * Generate Solana Explorer URL for a transaction signature\n */\nexport function getSolanaExplorerUrl(signature: string, options: ExplorerOptions = {}): string {\n const { cluster = 'mainnet', customUrl } = options;\n const normalizedCluster = cluster === 'mainnet-beta' ? 'mainnet' : cluster;\n\n // Handle localnet with custom URL - gill doesn't support this specific case\n if (normalizedCluster === 'localnet') {\n const url = customUrl || 'http://localhost:8899';\n return `https://explorer.solana.com/tx/${signature}?cluster=custom&customUrl=${encodeURIComponent(url)}`;\n }\n\n // Map to valid gill cluster types (custom clusters default to devnet)\n const validClusters = ['mainnet', 'devnet', 'testnet'] as const;\n const explorerCluster = validClusters.includes(normalizedCluster as 'mainnet' | 'devnet' | 'testnet')\n ? (normalizedCluster as 'mainnet' | 'devnet' | 'testnet')\n : 'devnet';\n\n // Use gill's getExplorerLink for standard clusters\n return getExplorerLink({\n transaction: signature,\n cluster: explorerCluster,\n });\n}\n\n/**\n * Generate Solscan URL for a transaction signature\n */\nexport function getSolscanUrl(signature: string, options: ExplorerOptions = {}): string {\n const { cluster = 'mainnet' } = options;\n const normalizedCluster = cluster === 'mainnet-beta' ? 'mainnet' : cluster;\n\n if (normalizedCluster === 'mainnet') {\n return `https://solscan.io/tx/${signature}`;\n }\n\n if (normalizedCluster === 'localnet') {\n return `https://solscan.io/tx/${signature}?cluster=custom`;\n }\n\n return `https://solscan.io/tx/${signature}?cluster=${normalizedCluster}`;\n}\n\n/**\n * Generate XRAY (Helius) URL for a transaction signature\n * Note: XRAY works best with mainnet transactions\n */\nexport function getXrayUrl(signature: string): string {\n return `https://xray.helius.xyz/tx/${signature}`;\n}\n\n/**\n * Generate SolanaFM URL for a transaction signature\n */\nexport function getSolanaFmUrl(signature: string, options: ExplorerOptions = {}): string {\n const { cluster = 'mainnet' } = options;\n const normalizedCluster = cluster === 'mainnet-beta' ? 'mainnet' : cluster;\n\n if (normalizedCluster === 'mainnet') {\n return `https://solana.fm/tx/${signature}`;\n }\n\n return `https://solana.fm/tx/${signature}?cluster=${normalizedCluster}`;\n}\n\n/**\n * Get all explorer URLs for a transaction\n */\nexport function getAllExplorerUrls(signature: string, options: ExplorerOptions = {}): Record<ExplorerType, string> {\n return {\n 'solana-explorer': getSolanaExplorerUrl(signature, options),\n solscan: getSolscanUrl(signature, options),\n xray: getXrayUrl(signature),\n 'solana-fm': getSolanaFmUrl(signature, options),\n };\n}\n\n/**\n * Format a transaction signature for display (truncated)\n */\nexport function formatSignature(signature: string, chars = 8): string {\n if (signature.length <= chars * 2) return signature;\n return `${signature.slice(0, chars)}...${signature.slice(-chars)}`;\n}\n\n/**\n * Copy signature to clipboard with enhanced error handling\n *\n * @deprecated Use copySignatureToClipboard from utils/clipboard instead\n * This is maintained for backwards compatibility but will be removed in a future version\n */\nexport async function copySignature(signature: string): Promise<boolean> {\n try {\n await navigator.clipboard.writeText(signature);\n return true;\n } catch {\n return false;\n }\n}\n"]}