@agalmic/contextengine 0.1.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -274,27 +274,27 @@ var require_bn = __commonJS({
274
274
  var total = number.length - start;
275
275
  var mod = total % limbLen;
276
276
  var end = Math.min(total, total - mod) + start;
277
- var word = 0;
277
+ var word2 = 0;
278
278
  for (var i = start; i < end; i += limbLen) {
279
- word = parseBase(number, i, i + limbLen, base);
279
+ word2 = parseBase(number, i, i + limbLen, base);
280
280
  this.imuln(limbPow);
281
- if (this.words[0] + word < 67108864) {
282
- this.words[0] += word;
281
+ if (this.words[0] + word2 < 67108864) {
282
+ this.words[0] += word2;
283
283
  } else {
284
- this._iaddn(word);
284
+ this._iaddn(word2);
285
285
  }
286
286
  }
287
287
  if (mod !== 0) {
288
288
  var pow = 1;
289
- word = parseBase(number, i, number.length, base);
289
+ word2 = parseBase(number, i, number.length, base);
290
290
  for (i = 0; i < mod; i++) {
291
291
  pow *= base;
292
292
  }
293
293
  this.imuln(pow);
294
- if (this.words[0] + word < 67108864) {
295
- this.words[0] += word;
294
+ if (this.words[0] + word2 < 67108864) {
295
+ this.words[0] += word2;
296
296
  } else {
297
- this._iaddn(word);
297
+ this._iaddn(word2);
298
298
  }
299
299
  }
300
300
  this._strip();
@@ -468,7 +468,7 @@ var require_bn = __commonJS({
468
468
  var carry = 0;
469
469
  for (var i = 0; i < this.length; i++) {
470
470
  var w = this.words[i];
471
- var word = ((w << off | carry) & 16777215).toString(16);
471
+ var word2 = ((w << off | carry) & 16777215).toString(16);
472
472
  carry = w >>> 24 - off & 16777215;
473
473
  off += 2;
474
474
  if (off >= 26) {
@@ -476,9 +476,9 @@ var require_bn = __commonJS({
476
476
  i--;
477
477
  }
478
478
  if (carry !== 0 || i !== this.length - 1) {
479
- out = zeros[6 - word.length] + word + out;
479
+ out = zeros[6 - word2.length] + word2 + out;
480
480
  } else {
481
- out = word + out;
481
+ out = word2 + out;
482
482
  }
483
483
  }
484
484
  if (carry !== 0) {
@@ -563,22 +563,22 @@ var require_bn = __commonJS({
563
563
  var position = 0;
564
564
  var carry = 0;
565
565
  for (var i = 0, shift = 0; i < this.length; i++) {
566
- var word = this.words[i] << shift | carry;
567
- res[position++] = word & 255;
566
+ var word2 = this.words[i] << shift | carry;
567
+ res[position++] = word2 & 255;
568
568
  if (position < res.length) {
569
- res[position++] = word >> 8 & 255;
569
+ res[position++] = word2 >> 8 & 255;
570
570
  }
571
571
  if (position < res.length) {
572
- res[position++] = word >> 16 & 255;
572
+ res[position++] = word2 >> 16 & 255;
573
573
  }
574
574
  if (shift === 6) {
575
575
  if (position < res.length) {
576
- res[position++] = word >> 24 & 255;
576
+ res[position++] = word2 >> 24 & 255;
577
577
  }
578
578
  carry = 0;
579
579
  shift = 0;
580
580
  } else {
581
- carry = word >>> 24;
581
+ carry = word2 >>> 24;
582
582
  shift += 2;
583
583
  }
584
584
  }
@@ -593,22 +593,22 @@ var require_bn = __commonJS({
593
593
  var position = res.length - 1;
594
594
  var carry = 0;
595
595
  for (var i = 0, shift = 0; i < this.length; i++) {
596
- var word = this.words[i] << shift | carry;
597
- res[position--] = word & 255;
596
+ var word2 = this.words[i] << shift | carry;
597
+ res[position--] = word2 & 255;
598
598
  if (position >= 0) {
599
- res[position--] = word >> 8 & 255;
599
+ res[position--] = word2 >> 8 & 255;
600
600
  }
601
601
  if (position >= 0) {
602
- res[position--] = word >> 16 & 255;
602
+ res[position--] = word2 >> 16 & 255;
603
603
  }
604
604
  if (shift === 6) {
605
605
  if (position >= 0) {
606
- res[position--] = word >> 24 & 255;
606
+ res[position--] = word2 >> 24 & 255;
607
607
  }
608
608
  carry = 0;
609
609
  shift = 0;
610
610
  } else {
611
- carry = word >>> 24;
611
+ carry = word2 >>> 24;
612
612
  shift += 2;
613
613
  }
614
614
  }
@@ -1847,9 +1847,9 @@ var require_bn = __commonJS({
1847
1847
  }
1848
1848
  var carry = 0;
1849
1849
  for (i = this.length - 1; i >= 0 && (carry !== 0 || i >= h); i--) {
1850
- var word = this.words[i] | 0;
1851
- this.words[i] = carry << 26 - r | word >>> r;
1852
- carry = word & mask;
1850
+ var word2 = this.words[i] | 0;
1851
+ this.words[i] = carry << 26 - r | word2 >>> r;
1852
+ carry = word2 & mask;
1853
1853
  }
1854
1854
  if (maskedWords && carry !== 0) {
1855
1855
  maskedWords.words[maskedWords.length++] = carry;
@@ -2830,9 +2830,9 @@ var require_bn = __commonJS({
2830
2830
  start = 26;
2831
2831
  }
2832
2832
  for (i = num.length - 1; i >= 0; i--) {
2833
- var word = num.words[i];
2833
+ var word2 = num.words[i];
2834
2834
  for (var j = start - 1; j >= 0; j--) {
2835
- var bit = word >> j & 1;
2835
+ var bit = word2 >> j & 1;
2836
2836
  if (res !== wnd[0]) {
2837
2837
  res = this.sqr(res);
2838
2838
  }
@@ -5521,12 +5521,12 @@ var require_abstract_coder = __commonJS({
5521
5521
  var logger = new logger_1.Logger(_version_1.version);
5522
5522
  function checkResultErrors(result) {
5523
5523
  var errors = [];
5524
- var checkErrors = function(path3, object) {
5524
+ var checkErrors = function(path4, object) {
5525
5525
  if (!Array.isArray(object)) {
5526
5526
  return;
5527
5527
  }
5528
5528
  for (var key in object) {
5529
- var childPath = path3.slice();
5529
+ var childPath = path4.slice();
5530
5530
  childPath.push(key);
5531
5531
  try {
5532
5532
  checkErrors(childPath, object[key]);
@@ -7618,8 +7618,8 @@ var require_bytes32 = __commonJS({
7618
7618
  var constants_1 = require_lib8();
7619
7619
  var bytes_1 = require_lib2();
7620
7620
  var utf8_1 = require_utf8();
7621
- function formatBytes32String(text4) {
7622
- var bytes = (0, utf8_1.toUtf8Bytes)(text4);
7621
+ function formatBytes32String(text6) {
7622
+ var bytes = (0, utf8_1.toUtf8Bytes)(text6);
7623
7623
  if (bytes.length > 31) {
7624
7624
  throw new Error("bytes32 string must be less than 32 bytes");
7625
7625
  }
@@ -8137,8 +8137,8 @@ var require_id = __commonJS({
8137
8137
  exports.id = void 0;
8138
8138
  var keccak256_1 = require_lib5();
8139
8139
  var strings_1 = require_lib9();
8140
- function id(text4) {
8141
- return (0, keccak256_1.keccak256)((0, strings_1.toUtf8Bytes)(text4));
8140
+ function id(text6) {
8141
+ return (0, keccak256_1.keccak256)((0, strings_1.toUtf8Bytes)(text6));
8142
8142
  }
8143
8143
  exports.id = id;
8144
8144
  }
@@ -11022,27 +11022,27 @@ var require_bn2 = __commonJS({
11022
11022
  var total = number.length - start;
11023
11023
  var mod = total % limbLen;
11024
11024
  var end = Math.min(total, total - mod) + start;
11025
- var word = 0;
11025
+ var word2 = 0;
11026
11026
  for (var i = start; i < end; i += limbLen) {
11027
- word = parseBase(number, i, i + limbLen, base);
11027
+ word2 = parseBase(number, i, i + limbLen, base);
11028
11028
  this.imuln(limbPow);
11029
- if (this.words[0] + word < 67108864) {
11030
- this.words[0] += word;
11029
+ if (this.words[0] + word2 < 67108864) {
11030
+ this.words[0] += word2;
11031
11031
  } else {
11032
- this._iaddn(word);
11032
+ this._iaddn(word2);
11033
11033
  }
11034
11034
  }
11035
11035
  if (mod !== 0) {
11036
11036
  var pow = 1;
11037
- word = parseBase(number, i, number.length, base);
11037
+ word2 = parseBase(number, i, number.length, base);
11038
11038
  for (i = 0; i < mod; i++) {
11039
11039
  pow *= base;
11040
11040
  }
11041
11041
  this.imuln(pow);
11042
- if (this.words[0] + word < 67108864) {
11043
- this.words[0] += word;
11042
+ if (this.words[0] + word2 < 67108864) {
11043
+ this.words[0] += word2;
11044
11044
  } else {
11045
- this._iaddn(word);
11045
+ this._iaddn(word2);
11046
11046
  }
11047
11047
  }
11048
11048
  this.strip();
@@ -11198,7 +11198,7 @@ var require_bn2 = __commonJS({
11198
11198
  var carry = 0;
11199
11199
  for (var i = 0; i < this.length; i++) {
11200
11200
  var w = this.words[i];
11201
- var word = ((w << off | carry) & 16777215).toString(16);
11201
+ var word2 = ((w << off | carry) & 16777215).toString(16);
11202
11202
  carry = w >>> 24 - off & 16777215;
11203
11203
  off += 2;
11204
11204
  if (off >= 26) {
@@ -11206,9 +11206,9 @@ var require_bn2 = __commonJS({
11206
11206
  i--;
11207
11207
  }
11208
11208
  if (carry !== 0 || i !== this.length - 1) {
11209
- out = zeros[6 - word.length] + word + out;
11209
+ out = zeros[6 - word2.length] + word2 + out;
11210
11210
  } else {
11211
- out = word + out;
11211
+ out = word2 + out;
11212
11212
  }
11213
11213
  }
11214
11214
  if (carry !== 0) {
@@ -12529,9 +12529,9 @@ var require_bn2 = __commonJS({
12529
12529
  }
12530
12530
  var carry = 0;
12531
12531
  for (i = this.length - 1; i >= 0 && (carry !== 0 || i >= h); i--) {
12532
- var word = this.words[i] | 0;
12533
- this.words[i] = carry << 26 - r | word >>> r;
12534
- carry = word & mask;
12532
+ var word2 = this.words[i] | 0;
12533
+ this.words[i] = carry << 26 - r | word2 >>> r;
12534
+ carry = word2 & mask;
12535
12535
  }
12536
12536
  if (maskedWords && carry !== 0) {
12537
12537
  maskedWords.words[maskedWords.length++] = carry;
@@ -13503,9 +13503,9 @@ var require_bn2 = __commonJS({
13503
13503
  start = 26;
13504
13504
  }
13505
13505
  for (i = num.length - 1; i >= 0; i--) {
13506
- var word = num.words[i];
13506
+ var word2 = num.words[i];
13507
13507
  for (var j = start - 1; j >= 0; j--) {
13508
- var bit = word >> j & 1;
13508
+ var bit = word2 >> j & 1;
13509
13509
  if (res !== wnd[0]) {
13510
13510
  res = this.sqr(res);
13511
13511
  }
@@ -13648,11 +13648,11 @@ var require_utils = __commonJS({
13648
13648
  return res;
13649
13649
  }
13650
13650
  utils.toArray = toArray;
13651
- function zero2(word) {
13652
- if (word.length === 1)
13653
- return "0" + word;
13651
+ function zero2(word2) {
13652
+ if (word2.length === 1)
13653
+ return "0" + word2;
13654
13654
  else
13655
- return word;
13655
+ return word2;
13656
13656
  }
13657
13657
  utils.zero2 = zero2;
13658
13658
  function toHex(msg) {
@@ -15422,30 +15422,30 @@ var require_utils3 = __commonJS({
15422
15422
  return res;
15423
15423
  }
15424
15424
  exports.toHex32 = toHex32;
15425
- function zero2(word) {
15426
- if (word.length === 1)
15427
- return "0" + word;
15425
+ function zero2(word2) {
15426
+ if (word2.length === 1)
15427
+ return "0" + word2;
15428
15428
  else
15429
- return word;
15429
+ return word2;
15430
15430
  }
15431
15431
  exports.zero2 = zero2;
15432
- function zero8(word) {
15433
- if (word.length === 7)
15434
- return "0" + word;
15435
- else if (word.length === 6)
15436
- return "00" + word;
15437
- else if (word.length === 5)
15438
- return "000" + word;
15439
- else if (word.length === 4)
15440
- return "0000" + word;
15441
- else if (word.length === 3)
15442
- return "00000" + word;
15443
- else if (word.length === 2)
15444
- return "000000" + word;
15445
- else if (word.length === 1)
15446
- return "0000000" + word;
15432
+ function zero8(word2) {
15433
+ if (word2.length === 7)
15434
+ return "0" + word2;
15435
+ else if (word2.length === 6)
15436
+ return "00" + word2;
15437
+ else if (word2.length === 5)
15438
+ return "000" + word2;
15439
+ else if (word2.length === 4)
15440
+ return "0000" + word2;
15441
+ else if (word2.length === 3)
15442
+ return "00000" + word2;
15443
+ else if (word2.length === 2)
15444
+ return "000000" + word2;
15445
+ else if (word2.length === 1)
15446
+ return "0000000" + word2;
15447
15447
  else
15448
- return word;
15448
+ return word2;
15449
15449
  }
15450
15450
  exports.zero8 = zero8;
15451
15451
  function join32(msg, start, end, endian) {
@@ -20715,11 +20715,11 @@ var require_wordlist = __commonJS({
20715
20715
  Wordlist2.check = function(wordlist) {
20716
20716
  var words = [];
20717
20717
  for (var i = 0; i < 2048; i++) {
20718
- var word = wordlist.getWord(i);
20719
- if (i !== wordlist.getWordIndex(word)) {
20718
+ var word2 = wordlist.getWord(i);
20719
+ if (i !== wordlist.getWordIndex(word2)) {
20720
20720
  return "0x";
20721
20721
  }
20722
- words.push(word);
20722
+ words.push(word2);
20723
20723
  }
20724
20724
  return (0, hash_1.id)(words.join("\n") + "\n");
20725
20725
  };
@@ -20795,9 +20795,9 @@ var require_lang_cz = __commonJS({
20795
20795
  loadWords(this);
20796
20796
  return wordlist[index];
20797
20797
  };
20798
- LangCz2.prototype.getWordIndex = function(word) {
20798
+ LangCz2.prototype.getWordIndex = function(word2) {
20799
20799
  loadWords(this);
20800
- return wordlist.indexOf(word);
20800
+ return wordlist.indexOf(word2);
20801
20801
  };
20802
20802
  return LangCz2;
20803
20803
  })(wordlist_1.Wordlist)
@@ -20857,9 +20857,9 @@ var require_lang_en = __commonJS({
20857
20857
  loadWords(this);
20858
20858
  return wordlist[index];
20859
20859
  };
20860
- LangEn2.prototype.getWordIndex = function(word) {
20860
+ LangEn2.prototype.getWordIndex = function(word2) {
20861
20861
  loadWords(this);
20862
- return wordlist.indexOf(word);
20862
+ return wordlist.indexOf(word2);
20863
20863
  };
20864
20864
  return LangEn2;
20865
20865
  })(wordlist_1.Wordlist)
@@ -20900,15 +20900,15 @@ var require_lang_es = __commonJS({
20900
20900
  var words = "A/bacoAbdomenAbejaAbiertoAbogadoAbonoAbortoAbrazoAbrirAbueloAbusoAcabarAcademiaAccesoAccio/nAceiteAcelgaAcentoAceptarA/cidoAclararAcne/AcogerAcosoActivoActoActrizActuarAcudirAcuerdoAcusarAdictoAdmitirAdoptarAdornoAduanaAdultoAe/reoAfectarAficio/nAfinarAfirmarA/gilAgitarAgoni/aAgostoAgotarAgregarAgrioAguaAgudoA/guilaAgujaAhogoAhorroAireAislarAjedrezAjenoAjusteAlacra/nAlambreAlarmaAlbaA/lbumAlcaldeAldeaAlegreAlejarAlertaAletaAlfilerAlgaAlgodo/nAliadoAlientoAlivioAlmaAlmejaAlmi/barAltarAltezaAltivoAltoAlturaAlumnoAlzarAmableAmanteAmapolaAmargoAmasarA/mbarA/mbitoAmenoAmigoAmistadAmorAmparoAmplioAnchoAncianoAnclaAndarAnde/nAnemiaA/nguloAnilloA/nimoAni/sAnotarAntenaAntiguoAntojoAnualAnularAnuncioA~adirA~ejoA~oApagarAparatoApetitoApioAplicarApodoAporteApoyoAprenderAprobarApuestaApuroAradoAra~aArarA/rbitroA/rbolArbustoArchivoArcoArderArdillaArduoA/reaA/ridoAriesArmoni/aArne/sAromaArpaArpo/nArregloArrozArrugaArteArtistaAsaAsadoAsaltoAscensoAsegurarAseoAsesorAsientoAsiloAsistirAsnoAsombroA/speroAstillaAstroAstutoAsumirAsuntoAtajoAtaqueAtarAtentoAteoA/ticoAtletaA/tomoAtraerAtrozAtu/nAudazAudioAugeAulaAumentoAusenteAutorAvalAvanceAvaroAveAvellanaAvenaAvestruzAvio/nAvisoAyerAyudaAyunoAzafra/nAzarAzoteAzu/carAzufreAzulBabaBaborBacheBahi/aBaileBajarBalanzaBalco/nBaldeBambu/BancoBandaBa~oBarbaBarcoBarnizBarroBa/sculaBasto/nBasuraBatallaBateri/aBatirBatutaBau/lBazarBebe/BebidaBelloBesarBesoBestiaBichoBienBingoBlancoBloqueBlusaBoaBobinaBoboBocaBocinaBodaBodegaBoinaBolaBoleroBolsaBombaBondadBonitoBonoBonsa/iBordeBorrarBosqueBoteBoti/nBo/vedaBozalBravoBrazoBrechaBreveBrilloBrincoBrisaBrocaBromaBronceBroteBrujaBruscoBrutoBuceoBucleBuenoBueyBufandaBufo/nBu/hoBuitreBultoBurbujaBurlaBurroBuscarButacaBuzo/nCaballoCabezaCabinaCabraCacaoCada/verCadenaCaerCafe/Cai/daCaima/nCajaCajo/nCalCalamarCalcioCaldoCalidadCalleCalmaCalorCalvoCamaCambioCamelloCaminoCampoCa/ncerCandilCanelaCanguroCanicaCantoCa~aCa~o/nCaobaCaosCapazCapita/nCapoteCaptarCapuchaCaraCarbo/nCa/rcelCaretaCargaCari~oCarneCarpetaCarroCartaCasaCascoCaseroCaspaCastorCatorceCatreCaudalCausaCazoCebollaCederCedroCeldaCe/lebreCelosoCe/lulaCementoCenizaCentroCercaCerdoCerezaCeroCerrarCertezaCe/spedCetroChacalChalecoChampu/ChanclaChapaCharlaChicoChisteChivoChoqueChozaChuletaChuparCiclo/nCiegoCieloCienCiertoCifraCigarroCimaCincoCineCintaCipre/sCircoCiruelaCisneCitaCiudadClamorClanClaroClaseClaveClienteClimaCli/nicaCobreCoccio/nCochinoCocinaCocoCo/digoCodoCofreCogerCoheteCoji/nCojoColaColchaColegioColgarColinaCollarColmoColumnaCombateComerComidaCo/modoCompraCondeConejoCongaConocerConsejoContarCopaCopiaCorazo/nCorbataCorchoCordo/nCoronaCorrerCoserCosmosCostaCra/neoCra/terCrearCrecerCrei/doCremaCri/aCrimenCriptaCrisisCromoCro/nicaCroquetaCrudoCruzCuadroCuartoCuatroCuboCubrirCucharaCuelloCuentoCuerdaCuestaCuevaCuidarCulebraCulpaCultoCumbreCumplirCunaCunetaCuotaCupo/nCu/pulaCurarCuriosoCursoCurvaCutisDamaDanzaDarDardoDa/tilDeberDe/bilDe/cadaDecirDedoDefensaDefinirDejarDelfi/nDelgadoDelitoDemoraDensoDentalDeporteDerechoDerrotaDesayunoDeseoDesfileDesnudoDestinoDesvi/oDetalleDetenerDeudaDi/aDiabloDiademaDiamanteDianaDiarioDibujoDictarDienteDietaDiezDifi/cilDignoDilemaDiluirDineroDirectoDirigirDiscoDise~oDisfrazDivaDivinoDobleDoceDolorDomingoDonDonarDoradoDormirDorsoDosDosisDrago/nDrogaDuchaDudaDueloDue~oDulceDu/oDuqueDurarDurezaDuroE/banoEbrioEcharEcoEcuadorEdadEdicio/nEdificioEditorEducarEfectoEficazEjeEjemploElefanteElegirElementoElevarElipseE/liteElixirElogioEludirEmbudoEmitirEmocio/nEmpateEmpe~oEmpleoEmpresaEnanoEncargoEnchufeEnci/aEnemigoEneroEnfadoEnfermoEnga~oEnigmaEnlaceEnormeEnredoEnsayoEnse~arEnteroEntrarEnvaseEnvi/oE/pocaEquipoErizoEscalaEscenaEscolarEscribirEscudoEsenciaEsferaEsfuerzoEspadaEspejoEspi/aEsposaEspumaEsqui/EstarEsteEstiloEstufaEtapaEternoE/ticaEtniaEvadirEvaluarEventoEvitarExactoExamenExcesoExcusaExentoExigirExilioExistirE/xitoExpertoExplicarExponerExtremoFa/bricaFa/bulaFachadaFa/cilFactorFaenaFajaFaldaFalloFalsoFaltarFamaFamiliaFamosoFarao/nFarmaciaFarolFarsaFaseFatigaFaunaFavorFaxFebreroFechaFelizFeoFeriaFerozFe/rtilFervorFesti/nFiableFianzaFiarFibraFiccio/nFichaFideoFiebreFielFieraFiestaFiguraFijarFijoFilaFileteFilialFiltroFinFincaFingirFinitoFirmaFlacoFlautaFlechaFlorFlotaFluirFlujoFlu/orFobiaFocaFogataFogo/nFolioFolletoFondoFormaForroFortunaForzarFosaFotoFracasoFra/gilFranjaFraseFraudeFrei/rFrenoFresaFri/oFritoFrutaFuegoFuenteFuerzaFugaFumarFuncio/nFundaFurgo/nFuriaFusilFu/tbolFuturoGacelaGafasGaitaGajoGalaGaleri/aGalloGambaGanarGanchoGangaGansoGarajeGarzaGasolinaGastarGatoGavila/nGemeloGemirGenGe/neroGenioGenteGeranioGerenteGermenGestoGiganteGimnasioGirarGiroGlaciarGloboGloriaGolGolfoGolosoGolpeGomaGordoGorilaGorraGotaGoteoGozarGradaGra/ficoGranoGrasaGratisGraveGrietaGrilloGripeGrisGritoGrosorGru/aGruesoGrumoGrupoGuanteGuapoGuardiaGuerraGui/aGui~oGuionGuisoGuitarraGusanoGustarHaberHa/bilHablarHacerHachaHadaHallarHamacaHarinaHazHaza~aHebillaHebraHechoHeladoHelioHembraHerirHermanoHe/roeHervirHieloHierroHi/gadoHigieneHijoHimnoHistoriaHocicoHogarHogueraHojaHombreHongoHonorHonraHoraHormigaHornoHostilHoyoHuecoHuelgaHuertaHuesoHuevoHuidaHuirHumanoHu/medoHumildeHumoHundirHuraca/nHurtoIconoIdealIdiomaI/doloIglesiaIglu/IgualIlegalIlusio/nImagenIma/nImitarImparImperioImponerImpulsoIncapazI/ndiceInerteInfielInformeIngenioInicioInmensoInmuneInnatoInsectoInstanteIntere/sI/ntimoIntuirInu/tilInviernoIraIrisIroni/aIslaIsloteJabali/Jabo/nJamo/nJarabeJardi/nJarraJaulaJazmi/nJefeJeringaJineteJornadaJorobaJovenJoyaJuergaJuevesJuezJugadorJugoJugueteJuicioJuncoJunglaJunioJuntarJu/piterJurarJustoJuvenilJuzgarKiloKoalaLabioLacioLacraLadoLadro/nLagartoLa/grimaLagunaLaicoLamerLa/minaLa/mparaLanaLanchaLangostaLanzaLa/pizLargoLarvaLa/stimaLataLa/texLatirLaurelLavarLazoLealLeccio/nLecheLectorLeerLegio/nLegumbreLejanoLenguaLentoLe~aLeo/nLeopardoLesio/nLetalLetraLeveLeyendaLibertadLibroLicorLi/derLidiarLienzoLigaLigeroLimaLi/miteLimo/nLimpioLinceLindoLi/neaLingoteLinoLinternaLi/quidoLisoListaLiteraLitioLitroLlagaLlamaLlantoLlaveLlegarLlenarLlevarLlorarLloverLluviaLoboLocio/nLocoLocuraLo/gicaLogroLombrizLomoLonjaLoteLuchaLucirLugarLujoLunaLunesLupaLustroLutoLuzMacetaMachoMaderaMadreMaduroMaestroMafiaMagiaMagoMai/zMaldadMaletaMallaMaloMama/MamboMamutMancoMandoManejarMangaManiqui/ManjarManoMansoMantaMa~anaMapaMa/quinaMarMarcoMareaMarfilMargenMaridoMa/rmolMarro/nMartesMarzoMasaMa/scaraMasivoMatarMateriaMatizMatrizMa/ximoMayorMazorcaMechaMedallaMedioMe/dulaMejillaMejorMelenaMelo/nMemoriaMenorMensajeMenteMenu/MercadoMerengueMe/ritoMesMeso/nMetaMeterMe/todoMetroMezclaMiedoMielMiembroMigaMilMilagroMilitarMillo/nMimoMinaMineroMi/nimoMinutoMiopeMirarMisaMiseriaMisilMismoMitadMitoMochilaMocio/nModaModeloMohoMojarMoldeMolerMolinoMomentoMomiaMonarcaMonedaMonjaMontoMo~oMoradaMorderMorenoMorirMorroMorsaMortalMoscaMostrarMotivoMoverMo/vilMozoMuchoMudarMuebleMuelaMuerteMuestraMugreMujerMulaMuletaMultaMundoMu~ecaMuralMuroMu/sculoMuseoMusgoMu/sicaMusloNa/carNacio/nNadarNaipeNaranjaNarizNarrarNasalNatalNativoNaturalNa/useaNavalNaveNavidadNecioNe/ctarNegarNegocioNegroNeo/nNervioNetoNeutroNevarNeveraNichoNidoNieblaNietoNi~ezNi~oNi/tidoNivelNoblezaNocheNo/minaNoriaNormaNorteNotaNoticiaNovatoNovelaNovioNubeNucaNu/cleoNudilloNudoNueraNueveNuezNuloNu/meroNutriaOasisObesoObispoObjetoObraObreroObservarObtenerObvioOcaOcasoOce/anoOchentaOchoOcioOcreOctavoOctubreOcultoOcuparOcurrirOdiarOdioOdiseaOesteOfensaOfertaOficioOfrecerOgroOi/doOi/rOjoOlaOleadaOlfatoOlivoOllaOlmoOlorOlvidoOmbligoOndaOnzaOpacoOpcio/nO/peraOpinarOponerOptarO/pticaOpuestoOracio/nOradorOralO/rbitaOrcaOrdenOrejaO/rganoOrgi/aOrgulloOrienteOrigenOrillaOroOrquestaOrugaOsadi/aOscuroOseznoOsoOstraOto~oOtroOvejaO/vuloO/xidoOxi/genoOyenteOzonoPactoPadrePaellaPa/ginaPagoPai/sPa/jaroPalabraPalcoPaletaPa/lidoPalmaPalomaPalparPanPanalPa/nicoPanteraPa~ueloPapa/PapelPapillaPaquetePararParcelaParedParirParoPa/rpadoParquePa/rrafoPartePasarPaseoPasio/nPasoPastaPataPatioPatriaPausaPautaPavoPayasoPeato/nPecadoPeceraPechoPedalPedirPegarPeinePelarPelda~oPeleaPeligroPellejoPeloPelucaPenaPensarPe~o/nPeo/nPeorPepinoPeque~oPeraPerchaPerderPerezaPerfilPericoPerlaPermisoPerroPersonaPesaPescaPe/simoPesta~aPe/taloPetro/leoPezPezu~aPicarPicho/nPiePiedraPiernaPiezaPijamaPilarPilotoPimientaPinoPintorPinzaPi~aPiojoPipaPirataPisarPiscinaPisoPistaPito/nPizcaPlacaPlanPlataPlayaPlazaPleitoPlenoPlomoPlumaPluralPobrePocoPoderPodioPoemaPoesi/aPoetaPolenPolici/aPolloPolvoPomadaPomeloPomoPompaPonerPorcio/nPortalPosadaPoseerPosiblePostePotenciaPotroPozoPradoPrecozPreguntaPremioPrensaPresoPrevioPrimoPri/ncipePrisio/nPrivarProaProbarProcesoProductoProezaProfesorProgramaProlePromesaProntoPropioPro/ximoPruebaPu/blicoPucheroPudorPuebloPuertaPuestoPulgaPulirPulmo/nPulpoPulsoPumaPuntoPu~alPu~oPupaPupilaPure/QuedarQuejaQuemarQuererQuesoQuietoQui/micaQuinceQuitarRa/banoRabiaRaboRacio/nRadicalRai/zRamaRampaRanchoRangoRapazRa/pidoRaptoRasgoRaspaRatoRayoRazaRazo/nReaccio/nRealidadReba~oReboteRecaerRecetaRechazoRecogerRecreoRectoRecursoRedRedondoReducirReflejoReformaRefra/nRefugioRegaloRegirReglaRegresoRehe/nReinoRei/rRejaRelatoRelevoRelieveRellenoRelojRemarRemedioRemoRencorRendirRentaRepartoRepetirReposoReptilResRescateResinaRespetoRestoResumenRetiroRetornoRetratoReunirReve/sRevistaReyRezarRicoRiegoRiendaRiesgoRifaRi/gidoRigorRinco/nRi~o/nRi/oRiquezaRisaRitmoRitoRizoRobleRoceRociarRodarRodeoRodillaRoerRojizoRojoRomeroRomperRonRoncoRondaRopaRoperoRosaRoscaRostroRotarRubi/RuborRudoRuedaRugirRuidoRuinaRuletaRuloRumboRumorRupturaRutaRutinaSa/badoSaberSabioSableSacarSagazSagradoSalaSaldoSaleroSalirSalmo/nSalo/nSalsaSaltoSaludSalvarSambaSancio/nSandi/aSanearSangreSanidadSanoSantoSapoSaqueSardinaSarte/nSastreSata/nSaunaSaxofo/nSeccio/nSecoSecretoSectaSedSeguirSeisSelloSelvaSemanaSemillaSendaSensorSe~alSe~orSepararSepiaSequi/aSerSerieSermo/nServirSesentaSesio/nSetaSetentaSeveroSexoSextoSidraSiestaSieteSigloSignoSi/labaSilbarSilencioSillaSi/mboloSimioSirenaSistemaSitioSituarSobreSocioSodioSolSolapaSoldadoSoledadSo/lidoSoltarSolucio/nSombraSondeoSonidoSonoroSonrisaSopaSoplarSoporteSordoSorpresaSorteoSoste/nSo/tanoSuaveSubirSucesoSudorSuegraSueloSue~oSuerteSufrirSujetoSulta/nSumarSuperarSuplirSuponerSupremoSurSurcoSure~oSurgirSustoSutilTabacoTabiqueTablaTabu/TacoTactoTajoTalarTalcoTalentoTallaTalo/nTama~oTamborTangoTanqueTapaTapeteTapiaTapo/nTaquillaTardeTareaTarifaTarjetaTarotTarroTartaTatuajeTauroTazaTazo/nTeatroTechoTeclaTe/cnicaTejadoTejerTejidoTelaTele/fonoTemaTemorTemploTenazTenderTenerTenisTensoTeori/aTerapiaTercoTe/rminoTernuraTerrorTesisTesoroTestigoTeteraTextoTezTibioTiburo/nTiempoTiendaTierraTiesoTigreTijeraTildeTimbreTi/midoTimoTintaTi/oTi/picoTipoTiraTiro/nTita/nTi/tereTi/tuloTizaToallaTobilloTocarTocinoTodoTogaToldoTomarTonoTontoToparTopeToqueTo/raxToreroTormentaTorneoToroTorpedoTorreTorsoTortugaTosToscoToserTo/xicoTrabajoTractorTraerTra/ficoTragoTrajeTramoTranceTratoTraumaTrazarTre/bolTreguaTreintaTrenTreparTresTribuTrigoTripaTristeTriunfoTrofeoTrompaTroncoTropaTroteTrozoTrucoTruenoTrufaTuberi/aTuboTuertoTumbaTumorTu/nelTu/nicaTurbinaTurismoTurnoTutorUbicarU/lceraUmbralUnidadUnirUniversoUnoUntarU~aUrbanoUrbeUrgenteUrnaUsarUsuarioU/tilUtopi/aUvaVacaVaci/oVacunaVagarVagoVainaVajillaValeVa/lidoValleValorVa/lvulaVampiroVaraVariarVaro/nVasoVecinoVectorVehi/culoVeinteVejezVelaVeleroVelozVenaVencerVendaVenenoVengarVenirVentaVenusVerVeranoVerboVerdeVeredaVerjaVersoVerterVi/aViajeVibrarVicioVi/ctimaVidaVi/deoVidrioViejoViernesVigorVilVillaVinagreVinoVi~edoVioli/nViralVirgoVirtudVisorVi/speraVistaVitaminaViudoVivazViveroVivirVivoVolca/nVolumenVolverVorazVotarVotoVozVueloVulgarYacerYateYeguaYemaYernoYesoYodoYogaYogurZafiroZanjaZapatoZarzaZonaZorroZumoZurdo";
20901
20901
  var lookup = {};
20902
20902
  var wordlist = null;
20903
- function dropDiacritic(word) {
20903
+ function dropDiacritic(word2) {
20904
20904
  wordlist_1.logger.checkNormalize();
20905
- return (0, strings_1.toUtf8String)(Array.prototype.filter.call((0, strings_1.toUtf8Bytes)(word.normalize("NFD").toLowerCase()), function(c) {
20905
+ return (0, strings_1.toUtf8String)(Array.prototype.filter.call((0, strings_1.toUtf8Bytes)(word2.normalize("NFD").toLowerCase()), function(c) {
20906
20906
  return c >= 65 && c <= 90 || c >= 97 && c <= 123;
20907
20907
  }));
20908
20908
  }
20909
- function expand(word) {
20909
+ function expand(word2) {
20910
20910
  var output = [];
20911
- Array.prototype.forEach.call((0, strings_1.toUtf8Bytes)(word), function(c) {
20911
+ Array.prototype.forEach.call((0, strings_1.toUtf8Bytes)(word2), function(c) {
20912
20912
  if (c === 47) {
20913
20913
  output.push(204);
20914
20914
  output.push(129);
@@ -20929,8 +20929,8 @@ var require_lang_es = __commonJS({
20929
20929
  wordlist = words.replace(/([A-Z])/g, " $1").toLowerCase().substring(1).split(" ").map(function(w) {
20930
20930
  return expand(w);
20931
20931
  });
20932
- wordlist.forEach(function(word, index) {
20933
- lookup[dropDiacritic(word)] = index;
20932
+ wordlist.forEach(function(word2, index) {
20933
+ lookup[dropDiacritic(word2)] = index;
20934
20934
  });
20935
20935
  if (wordlist_1.Wordlist.check(lang) !== "0xf74fb7092aeacdfbf8959557de22098da512207fb9f109cb526994938cf40300") {
20936
20936
  wordlist = null;
@@ -20948,9 +20948,9 @@ var require_lang_es = __commonJS({
20948
20948
  loadWords(this);
20949
20949
  return wordlist[index];
20950
20950
  };
20951
- LangEs2.prototype.getWordIndex = function(word) {
20951
+ LangEs2.prototype.getWordIndex = function(word2) {
20952
20952
  loadWords(this);
20953
- return lookup[dropDiacritic(word)];
20953
+ return lookup[dropDiacritic(word2)];
20954
20954
  };
20955
20955
  return LangEs2;
20956
20956
  })(wordlist_1.Wordlist)
@@ -20991,15 +20991,15 @@ var require_lang_fr = __commonJS({
20991
20991
  var words = "AbaisserAbandonAbdiquerAbeilleAbolirAborderAboutirAboyerAbrasifAbreuverAbriterAbrogerAbruptAbsenceAbsoluAbsurdeAbusifAbyssalAcade/mieAcajouAcarienAccablerAccepterAcclamerAccoladeAccrocheAccuserAcerbeAchatAcheterAcidulerAcierAcompteAcque/rirAcronymeActeurActifActuelAdepteAde/quatAdhe/sifAdjectifAdjugerAdmettreAdmirerAdopterAdorerAdoucirAdresseAdroitAdulteAdverbeAe/rerAe/ronefAffaireAffecterAfficheAffreuxAffublerAgacerAgencerAgileAgiterAgraferAgre/ableAgrumeAiderAiguilleAilierAimableAisanceAjouterAjusterAlarmerAlchimieAlerteAlge-breAlgueAlie/nerAlimentAlle/gerAlliageAllouerAllumerAlourdirAlpagaAltesseAlve/oleAmateurAmbiguAmbreAme/nagerAmertumeAmidonAmiralAmorcerAmourAmovibleAmphibieAmpleurAmusantAnalyseAnaphoreAnarchieAnatomieAncienAne/antirAngleAngoisseAnguleuxAnimalAnnexerAnnonceAnnuelAnodinAnomalieAnonymeAnormalAntenneAntidoteAnxieuxApaiserApe/ritifAplanirApologieAppareilAppelerApporterAppuyerAquariumAqueducArbitreArbusteArdeurArdoiseArgentArlequinArmatureArmementArmoireArmureArpenterArracherArriverArroserArsenicArte/rielArticleAspectAsphalteAspirerAssautAsservirAssietteAssocierAssurerAsticotAstreAstuceAtelierAtomeAtriumAtroceAttaqueAttentifAttirerAttraperAubaineAubergeAudaceAudibleAugurerAuroreAutomneAutrucheAvalerAvancerAvariceAvenirAverseAveugleAviateurAvideAvionAviserAvoineAvouerAvrilAxialAxiomeBadgeBafouerBagageBaguetteBaignadeBalancerBalconBaleineBalisageBambinBancaireBandageBanlieueBannie-reBanquierBarbierBarilBaronBarqueBarrageBassinBastionBatailleBateauBatterieBaudrierBavarderBeletteBe/lierBeloteBe/ne/ficeBerceauBergerBerlineBermudaBesaceBesogneBe/tailBeurreBiberonBicycleBiduleBijouBilanBilingueBillardBinaireBiologieBiopsieBiotypeBiscuitBisonBistouriBitumeBizarreBlafardBlagueBlanchirBlessantBlinderBlondBloquerBlousonBobardBobineBoireBoiserBolideBonbonBondirBonheurBonifierBonusBordureBorneBotteBoucleBoueuxBougieBoulonBouquinBourseBoussoleBoutiqueBoxeurBrancheBrasierBraveBrebisBre-cheBreuvageBricolerBrigadeBrillantBriocheBriqueBrochureBroderBronzerBrousseBroyeurBrumeBrusqueBrutalBruyantBuffleBuissonBulletinBureauBurinBustierButinerButoirBuvableBuvetteCabanonCabineCachetteCadeauCadreCafe/ineCaillouCaissonCalculerCalepinCalibreCalmerCalomnieCalvaireCamaradeCame/raCamionCampagneCanalCanetonCanonCantineCanularCapableCaporalCapriceCapsuleCapterCapucheCarabineCarboneCaresserCaribouCarnageCarotteCarreauCartonCascadeCasierCasqueCassureCauserCautionCavalierCaverneCaviarCe/dilleCeintureCe/lesteCelluleCendrierCensurerCentralCercleCe/re/bralCeriseCernerCerveauCesserChagrinChaiseChaleurChambreChanceChapitreCharbonChasseurChatonChaussonChavirerChemiseChenilleChe/quierChercherChevalChienChiffreChignonChime-reChiotChlorureChocolatChoisirChoseChouetteChromeChuteCigareCigogneCimenterCine/maCintrerCirculerCirerCirqueCiterneCitoyenCitronCivilClaironClameurClaquerClasseClavierClientClignerClimatClivageClocheClonageCloporteCobaltCobraCocasseCocotierCoderCodifierCoffreCognerCohe/sionCoifferCoincerCole-reColibriCollineColmaterColonelCombatCome/dieCommandeCompactConcertConduireConfierCongelerConnoterConsonneContactConvexeCopainCopieCorailCorbeauCordageCornicheCorpusCorrectCorte-geCosmiqueCostumeCotonCoudeCoupureCourageCouteauCouvrirCoyoteCrabeCrainteCravateCrayonCre/atureCre/diterCre/meuxCreuserCrevetteCriblerCrierCristalCrite-reCroireCroquerCrotaleCrucialCruelCrypterCubiqueCueillirCuille-reCuisineCuivreCulminerCultiverCumulerCupideCuratifCurseurCyanureCycleCylindreCyniqueDaignerDamierDangerDanseurDauphinDe/battreDe/biterDe/borderDe/briderDe/butantDe/calerDe/cembreDe/chirerDe/ciderDe/clarerDe/corerDe/crireDe/cuplerDe/daleDe/ductifDe/esseDe/fensifDe/filerDe/frayerDe/gagerDe/givrerDe/glutirDe/graferDe/jeunerDe/liceDe/logerDemanderDemeurerDe/molirDe/nicherDe/nouerDentelleDe/nuderDe/partDe/penserDe/phaserDe/placerDe/poserDe/rangerDe/roberDe/sastreDescenteDe/sertDe/signerDe/sobe/irDessinerDestrierDe/tacherDe/testerDe/tourerDe/tresseDevancerDevenirDevinerDevoirDiableDialogueDiamantDicterDiffe/rerDige/rerDigitalDigneDiluerDimancheDiminuerDioxydeDirectifDirigerDiscuterDisposerDissiperDistanceDivertirDiviserDocileDocteurDogmeDoigtDomaineDomicileDompterDonateurDonjonDonnerDopamineDortoirDorureDosageDoseurDossierDotationDouanierDoubleDouceurDouterDoyenDragonDraperDresserDribblerDroitureDuperieDuplexeDurableDurcirDynastieE/blouirE/carterE/charpeE/chelleE/clairerE/clipseE/cloreE/cluseE/coleE/conomieE/corceE/couterE/craserE/cre/merE/crivainE/crouE/cumeE/cureuilE/difierE/duquerEffacerEffectifEffigieEffortEffrayerEffusionE/galiserE/garerE/jecterE/laborerE/largirE/lectronE/le/gantE/le/phantE/le-veE/ligibleE/litismeE/logeE/luciderE/luderEmballerEmbellirEmbryonE/meraudeE/missionEmmenerE/motionE/mouvoirEmpereurEmployerEmporterEmpriseE/mulsionEncadrerEnche-reEnclaveEncocheEndiguerEndosserEndroitEnduireE/nergieEnfanceEnfermerEnfouirEngagerEnginEngloberE/nigmeEnjamberEnjeuEnleverEnnemiEnnuyeuxEnrichirEnrobageEnseigneEntasserEntendreEntierEntourerEntraverE/nume/rerEnvahirEnviableEnvoyerEnzymeE/olienE/paissirE/pargneE/patantE/pauleE/picerieE/pide/mieE/pierE/pilogueE/pineE/pisodeE/pitapheE/poqueE/preuveE/prouverE/puisantE/querreE/quipeE/rigerE/rosionErreurE/ruptionEscalierEspadonEspe-ceEspie-gleEspoirEspritEsquiverEssayerEssenceEssieuEssorerEstimeEstomacEstradeE/tage-reE/talerE/tancheE/tatiqueE/teindreE/tendoirE/ternelE/thanolE/thiqueEthnieE/tirerE/tofferE/toileE/tonnantE/tourdirE/trangeE/troitE/tudeEuphorieE/valuerE/vasionE/ventailE/videnceE/viterE/volutifE/voquerExactExage/rerExaucerExcellerExcitantExclusifExcuseExe/cuterExempleExercerExhalerExhorterExigenceExilerExisterExotiqueExpe/dierExplorerExposerExprimerExquisExtensifExtraireExulterFableFabuleuxFacetteFacileFactureFaiblirFalaiseFameuxFamilleFarceurFarfeluFarineFaroucheFascinerFatalFatigueFauconFautifFaveurFavoriFe/brileFe/conderFe/de/rerFe/linFemmeFe/murFendoirFe/odalFermerFe/roceFerveurFestivalFeuilleFeutreFe/vrierFiascoFicelerFictifFide-leFigureFilatureFiletageFilie-reFilleulFilmerFilouFiltrerFinancerFinirFioleFirmeFissureFixerFlairerFlammeFlasqueFlatteurFle/auFle-cheFleurFlexionFloconFloreFluctuerFluideFluvialFolieFonderieFongibleFontaineForcerForgeronFormulerFortuneFossileFoudreFouge-reFouillerFoulureFourmiFragileFraiseFranchirFrapperFrayeurFre/gateFreinerFrelonFre/mirFre/ne/sieFre-reFriableFrictionFrissonFrivoleFroidFromageFrontalFrotterFruitFugitifFuiteFureurFurieuxFurtifFusionFuturGagnerGalaxieGalerieGambaderGarantirGardienGarnirGarrigueGazelleGazonGe/antGe/latineGe/luleGendarmeGe/ne/ralGe/nieGenouGentilGe/ologieGe/ome-treGe/raniumGermeGestuelGeyserGibierGiclerGirafeGivreGlaceGlaiveGlisserGlobeGloireGlorieuxGolfeurGommeGonflerGorgeGorilleGoudronGouffreGoulotGoupilleGourmandGoutteGraduelGraffitiGraineGrandGrappinGratuitGravirGrenatGriffureGrillerGrimperGrognerGronderGrotteGroupeGrugerGrutierGruye-reGue/pardGuerrierGuideGuimauveGuitareGustatifGymnasteGyrostatHabitudeHachoirHalteHameauHangarHannetonHaricotHarmonieHarponHasardHe/liumHe/matomeHerbeHe/rissonHermineHe/ronHe/siterHeureuxHibernerHibouHilarantHistoireHiverHomardHommageHomoge-neHonneurHonorerHonteuxHordeHorizonHorlogeHormoneHorribleHouleuxHousseHublotHuileuxHumainHumbleHumideHumourHurlerHydromelHygie-neHymneHypnoseIdylleIgnorerIguaneIlliciteIllusionImageImbiberImiterImmenseImmobileImmuableImpactImpe/rialImplorerImposerImprimerImputerIncarnerIncendieIncidentInclinerIncoloreIndexerIndiceInductifIne/ditIneptieInexactInfiniInfligerInformerInfusionInge/rerInhalerInhiberInjecterInjureInnocentInoculerInonderInscrireInsecteInsigneInsoliteInspirerInstinctInsulterIntactIntenseIntimeIntrigueIntuitifInutileInvasionInventerInviterInvoquerIroniqueIrradierIrre/elIrriterIsolerIvoireIvresseJaguarJaillirJambeJanvierJardinJaugerJauneJavelotJetableJetonJeudiJeunesseJoindreJoncherJonglerJoueurJouissifJournalJovialJoyauJoyeuxJubilerJugementJuniorJuponJuristeJusticeJuteuxJuve/nileKayakKimonoKiosqueLabelLabialLabourerLace/rerLactoseLaguneLaineLaisserLaitierLambeauLamelleLampeLanceurLangageLanterneLapinLargeurLarmeLaurierLavaboLavoirLectureLe/galLe/gerLe/gumeLessiveLettreLevierLexiqueLe/zardLiasseLibe/rerLibreLicenceLicorneLie-geLie-vreLigatureLigoterLigueLimerLimiteLimonadeLimpideLine/aireLingotLionceauLiquideLisie-reListerLithiumLitigeLittoralLivreurLogiqueLointainLoisirLombricLoterieLouerLourdLoutreLouveLoyalLubieLucideLucratifLueurLugubreLuisantLumie-reLunaireLundiLuronLutterLuxueuxMachineMagasinMagentaMagiqueMaigreMaillonMaintienMairieMaisonMajorerMalaxerMale/ficeMalheurMaliceMalletteMammouthMandaterManiableManquantManteauManuelMarathonMarbreMarchandMardiMaritimeMarqueurMarronMartelerMascotteMassifMate/rielMatie-reMatraqueMaudireMaussadeMauveMaximalMe/chantMe/connuMe/dailleMe/decinMe/diterMe/duseMeilleurMe/langeMe/lodieMembreMe/moireMenacerMenerMenhirMensongeMentorMercrediMe/riteMerleMessagerMesureMe/talMe/te/oreMe/thodeMe/tierMeubleMiaulerMicrobeMietteMignonMigrerMilieuMillionMimiqueMinceMine/ralMinimalMinorerMinuteMiracleMiroiterMissileMixteMobileModerneMoelleuxMondialMoniteurMonnaieMonotoneMonstreMontagneMonumentMoqueurMorceauMorsureMortierMoteurMotifMoucheMoufleMoulinMoussonMoutonMouvantMultipleMunitionMurailleMure-neMurmureMuscleMuse/umMusicienMutationMuterMutuelMyriadeMyrtilleMyste-reMythiqueNageurNappeNarquoisNarrerNatationNationNatureNaufrageNautiqueNavireNe/buleuxNectarNe/fasteNe/gationNe/gligerNe/gocierNeigeNerveuxNettoyerNeuroneNeutronNeveuNicheNickelNitrateNiveauNobleNocifNocturneNoirceurNoisetteNomadeNombreuxNommerNormatifNotableNotifierNotoireNourrirNouveauNovateurNovembreNoviceNuageNuancerNuireNuisibleNume/roNuptialNuqueNutritifObe/irObjectifObligerObscurObserverObstacleObtenirObturerOccasionOccuperOce/anOctobreOctroyerOctuplerOculaireOdeurOdorantOffenserOfficierOffrirOgiveOiseauOisillonOlfactifOlivierOmbrageOmettreOnctueuxOndulerOne/reuxOniriqueOpaleOpaqueOpe/rerOpinionOpportunOpprimerOpterOptiqueOrageuxOrangeOrbiteOrdonnerOreilleOrganeOrgueilOrificeOrnementOrqueOrtieOscillerOsmoseOssatureOtarieOuraganOursonOutilOutragerOuvrageOvationOxydeOxyge-neOzonePaisiblePalacePalmare-sPalourdePalperPanachePandaPangolinPaniquerPanneauPanoramaPantalonPapayePapierPapoterPapyrusParadoxeParcelleParesseParfumerParlerParoleParrainParsemerPartagerParureParvenirPassionPaste-quePaternelPatiencePatronPavillonPavoiserPayerPaysagePeignePeintrePelagePe/licanPellePelousePeluchePendulePe/ne/trerPe/niblePensifPe/nuriePe/pitePe/plumPerdrixPerforerPe/riodePermuterPerplexePersilPertePeserPe/talePetitPe/trirPeuplePharaonPhobiePhoquePhotonPhrasePhysiquePianoPicturalPie-cePierrePieuvrePilotePinceauPipettePiquerPiroguePiscinePistonPivoterPixelPizzaPlacardPlafondPlaisirPlanerPlaquePlastronPlateauPleurerPlexusPliagePlombPlongerPluiePlumagePochettePoe/siePoe-tePointePoirierPoissonPoivrePolairePolicierPollenPolygonePommadePompierPonctuelPonde/rerPoneyPortiquePositionPosse/derPosturePotagerPoteauPotionPoucePoulainPoumonPourprePoussinPouvoirPrairiePratiquePre/cieuxPre/direPre/fixePre/ludePre/nomPre/sencePre/textePre/voirPrimitifPrincePrisonPriverProble-meProce/derProdigeProfondProgre-sProieProjeterProloguePromenerPropreProspe-reProte/gerProuesseProverbePrudencePruneauPsychosePublicPuceronPuiserPulpePulsarPunaisePunitifPupitrePurifierPuzzlePyramideQuasarQuerelleQuestionQuie/tudeQuitterQuotientRacineRaconterRadieuxRagondinRaideurRaisinRalentirRallongeRamasserRapideRasageRatisserRavagerRavinRayonnerRe/actifRe/agirRe/aliserRe/animerRecevoirRe/citerRe/clamerRe/colterRecruterReculerRecyclerRe/digerRedouterRefaireRe/flexeRe/formerRefrainRefugeRe/galienRe/gionRe/glageRe/gulierRe/ite/rerRejeterRejouerRelatifReleverReliefRemarqueReme-deRemiseRemonterRemplirRemuerRenardRenfortReniflerRenoncerRentrerRenvoiReplierReporterRepriseReptileRequinRe/serveRe/sineuxRe/soudreRespectResterRe/sultatRe/tablirRetenirRe/ticuleRetomberRetracerRe/unionRe/ussirRevancheRevivreRe/volteRe/vulsifRichesseRideauRieurRigideRigolerRincerRiposterRisibleRisqueRituelRivalRivie-reRocheuxRomanceRompreRonceRondinRoseauRosierRotatifRotorRotuleRougeRouilleRouleauRoutineRoyaumeRubanRubisRucheRuelleRugueuxRuinerRuisseauRuserRustiqueRythmeSablerSaboterSabreSacocheSafariSagesseSaisirSaladeSaliveSalonSaluerSamediSanctionSanglierSarcasmeSardineSaturerSaugrenuSaumonSauterSauvageSavantSavonnerScalpelScandaleSce/le/ratSce/narioSceptreSche/maScienceScinderScoreScrutinSculpterSe/anceSe/cableSe/cherSecouerSe/cre/terSe/datifSe/duireSeigneurSe/jourSe/lectifSemaineSemblerSemenceSe/minalSe/nateurSensibleSentenceSe/parerSe/quenceSereinSergentSe/rieuxSerrureSe/rumServiceSe/sameSe/virSevrageSextupleSide/ralSie-cleSie/gerSifflerSigleSignalSilenceSiliciumSimpleSince-reSinistreSiphonSiropSismiqueSituerSkierSocialSocleSodiumSoigneuxSoldatSoleilSolitudeSolubleSombreSommeilSomnolerSondeSongeurSonnetteSonoreSorcierSortirSosieSottiseSoucieuxSoudureSouffleSouleverSoupapeSourceSoutirerSouvenirSpacieuxSpatialSpe/cialSphe-reSpiralStableStationSternumStimulusStipulerStrictStudieuxStupeurStylisteSublimeSubstratSubtilSubvenirSucce-sSucreSuffixeSugge/rerSuiveurSulfateSuperbeSupplierSurfaceSuricateSurmenerSurpriseSursautSurvieSuspectSyllabeSymboleSyme/trieSynapseSyntaxeSyste-meTabacTablierTactileTaillerTalentTalismanTalonnerTambourTamiserTangibleTapisTaquinerTarderTarifTartineTasseTatamiTatouageTaupeTaureauTaxerTe/moinTemporelTenailleTendreTeneurTenirTensionTerminerTerneTerribleTe/tineTexteThe-meThe/orieThe/rapieThoraxTibiaTie-deTimideTirelireTiroirTissuTitaneTitreTituberTobogganTole/rantTomateToniqueTonneauToponymeTorcheTordreTornadeTorpilleTorrentTorseTortueTotemToucherTournageTousserToxineTractionTraficTragiqueTrahirTrainTrancherTravailTre-fleTremperTre/sorTreuilTriageTribunalTricoterTrilogieTriompheTriplerTriturerTrivialTromboneTroncTropicalTroupeauTuileTulipeTumulteTunnelTurbineTuteurTutoyerTuyauTympanTyphonTypiqueTyranUbuesqueUltimeUltrasonUnanimeUnifierUnionUniqueUnitaireUniversUraniumUrbainUrticantUsageUsineUsuelUsureUtileUtopieVacarmeVaccinVagabondVagueVaillantVaincreVaisseauValableValiseVallonValveVampireVanilleVapeurVarierVaseuxVassalVasteVecteurVedetteVe/ge/talVe/hiculeVeinardVe/loceVendrediVe/ne/rerVengerVenimeuxVentouseVerdureVe/rinVernirVerrouVerserVertuVestonVe/te/ranVe/tusteVexantVexerViaducViandeVictoireVidangeVide/oVignetteVigueurVilainVillageVinaigreViolonVipe-reVirementVirtuoseVirusVisageViseurVisionVisqueuxVisuelVitalVitesseViticoleVitrineVivaceVivipareVocationVoguerVoileVoisinVoitureVolailleVolcanVoltigerVolumeVoraceVortexVoterVouloirVoyageVoyelleWagonXe/nonYachtZe-breZe/nithZesteZoologie";
20992
20992
  var wordlist = null;
20993
20993
  var lookup = {};
20994
- function dropDiacritic(word) {
20994
+ function dropDiacritic(word2) {
20995
20995
  wordlist_1.logger.checkNormalize();
20996
- return (0, strings_1.toUtf8String)(Array.prototype.filter.call((0, strings_1.toUtf8Bytes)(word.normalize("NFD").toLowerCase()), function(c) {
20996
+ return (0, strings_1.toUtf8String)(Array.prototype.filter.call((0, strings_1.toUtf8Bytes)(word2.normalize("NFD").toLowerCase()), function(c) {
20997
20997
  return c >= 65 && c <= 90 || c >= 97 && c <= 123;
20998
20998
  }));
20999
20999
  }
21000
- function expand(word) {
21000
+ function expand(word2) {
21001
21001
  var output = [];
21002
- Array.prototype.forEach.call((0, strings_1.toUtf8Bytes)(word), function(c) {
21002
+ Array.prototype.forEach.call((0, strings_1.toUtf8Bytes)(word2), function(c) {
21003
21003
  if (c === 47) {
21004
21004
  output.push(204);
21005
21005
  output.push(129);
@@ -21019,8 +21019,8 @@ var require_lang_fr = __commonJS({
21019
21019
  wordlist = words.replace(/([A-Z])/g, " $1").toLowerCase().substring(1).split(" ").map(function(w) {
21020
21020
  return expand(w);
21021
21021
  });
21022
- wordlist.forEach(function(word, index) {
21023
- lookup[dropDiacritic(word)] = index;
21022
+ wordlist.forEach(function(word2, index) {
21023
+ lookup[dropDiacritic(word2)] = index;
21024
21024
  });
21025
21025
  if (wordlist_1.Wordlist.check(lang) !== "0x51deb7ae009149dc61a6bd18a918eb7ac78d2775726c68e598b92d002519b045") {
21026
21026
  wordlist = null;
@@ -21038,9 +21038,9 @@ var require_lang_fr = __commonJS({
21038
21038
  loadWords(this);
21039
21039
  return wordlist[index];
21040
21040
  };
21041
- LangFr2.prototype.getWordIndex = function(word) {
21041
+ LangFr2.prototype.getWordIndex = function(word2) {
21042
21042
  loadWords(this);
21043
- return lookup[dropDiacritic(word)];
21043
+ return lookup[dropDiacritic(word2)];
21044
21044
  };
21045
21045
  return LangFr2;
21046
21046
  })(wordlist_1.Wordlist)
@@ -21097,8 +21097,8 @@ var require_lang_ja = __commonJS({
21097
21097
  ];
21098
21098
  var mapping = "~~AzB~X~a~KN~Q~D~S~C~G~E~Y~p~L~I~O~eH~g~V~hxyumi~~U~~Z~~v~~s~~dkoblPjfnqwMcRTr~W~~~F~~~~~Jt";
21099
21099
  var wordlist = null;
21100
- function hex(word) {
21101
- return (0, bytes_1.hexlify)((0, strings_1.toUtf8Bytes)(word));
21100
+ function hex(word2) {
21101
+ return (0, bytes_1.hexlify)((0, strings_1.toUtf8Bytes)(word2));
21102
21102
  }
21103
21103
  var KiYoKu = "0xe3818de38284e3818f";
21104
21104
  var KyoKu = "0xe3818de38283e3818f";
@@ -21114,10 +21114,10 @@ var require_lang_ja = __commonJS({
21114
21114
  transform[(0, strings_1.toUtf8String)([227, 129, 163])] = (0, strings_1.toUtf8String)([227, 129, 164]);
21115
21115
  transform[(0, strings_1.toUtf8String)([227, 130, 131])] = (0, strings_1.toUtf8String)([227, 130, 132]);
21116
21116
  transform[(0, strings_1.toUtf8String)([227, 130, 135])] = (0, strings_1.toUtf8String)([227, 130, 136]);
21117
- function normalize2(word2) {
21117
+ function normalize2(word3) {
21118
21118
  var result = "";
21119
- for (var i2 = 0; i2 < word2.length; i2++) {
21120
- var kana = word2[i2];
21119
+ for (var i2 = 0; i2 < word3.length; i2++) {
21120
+ var kana = word3[i2];
21121
21121
  var target = transform[kana];
21122
21122
  if (target === false) {
21123
21123
  continue;
@@ -21143,14 +21143,14 @@ var require_lang_ja = __commonJS({
21143
21143
  for (var length_1 = 3; length_1 <= 9; length_1++) {
21144
21144
  var d = data[length_1 - 3];
21145
21145
  for (var offset = 0; offset < d.length; offset += length_1) {
21146
- var word = [];
21146
+ var word2 = [];
21147
21147
  for (var i = 0; i < length_1; i++) {
21148
21148
  var k = mapping.indexOf(d[offset + i]);
21149
- word.push(227);
21150
- word.push(k & 64 ? 130 : 129);
21151
- word.push((k & 63) + 128);
21149
+ word2.push(227);
21150
+ word2.push(k & 64 ? 130 : 129);
21151
+ word2.push((k & 63) + 128);
21152
21152
  }
21153
- wordlist.push((0, strings_1.toUtf8String)(word));
21153
+ wordlist.push((0, strings_1.toUtf8String)(word2));
21154
21154
  }
21155
21155
  }
21156
21156
  wordlist.sort(sortJapanese);
@@ -21175,9 +21175,9 @@ var require_lang_ja = __commonJS({
21175
21175
  loadWords(this);
21176
21176
  return wordlist[index];
21177
21177
  };
21178
- LangJa2.prototype.getWordIndex = function(word) {
21178
+ LangJa2.prototype.getWordIndex = function(word2) {
21179
21179
  loadWords(this);
21180
- return wordlist.indexOf(word);
21180
+ return wordlist.indexOf(word2);
21181
21181
  };
21182
21182
  LangJa2.prototype.split = function(mnemonic) {
21183
21183
  wordlist_1.logger.checkNormalize();
@@ -21250,11 +21250,11 @@ var require_lang_ko = __commonJS({
21250
21250
  data.forEach(function(data2, length) {
21251
21251
  length += 4;
21252
21252
  for (var i = 0; i < data2.length; i += length) {
21253
- var word = "";
21253
+ var word2 = "";
21254
21254
  for (var j = 0; j < length; j++) {
21255
- word += getHangul(codes.indexOf(data2[i + j]));
21255
+ word2 += getHangul(codes.indexOf(data2[i + j]));
21256
21256
  }
21257
- wordlist.push(word);
21257
+ wordlist.push(word2);
21258
21258
  }
21259
21259
  });
21260
21260
  wordlist.sort();
@@ -21274,9 +21274,9 @@ var require_lang_ko = __commonJS({
21274
21274
  loadWords(this);
21275
21275
  return wordlist[index];
21276
21276
  };
21277
- LangKo2.prototype.getWordIndex = function(word) {
21277
+ LangKo2.prototype.getWordIndex = function(word2) {
21278
21278
  loadWords(this);
21279
- return wordlist.indexOf(word);
21279
+ return wordlist.indexOf(word2);
21280
21280
  };
21281
21281
  return LangKo2;
21282
21282
  })(wordlist_1.Wordlist)
@@ -21336,9 +21336,9 @@ var require_lang_it = __commonJS({
21336
21336
  loadWords(this);
21337
21337
  return wordlist[index];
21338
21338
  };
21339
- LangIt2.prototype.getWordIndex = function(word) {
21339
+ LangIt2.prototype.getWordIndex = function(word2) {
21340
21340
  loadWords(this);
21341
- return wordlist.indexOf(word);
21341
+ return wordlist.indexOf(word2);
21342
21342
  };
21343
21343
  return LangIt2;
21344
21344
  })(wordlist_1.Wordlist)
@@ -21425,9 +21425,9 @@ var require_lang_zh = __commonJS({
21425
21425
  loadWords(this);
21426
21426
  return wordlist[this.locale][index];
21427
21427
  };
21428
- LangZh2.prototype.getWordIndex = function(word) {
21428
+ LangZh2.prototype.getWordIndex = function(word2) {
21429
21429
  loadWords(this);
21430
- return wordlist[this.locale].indexOf(word);
21430
+ return wordlist[this.locale].indexOf(word2);
21431
21431
  };
21432
21432
  LangZh2.prototype.split = function(mnemonic) {
21433
21433
  mnemonic = mnemonic.replace(/(?:\u3000| )+/g, "");
@@ -21610,9 +21610,9 @@ var require_lib23 = __commonJS({
21610
21610
  if (index > 4294967295) {
21611
21611
  throw new Error("invalid index - " + String(index));
21612
21612
  }
21613
- var path3 = this.path;
21614
- if (path3) {
21615
- path3 += "/" + (index & ~HardenedBit);
21613
+ var path4 = this.path;
21614
+ if (path4) {
21615
+ path4 += "/" + (index & ~HardenedBit);
21616
21616
  }
21617
21617
  var data = new Uint8Array(37);
21618
21618
  if (index & HardenedBit) {
@@ -21620,8 +21620,8 @@ var require_lib23 = __commonJS({
21620
21620
  throw new Error("cannot derive child of neutered node");
21621
21621
  }
21622
21622
  data.set((0, bytes_1.arrayify)(this.privateKey), 1);
21623
- if (path3) {
21624
- path3 += "'";
21623
+ if (path4) {
21624
+ path4 += "'";
21625
21625
  }
21626
21626
  } else {
21627
21627
  data.set((0, bytes_1.arrayify)(this.publicKey));
@@ -21640,21 +21640,21 @@ var require_lib23 = __commonJS({
21640
21640
  var ek = new signing_key_1.SigningKey((0, bytes_1.hexlify)(IL));
21641
21641
  Ki = ek._addPoint(this.publicKey);
21642
21642
  }
21643
- var mnemonicOrPath = path3;
21643
+ var mnemonicOrPath = path4;
21644
21644
  var srcMnemonic = this.mnemonic;
21645
21645
  if (srcMnemonic) {
21646
21646
  mnemonicOrPath = Object.freeze({
21647
21647
  phrase: srcMnemonic.phrase,
21648
- path: path3,
21648
+ path: path4,
21649
21649
  locale: srcMnemonic.locale || "en"
21650
21650
  });
21651
21651
  }
21652
21652
  return new HDNode2(_constructorGuard, ki, Ki, this.fingerprint, bytes32(IR), index, this.depth + 1, mnemonicOrPath);
21653
21653
  };
21654
- HDNode2.prototype.derivePath = function(path3) {
21655
- var components = path3.split("/");
21654
+ HDNode2.prototype.derivePath = function(path4) {
21655
+ var components = path4.split("/");
21656
21656
  if (components.length === 0 || components[0] === "m" && this.depth !== 0) {
21657
- throw new Error("invalid path - " + path3);
21657
+ throw new Error("invalid path - " + path4);
21658
21658
  }
21659
21659
  if (components[0] === "m") {
21660
21660
  components.shift();
@@ -21923,13 +21923,13 @@ var require_aes_js = __commonJS({
21923
21923
  targetArray.set(sourceArray, targetStart);
21924
21924
  }
21925
21925
  var convertUtf8 = /* @__PURE__ */ (function() {
21926
- function toBytes(text4) {
21926
+ function toBytes(text6) {
21927
21927
  var result = [], i = 0;
21928
- text4 = encodeURI(text4);
21929
- while (i < text4.length) {
21930
- var c = text4.charCodeAt(i++);
21928
+ text6 = encodeURI(text6);
21929
+ while (i < text6.length) {
21930
+ var c = text6.charCodeAt(i++);
21931
21931
  if (c === 37) {
21932
- result.push(parseInt(text4.substr(i, 2), 16));
21932
+ result.push(parseInt(text6.substr(i, 2), 16));
21933
21933
  i += 2;
21934
21934
  } else {
21935
21935
  result.push(c);
@@ -21960,10 +21960,10 @@ var require_aes_js = __commonJS({
21960
21960
  };
21961
21961
  })();
21962
21962
  var convertHex = /* @__PURE__ */ (function() {
21963
- function toBytes(text4) {
21963
+ function toBytes(text6) {
21964
21964
  var result = [];
21965
- for (var i = 0; i < text4.length; i += 2) {
21966
- result.push(parseInt(text4.substr(i, 2), 16));
21965
+ for (var i = 0; i < text6.length; i += 2) {
21966
+ result.push(parseInt(text6.substr(i, 2), 16));
21967
21967
  }
21968
21968
  return result;
21969
21969
  }
@@ -22460,9 +22460,9 @@ var require_utils4 = __commonJS({
22460
22460
  return (0, bytes_1.arrayify)(password);
22461
22461
  }
22462
22462
  exports.getPassword = getPassword;
22463
- function searchPath(object, path3) {
22463
+ function searchPath(object, path4) {
22464
22464
  var currentChild = object;
22465
- var comps = path3.toLowerCase().split("/");
22465
+ var comps = path4.toLowerCase().split("/");
22466
22466
  for (var i = 0; i < comps.length; i++) {
22467
22467
  var matchingChild = null;
22468
22468
  for (var key in currentChild) {
@@ -23297,12 +23297,12 @@ var require_keystore = __commonJS({
23297
23297
  var mnemonicIv = (0, utils_1.looseArrayify)((0, utils_1.searchPath)(data, "x-ethers/mnemonicCounter"));
23298
23298
  var mnemonicCounter = new aes_js_1.default.Counter(mnemonicIv);
23299
23299
  var mnemonicAesCtr = new aes_js_1.default.ModeOfOperation.ctr(mnemonicKey, mnemonicCounter);
23300
- var path3 = (0, utils_1.searchPath)(data, "x-ethers/path") || hdnode_1.defaultPath;
23300
+ var path4 = (0, utils_1.searchPath)(data, "x-ethers/path") || hdnode_1.defaultPath;
23301
23301
  var locale = (0, utils_1.searchPath)(data, "x-ethers/locale") || "en";
23302
23302
  var entropy = (0, bytes_1.arrayify)(mnemonicAesCtr.decrypt(mnemonicCiphertext));
23303
23303
  try {
23304
23304
  var mnemonic = (0, hdnode_1.entropyToMnemonic)(entropy, locale);
23305
- var node = hdnode_1.HDNode.fromMnemonic(mnemonic, null, locale).derivePath(path3);
23305
+ var node = hdnode_1.HDNode.fromMnemonic(mnemonic, null, locale).derivePath(path4);
23306
23306
  if (node.privateKey != account.privateKey) {
23307
23307
  throw new Error("mnemonic mismatch");
23308
23308
  }
@@ -23412,12 +23412,12 @@ var require_keystore = __commonJS({
23412
23412
  var privateKey = (0, bytes_1.arrayify)(account.privateKey);
23413
23413
  var passwordBytes = (0, utils_1.getPassword)(password);
23414
23414
  var entropy = null;
23415
- var path3 = null;
23415
+ var path4 = null;
23416
23416
  var locale = null;
23417
23417
  if (hasMnemonic(account)) {
23418
23418
  var srcMnemonic = account.mnemonic;
23419
23419
  entropy = (0, bytes_1.arrayify)((0, hdnode_1.mnemonicToEntropy)(srcMnemonic.phrase, srcMnemonic.locale || "en"));
23420
- path3 = srcMnemonic.path || hdnode_1.defaultPath;
23420
+ path4 = srcMnemonic.path || hdnode_1.defaultPath;
23421
23421
  locale = srcMnemonic.locale || "en";
23422
23422
  }
23423
23423
  var client = options.client;
@@ -23503,7 +23503,7 @@ var require_keystore = __commonJS({
23503
23503
  gethFilename: "UTC--" + timestamp + "--" + data.address,
23504
23504
  mnemonicCounter: (0, bytes_1.hexlify)(mnemonicIv).substring(2),
23505
23505
  mnemonicCiphertext: (0, bytes_1.hexlify)(mnemonicCiphertext).substring(2),
23506
- path: path3,
23506
+ path: path4,
23507
23507
  locale,
23508
23508
  version: "0.1"
23509
23509
  };
@@ -23894,11 +23894,11 @@ var require_lib26 = __commonJS({
23894
23894
  Wallet2.fromEncryptedJsonSync = function(json, password) {
23895
23895
  return new Wallet2((0, json_wallets_1.decryptJsonWalletSync)(json, password));
23896
23896
  };
23897
- Wallet2.fromMnemonic = function(mnemonic, path3, wordlist) {
23898
- if (!path3) {
23899
- path3 = hdnode_1.defaultPath;
23897
+ Wallet2.fromMnemonic = function(mnemonic, path4, wordlist) {
23898
+ if (!path4) {
23899
+ path4 = hdnode_1.defaultPath;
23900
23900
  }
23901
- return new Wallet2(hdnode_1.HDNode.fromMnemonic(mnemonic, null, wordlist).derivePath(path3));
23901
+ return new Wallet2(hdnode_1.HDNode.fromMnemonic(mnemonic, null, wordlist).derivePath(path4));
23902
23902
  };
23903
23903
  return Wallet2;
23904
23904
  })(abstract_signer_1.Signer)
@@ -32137,7 +32137,7 @@ var require_websocket_server = __commonJS({
32137
32137
  const ws = new WebSocket(null);
32138
32138
  let protocol = req.headers["sec-websocket-protocol"];
32139
32139
  if (protocol) {
32140
- protocol = protocol.split(",").map(trim8);
32140
+ protocol = protocol.split(",").map(trim9);
32141
32141
  if (this.options.handleProtocols) {
32142
32142
  protocol = this.options.handleProtocols(protocol, req);
32143
32143
  } else {
@@ -32206,7 +32206,7 @@ var require_websocket_server = __commonJS({
32206
32206
  socket.removeListener("error", socketOnError);
32207
32207
  socket.destroy();
32208
32208
  }
32209
- function trim8(str) {
32209
+ function trim9(str) {
32210
32210
  return str.trim();
32211
32211
  }
32212
32212
  }
@@ -34673,13 +34673,13 @@ var require_ipc_provider = __commonJS({
34673
34673
  /** @class */
34674
34674
  (function(_super) {
34675
34675
  __extends(IpcProvider2, _super);
34676
- function IpcProvider2(path3, network) {
34676
+ function IpcProvider2(path4, network) {
34677
34677
  var _this = this;
34678
- if (path3 == null) {
34678
+ if (path4 == null) {
34679
34679
  logger.throwError("missing path", logger_1.Logger.errors.MISSING_ARGUMENT, { arg: "path" });
34680
34680
  }
34681
- _this = _super.call(this, "ipc://" + path3, network) || this;
34682
- (0, properties_1.defineReadOnly)(_this, "path", path3);
34681
+ _this = _super.call(this, "ipc://" + path4, network) || this;
34682
+ (0, properties_1.defineReadOnly)(_this, "path", path4);
34683
34683
  return _this;
34684
34684
  }
34685
34685
  IpcProvider2.prototype.send = function(method, params) {
@@ -35278,21 +35278,21 @@ var require_web3_provider = __commonJS({
35278
35278
  if (provider == null) {
35279
35279
  logger.throwArgumentError("missing provider", "provider", provider);
35280
35280
  }
35281
- var path3 = null;
35281
+ var path4 = null;
35282
35282
  var jsonRpcFetchFunc = null;
35283
35283
  var subprovider = null;
35284
35284
  if (typeof provider === "function") {
35285
- path3 = "unknown:";
35285
+ path4 = "unknown:";
35286
35286
  jsonRpcFetchFunc = provider;
35287
35287
  } else {
35288
- path3 = provider.host || provider.path || "";
35289
- if (!path3 && provider.isMetaMask) {
35290
- path3 = "metamask";
35288
+ path4 = provider.host || provider.path || "";
35289
+ if (!path4 && provider.isMetaMask) {
35290
+ path4 = "metamask";
35291
35291
  }
35292
35292
  subprovider = provider;
35293
35293
  if (provider.request) {
35294
- if (path3 === "") {
35295
- path3 = "eip-1193:";
35294
+ if (path4 === "") {
35295
+ path4 = "eip-1193:";
35296
35296
  }
35297
35297
  jsonRpcFetchFunc = buildEip1193Fetcher(provider);
35298
35298
  } else if (provider.sendAsync) {
@@ -35302,11 +35302,11 @@ var require_web3_provider = __commonJS({
35302
35302
  } else {
35303
35303
  logger.throwArgumentError("unsupported provider", "provider", provider);
35304
35304
  }
35305
- if (!path3) {
35306
- path3 = "unknown:";
35305
+ if (!path4) {
35306
+ path4 = "unknown:";
35307
35307
  }
35308
35308
  }
35309
- _this = _super.call(this, path3, network) || this;
35309
+ _this = _super.call(this, path4, network) || this;
35310
35310
  (0, properties_1.defineReadOnly)(_this, "jsonRpcFetchFunc", jsonRpcFetchFunc);
35311
35311
  (0, properties_1.defineReadOnly)(_this, "provider", subprovider);
35312
35312
  return _this;
@@ -36406,15 +36406,15 @@ var SETTINGS = Object.freeze({
36406
36406
  var MAX_LABEL_LENGTH = 80;
36407
36407
  var trim = (value) => String(value ?? "").trim();
36408
36408
  var normalizeLabel = (value, field) => {
36409
- const text4 = trim(value).replace(/\s+/g, " ");
36410
- if (text4.length > MAX_LABEL_LENGTH) throw new Error(`${field} must be ${MAX_LABEL_LENGTH} characters or fewer.`);
36411
- return text4;
36409
+ const text6 = trim(value).replace(/\s+/g, " ");
36410
+ if (text6.length > MAX_LABEL_LENGTH) throw new Error(`${field} must be ${MAX_LABEL_LENGTH} characters or fewer.`);
36411
+ return text6;
36412
36412
  };
36413
36413
  var normalizeHttpOrigin = (value, field) => {
36414
- const text4 = trim(value);
36414
+ const text6 = trim(value);
36415
36415
  let parsed;
36416
36416
  try {
36417
- parsed = new URL(text4);
36417
+ parsed = new URL(text6);
36418
36418
  } catch {
36419
36419
  throw new Error(`${field} must be an http(s) origin.`);
36420
36420
  }
@@ -36425,11 +36425,11 @@ var normalizeHttpOrigin = (value, field) => {
36425
36425
  };
36426
36426
  var isLocalUrl = (url) => ["localhost", "127.0.0.1", "[::1]"].includes(url.hostname);
36427
36427
  var normalizeRpcUrl = (value, allowLocal) => {
36428
- const text4 = trim(value);
36429
- if (!text4) return "";
36428
+ const text6 = trim(value);
36429
+ if (!text6) return "";
36430
36430
  let parsed;
36431
36431
  try {
36432
- parsed = new URL(text4);
36432
+ parsed = new URL(text6);
36433
36433
  } catch {
36434
36434
  throw new Error("CE_MCP_RPC_URL must be an https URL.");
36435
36435
  }
@@ -36494,13 +36494,22 @@ var ensureStateDir = async (stateDir) => {
36494
36494
  var writeOwnerOnlyJson = async (filePath, value, { exclusive = false } = {}) => {
36495
36495
  const body = `${JSON.stringify(value, null, 2)}
36496
36496
  `;
36497
- if (exclusive) {
36498
- await fs.writeFile(filePath, body, { mode: OWNER_ONLY_FILE, flag: "wx" });
36499
- return;
36500
- }
36501
36497
  const temporary = `${filePath}.${process.pid}.${crypto.randomBytes(6).toString("hex")}.tmp`;
36502
36498
  await fs.writeFile(temporary, body, { mode: OWNER_ONLY_FILE, flag: "wx" });
36503
- await fs.rename(temporary, filePath);
36499
+ try {
36500
+ if (exclusive) {
36501
+ try {
36502
+ await fs.link(temporary, filePath);
36503
+ } catch (error) {
36504
+ if (!["EPERM", "ENOTSUP", "EXDEV"].includes(error?.code)) throw error;
36505
+ await fs.writeFile(filePath, body, { mode: OWNER_ONLY_FILE, flag: "wx" });
36506
+ }
36507
+ } else {
36508
+ await fs.rename(temporary, filePath);
36509
+ }
36510
+ } finally {
36511
+ await fs.rm(temporary, { force: true });
36512
+ }
36504
36513
  };
36505
36514
  var readKeyFile = async (keyPath) => {
36506
36515
  const info = await fs.lstat(keyPath);
@@ -36631,9 +36640,9 @@ var DIAGNOSTICS = /\[ See: |\((?=\w+=)|\b(?:requestBody|body|url|transaction|dat
36631
36640
  var URLS = /\b[a-z][\w+.-]*:\/\/[^\s"'`]+/gi;
36632
36641
  var hostOnly = (url) => /<\w+>/.test(url) ? url : url.replace(/^([^:]+:\/\/)(?:[^/?#]*@)?([^/?#]*)[\s\S]*$/, "$1$2");
36633
36642
  var describeError = (error) => {
36634
- const text4 = String(error?.message || error || "").slice(0, MAX_ERROR_LENGTH);
36635
- const cut = text4.search(DIAGNOSTICS);
36636
- return (cut < 0 ? text4 : text4.slice(0, cut)).trimEnd().replace(URLS, hostOnly) || "Unknown error.";
36643
+ const text6 = String(error?.message || error || "").slice(0, MAX_ERROR_LENGTH);
36644
+ const cut = text6.search(DIAGNOSTICS);
36645
+ return (cut < 0 ? text6 : text6.slice(0, cut)).trimEnd().replace(URLS, hostOnly) || "Unknown error.";
36637
36646
  };
36638
36647
  var DEFAULT_TOOL_TIMEOUT_MS = 15 * 60 * 1e3;
36639
36648
  var createMcpServer = ({
@@ -36656,8 +36665,8 @@ var createMcpServer = ({
36656
36665
  ...annotations ? { annotations } : {}
36657
36666
  }));
36658
36667
  const toolResult = (value, isError = false) => {
36659
- const text4 = typeof value === "string" ? value : JSON.stringify(value, null, 2);
36660
- const result = { content: [{ type: "text", text: text4 }] };
36668
+ const text6 = typeof value === "string" ? value : JSON.stringify(value, null, 2);
36669
+ const result = { content: [{ type: "text", text: text6 }] };
36661
36670
  if (!isError && isRecord2(value) && protocolVersion >= STRUCTURED_CONTENT_SINCE) {
36662
36671
  result.structuredContent = value;
36663
36672
  }
@@ -36752,11 +36761,11 @@ var createMcpServer = ({
36752
36761
  }
36753
36762
  };
36754
36763
  const handleLine = async (line) => {
36755
- const text4 = String(line || "").trim();
36756
- if (!text4) return "";
36764
+ const text6 = String(line || "").trim();
36765
+ if (!text6) return "";
36757
36766
  let decoded;
36758
36767
  try {
36759
- decoded = JSON.parse(text4);
36768
+ decoded = JSON.parse(text6);
36760
36769
  } catch {
36761
36770
  return JSON.stringify(errorResponse(null, PARSE_ERROR, "Parse error."));
36762
36771
  }
@@ -36905,6 +36914,7 @@ var createTestEthRequester = ({
36905
36914
  paid = await ctx.client.request("/", {
36906
36915
  method: "POST",
36907
36916
  auth: true,
36917
+ signal,
36908
36918
  headers: { "X-Session-Slug": ctx.info.slug },
36909
36919
  body: { action: "request_test_eth", to: wallet.address }
36910
36920
  });
@@ -36961,6 +36971,17 @@ import { createHash, randomUUID as randomUUID2 } from "node:crypto";
36961
36971
  // mcp/lib/registrySession.mjs
36962
36972
  var import_ethers5 = __toESM(require_lib32(), 1);
36963
36973
 
36974
+ // shared/responseReadWindow.mjs
36975
+ var responsePairKey = (responder, id) => `${String(responder || "").toLowerCase()}|${String(id || "").toLowerCase()}`;
36976
+ var responseReadWindowOptions = (window2, responder, id) => window2 ? {
36977
+ _responseReadWindow: window2,
36978
+ blockTag: window2.laterPairs && !window2.laterPairs.has(responsePairKey(responder, id)) ? window2.unchangedBlockTag : window2.blockTag
36979
+ } : {};
36980
+ var historicalResponseReadError = (error, blockTag) => Object.assign(
36981
+ new Error(`Response state at block ${String(blockTag)} is unavailable: ${error instanceof Error ? error.message : String(error)}`),
36982
+ { code: "RESPONSE_HISTORY_UNAVAILABLE", retryable: true, blockTag, cause: error }
36983
+ );
36984
+
36964
36985
  // client/src/variables/contracts.json
36965
36986
  var contracts_default = {
36966
36987
  sessionRegistryAddresses: {
@@ -38202,40 +38223,6 @@ function summarizeQuadraticAllocations(responses, question) {
38202
38223
  return { options, totalResponders, excludedResponses };
38203
38224
  }
38204
38225
 
38205
- // shared/questions/questionId.mjs
38206
- var validOptions = (options) => Array.isArray(options) ? options.filter((o) => o && o.trim() !== "") : [];
38207
- var legacyPreimage = (type, prompt, options, singleSelect, voiceCredits) => {
38208
- let preimage = `${type}:${(prompt || "").trim().toLowerCase()}`;
38209
- const validOpts = validOptions(options);
38210
- if (type === "multichoice") {
38211
- if (validOpts.length > 0)
38212
- preimage += `:${validOpts.map((o) => o.trim()).join(",").toLowerCase()}`;
38213
- if (singleSelect) preimage += ":single";
38214
- }
38215
- if (type === "quadratic") {
38216
- preimage += `:${JSON.stringify(validOpts.map((option) => option.trim().toLowerCase()))}:${voiceCredits}`;
38217
- }
38218
- return preimage;
38219
- };
38220
- var legacyIsAmbiguous = (type, options, singleSelect) => {
38221
- if (type !== "multichoice") return false;
38222
- const labels = validOptions(options).map((o) => o.trim().toLowerCase());
38223
- return labels.length === 0 || labels.some((label) => label.includes(":") || label.includes(",")) || !singleSelect && labels.length === 1 && labels[0] === "single";
38224
- };
38225
- var v2Text = (text4) => (text4 || "").trim().toLowerCase().normalize("NFC");
38226
- var v2Preimage = (type, prompt, options, singleSelect) => JSON.stringify(["ce-question-id", 2, type, v2Text(prompt), validOptions(options).map(v2Text), !!singleSelect]);
38227
- var createQuestionIdDerivation = (ethers7) => {
38228
- const { id: hash } = ethers7.utils;
38229
- const generateQuestionId2 = (type, prompt, options = [], singleSelect = false, voiceCredits = 99) => hash(
38230
- legacyIsAmbiguous(type, options, singleSelect) ? v2Preimage(type, prompt, options, singleSelect) : legacyPreimage(type, prompt, options, singleSelect, voiceCredits)
38231
- );
38232
- const questionIdMatchesContent2 = (id, { type, prompt, options = [], singleSelect = false, voiceCredits = 99 } = {}) => {
38233
- const wanted = String(id).toLowerCase();
38234
- return hash(legacyPreimage(type, prompt, options, singleSelect, voiceCredits)) === wanted || type === "multichoice" && hash(v2Preimage(type, prompt, options, singleSelect)) === wanted;
38235
- };
38236
- return Object.freeze({ generateQuestionId: generateQuestionId2, questionIdMatchesContent: questionIdMatchesContent2 });
38237
- };
38238
-
38239
38226
  // shared/questions/ratingScale.mjs
38240
38227
  var trim2 = (value) => String(value == null ? "" : value).trim();
38241
38228
  var isObj = (value) => !!value && typeof value === "object" && !Array.isArray(value);
@@ -38290,39 +38277,41 @@ var normalizeRatingScale = (question = {}) => {
38290
38277
  )
38291
38278
  };
38292
38279
  };
38280
+ var DEFAULT_RATING_SCALE = Object.freeze({ min: 0, max: 10, minLabel: "0", maxLabel: "10" });
38281
+ var ratingStepFor = (question = {}) => {
38282
+ const source = [question.scale, question.ratingScale].find((record) => isObj(record) && recordHasRatingScaleMetadata(record)) || question;
38283
+ const step = Number(source.step);
38284
+ return Number.isFinite(step) && step > 0 ? step : 1;
38285
+ };
38286
+ var decimalPlaces = (value) => {
38287
+ const [coefficient, exponent = "0"] = String(value).split("e");
38288
+ return Math.max(0, (coefficient.split(".")[1]?.length || 0) - Number(exponent));
38289
+ };
38290
+ var normalizeRatingAnswer = (value, question = {}) => {
38291
+ if (typeof value !== "number" && typeof value !== "string") return null;
38292
+ if (typeof value === "string" && value.trim() === "") return null;
38293
+ const number = Number(value);
38294
+ const { min, max } = normalizeRatingScale(question) || DEFAULT_RATING_SCALE;
38295
+ const step = ratingStepFor(question);
38296
+ const index = (number - min) / step;
38297
+ if (!Number.isFinite(number) || number < min || number > max || !Number.isFinite(index) || Math.abs(index - Math.round(index)) > 1e-9) return null;
38298
+ const precision = Math.min(100, Math.max(decimalPlaces(step), decimalPlaces(min)));
38299
+ return Number((min + Math.round(index) * step).toFixed(precision));
38300
+ };
38293
38301
 
38294
- // mcp/lib/records.mjs
38302
+ // shared/questions/answerValue.mjs
38295
38303
  var QUESTION_TYPES = Object.freeze(["binary", "rating", "multichoice", "quadratic", "freeform"]);
38296
38304
  var BINARY_ANSWERS = Object.freeze(["Agree", "Unsure", "Disagree"]);
38297
- var MAX_PROMPT_LENGTH = 1e3;
38298
- var MAX_OPTION_LENGTH = 200;
38299
- var MAX_OPTIONS = 12;
38300
- var MAX_TAGS = 10;
38301
- var MAX_TAG_LENGTH = 40;
38302
38305
  var MAX_FREEFORM_LENGTH = 8e3;
38303
- var MAX_COMMENT_LENGTH = 4e3;
38304
38306
  var trim3 = (value) => typeof value === "string" ? value.trim() : typeof value === "number" ? String(value) : "";
38305
- var isRecord3 = (value) => !!value && typeof value === "object" && !Array.isArray(value);
38306
38307
  var fail = (error) => ({ ok: false, error });
38307
- var { generateQuestionId, questionIdMatchesContent } = createQuestionIdDerivation(import_ethers3.ethers);
38308
- var ratingScaleFor = (question = {}) => normalizeRatingScale(question) || { min: 0, max: 10, minLabel: "0", maxLabel: "10" };
38308
+ var ratingScaleFor = (question = {}) => ({ ...normalizeRatingScale(question) || DEFAULT_RATING_SCALE, step: ratingStepFor(question) });
38309
38309
  var optionsOf = (question) => Array.isArray(question.options) ? question.options.filter((option) => typeof option === "string") : [];
38310
38310
  var isSingleSelect = (question) => question.singleSelect === true || question.oneSelectionOnly === true || question.singleChoice === true;
38311
- var isLockedQuestion = (question) => question?.locked === true || !!question?.promptEncrypted || !!question?.encryption && typeof question.encryption === "object" || typeof question?.prompt === "string" && question.prompt.trim() === "[encrypted]";
38312
- var normalizeRecruitmentSource = (value) => {
38313
- const normalized2 = (typeof value === "string" ? value : "").trim().replace(/\s+/g, "-").slice(0, 128);
38314
- return /^[a-zA-Z0-9][a-zA-Z0-9._:-]{0,127}$/.test(normalized2) ? normalized2 : "";
38315
- };
38316
38311
  var matchOption = (options, value) => {
38317
38312
  const wanted = trim3(value).toLowerCase();
38318
38313
  return options.find((option) => option.trim().toLowerCase() === wanted);
38319
38314
  };
38320
- var readScore = (value, field) => {
38321
- if (value === void 0 || value === null || value === "") return { ok: true, value: null };
38322
- const number = Number(value);
38323
- if (!Number.isInteger(number) || number < 0 || number > 10) return fail(`${field} must be a whole number from 0 to 10.`);
38324
- return { ok: true, value: number };
38325
- };
38326
38315
  var normalizeAnswerValue = (question = {}, value) => {
38327
38316
  switch (question.type) {
38328
38317
  case "binary": {
@@ -38331,9 +38320,9 @@ var normalizeAnswerValue = (question = {}, value) => {
38331
38320
  }
38332
38321
  case "rating": {
38333
38322
  const scale = ratingScaleFor(question);
38334
- const number = typeof value === "string" && trim3(value) !== "" ? Number(value) : value;
38335
- if (!Number.isInteger(number) || number < scale.min || number > scale.max) {
38336
- return fail(`Rating answers must be a whole number from ${scale.min} to ${scale.max}.`);
38323
+ const number = normalizeRatingAnswer(value, question);
38324
+ if (number === null) {
38325
+ return fail(`Rating answers must be from ${scale.min} to ${scale.max} in increments of ${scale.step} from ${scale.min}.`);
38337
38326
  }
38338
38327
  return { ok: true, value: number };
38339
38328
  }
@@ -38361,15 +38350,72 @@ var normalizeAnswerValue = (question = {}, value) => {
38361
38350
  return { ok: true, value: votes };
38362
38351
  }
38363
38352
  case "freeform": {
38364
- const text4 = trim3(value);
38365
- if (!text4) return fail("Freeform answers must be non-empty text.");
38366
- if (text4.length > MAX_FREEFORM_LENGTH) return fail(`Freeform answers must be ${MAX_FREEFORM_LENGTH} characters or fewer.`);
38367
- return { ok: true, value: text4 };
38353
+ const text6 = trim3(value);
38354
+ if (!text6) return fail("Freeform answers must be non-empty text.");
38355
+ if (text6.length > MAX_FREEFORM_LENGTH) return fail(`Freeform answers must be ${MAX_FREEFORM_LENGTH} characters or fewer.`);
38356
+ return { ok: true, value: text6 };
38368
38357
  }
38369
38358
  default:
38370
38359
  return fail(`Unsupported question type "${trim3(question.type)}".`);
38371
38360
  }
38372
38361
  };
38362
+
38363
+ // shared/questions/questionId.mjs
38364
+ var validOptions = (options) => Array.isArray(options) ? options.filter((o) => o && o.trim() !== "") : [];
38365
+ var legacyPreimage = (type, prompt, options, singleSelect, voiceCredits) => {
38366
+ let preimage = `${type}:${(prompt || "").trim().toLowerCase()}`;
38367
+ const validOpts = validOptions(options);
38368
+ if (type === "multichoice") {
38369
+ if (validOpts.length > 0)
38370
+ preimage += `:${validOpts.map((o) => o.trim()).join(",").toLowerCase()}`;
38371
+ if (singleSelect) preimage += ":single";
38372
+ }
38373
+ if (type === "quadratic") {
38374
+ preimage += `:${JSON.stringify(validOpts.map((option) => option.trim().toLowerCase()))}:${voiceCredits}`;
38375
+ }
38376
+ return preimage;
38377
+ };
38378
+ var legacyIsAmbiguous = (type, options, singleSelect) => {
38379
+ if (type !== "multichoice") return false;
38380
+ const labels = validOptions(options).map((o) => o.trim().toLowerCase());
38381
+ return labels.length === 0 || labels.some((label) => label.includes(":") || label.includes(",")) || !singleSelect && labels.length === 1 && labels[0] === "single";
38382
+ };
38383
+ var v2Text = (text6) => (text6 || "").trim().toLowerCase().normalize("NFC");
38384
+ var v2Preimage = (type, prompt, options, singleSelect) => JSON.stringify(["ce-question-id", 2, type, v2Text(prompt), validOptions(options).map(v2Text), !!singleSelect]);
38385
+ var createQuestionIdDerivation = (ethers7) => {
38386
+ const { id: hash } = ethers7.utils;
38387
+ const generateQuestionId2 = (type, prompt, options = [], singleSelect = false, voiceCredits = 99) => hash(
38388
+ legacyIsAmbiguous(type, options, singleSelect) ? v2Preimage(type, prompt, options, singleSelect) : legacyPreimage(type, prompt, options, singleSelect, voiceCredits)
38389
+ );
38390
+ const questionIdMatchesContent2 = (id, { type, prompt, options = [], singleSelect = false, voiceCredits = 99 } = {}) => {
38391
+ const wanted = String(id).toLowerCase();
38392
+ return hash(legacyPreimage(type, prompt, options, singleSelect, voiceCredits)) === wanted || type === "multichoice" && hash(v2Preimage(type, prompt, options, singleSelect)) === wanted;
38393
+ };
38394
+ return Object.freeze({ generateQuestionId: generateQuestionId2, questionIdMatchesContent: questionIdMatchesContent2 });
38395
+ };
38396
+
38397
+ // mcp/lib/records.mjs
38398
+ var MAX_PROMPT_LENGTH = 1e3;
38399
+ var MAX_OPTION_LENGTH = 200;
38400
+ var MAX_OPTIONS = 12;
38401
+ var MAX_TAGS = 10;
38402
+ var MAX_TAG_LENGTH = 40;
38403
+ var MAX_COMMENT_LENGTH = 4e3;
38404
+ var trim4 = (value) => typeof value === "string" ? value.trim() : typeof value === "number" ? String(value) : "";
38405
+ var isRecord3 = (value) => !!value && typeof value === "object" && !Array.isArray(value);
38406
+ var fail2 = (error) => ({ ok: false, error });
38407
+ var { generateQuestionId, questionIdMatchesContent } = createQuestionIdDerivation(import_ethers3.ethers);
38408
+ var isLockedQuestion = (question) => question?.locked === true || !!question?.promptEncrypted || !!question?.encryption && typeof question.encryption === "object" || typeof question?.prompt === "string" && question.prompt.trim() === "[encrypted]";
38409
+ var normalizeRecruitmentSource = (value) => {
38410
+ const normalized2 = (typeof value === "string" ? value : "").trim().replace(/\s+/g, "-").slice(0, 128);
38411
+ return /^[a-zA-Z0-9][a-zA-Z0-9._:-]{0,127}$/.test(normalized2) ? normalized2 : "";
38412
+ };
38413
+ var readScore = (value, field) => {
38414
+ if (value === void 0 || value === null || value === "") return { ok: true, value: null };
38415
+ const number = Number(value);
38416
+ if (!Number.isInteger(number) || number < 0 || number > 10) return fail2(`${field} must be a whole number from 0 to 10.`);
38417
+ return { ok: true, value: number };
38418
+ };
38373
38419
  var plaintextField = (value, hash) => ({
38374
38420
  value,
38375
38421
  encrypted: false,
@@ -38382,8 +38428,8 @@ var plaintextField = (value, hash) => ({
38382
38428
  var textHash = (value) => typeof value === "string" && value ? import_ethers3.ethers.utils.id(value) : "";
38383
38429
  var buildParticipantMarker = ({ modelId = "", platform = "" } = {}) => ({
38384
38430
  kind: "agent",
38385
- ...trim3(modelId) ? { modelId: trim3(modelId) } : {},
38386
- ...trim3(platform) ? { platform: trim3(platform) } : {},
38431
+ ...trim4(modelId) ? { modelId: trim4(modelId) } : {},
38432
+ ...trim4(platform) ? { platform: trim4(platform) } : {},
38387
38433
  verification: "self_reported"
38388
38434
  });
38389
38435
  var buildResponseRecord = ({
@@ -38397,21 +38443,21 @@ var buildResponseRecord = ({
38397
38443
  profile = {},
38398
38444
  recruitmentSource = ""
38399
38445
  }) => {
38400
- if (!isRecord3(question) || !trim3(question.id)) return fail("Unknown question.");
38401
- if (isLockedQuestion(question)) return fail("This question is locked to certain members; agents cannot answer locked questions yet.");
38446
+ if (!isRecord3(question) || !trim4(question.id)) return fail2("Unknown question.");
38447
+ if (isLockedQuestion(question)) return fail2("This question is locked to certain members; agents cannot answer locked questions yet.");
38402
38448
  const answer = normalizeAnswerValue(question, value);
38403
38449
  if (!answer.ok) return answer;
38404
- const note = trim3(comment);
38405
- if (note.length > MAX_COMMENT_LENGTH) return fail(`Comments must be ${MAX_COMMENT_LENGTH} characters or fewer.`);
38450
+ const note = trim4(comment);
38451
+ if (note.length > MAX_COMMENT_LENGTH) return fail2(`Comments must be ${MAX_COMMENT_LENGTH} characters or fewer.`);
38406
38452
  const convictionScore = readScore(conviction, "Conviction");
38407
38453
  if (!convictionScore.ok) return convictionScore;
38408
38454
  const importanceScore = readScore(importance, "Importance");
38409
38455
  if (!importanceScore.ok) return importanceScore;
38410
- const displayName = trim3(profile.displayName);
38456
+ const displayName = trim4(profile.displayName);
38411
38457
  return {
38412
38458
  ok: true,
38413
38459
  record: {
38414
- questionID: trim3(question.id).toLowerCase(),
38460
+ questionID: trim4(question.id).toLowerCase(),
38415
38461
  responder: import_ethers3.ethers.utils.getAddress(responder),
38416
38462
  type: question.type,
38417
38463
  prompt: typeof question.prompt === "string" ? question.prompt : "",
@@ -38429,19 +38475,19 @@ var buildResponseRecord = ({
38429
38475
  };
38430
38476
  };
38431
38477
  var normalizeOptionList = (options) => {
38432
- const list = (Array.isArray(options) ? options : []).map(trim3).filter(Boolean);
38433
- if (list.length < 2) return fail("Provide at least two options.");
38434
- if (list.length > MAX_OPTIONS) return fail(`Provide at most ${MAX_OPTIONS} options.`);
38435
- if (list.some((option) => option.length > MAX_OPTION_LENGTH)) return fail(`Options must be ${MAX_OPTION_LENGTH} characters or fewer.`);
38436
- if (new Set(list.map((option) => option.toLowerCase())).size !== list.length) return fail("Options must be unique.");
38478
+ const list = (Array.isArray(options) ? options : []).map(trim4).filter(Boolean);
38479
+ if (list.length < 2) return fail2("Provide at least two options.");
38480
+ if (list.length > MAX_OPTIONS) return fail2(`Provide at most ${MAX_OPTIONS} options.`);
38481
+ if (list.some((option) => option.length > MAX_OPTION_LENGTH)) return fail2(`Options must be ${MAX_OPTION_LENGTH} characters or fewer.`);
38482
+ if (new Set(list.map((option) => option.toLowerCase())).size !== list.length) return fail2("Options must be unique.");
38437
38483
  return { ok: true, value: list };
38438
38484
  };
38439
38485
  var buildQuestionRecord = ({ type = "binary", prompt, options, singleSelect = false, voiceCredits, tags = [], creator, session, profile = {} }) => {
38440
- if (!QUESTION_TYPES.includes(type)) return fail(`Question type must be one of: ${QUESTION_TYPES.join(", ")}.`);
38441
- const text4 = trim3(prompt);
38442
- if (!text4) return fail("The statement text is empty.");
38443
- if (text4.length > MAX_PROMPT_LENGTH) return fail(`Statements must be ${MAX_PROMPT_LENGTH} characters or fewer.`);
38444
- const record = { id: "", type, prompt: text4 };
38486
+ if (!QUESTION_TYPES.includes(type)) return fail2(`Question type must be one of: ${QUESTION_TYPES.join(", ")}.`);
38487
+ const text6 = trim4(prompt);
38488
+ if (!text6) return fail2("The statement text is empty.");
38489
+ if (text6.length > MAX_PROMPT_LENGTH) return fail2(`Statements must be ${MAX_PROMPT_LENGTH} characters or fewer.`);
38490
+ const record = { id: "", type, prompt: text6 };
38445
38491
  let optionList = [];
38446
38492
  if (type === "multichoice" || type === "quadratic") {
38447
38493
  const normalized2 = normalizeOptionList(options);
@@ -38455,20 +38501,20 @@ var buildQuestionRecord = ({ type = "binary", prompt, options, singleSelect = fa
38455
38501
  credits = voiceCredits === void 0 || voiceCredits === null ? 99 : Number(voiceCredits);
38456
38502
  record.voiceCredits = credits;
38457
38503
  const error = validateQuadraticQuestion(record);
38458
- if (error) return fail(error);
38504
+ if (error) return fail2(error);
38459
38505
  }
38460
- const tagList = (Array.isArray(tags) ? tags : []).map(trim3).filter(Boolean);
38506
+ const tagList = (Array.isArray(tags) ? tags : []).map(trim4).filter(Boolean);
38461
38507
  if (tagList.length > MAX_TAGS || tagList.some((tag) => tag.length > MAX_TAG_LENGTH)) {
38462
- return fail(`Use at most ${MAX_TAGS} tags of ${MAX_TAG_LENGTH} characters or fewer.`);
38508
+ return fail2(`Use at most ${MAX_TAGS} tags of ${MAX_TAG_LENGTH} characters or fewer.`);
38463
38509
  }
38464
38510
  record.tags = tagList;
38465
38511
  record.creator = import_ethers3.ethers.utils.getAddress(creator);
38466
38512
  record.associatedSurveyId = import_ethers3.ethers.constants.HashZero;
38467
38513
  record.participant = buildParticipantMarker(profile);
38468
- record.sessionName = trim3(session.sessionName) || session.sessionSlug;
38514
+ record.sessionName = trim4(session.sessionName) || session.sessionSlug;
38469
38515
  record.sessionSlug = session.sessionSlug;
38470
38516
  record.sessionId = session.sessionId;
38471
- record.id = generateQuestionId(type, text4, optionList, record.singleSelect === true, credits);
38517
+ record.id = generateQuestionId(type, text6, optionList, record.singleSelect === true, credits);
38472
38518
  return { ok: true, id: record.id, record };
38473
38519
  };
38474
38520
 
@@ -38476,9 +38522,9 @@ var buildQuestionRecord = ({ type = "binary", prompt, options, singleSelect = fa
38476
38522
  var SLUG_RE = /^[a-z0-9_-]{1,128}$/;
38477
38523
  var ADDRESS_RE = /^0x[0-9a-fA-F]{40}$/;
38478
38524
  var GROUP_ID_RE = /^[A-Za-z0-9._:-]{1,128}$/;
38479
- var trim4 = (value) => String(value ?? "").trim();
38525
+ var trim5 = (value) => String(value ?? "").trim();
38480
38526
  var normalizeSessionSlug = (value) => {
38481
- const slug = trim4(value).toLowerCase();
38527
+ const slug = trim5(value).toLowerCase();
38482
38528
  if (!SLUG_RE.test(slug)) throw new Error("Session slug must be 1-128 lowercase letters, digits, dashes, or underscores.");
38483
38529
  return slug;
38484
38530
  };
@@ -38501,9 +38547,9 @@ var readClaimPairs = (params) => {
38501
38547
  const pairs = [];
38502
38548
  const seen = /* @__PURE__ */ new Set();
38503
38549
  const add = (sbt, gp, inv, auto) => {
38504
- const address = trim4(sbt);
38550
+ const address = trim5(sbt);
38505
38551
  if (!ADDRESS_RE.test(address)) return;
38506
- const pair = { sbt: address, groupPassword: trim4(gp), inviteCode: trim4(inv), auto };
38552
+ const pair = { sbt: address, groupPassword: trim5(gp), inviteCode: trim5(inv), auto };
38507
38553
  const key = `${address.toLowerCase()}|${pair.groupPassword}|${pair.inviteCode}`;
38508
38554
  if (seen.has(key)) return;
38509
38555
  seen.add(key);
@@ -38521,7 +38567,7 @@ var readClaimPairs = (params) => {
38521
38567
  var parseSessionLink = (link, { allowLocalWorkers = false } = {}) => {
38522
38568
  let url;
38523
38569
  try {
38524
- url = new URL(trim4(link));
38570
+ url = new URL(trim5(link));
38525
38571
  } catch {
38526
38572
  throw new Error("Session link must be a full URL, such as https://contextengine.sh/session/<slug>?worker=<origin>.");
38527
38573
  }
@@ -38534,7 +38580,7 @@ var parseSessionLink = (link, { allowLocalWorkers = false } = {}) => {
38534
38580
  if (workers.length > 1) {
38535
38581
  throw new Error("Session link must name exactly one hosted Worker when using ?worker=.");
38536
38582
  }
38537
- const joinGroup = trim4(params.get("joinGroup"));
38583
+ const joinGroup = trim5(params.get("joinGroup"));
38538
38584
  if (joinGroup && !GROUP_ID_RE.test(joinGroup)) throw new Error("Session link has an invalid group id.");
38539
38585
  return {
38540
38586
  appOrigin: normalizeHttpOrigin(url.origin, "Session link"),
@@ -38616,14 +38662,14 @@ var WorkerRequestError = class extends Error {
38616
38662
  this.details = details;
38617
38663
  }
38618
38664
  };
38619
- var explainFailure = (status, error, path3) => {
38665
+ var explainFailure = (status, error, path4) => {
38620
38666
  const detail = error.slice(0, MAX_ERROR_DETAIL);
38621
38667
  if (status === 401) return `Sign-in expired or was rejected (${detail || "401"}).`;
38622
38668
  if (status === 403 && /origin/i.test(detail)) {
38623
38669
  return `The Worker refused this sign-in origin (${detail}). Ask the session admin to allow it.`;
38624
38670
  }
38625
38671
  if (status === 403) return `Not allowed: ${detail || "this session\u2019s access rules deny the request"}.`;
38626
- if (status === 404 && path3.startsWith("/session-config")) return "No hosted session with that name exists on this Worker.";
38672
+ if (status === 404 && path4.startsWith("/session-config")) return "No hosted session with that name exists on this Worker.";
38627
38673
  if (status === 410) return "This session has ended and no longer accepts answers.";
38628
38674
  if (status === 429) return `Rate limited by the Worker (${detail || "429"}). Wait a minute and retry.`;
38629
38675
  return detail || `Worker request failed (${status}).`;
@@ -38700,8 +38746,17 @@ var resolveLoginOrigin = (config, trustedOrigins) => {
38700
38746
  }
38701
38747
  return origin;
38702
38748
  };
38703
- var createWorkerClient = ({ workerOrigin, slug, trustedOrigins, wallet, fetchImpl = globalThis.fetch, now = () => Date.now(), registryConfigLoader }) => {
38704
- let sessionId = "";
38749
+ var createWorkerClient = ({
38750
+ workerOrigin,
38751
+ slug,
38752
+ trustedOrigins,
38753
+ wallet,
38754
+ fetchImpl = globalThis.fetch,
38755
+ now = () => Date.now(),
38756
+ registryConfigLoader,
38757
+ sessionId: joinedSessionId = ""
38758
+ }) => {
38759
+ let sessionId = joinedSessionId;
38705
38760
  let config = null;
38706
38761
  let configLoadedAt = 0;
38707
38762
  let loginOrigin = "";
@@ -38710,11 +38765,18 @@ var createWorkerClient = ({ workerOrigin, slug, trustedOrigins, wallet, fetchImp
38710
38765
  let pendingLogin = null;
38711
38766
  let presence = null;
38712
38767
  let presenceLoadedAt = -Infinity;
38713
- const request = async (path3, { method = "GET", headers = {}, body, auth = false, retried = false, maxBytes = MAX_RESPONSE_BYTES } = {}) => {
38768
+ let features = null;
38769
+ let featuresLoadedAt = -Infinity;
38770
+ const request = async (path4, { method = "GET", headers = {}, body, form, auth = false, retried = false, maxBytes = MAX_RESPONSE_BYTES, signal } = {}) => {
38771
+ const checkpoint = () => {
38772
+ if (signal?.aborted) throw new Error("Stopped before the Worker request was sent.");
38773
+ };
38774
+ checkpoint();
38714
38775
  if (auth) await ensureToken();
38776
+ checkpoint();
38715
38777
  let response;
38716
38778
  try {
38717
- response = await fetchImpl(`${workerOrigin}${path3}`, {
38779
+ response = await fetchImpl(`${workerOrigin}${path4}`, {
38718
38780
  method,
38719
38781
  redirect: "error",
38720
38782
  headers: {
@@ -38722,7 +38784,7 @@ var createWorkerClient = ({ workerOrigin, slug, trustedOrigins, wallet, fetchImp
38722
38784
  ...auth ? { Authorization: `Bearer ${token}`, "X-Group-Slug": slug } : {},
38723
38785
  ...headers
38724
38786
  },
38725
- ...body === void 0 ? {} : { body: JSON.stringify(body) },
38787
+ ...form ? { body: form } : body === void 0 ? {} : { body: JSON.stringify(body) },
38726
38788
  signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
38727
38789
  });
38728
38790
  } catch (error2) {
@@ -38741,13 +38803,13 @@ var createWorkerClient = ({ workerOrigin, slug, trustedOrigins, wallet, fetchImp
38741
38803
  const error = isRecord4(data) ? text(data.error) || text(data.message) : "";
38742
38804
  if (response.status === 401 && auth && !retried && (!error || TOKEN_ERROR_RE.test(error))) {
38743
38805
  token = "";
38744
- return request(path3, { method, headers, body, auth, retried: true, maxBytes });
38806
+ return request(path4, { method, headers, body, form, auth, retried: true, maxBytes, signal });
38745
38807
  }
38746
38808
  if (response.status === 401 && error && !TOKEN_ERROR_RE.test(error)) {
38747
38809
  throw new WorkerRequestError(error.slice(0, MAX_ERROR_DETAIL), { status: 401, code: error });
38748
38810
  }
38749
38811
  if (!response.ok) {
38750
- throw new WorkerRequestError(explainFailure(response.status, error, path3), {
38812
+ throw new WorkerRequestError(explainFailure(response.status, error, path4), {
38751
38813
  status: response.status,
38752
38814
  code: isRecord4(data) ? text(data.code) || text(data.reason) || error : "",
38753
38815
  details: { balanceEth: text(data?.balanceEth), thresholdEth: text(data?.thresholdEth) }
@@ -38859,15 +38921,37 @@ var createWorkerClient = ({ workerOrigin, slug, trustedOrigins, wallet, fetchImp
38859
38921
  }
38860
38922
  return data;
38861
38923
  };
38862
- const upload = async ({ resource, data, tags = [], requestId = "" }) => {
38924
+ const upload = async ({ resource, data, tags = [], requestId = "", signal }) => {
38863
38925
  const result = await request("/storage/upload", {
38926
+ signal,
38864
38927
  method: "POST",
38865
38928
  auth: true,
38866
38929
  body: { backend: "cloudflare", resource, contentType: "application/json", payloadEncrypted: false, tags, data, ...requestId ? { requestId } : {} }
38867
38930
  });
38868
38931
  return isRecord4(result?.storageRef) ? result.storageRef : { id: text(result?.id) };
38869
38932
  };
38870
- const joinGroup = (groupId) => request("/groups/join", { method: "POST", auth: true, body: { sessionId, groupId } });
38933
+ const uploadForm = async (form, { signal } = {}) => {
38934
+ const result = await request("/storage/upload", { signal, method: "POST", auth: true, form });
38935
+ return isRecord4(result?.storageRef) ? result.storageRef : { id: text(result?.id) };
38936
+ };
38937
+ const contextAction = (body, { signal } = {}) => request("/storage/context", { method: "POST", auth: true, signal, body });
38938
+ const joinGroup = (groupId, { signal } = {}) => request("/groups/join", { method: "POST", auth: true, signal, body: { sessionId, groupId } });
38939
+ const leaveGroup = (groupId, { signal } = {}) => request("/groups/leave", { method: "POST", auth: true, signal, body: { sessionId, groupId } });
38940
+ const listGroups = async () => {
38941
+ const data = await request(`/groups/list?sessionId=${encodeURIComponent(sessionId)}`, { auth: true });
38942
+ return Array.isArray(data?.groups) ? data.groups.filter(isRecord4) : [];
38943
+ };
38944
+ const listMyMemberships = async () => {
38945
+ const data = await request(`/groups/my-memberships?sessionId=${encodeURIComponent(sessionId)}`, { auth: true });
38946
+ return Array.isArray(data?.memberships) ? data.memberships.filter(isRecord4) : [];
38947
+ };
38948
+ const readFeatures = async () => {
38949
+ if (now() - featuresLoadedAt >= CONFIG_MAX_AGE_MS) {
38950
+ features = await request("/capabilities").then((data) => Array.isArray(data?.features) ? data.features.map(text).filter(Boolean) : null).catch(() => null);
38951
+ featuresLoadedAt = now();
38952
+ }
38953
+ return features;
38954
+ };
38871
38955
  const describeTestEth = async () => {
38872
38956
  await refreshConfig();
38873
38957
  if (now() - presenceLoadedAt >= CONFIG_MAX_AGE_MS) {
@@ -38888,7 +38972,13 @@ var createWorkerClient = ({ workerOrigin, slug, trustedOrigins, wallet, fetchImp
38888
38972
  listAll,
38889
38973
  read,
38890
38974
  upload,
38975
+ uploadForm,
38976
+ contextAction,
38891
38977
  joinGroup,
38978
+ leaveGroup,
38979
+ listGroups,
38980
+ listMyMemberships,
38981
+ readFeatures,
38892
38982
  request,
38893
38983
  get config() {
38894
38984
  return config;
@@ -39101,6 +39191,7 @@ var createRegistryWriter = ({ provider, chainId, wallet, surveys, slug, remember
39101
39191
  if (offer.offered && offer.tokenHasFaucetScope !== false) {
39102
39192
  let funding;
39103
39193
  try {
39194
+ stopped(signal);
39104
39195
  funding = await fund();
39105
39196
  } catch (error) {
39106
39197
  throw new Error(`${shortfall} ${String(error?.message || "The faucet request failed.").slice(0, 250)}`);
@@ -39117,7 +39208,7 @@ var createRegistryWriter = ({ provider, chainId, wallet, surveys, slug, remember
39117
39208
  };
39118
39209
  const upload = async (client, resource, id, record, signal) => {
39119
39210
  stopped(signal);
39120
- const result = await client.request("/arweave/upload", { method: "POST", auth: true, body: {
39211
+ const result = await client.request("/arweave/upload", { method: "POST", auth: true, signal, body: {
39121
39212
  data: JSON.stringify(record),
39122
39213
  contentType: "application/json",
39123
39214
  requestId: randomUUID(),
@@ -39163,6 +39254,7 @@ var createRegistryWriter = ({ provider, chainId, wallet, surveys, slug, remember
39163
39254
  for (const record of records) pointers.push(await upload(client, "responses", record.questionID, record, signal));
39164
39255
  stopped(signal);
39165
39256
  await checkChain();
39257
+ stopped(signal);
39166
39258
  const tx = await chainRequest(() => surveys.connect(wallet.connect(provider)).submitResponses(ids, pointers, import_ethers4.ethers.constants.HashZero, import_ethers4.ethers.constants.HashZero, fees), { submission: true });
39167
39259
  const receipt = await confirm(tx, "ResponsesSubmitted", ids);
39168
39260
  records.forEach((record, index) => remember("responses", record.questionID, record, pointers[index], receipt));
@@ -39177,6 +39269,7 @@ var createRegistryWriter = ({ provider, chainId, wallet, surveys, slug, remember
39177
39269
  const pointer = await upload(client, "questions", record.id, record, signal);
39178
39270
  stopped(signal);
39179
39271
  await checkChain();
39272
+ stopped(signal);
39180
39273
  const tx = await chainRequest(() => surveys.connect(wallet.connect(provider)).addQuestions([record.id], [pointer], [import_ethers4.ethers.constants.HashZero], fees), { submission: true });
39181
39274
  const receipt = await confirm(tx, "QuestionsAdded", [record.id]);
39182
39275
  remember("questions", record.id, record, pointer, receipt);
@@ -39240,6 +39333,11 @@ var createRegistrySession = async ({ info, config, wallet, fetchImpl = globalThi
39240
39333
  let workerOrigin;
39241
39334
  let surveys;
39242
39335
  let startBlock;
39336
+ const creationBlocks = /* @__PURE__ */ new Map();
39337
+ let endBlock = null;
39338
+ let readEnd;
39339
+ let windowKey;
39340
+ let questionMark = null;
39243
39341
  let questionCursor;
39244
39342
  const pending = /* @__PURE__ */ new Map();
39245
39343
  const questions = /* @__PURE__ */ new Map();
@@ -39247,9 +39345,23 @@ var createRegistrySession = async ({ info, config, wallet, fetchImpl = globalThi
39247
39345
  const localAnswers = /* @__PURE__ */ new Map();
39248
39346
  const answerScans = /* @__PURE__ */ new Map();
39249
39347
  let loadingQuestions;
39348
+ const containsBlock = (block) => Number.isSafeInteger(block) && block >= startBlock && (endBlock === null || block <= readEnd);
39349
+ const readWindowEnd = async () => {
39350
+ const head = await chainRequest(() => provider.getBlockNumber());
39351
+ readEnd = endBlock === null ? head : Math.min(endBlock, head);
39352
+ return readEnd;
39353
+ };
39354
+ const configuredBlock = (value, name) => {
39355
+ if (value == null) return null;
39356
+ const block = Number(value);
39357
+ if (typeof value !== "number" && typeof value !== "string" || String(value).trim() === "" || !Number.isSafeInteger(block) || block < 0) {
39358
+ throw new Error(`Invalid session block limit: ${name} must be a nonnegative integer.`);
39359
+ }
39360
+ return block;
39361
+ };
39250
39362
  const loadConfig = async () => {
39251
39363
  await checkRegistryChain(provider, chainId);
39252
- const slug = info.slug === "general" ? "" : info.slug;
39364
+ const slug = info.slug || "general";
39253
39365
  const row = await chainRequest(() => registry.getSessionBySlug(slug));
39254
39366
  if (normalized(row[0]) !== slug) throw new Error("The registry returned a different session.");
39255
39367
  if (text(row[3])) throw new Error("Encrypted registry metadata is unsupported; use an unencrypted session.");
@@ -39277,11 +39389,32 @@ var createRegistrySession = async ({ info, config, wallet, fetchImpl = globalThi
39277
39389
  corsWorkerUrl: workerOrigin,
39278
39390
  contracts: { ...metadata.contracts, surveys: { address, chainId } }
39279
39391
  };
39280
- if (startBlock === void 0) {
39281
- const configured = Number(metadata.blockLimits?.start);
39282
- const head = await chainRequest(() => provider.getBlockNumber());
39283
- startBlock = metadata.blockLimits?.start !== void 0 && Number.isSafeInteger(configured) && configured >= 0 ? configured : await findStartBlock(provider, Number(row[5]), head);
39392
+ const head = await chainRequest(() => provider.getBlockNumber());
39393
+ let nextStart = configuredBlock(metadata.blockLimits?.start, "start");
39394
+ if (nextStart === null) {
39395
+ const createdAt = Number(row[5]);
39396
+ if (!creationBlocks.has(createdAt)) {
39397
+ const lookup = findStartBlock(provider, createdAt, head).catch((error) => {
39398
+ creationBlocks.delete(createdAt);
39399
+ throw error;
39400
+ });
39401
+ creationBlocks.set(createdAt, lookup);
39402
+ }
39403
+ nextStart = await creationBlocks.get(createdAt);
39404
+ }
39405
+ const nextEnd = configuredBlock(metadata.blockLimits?.end, "end");
39406
+ if (nextEnd !== null && nextEnd < nextStart) throw new Error("Invalid session block window: end must not precede start.");
39407
+ const nextKey = `${nextStart}:${nextEnd ?? "head"}`;
39408
+ startBlock = nextStart;
39409
+ endBlock = nextEnd;
39410
+ readEnd = endBlock === null ? head : Math.min(endBlock, head);
39411
+ if (windowKey !== nextKey) {
39412
+ windowKey = nextKey;
39284
39413
  questionCursor = { block: startBlock, offset: 0 };
39414
+ questionMark = null;
39415
+ pending.clear();
39416
+ for (const [id, entry] of questions) if (!entry.local || !containsBlock(entry.blockNumber)) questions.delete(id);
39417
+ answerScans.clear();
39285
39418
  }
39286
39419
  return sessionConfig;
39287
39420
  };
@@ -39311,14 +39444,14 @@ var createRegistrySession = async ({ info, config, wallet, fetchImpl = globalThi
39311
39444
  return block?.hash ? block.hash !== mark.hash : null;
39312
39445
  };
39313
39446
  const replacedWrite = (entry, blocks = /* @__PURE__ */ new Map()) => historyReplaced(entry?.blockHash ? { number: entry.blockNumber, hash: entry.blockHash } : null, blocks);
39314
- let questionMark = null;
39315
39447
  const visibleQuestions = () => {
39316
39448
  const blocked = new Set((Array.isArray(sessionConfig.BLOCKED_QUESTION_IDS) ? sessionConfig.BLOCKED_QUESTION_IDS : []).map(normalized));
39317
- return [...questions.values()].filter((entry) => !blocked.has(entry.id));
39449
+ return [...questions.values()].filter((entry) => !blocked.has(entry.id) && containsBlock(entry.blockNumber));
39318
39450
  };
39319
39451
  const readQuestions = async ({ signal } = {}) => {
39320
39452
  const deadline = now() + 9e4;
39321
39453
  const blocks = /* @__PURE__ */ new Map();
39454
+ const end = await readWindowEnd();
39322
39455
  let complete = true;
39323
39456
  const replaced = await historyReplaced(questionMark, blocks);
39324
39457
  if (replaced === null) return { items: visibleQuestions(), complete: false };
@@ -39335,7 +39468,7 @@ var createRegistrySession = async ({ info, config, wallet, fetchImpl = globalThi
39335
39468
  if (replaced2) questions.delete(id);
39336
39469
  }
39337
39470
  if (pending.size < MAX_CACHE && questions.size < MAX_QUESTIONS) {
39338
- const head = await readHeadMark(await chainRequest(() => provider.getBlockNumber()), blocks);
39471
+ const head = await readHeadMark(end, blocks);
39339
39472
  if (head) {
39340
39473
  const scanned = await scanRegistryLogs({
39341
39474
  provider,
@@ -39389,7 +39522,7 @@ var createRegistrySession = async ({ info, config, wallet, fetchImpl = globalThi
39389
39522
  let verified = true;
39390
39523
  const responseFilter = filter("ResponsesSubmitted");
39391
39524
  if (mine) responseFilter.topics.push(import_ethers5.ethers.utils.hexZeroPad(wallet.address, 32));
39392
- const head = await chainRequest(() => provider.getBlockNumber());
39525
+ const head = await readWindowEnd();
39393
39526
  const scope = [...known].sort().join(",");
39394
39527
  let state = answerScans.get(mine);
39395
39528
  const replaced = !!state && state.scope === scope && head >= state.head && await historyReplaced(state.mark, blocks);
@@ -39397,7 +39530,7 @@ var createRegistrySession = async ({ info, config, wallet, fetchImpl = globalThi
39397
39530
  const held = new Map((state.result?.entries || []).map((entry) => [`${entry.questionId}:${normalized(entry.responder)}`, entry]));
39398
39531
  const chainOrders2 = new Map(state.result?.chainOrders || []);
39399
39532
  for (const entry of localAnswers.values()) {
39400
- if (!known.has(entry.questionId)) continue;
39533
+ if (!known.has(entry.questionId) || !containsBlock(entry.blockNumber)) continue;
39401
39534
  const key = `${entry.questionId}:${normalized(entry.responder)}`;
39402
39535
  if ([state.latest.get(key), held.get(key)].some((previous) => previous && compareChainOrder(entry, previous) < 0)) continue;
39403
39536
  chainOrders2.set(entry.questionId, entry);
@@ -39407,7 +39540,8 @@ var createRegistrySession = async ({ info, config, wallet, fetchImpl = globalThi
39407
39540
  return {
39408
39541
  entries: [...held.values()].sort((a, b) => compareChainOrder(b, a)).slice(0, maxRecords),
39409
39542
  complete: false,
39410
- chainOrders: chainOrders2
39543
+ chainOrders: chainOrders2,
39544
+ unreadAnswers: state.result?.unreadAnswers || 0
39411
39545
  };
39412
39546
  }
39413
39547
  if (!state || state.scope !== scope || head < state.head || replaced) {
@@ -39473,7 +39607,7 @@ var createRegistrySession = async ({ info, config, wallet, fetchImpl = globalThi
39473
39607
  const scannedAll = !state.ranges.length && !state.capped;
39474
39608
  const latest = new Map(state.latest);
39475
39609
  for (const [id, entry] of localAnswers) {
39476
- if (!known.has(entry.questionId)) continue;
39610
+ if (!known.has(entry.questionId) || !containsBlock(entry.blockNumber)) continue;
39477
39611
  const replaced2 = await replacedWrite(entry, blocks);
39478
39612
  if (replaced2 === null) verified = false;
39479
39613
  if (replaced2) {
@@ -39488,6 +39622,7 @@ var createRegistrySession = async ({ info, config, wallet, fetchImpl = globalThi
39488
39622
  const chainOrders = new Map(candidates.filter((entry) => normalized(entry.responder) === normalized(wallet.address)).map((entry) => [entry.questionId, entry]));
39489
39623
  const entries = [];
39490
39624
  let complete = verified && scannedAll && candidates.length <= maxRecords;
39625
+ let unreadAnswers = 0;
39491
39626
  let next = 0;
39492
39627
  const selected = candidates.slice(0, maxRecords);
39493
39628
  await Promise.all(Array.from({ length: Math.min(6, selected.length) }, async () => {
@@ -39498,7 +39633,16 @@ var createRegistrySession = async ({ info, config, wallet, fetchImpl = globalThi
39498
39633
  }
39499
39634
  const entry = selected[next++];
39500
39635
  try {
39501
- const pointer = entry.local ? entry.storageId : await chainRequest(() => surveys.getResponse(entry.responder, entry.questionId));
39636
+ const { blockTag } = responseReadWindowOptions(endBlock === null ? null : { blockTag: head }, entry.responder, entry.questionId);
39637
+ let pointer;
39638
+ if (entry.local) pointer = entry.storageId;
39639
+ else {
39640
+ try {
39641
+ pointer = await chainRequest(() => blockTag == null ? surveys.getResponse(entry.responder, entry.questionId) : surveys.getResponse(entry.responder, entry.questionId, { blockTag }));
39642
+ } catch (error) {
39643
+ throw blockTag == null ? error : historicalResponseReadError(error, blockTag);
39644
+ }
39645
+ }
39502
39646
  const payload = await readPayload(pointer);
39503
39647
  if (!registryResponseMatchesSession(payload, sessionConfig) || payload.answer?.encrypted === true) continue;
39504
39648
  if (normalized(payload.questionID || payload.questionId) !== entry.questionId) continue;
@@ -39508,10 +39652,12 @@ var createRegistrySession = async ({ info, config, wallet, fetchImpl = globalThi
39508
39652
  entries.push({ ...entry, storageId: pointer, createdAt, payload });
39509
39653
  } catch {
39510
39654
  complete = false;
39655
+ unreadAnswers++;
39511
39656
  }
39512
39657
  }
39513
39658
  }));
39514
- state.result = { entries, complete, chainOrders };
39659
+ unreadAnswers += selected.length - next;
39660
+ state.result = { entries, complete, chainOrders, unreadAnswers };
39515
39661
  return state.result;
39516
39662
  };
39517
39663
  const writer = createRegistryWriter({ provider, chainId, wallet, surveys, slug: info.slug, remember: (resource, id, payload, pointer, receipt) => {
@@ -39531,15 +39677,17 @@ var createRegistrySession = async ({ info, config, wallet, fetchImpl = globalThi
39531
39677
  if (resource === "questions") questions.set(id, { ...entry, local: true });
39532
39678
  else localAnswers.set(id, entry);
39533
39679
  } });
39534
- return { loadConfig, loadQuestions, readAnswers, replacedWrite, ...writer, get config() {
39680
+ return { loadConfig, loadQuestions, readAnswers, replacedWrite, containsBlock, get windowKey() {
39681
+ return windowKey;
39682
+ }, ...writer, get config() {
39535
39683
  return sessionConfig;
39536
39684
  }, workerOrigin };
39537
39685
  };
39538
39686
 
39539
39687
  // shared/storage/canonicalStorageVersions.mjs
39540
- var trim5 = (value) => (typeof value === "string" ? value : value == null ? "" : String(value)).trim();
39688
+ var trim6 = (value) => (typeof value === "string" ? value : value == null ? "" : String(value)).trim();
39541
39689
  var compareStorageIds = (left, right) => left < right ? -1 : left > right ? 1 : 0;
39542
- var compareVersionAge = (left, right) => (Number(left.createdAtMs) || 0) - (Number(right.createdAtMs) || 0) || compareStorageIds(trim5(left.storageRefId), trim5(right.storageRefId));
39690
+ var compareVersionAge = (left, right) => (Number(left.createdAtMs) || 0) - (Number(right.createdAtMs) || 0) || compareStorageIds(trim6(left.storageRefId), trim6(right.storageRefId));
39543
39691
  var isAdminStorageVersion = (candidate) => candidate.uploadAuthority === "admin";
39544
39692
  var isPreferredStorageVersion = (candidate, current) => {
39545
39693
  if (!current) return true;
@@ -39550,8 +39698,428 @@ var isPreferredStorageVersion = (candidate, current) => {
39550
39698
  return candidateAdmin ? age > 0 : age < 0;
39551
39699
  };
39552
39700
 
39553
- // mcp/lib/results.mjs
39701
+ // shared/secretText.mjs
39702
+ var SECRET_PATTERNS = [
39703
+ /\bsk-[\w-]{16,}/,
39704
+ /\b[rs]k_(?:live|test)_[A-Za-z\d]{16,}/,
39705
+ /\bhf_[A-Za-z\d]{30,}/,
39706
+ /\bAIza[\w-]{30,}/,
39707
+ /\b(?:gsk|ghp|gho|ghu|ghs|ghr|github_pat|glpat|xox[abpr])[-_][\w-]{16,}/,
39708
+ /(?<![\w:])\d{6,12}:[\w-]{30,40}(?![\w-])/,
39709
+ /\balchemy(?:api)?\.(?:com|io)\/v2\/[\w-]{16,}/i,
39710
+ /\binfura\.io\/v3\/[\da-f]{32}/i,
39711
+ /-----BEGIN [A-Z ]{0,40}PRIVATE KEY-----/,
39712
+ /"kty"\s*:/,
39713
+ /\bBearer\s+[\w.~+/=-]{16,}/i,
39714
+ /\b[a-z][a-z\d+.-]{0,31}:\/\/[^\s/?#@]*@/i,
39715
+ /[?&#](?:access_token|api[_-]?key|key|token|secret|password|sig|signature|auth)=[^&#\s]/i,
39716
+ /#(?:[^\s#]*&)?k=[^&#\s]/
39717
+ ];
39718
+ var HEX_KEY = /(?<![/\w])(?:0x)?[0-9a-f]{64,}\b/i;
39719
+ var TOKEN_RUN = /(?<![\w/-])[\w-]{40}(?![\w-])/g;
39720
+ var hasHexKey = (text6) => typeof text6 === "string" && HEX_KEY.test(text6);
39721
+ var looksSecret = (text6) => typeof text6 === "string" && (hasHexKey(text6) || SECRET_PATTERNS.some((pattern) => pattern.test(text6)) || (text6.match(TOKEN_RUN) || []).some((run) => /[A-Z]/.test(run) && /[a-z]/.test(run) && /\d/.test(run)));
39722
+
39723
+ // shared/sessionContext.mjs
39724
+ var SESSION_CONTEXT_LIMITS = Object.freeze({
39725
+ titleChars: 80,
39726
+ paragraphs: 6,
39727
+ paragraphChars: 2e3,
39728
+ links: 8,
39729
+ labelChars: 120,
39730
+ urlChars: 2e3,
39731
+ htmlChars: 2e4
39732
+ });
39733
+ var L = SESSION_CONTEXT_LIMITS;
39734
+ var isRecord5 = (value) => !!value && typeof value === "object" && !Array.isArray(value);
39554
39735
  var text2 = (value) => typeof value === "string" ? value.trim() : "";
39736
+ var NAMED_ENTITIES = { amp: "&", lt: "<", gt: ">", quot: '"', apos: "'", nbsp: " " };
39737
+ var decodeEntity = (match, entity) => {
39738
+ const code = /^#x/i.test(entity) ? parseInt(entity.slice(2), 16) : /^#/.test(entity) ? parseInt(entity.slice(1), 10) : NaN;
39739
+ if (Number.isInteger(code)) return code > 0 && code <= 1114111 ? String.fromCodePoint(code) : " ";
39740
+ return NAMED_ENTITIES[entity.toLowerCase()] ?? match;
39741
+ };
39742
+ var htmlToPlainText = (html) => String(html ?? "").replace(/<(script|style|template)\b[\s\S]*?<\/\1\s*>/gi, " ").replace(/<!--[\s\S]*?-->/g, " ").replace(/<br\s*\/?>|<\/(?:p|div|li|h[1-6]|tr|summary|details|blockquote|pre|table|ul|ol|dt|dd)>/gi, "\n").replace(/<[^>]*>/g, " ").replace(/&(#x[0-9a-f]+|#\d+|[a-z]+);/gi, decodeEntity).split("\n").map((line) => line.replace(/\s+/g, " ").trim()).filter(Boolean).join("\n");
39743
+ var isHttpsUrl = (value) => {
39744
+ if (typeof value !== "string" || !value || value.length > L.urlChars) return false;
39745
+ try {
39746
+ return new URL(value).protocol === "https:";
39747
+ } catch {
39748
+ return false;
39749
+ }
39750
+ };
39751
+ var normalizeSessionContext = (value) => {
39752
+ const context = isRecord5(value) ? value : {};
39753
+ const title = text2(context.title).slice(0, L.titleChars);
39754
+ const html = text2(context.html).slice(0, L.htmlChars);
39755
+ if (html) return { title, html, paragraphs: [], links: [] };
39756
+ const paragraphs = (Array.isArray(context.paragraphs) ? context.paragraphs : [context.body]).map(text2).filter(Boolean).slice(0, L.paragraphs).map((paragraph) => paragraph.slice(0, L.paragraphChars));
39757
+ const links = (Array.isArray(context.links) ? context.links : []).filter(isRecord5).map((link) => ({ label: text2(link.label).slice(0, L.labelChars), url: text2(link.url) })).filter((link) => isHttpsUrl(link.url)).slice(0, L.links).map((link) => ({ label: link.label || link.url, url: link.url }));
39758
+ return { title, paragraphs, links };
39759
+ };
39760
+
39761
+ // shared/sessionConfigEdits.mjs
39762
+ var WORKER_CANONICAL_SET_CONFIG_KEYS = Object.freeze([
39763
+ "slug",
39764
+ "sessionId",
39765
+ "sessionIdHex",
39766
+ "configRevision",
39767
+ "sessionName",
39768
+ "sessionInfo",
39769
+ "sessionContext",
39770
+ "appearance",
39771
+ "sessionHeaderImg",
39772
+ "sessionEndsAt",
39773
+ "defaultTags",
39774
+ "defaultGroupTags",
39775
+ "defaultSbtTags",
39776
+ "questionsGenPrompt",
39777
+ "agentInstructions",
39778
+ "interviewMode",
39779
+ "interviewModeEnabled",
39780
+ "pileAutoAdvanceEnabled",
39781
+ "defaultFilterState",
39782
+ "defaultFeaturedSBTs",
39783
+ "autoFeatureSBTsBySessionSlug",
39784
+ "HIGHLIGHTED_QUESTION_IDS",
39785
+ "BLOCKED_QUESTION_IDS",
39786
+ "HIGHLIGHTED_SURVEY_IDS",
39787
+ "BLOCKED_SURVEY_IDS",
39788
+ "adminAddress",
39789
+ "adminAddresses",
39790
+ "resultsAdminAddresses",
39791
+ "corsWorkerUrl",
39792
+ "allowOrigins",
39793
+ "sessionModeProfile",
39794
+ "agentSessionWrapped",
39795
+ "agentHttp",
39796
+ "resultsExposure",
39797
+ "workerAuthority",
39798
+ "workerRoles",
39799
+ "roles",
39800
+ "authorization",
39801
+ "groupCreationPolicy",
39802
+ "contextAdditionPolicy",
39803
+ "storageProfile",
39804
+ "storageEnvelope",
39805
+ "ai",
39806
+ "limits",
39807
+ "scopes",
39808
+ "networkChainId",
39809
+ "contracts",
39810
+ "embeddedDeployHelperEnabled",
39811
+ "litCredentials",
39812
+ "resultsAnalysis",
39813
+ "responseFieldEncryption",
39814
+ "linkedWorkerGroups",
39815
+ "workerGroupsBootstrap"
39816
+ ]);
39817
+ var CURATED_ID_LIST_KEYS = Object.freeze([
39818
+ "HIGHLIGHTED_QUESTION_IDS",
39819
+ "BLOCKED_QUESTION_IDS",
39820
+ "HIGHLIGHTED_SURVEY_IDS",
39821
+ "BLOCKED_SURVEY_IDS"
39822
+ ]);
39823
+ var MAX_AGENT_INSTRUCTIONS_CHARS = 8e3;
39824
+ var CONTENT_FIELDS = /* @__PURE__ */ new Set([
39825
+ "sessionName",
39826
+ "sessionInfo",
39827
+ "sessionContext",
39828
+ "questionsGenPrompt",
39829
+ "appearance",
39830
+ "sessionHeaderImg",
39831
+ "agentInstructions",
39832
+ // Checked again when each file publishes, so changing it signs no one out.
39833
+ "contextAdditionPolicy",
39834
+ // Checked on each atlas build and read and never held in a sign-in, so
39835
+ // changing it signs no one out either.
39836
+ "resultsAdminAddresses",
39837
+ // Read on each interview request and never held in a sign-in, so changing
39838
+ // any interview setting, even turning interviews off, signs no one out.
39839
+ "interviewModeEnabled",
39840
+ "interviewMode",
39841
+ ...CURATED_ID_LIST_KEYS
39842
+ ]);
39843
+
39844
+ // shared/sessionContextSources.mjs
39845
+ var CONTEXT_ROLE = "context";
39846
+ var CONTEXT_TAGS = Object.freeze({
39847
+ role: "CE-DocRole",
39848
+ kind: "CE-DocKind",
39849
+ name: "CE-DocName",
39850
+ mime: "CE-DocMime",
39851
+ url: "CE-ContextUrl",
39852
+ fetchedAt: "CE-ContextFetchedAt",
39853
+ derivedFrom: "CE-DocDerivedFromTx",
39854
+ readBy: "CE-ReadBy",
39855
+ readModel: "CE-ReadModel",
39856
+ readAt: "CE-ReadAt",
39857
+ // Self-declared by an agent on what it adds: a label in the list, never a reason for access.
39858
+ adderKind: "CE-AdderKind",
39859
+ adderName: "CE-AdderName"
39860
+ });
39861
+ var CONTEXT_SOURCE_LIMITS = Object.freeze({
39862
+ pdfBytes: 20 * 1024 * 1024,
39863
+ textFileBytes: 1024 * 1024,
39864
+ // A linked page as fetched, before its text is taken out.
39865
+ pageBytes: 2 * 1024 * 1024,
39866
+ snapshotChars: 1e5,
39867
+ // Text the session's AI returns for a PDF.
39868
+ readTextChars: 1e5,
39869
+ titleChars: 120,
39870
+ // A link is also a storage tag, and tag values stop at 1,024 characters.
39871
+ urlChars: 1e3,
39872
+ // The groups one item may be locked to; reading it checks each in turn.
39873
+ lockedGroups: 20,
39874
+ // An agent's display name, as long as its profile allows.
39875
+ adderNameChars: 80
39876
+ });
39877
+ var CONTEXT_FILE_TYPES = Object.freeze({
39878
+ pdf: "application/pdf",
39879
+ md: "text/markdown",
39880
+ markdown: "text/markdown",
39881
+ txt: "text/plain",
39882
+ csv: "text/csv",
39883
+ json: "application/json"
39884
+ });
39885
+ var CONTEXT_FILE_MIMES = new Set(Object.values(CONTEXT_FILE_TYPES));
39886
+ var ADMINS_ONLY_ACCESS = Object.freeze({
39887
+ match: "all",
39888
+ conditions: Object.freeze([Object.freeze({ kind: "worker_role", role: "admin" })])
39889
+ });
39890
+ var text3 = (value) => typeof value === "string" ? value.trim() : "";
39891
+ var participantsMayAddContext = (config) => config?.contextAdditionPolicy !== "admin_only";
39892
+ var CONTEXT_AGENT_ADDER = "agent";
39893
+ var NAME_CONTROLS = /[\p{Cc}\u061C\u200E\u200F\u202A-\u202E\u2066-\u2069]/gu;
39894
+ var agentAdderName = (name = "") => text3(text3(name).replace(NAME_CONTROLS, " ").replace(/\s+/g, " ").slice(0, CONTEXT_SOURCE_LIMITS.adderNameChars));
39895
+ var agentAdderTags = (name = "") => {
39896
+ const clean = agentAdderName(name);
39897
+ return [
39898
+ { name: CONTEXT_TAGS.adderKind, value: CONTEXT_AGENT_ADDER },
39899
+ ...clean ? [{ name: CONTEXT_TAGS.adderName, value: clean }] : []
39900
+ ];
39901
+ };
39902
+ var resolveContextFileType = ({ name = "", type = "" } = {}) => {
39903
+ const declared = text3(type).split(";")[0].toLowerCase();
39904
+ if (CONTEXT_FILE_MIMES.has(declared)) return declared;
39905
+ const extension = /\.([a-z0-9]+)$/i.exec(text3(name))?.[1]?.toLowerCase() || "";
39906
+ return Object.hasOwn(CONTEXT_FILE_TYPES, extension) ? CONTEXT_FILE_TYPES[extension] : "";
39907
+ };
39908
+ var contextFileByteLimit = (contentType) => contentType === CONTEXT_FILE_TYPES.pdf ? CONTEXT_SOURCE_LIMITS.pdfBytes : CONTEXT_SOURCE_LIMITS.textFileBytes;
39909
+
39910
+ // mcp/lib/contextAdditions.mjs
39911
+ import fs2 from "node:fs/promises";
39912
+ import path3 from "node:path";
39913
+ var MIB = 1024 * 1024;
39914
+ var PDF = CONTEXT_FILE_TYPES.pdf;
39915
+ var MAX_FILE_NAME = 180;
39916
+ var isRecord6 = (value) => !!value && typeof value === "object" && !Array.isArray(value);
39917
+ var word = (value) => String(value ?? "").trim().toLowerCase();
39918
+ var plain = (value) => String(value ?? "").replace(new RegExp("\\p{Cc}", "gu"), " ").replace(/\s+/g, " ").trim();
39919
+ var megabytes = (bytes) => `${bytes / MIB} MB`;
39920
+ var workerReadsContext = (config) => {
39921
+ const profile = isRecord6(config?.storageProfile) ? config.storageProfile : {};
39922
+ const access = isRecord6(profile.payloadAccessControl) ? profile.payloadAccessControl : {};
39923
+ return ["cloudflare", "cf", "r2"].includes(word(profile.backend)) && word(access.encryption) !== "lit" && word(access.mode) !== "lit_encrypted";
39924
+ };
39925
+ var contextInvitation = ({ links }) => ({
39926
+ invitation: `You\u2019re invited to add context to this session: ${links ? "a file, a link or text" : "a file or text"}. Everyone in the session will see it.`,
39927
+ how: `Call add_context with exactly one of file (a local path)${links ? ", url" : ""} or text (with an optional title). Pass adminsOnly to show it to the session\u2019s admins alone.`,
39928
+ limits: {
39929
+ file: `PDF up to ${megabytes(CONTEXT_SOURCE_LIMITS.pdfBytes)}; Markdown, plain text, CSV or JSON up to ${megabytes(CONTEXT_SOURCE_LIMITS.textFileBytes)}.`,
39930
+ ...links ? { url: `A public https:// page of up to ${megabytes(CONTEXT_SOURCE_LIMITS.pageBytes)}, which the Session Worker reads once; the link up to ${CONTEXT_SOURCE_LIMITS.urlChars} characters.` } : {},
39931
+ text: `Up to ${megabytes(CONTEXT_SOURCE_LIMITS.textFileBytes)}, stored as a Markdown file; a title up to ${CONTEXT_SOURCE_LIMITS.titleChars} characters.`
39932
+ }
39933
+ });
39934
+ var MORE_SECRETS = [
39935
+ /\beyJ[\w-]{10,}\.eyJ[\w-]{10,}\.[\w-]{10,}/,
39936
+ /"(?:client_?secret|(?:refresh|access|id|auth|session)_?token|private_?key|api_?key|secret_?(?:access_?)?key|password|passwd)"\s*:\s*"[^"\s]{8,}"/i
39937
+ ];
39938
+ var refuseSecret = (value, what) => {
39939
+ if (looksSecret(value) || MORE_SECRETS.some((pattern) => pattern.test(value))) {
39940
+ throw new Error(`${what} looks like it holds a key, token or password, so nothing was added.`);
39941
+ }
39942
+ };
39943
+ var checkContextLink = ({ url, title }) => {
39944
+ const link = String(url ?? "").trim();
39945
+ if (!/^https:\/\/\S+$/i.test(link)) throw new Error("Pass an https:// link to a public page.");
39946
+ if (link.length > CONTEXT_SOURCE_LIMITS.urlChars) throw new Error(`The link must be ${CONTEXT_SOURCE_LIMITS.urlChars} characters or fewer.`);
39947
+ const name = plain(title);
39948
+ if (name.length > CONTEXT_SOURCE_LIMITS.titleChars) throw new Error(`The title must be ${CONTEXT_SOURCE_LIMITS.titleChars} characters or fewer.`);
39949
+ refuseSecret(link, "The link");
39950
+ refuseSecret(name, "The title");
39951
+ return { url: link, title: name };
39952
+ };
39953
+ var readContextFile = async (filePath, { stateDir }) => {
39954
+ const given = path3.resolve(String(filePath ?? "").trim());
39955
+ let real;
39956
+ try {
39957
+ real = await fs2.realpath(given);
39958
+ } catch {
39959
+ throw new Error(`There is no file at ${given}.`);
39960
+ }
39961
+ const state = await fs2.realpath(stateDir).catch(() => path3.resolve(stateDir));
39962
+ if (real === state || real.startsWith(`${state}${path3.sep}`)) {
39963
+ throw new Error("Files in the MCP\u2019s state folder, which holds this agent\u2019s key, are never added.");
39964
+ }
39965
+ if (real.split(path3.sep).some((part) => part.startsWith("."))) {
39966
+ throw new Error("Hidden files, and files in hidden folders, often hold keys and settings, so they are never added. Copy the file to an ordinary folder to add it.");
39967
+ }
39968
+ const stat = await fs2.stat(real);
39969
+ if (!stat.isFile()) throw new Error(`${given} is not a file.`);
39970
+ const name = path3.basename(real);
39971
+ const contentType = resolveContextFileType({ name });
39972
+ if (!contentType) throw new Error("Add a PDF, Markdown, plain text, CSV or JSON file.");
39973
+ const limit = contextFileByteLimit(contentType);
39974
+ const tooLarge = () => new Error(`${name} is larger than ${megabytes(limit)}, the most for a ${contentType === PDF ? "PDF" : "text file"}.`);
39975
+ if (stat.size > limit) throw tooLarge();
39976
+ const bytes = await fs2.readFile(real);
39977
+ if (bytes.length > limit) throw tooLarge();
39978
+ if (contentType === PDF) {
39979
+ if (bytes.subarray(0, 5).toString("latin1") !== "%PDF-") throw new Error(`${name} is not a PDF.`);
39980
+ } else {
39981
+ let content;
39982
+ try {
39983
+ content = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
39984
+ } catch {
39985
+ throw new Error(`${name} is not UTF-8 text.`);
39986
+ }
39987
+ refuseSecret(content, name);
39988
+ }
39989
+ return { name: name.slice(0, MAX_FILE_NAME), contentType, bytes };
39990
+ };
39991
+ var buildNote = ({ text: text6, title }) => {
39992
+ const content = typeof text6 === "string" ? text6.trim() : "";
39993
+ if (!content) throw new Error("Pass the text to add.");
39994
+ const bytes = Buffer.from(content, "utf8");
39995
+ if (bytes.length > CONTEXT_SOURCE_LIMITS.textFileBytes) {
39996
+ throw new Error(`The text is larger than ${megabytes(CONTEXT_SOURCE_LIMITS.textFileBytes)}, the most for a text file.`);
39997
+ }
39998
+ const named = plain(title);
39999
+ if (named.length > CONTEXT_SOURCE_LIMITS.titleChars) throw new Error(`The title must be ${CONTEXT_SOURCE_LIMITS.titleChars} characters or fewer.`);
40000
+ refuseSecret(content, "The text");
40001
+ refuseSecret(named, "The title");
40002
+ const firstLine = plain(content.split("\n")[0].replace(/^#+\s*/, "")).slice(0, CONTEXT_SOURCE_LIMITS.titleChars);
40003
+ const base = (named || firstLine || "Note").replace(/\.(?:md|markdown)$/i, "") || "Note";
40004
+ return { name: `${base}.md`, contentType: CONTEXT_FILE_TYPES.md, bytes };
40005
+ };
40006
+ var contextUploadForm = ({ name, contentType, bytes }, { adminsOnly = false, adderName = "" } = {}) => {
40007
+ const form = new FormData();
40008
+ form.append("file", new Blob([bytes], { type: contentType }), name);
40009
+ form.append("backend", "cloudflare");
40010
+ form.append("resource", "docsContext");
40011
+ form.append("contentType", contentType);
40012
+ form.append("payloadEncrypted", "false");
40013
+ form.append("tags", JSON.stringify([
40014
+ { name: "CE-DocLibrary", value: "1" },
40015
+ { name: CONTEXT_TAGS.kind, value: "file" },
40016
+ { name: "CE-DocStorage", value: "cloudflare" },
40017
+ { name: CONTEXT_TAGS.role, value: CONTEXT_ROLE },
40018
+ { name: CONTEXT_TAGS.name, value: name },
40019
+ { name: CONTEXT_TAGS.mime, value: contentType },
40020
+ ...agentAdderTags(adderName)
40021
+ ]));
40022
+ if (adminsOnly) form.append("accessConditions", JSON.stringify(ADMINS_ONLY_ACCESS));
40023
+ return form;
40024
+ };
40025
+
40026
+ // mcp/lib/knownSessions.mjs
40027
+ var LIST_PATH = "/known-sessions.json";
40028
+ var TIMEOUT_MS = 1e4;
40029
+ var MAX_LIST_BYTES = 512 * 1024;
40030
+ var MAX_AGE_MS = 6e4;
40031
+ var MAX_REDIRECTS = 2;
40032
+ var MAX_NAME_LENGTH = 120;
40033
+ var isRecord7 = (value) => !!value && typeof value === "object" && !Array.isArray(value);
40034
+ var Unreadable = class extends Error {
40035
+ };
40036
+ var createKnownSessions = ({ fetchImpl = globalThis.fetch, now = () => Date.now(), allowLocalWorkers = false } = {}) => {
40037
+ const cache = /* @__PURE__ */ new Map();
40038
+ const siteOf = (origin) => normalizeWorkerOrigin(origin, { allowLocalWorkers });
40039
+ const fetchList = async (site) => {
40040
+ let url = `${site}${LIST_PATH}`;
40041
+ for (let hop = 0; ; hop += 1) {
40042
+ let response;
40043
+ try {
40044
+ response = await fetchImpl(url, { redirect: "manual", headers: { Accept: "application/json" }, signal: AbortSignal.timeout(TIMEOUT_MS) });
40045
+ } catch (error) {
40046
+ throw new Unreadable(error?.name === "TimeoutError" ? "the site took too long to answer" : "the site could not be reached");
40047
+ }
40048
+ if (response.status >= 300 && response.status < 400) {
40049
+ if (hop >= MAX_REDIRECTS) throw new Unreadable("the site redirected too many times");
40050
+ let next;
40051
+ try {
40052
+ next = new URL(text(response.headers.get("location")), url);
40053
+ if (next.pathname !== LIST_PATH || next.search || next.username || next.password) throw new Error();
40054
+ url = `${siteOf(next.origin)}${LIST_PATH}`;
40055
+ } catch {
40056
+ throw new Unreadable("the site redirected somewhere other than a public https copy of the list");
40057
+ }
40058
+ continue;
40059
+ }
40060
+ if (response.status === 404) return null;
40061
+ if (!response.ok) throw new Unreadable(`the site answered ${response.status}`);
40062
+ if (!text(response.headers.get("content-type")).toLowerCase().includes("json")) return null;
40063
+ let body;
40064
+ try {
40065
+ body = await readLimitedText(response, MAX_LIST_BYTES);
40066
+ } catch (error) {
40067
+ if (error instanceof WorkerRequestError) throw new Unreadable("the list is too large");
40068
+ throw new Unreadable(error?.name === "TimeoutError" ? "the site took too long to answer" : "the list could not be read");
40069
+ }
40070
+ let list;
40071
+ try {
40072
+ list = JSON.parse(body);
40073
+ } catch {
40074
+ throw new Unreadable("the list is not valid JSON");
40075
+ }
40076
+ if (!isRecord7(list)) throw new Unreadable("the list is not a set of sessions");
40077
+ return list;
40078
+ }
40079
+ };
40080
+ const readList = (site) => {
40081
+ const cached = cache.get(site);
40082
+ if (cached && now() - cached.at < MAX_AGE_MS) return cached.list;
40083
+ const list = fetchList(site);
40084
+ cache.set(site, { at: now(), list });
40085
+ list.catch(() => {
40086
+ if (cache.get(site)?.list === list) cache.delete(site);
40087
+ });
40088
+ return list;
40089
+ };
40090
+ const lookup = async (appOrigin, slug) => {
40091
+ let site;
40092
+ try {
40093
+ site = siteOf(appOrigin);
40094
+ } catch {
40095
+ return { status: "unlisted" };
40096
+ }
40097
+ const listUrl = `${site}${LIST_PATH}`;
40098
+ let list;
40099
+ try {
40100
+ list = await readList(site);
40101
+ } catch (error) {
40102
+ return { status: "unreadable", listUrl, reason: error instanceof Unreadable ? error.message : "the list could not be read" };
40103
+ }
40104
+ if (!list || !Object.hasOwn(list, slug)) return { status: "unlisted" };
40105
+ const entry = list[slug];
40106
+ let workerOrigin = "";
40107
+ try {
40108
+ workerOrigin = normalizeWorkerOrigin(text(entry?.worker), { allowLocalWorkers });
40109
+ } catch {
40110
+ }
40111
+ const sessionId = normalizeSessionIdHex(text(entry?.sessionId));
40112
+ if (!isRecord7(entry) || !workerOrigin || !sessionId) {
40113
+ return { status: "unreadable", listUrl, reason: `its entry for "${slug}" has no usable Worker or session ID` };
40114
+ }
40115
+ const name = text(entry.name).slice(0, MAX_NAME_LENGTH);
40116
+ return { status: "listed", workerOrigin, sessionId, ...name ? { name } : {} };
40117
+ };
40118
+ return { lookup };
40119
+ };
40120
+
40121
+ // mcp/lib/results.mjs
40122
+ var text4 = (value) => typeof value === "string" ? value.trim() : "";
39555
40123
  var MAX_FREEFORM_SAMPLES = 5;
39556
40124
  var MAX_SAMPLE_LENGTH = 280;
39557
40125
  var isNewer = (candidate, current) => !current || candidate.createdAt > current.createdAt || candidate.createdAt === current.createdAt && candidate.storageId > current.storageId;
@@ -39560,11 +40128,11 @@ var latestAnswersByQuestion = (entries, { sessionSlug, sessionId, registryConfig
39560
40128
  for (const entry of entries) {
39561
40129
  const payload = entry?.payload;
39562
40130
  if (!payload || typeof payload !== "object" || Array.isArray(payload)) continue;
39563
- const questionId = (text2(payload.questionID) || text2(payload.questionId)).toLowerCase();
40131
+ const questionId = (text4(payload.questionID) || text4(payload.questionId)).toLowerCase();
39564
40132
  if (registryConfig) {
39565
40133
  if (!questionIds?.has(questionId) || !registryResponseMatchesSession(payload, registryConfig) || payload.answer?.encrypted === true) continue;
39566
- } else if (text2(payload.sessionSlug) !== sessionSlug || normalizeSessionIdHex(text2(payload.sessionId)) !== sessionId) continue;
39567
- const responder = text2(entry.responder).toLowerCase();
40134
+ } else if (text4(payload.sessionSlug) !== sessionSlug || normalizeSessionIdHex(text4(payload.sessionId)) !== sessionId) continue;
40135
+ const responder = text4(entry.responder).toLowerCase();
39568
40136
  if (!questionId || !responder) continue;
39569
40137
  const answers = byQuestion.get(questionId) || /* @__PURE__ */ new Map();
39570
40138
  const current = answers.get(responder);
@@ -39596,25 +40164,21 @@ var BINARY_VOTES = Object.freeze({
39596
40164
  0: "Unsure"
39597
40165
  });
39598
40166
  var validValue = (question, entry) => {
39599
- const payloadType = text2(entry?.payload?.type);
40167
+ const payloadType = text4(entry?.payload?.type);
39600
40168
  if (payloadType && payloadType !== question.type) return void 0;
39601
40169
  const value = rawValue(entry);
39602
40170
  if (value === void 0 || value === null || value === "*") return void 0;
39603
40171
  switch (question.type) {
39604
40172
  case "binary": {
39605
40173
  const scalar = Array.isArray(value) && value.every((item) => ["string", "number"].includes(typeof item)) ? value.join(",") : value;
39606
- const key = typeof scalar === "boolean" || typeof scalar === "number" ? String(scalar) : text2(scalar).toLowerCase();
40174
+ const key = typeof scalar === "boolean" || typeof scalar === "number" ? String(scalar) : text4(scalar).toLowerCase();
39607
40175
  return Object.hasOwn(BINARY_VOTES, key) ? BINARY_VOTES[key] : void 0;
39608
40176
  }
39609
- case "rating": {
39610
- if (typeof value !== "number" && !(typeof value === "string" && value.trim())) return void 0;
39611
- const number = Number(value);
39612
- const scale = ratingScaleFor(question);
39613
- return Number.isFinite(number) && number >= scale.min && number <= scale.max ? number : void 0;
39614
- }
40177
+ case "rating":
40178
+ return normalizeRatingAnswer(value, question) ?? void 0;
39615
40179
  case "multichoice": {
39616
- const options = (Array.isArray(question.options) ? question.options : []).map(text2).filter(Boolean);
39617
- const picks = (Array.isArray(value) ? value : [value]).map(text2);
40180
+ const options = (Array.isArray(question.options) ? question.options : []).map(text4).filter(Boolean);
40181
+ const picks = (Array.isArray(value) ? value : [value]).map(text4);
39618
40182
  if (!picks.length || picks.some((pick) => !pick)) return void 0;
39619
40183
  const canonical = options.length ? picks.map((pick) => options.find((option) => option.toLowerCase() === pick.toLowerCase()) || "") : picks;
39620
40184
  if (canonical.some((pick) => !pick)) return void 0;
@@ -39665,7 +40229,7 @@ var summarizeQuestion = (question, answersByResponder = /* @__PURE__ */ new Map(
39665
40229
  return { ...summary, scale: { min: scale.min, max: scale.max }, mean, histogram };
39666
40230
  }
39667
40231
  case "multichoice": {
39668
- const counts = new Map((Array.isArray(question.options) ? question.options : []).map(text2).filter(Boolean).map((option) => [option, 0]));
40232
+ const counts = new Map((Array.isArray(question.options) ? question.options : []).map(text4).filter(Boolean).map((option) => [option, 0]));
39669
40233
  answered.forEach((entry) => validValue(question, entry).forEach((option) => counts.set(option, (counts.get(option) || 0) + 1)));
39670
40234
  return { ...summary, counts: Object.fromEntries(counts) };
39671
40235
  }
@@ -39715,12 +40279,12 @@ var REVEAL_WAIT_MS = 9e4;
39715
40279
  var POLL_MS = 2e3;
39716
40280
  var GAS_HEADROOM_PERCENT = 130;
39717
40281
  var PASSWORD_CLAIM_GAS_BUDGET = 4e5;
39718
- var trim6 = (value) => typeof value === "string" ? value.trim() : typeof value === "number" ? String(value) : "";
39719
- var isRecord5 = (value) => !!value && typeof value === "object" && !Array.isArray(value);
40282
+ var trim7 = (value) => typeof value === "string" ? value.trim() : typeof value === "number" ? String(value) : "";
40283
+ var isRecord8 = (value) => !!value && typeof value === "object" && !Array.isArray(value);
39720
40284
  var defaultSleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
39721
40285
  var { deriveGroupPasswordWallet } = createGroupPasswordDerivation(import_ethers6.ethers);
39722
40286
  var normalizeGroupPasswordInput = (raw) => {
39723
- const compact = trim6(raw).replace(/\s+/g, "");
40287
+ const compact = trim7(raw).replace(/\s+/g, "");
39724
40288
  if (!compact) return "";
39725
40289
  if (import_ethers6.ethers.utils.isHexString(compact)) {
39726
40290
  try {
@@ -39732,14 +40296,14 @@ var normalizeGroupPasswordInput = (raw) => {
39732
40296
  return compact;
39733
40297
  };
39734
40298
  var decodeInviteCode = (raw) => {
39735
- let code = trim6(raw);
40299
+ let code = trim7(raw);
39736
40300
  const lower = code.toLowerCase();
39737
40301
  if (lower.startsWith("inv:")) code = code.slice(4).trim();
39738
40302
  else if (lower.startsWith("invite:")) code = code.slice(7).trim();
39739
40303
  if (!code || code.length > 4096) return null;
39740
40304
  try {
39741
40305
  const parsed = JSON.parse(Buffer.from(code.replace(/-/g, "+").replace(/_/g, "/"), "base64").toString("utf8"));
39742
- if (!isRecord5(parsed) || Object.keys(parsed).sort().join(",") !== "a,c,n,s") return null;
40306
+ if (!isRecord8(parsed) || Object.keys(parsed).sort().join(",") !== "a,c,n,s") return null;
39743
40307
  const chainId = import_ethers6.ethers.BigNumber.from(String(parsed.c));
39744
40308
  const slot = import_ethers6.ethers.BigNumber.from(String(parsed.n));
39745
40309
  const sbtAddress = import_ethers6.ethers.utils.getAddress(String(parsed.a));
@@ -39760,13 +40324,13 @@ var accessConditionsOf = (config) => [
39760
40324
  config?.sessionModeProfile?.encryption?.accessConditions,
39761
40325
  config?.storageProfile?.payloadAccessControl?.accessConditions
39762
40326
  ].flatMap((document) => Array.isArray(document?.conditions) ? document.conditions : []);
39763
- var conditionAddresses = (condition) => [condition?.contract, condition?.address, ...Array.isArray(condition?.sbtAddresses) ? condition.sbtAddresses : []].map((value) => trim6(value).toLowerCase()).filter(Boolean);
40327
+ var conditionAddresses = (condition) => [condition?.contract, condition?.address, ...Array.isArray(condition?.sbtAddresses) ? condition.sbtAddresses : []].map((value) => trim7(value).toLowerCase()).filter(Boolean);
39764
40328
  var positiveChainId = (value) => {
39765
40329
  const number = typeof value === "number" ? value : typeof value === "string" && value.trim() ? Number(value) : NaN;
39766
40330
  return Number.isSafeInteger(number) && number > 0 ? number : 0;
39767
40331
  };
39768
40332
  var resolveSbtChainId = (config, sbtAddress) => {
39769
- const target = trim6(sbtAddress).toLowerCase();
40333
+ const target = trim7(sbtAddress).toLowerCase();
39770
40334
  const condition = accessConditionsOf(config).find(
39771
40335
  (entry) => entry?.kind === "sbt_onchain" && conditionAddresses(entry).includes(target) && positiveChainId(entry.chainId)
39772
40336
  );
@@ -39784,7 +40348,7 @@ var listSessionSbts = (config) => {
39784
40348
  return [...seen.values()];
39785
40349
  };
39786
40350
  var defaultCreateProvider = (rpcOverride) => (chainId) => {
39787
- const url = trim6(rpcOverride) || import_rpcDefaults3.default.getPublicRpcUrls(chainId)[0] || import_rpcDefaults3.default.getPathRpcUrl(chainId);
40351
+ const url = trim7(rpcOverride) || import_rpcDefaults3.default.getPublicRpcUrls(chainId)[0] || import_rpcDefaults3.default.getPathRpcUrl(chainId);
39788
40352
  if (!url) throw new Error(`No public RPC is known for chain ${chainId}; set CE_MCP_RPC_URL.`);
39789
40353
  return new import_ethers6.ethers.providers.StaticJsonRpcProvider(url, chainId);
39790
40354
  };
@@ -39903,7 +40467,7 @@ var createSbtClaimer = ({
39903
40467
  const claimWithGroupPassword = async ({ ctx, provider, chainId, contract, sbtAddress, password }) => {
39904
40468
  const normalized2 = normalizeGroupPasswordInput(password);
39905
40469
  if (!normalized2) throw new ClaimError("This SBT needs a group password.");
39906
- const expectedHash = trim6(await contract.groupPasswordHash()).toLowerCase();
40470
+ const expectedHash = trim7(await contract.groupPasswordHash()).toLowerCase();
39907
40471
  if (!expectedHash || expectedHash === import_ethers6.ethers.constants.HashZero) throw new ClaimError("This SBT has no group password set.");
39908
40472
  const groupWallet = await deriveGroupPasswordWallet({ password: normalized2, sbtAddress });
39909
40473
  if (import_ethers6.ethers.utils.solidityKeccak256(["address"], [groupWallet.address]) !== expectedHash) {
@@ -39937,7 +40501,7 @@ var createSbtClaimer = ({
39937
40501
  signal = callSignal;
39938
40502
  let address;
39939
40503
  try {
39940
- address = import_ethers6.ethers.utils.getAddress(trim6(sbtAddress));
40504
+ address = import_ethers6.ethers.utils.getAddress(trim7(sbtAddress));
39941
40505
  } catch {
39942
40506
  throw new ClaimError("Pass the SBT contract address (0x\u2026).");
39943
40507
  }
@@ -39970,7 +40534,7 @@ var createSbtClaimer = ({
39970
40534
  const args = { ctx, provider, chainId, contract, sbtAddress: address };
39971
40535
  let transactions;
39972
40536
  if (mode === "public") transactions = [(await send({ ...args, method: "claim", args: [] })).transactionHash];
39973
- else if (mode === "password") transactions = await claimWithCommitReveal({ ...args, password: trim6(claimPassword) || trim6(groupPassword) });
40537
+ else if (mode === "password") transactions = await claimWithCommitReveal({ ...args, password: trim7(claimPassword) || trim7(groupPassword) });
39974
40538
  else if (mode === "group_password") transactions = await claimWithGroupPassword({ ...args, password: groupPassword });
39975
40539
  else transactions = await claimWithInviteCode({ ...args, code: inviteCode || groupPassword });
39976
40540
  return { ...base, mode, status: "claimed", transactions };
@@ -39996,11 +40560,17 @@ var MAX_CACHED_RECORDS = 2e4;
39996
40560
  var MISSING_RECORD_RETRY_MS = 6e4;
39997
40561
  var MAX_OWN_ANSWER_ITEMS = 5e3;
39998
40562
  var MAX_TITLE_LENGTH = 120;
39999
- var MAX_CONTEXT_PARAGRAPHS = 4;
40000
- var MAX_CONTEXT_LENGTH = 2e3;
40001
- var MAX_CONTEXT_LINKS = 4;
40002
- var trim7 = (value) => typeof value === "string" ? value.trim() : typeof value === "number" ? String(value) : "";
40003
- var isRecord6 = (value) => !!value && typeof value === "object" && !Array.isArray(value);
40563
+ var MAX_DESCRIPTION_LENGTH = 2e3;
40564
+ var MAX_GROUPS = 100;
40565
+ var MAX_GROUP_TAGS = 20;
40566
+ var MAX_TAG_LENGTH2 = 80;
40567
+ var CONTEXT_ADMINS_ONLY = "This session limits context to its admins, so nothing was added.";
40568
+ var CONTEXT_ENDED = "This session has ended, so it takes no more context.";
40569
+ var CONTEXT_NO_LINKS = "This session\u2019s Worker doesn\u2019t take links from participants yet. You can add a file or text.";
40570
+ var CONTEXT_NO_FETCH = "This session doesn\u2019t let you have its Worker fetch pages, so it takes no links from you. You can add a file or text.";
40571
+ var CONTEXT_RATE_LIMITED = "The session\u2019s Worker is rate limiting you, so nothing was added. Retry in a few minutes; if it still refuses, you may have reached the session\u2019s daily limit for your address, which clears within a day.";
40572
+ var trim8 = (value) => typeof value === "string" ? value.trim() : typeof value === "number" ? String(value) : "";
40573
+ var isRecord9 = (value) => !!value && typeof value === "object" && !Array.isArray(value);
40004
40574
  var sessionKey = (info) => info.kind === "registry" ? `registry ${info.chainId || 11155420} ${info.slug}` : `${info.workerOrigin} ${info.slug}`;
40005
40575
  var mapLimit = async (items, limit, task) => {
40006
40576
  const results = new Array(items.length);
@@ -40016,10 +40586,10 @@ var mapLimit = async (items, limit, task) => {
40016
40586
  return results;
40017
40587
  };
40018
40588
  var contextOf = (config) => {
40019
- const context = isRecord6(config?.sessionContext) ? config.sessionContext : {};
40020
- const paragraphs = (Array.isArray(context.paragraphs) ? context.paragraphs.map(text) : [text(context.body)]).filter(Boolean).slice(0, MAX_CONTEXT_PARAGRAPHS).map((paragraph) => paragraph.slice(0, MAX_CONTEXT_LENGTH));
40021
- const links = (Array.isArray(context.links) ? context.links : []).filter((link) => isRecord6(link) && /^https?:\/\//i.test(text(link.url))).slice(0, MAX_CONTEXT_LINKS).map((link) => ({ label: (text(link.label) || text(link.url)).slice(0, 200), url: text(link.url).slice(0, 2e3) }));
40022
- return { title: text(context.title).slice(0, 200), paragraphs, links };
40589
+ const { html, ...context } = normalizeSessionContext(config?.sessionContext);
40590
+ if (!html) return context;
40591
+ const words = htmlToPlainText(html);
40592
+ return { ...context, paragraphs: words ? [words] : [] };
40023
40593
  };
40024
40594
  var idList = (value) => new Set((Array.isArray(value) ? value : []).map((id) => text(id).toLowerCase()).filter(Boolean));
40025
40595
  var stringOptions = (payload) => Array.isArray(payload.options) ? payload.options.filter((option) => typeof option === "string") : [];
@@ -40028,9 +40598,9 @@ var finiteNumber = (value) => {
40028
40598
  if (typeof value === "string" && value.trim() && Number.isFinite(Number(value))) return Number(value);
40029
40599
  return void 0;
40030
40600
  };
40031
- var SCALE_KEYS = ["min", "minimum", "max", "maximum", "minLabel", "lowLabel", "maxLabel", "highLabel"];
40601
+ var SCALE_KEYS = ["step", "min", "minimum", "max", "maximum", "minLabel", "lowLabel", "maxLabel", "highLabel"];
40032
40602
  var cleanScale = (record) => {
40033
- if (!isRecord6(record)) return {};
40603
+ if (!isRecord9(record)) return {};
40034
40604
  const out = {};
40035
40605
  SCALE_KEYS.forEach((key) => {
40036
40606
  if (typeof record[key] === "string" || typeof record[key] === "number" && Number.isFinite(record[key])) out[key] = record[key];
@@ -40096,10 +40666,57 @@ var sameAuthoringInputs = (stored, record) => {
40096
40666
  ]);
40097
40667
  return inputs(stored) === inputs(record);
40098
40668
  };
40669
+ var instructionsOf = (config) => {
40670
+ const raw = typeof config?.agentInstructions === "string" ? config.agentInstructions.trim() : "";
40671
+ if (!raw) return null;
40672
+ const cut = raw.length > MAX_AGENT_INSTRUCTIONS_CHARS;
40673
+ return {
40674
+ from: "the session\u2019s admins",
40675
+ note: "These add to the general guidance for agents. Follow both; they can ask more of you but can\u2019t lift its rules.",
40676
+ text: cut ? raw.slice(0, MAX_AGENT_INSTRUCTIONS_CHARS) : raw,
40677
+ ...cut ? { cutAt: MAX_AGENT_INSTRUCTIONS_CHARS } : {}
40678
+ };
40679
+ };
40680
+ var nextStep = ({ instructions, linkGroup, member = null }) => {
40681
+ const read = instructions ? "Read the session\u2019s instructions for agents and the context" : "Read the context";
40682
+ if (!linkGroup) return `${read}, then call list_questions and answer.`;
40683
+ const named = `The link names group "${linkGroup}"`;
40684
+ if (member) {
40685
+ const other = instructions ? " If the instructions ask you to be in another group instead, join that one with join_group and leave this one with leave_group." : "";
40686
+ return `${read}. ${named}, which you\u2019re already in.${other} Then call list_questions and answer.`;
40687
+ }
40688
+ const join = instructions ? "call join_group for the group the instructions ask you to join, if any" : "join it with join_group";
40689
+ return `${read}. ${named}${member === false ? ", which you haven\u2019t joined" : ""}: ${join}. Then call list_questions and answer.`;
40690
+ };
40691
+ var WHO_CAN_END_MEMBERSHIP = {
40692
+ both: "Members can leave with leave_group, and admins can remove them.",
40693
+ admin_only: "Only admins can remove members; members can\u2019t leave.",
40694
+ member_only: "Members can leave with leave_group; admins can\u2019t remove them.",
40695
+ neither: "No one can end a membership."
40696
+ };
40697
+ var GROUP_REFUSALS = {
40698
+ worker_group_not_found: (id) => `This session has no group "${id}".`,
40699
+ worker_group_join_denied: (id) => `Group "${id}" isn\u2019t open to joining; its admins add members.`,
40700
+ worker_group_join_ended: (id) => `Joining group "${id}" has closed.`,
40701
+ worker_group_member_cap_exceeded: (id) => `Group "${id}" has no room for more members.`,
40702
+ worker_group_member_not_found: (id) => `You aren\u2019t a member of group "${id}".`,
40703
+ worker_group_leave_denied: (id) => `Group "${id}" doesn\u2019t let members leave.`
40704
+ };
40705
+ var groupRefusal = (error, id) => error instanceof WorkerRequestError && Object.hasOwn(GROUP_REFUSALS, error.code) ? new Error(GROUP_REFUSALS[error.code](id)) : error;
40706
+ var contextRefusal = (error, { olderLink = false } = {}) => {
40707
+ if (!(error instanceof WorkerRequestError)) return error;
40708
+ if (error.code === "context_admin_required") return new Error(olderLink ? CONTEXT_NO_LINKS : CONTEXT_ADMINS_ONLY);
40709
+ if (error.code === "context_link_fetch_denied") return new Error(CONTEXT_NO_FETCH);
40710
+ if (error.status === 410) return new Error(CONTEXT_ENDED);
40711
+ if (error.status === 429) return new Error(CONTEXT_RATE_LIMITED);
40712
+ return error;
40713
+ };
40099
40714
  var progressNotes = (questions, mine) => ({
40100
40715
  ...questions.locked ? { lockedQuestions: questions.locked } : {},
40101
40716
  ...questions.complete === false ? { questionsComplete: false } : {},
40102
- ...mine.complete === false ? { myAnswersComplete: false, note: "This session is large: answers made outside this agent may not all be listed." } : {}
40717
+ ...questions.unread ? { unreadQuestions: questions.unread } : {},
40718
+ ...mine.unread ? { unreadMyAnswers: mine.unread } : {},
40719
+ ...mine.complete === false ? { myAnswersComplete: false, note: "Some answers could not be read or the scan is unfinished; the answers shown may be incomplete." } : {}
40103
40720
  });
40104
40721
  var createParticipant = ({ config, wallet, fetchImpl = globalThis.fetch, now = () => Date.now(), sbt = null, createProvider, sleep, registry = {} }) => {
40105
40722
  const requestTestEth = createTestEthRequester({ config, wallet, createProvider, now, sleep });
@@ -40125,9 +40742,9 @@ var createParticipant = ({ config, wallet, fetchImpl = globalThis.fetch, now = (
40125
40742
  state = await updateAgentState(config.stateDir, mutate);
40126
40743
  };
40127
40744
  const profile = () => ({
40128
- displayName: trim7(state?.profile?.displayName ?? config.profile.displayName),
40129
- modelId: trim7(state?.profile?.modelId ?? config.profile.modelId),
40130
- platform: trim7(state?.profile?.platform ?? config.profile.platform)
40745
+ displayName: trim8(state?.profile?.displayName ?? config.profile.displayName),
40746
+ modelId: trim8(state?.profile?.modelId ?? config.profile.modelId),
40747
+ platform: trim8(state?.profile?.platform ?? config.profile.platform)
40131
40748
  });
40132
40749
  const trustedOriginsFor = (preferred) => config.trustedAppOrigins.includes(preferred) ? [preferred, ...config.trustedAppOrigins.filter((origin) => origin !== preferred)] : config.trustedAppOrigins;
40133
40750
  const openSession = async (info) => {
@@ -40145,7 +40762,8 @@ var createParticipant = ({ config, wallet, fetchImpl = globalThis.fetch, now = (
40145
40762
  wallet,
40146
40763
  fetchImpl,
40147
40764
  now,
40148
- ...onchain ? { registryConfigLoader: onchain.loadConfig } : {}
40765
+ // A hosted session reopened from state must still be the one the agent joined.
40766
+ ...onchain ? { registryConfigLoader: onchain.loadConfig } : { sessionId: text(info.sessionId) }
40149
40767
  }),
40150
40768
  records: /* @__PURE__ */ new Map(),
40151
40769
  missing: /* @__PURE__ */ new Map()
@@ -40153,9 +40771,84 @@ var createParticipant = ({ config, wallet, fetchImpl = globalThis.fetch, now = (
40153
40771
  }
40154
40772
  return sessions.get(key);
40155
40773
  };
40774
+ const knownSessions = createKnownSessions({ fetchImpl, now, allowLocalWorkers: config.allowLocalWorkers });
40775
+ const resolveLink = async (link) => {
40776
+ const parsed = parseSessionLink(link, { allowLocalWorkers: config.allowLocalWorkers });
40777
+ if (parsed.kind !== "registry") return parsed;
40778
+ const found = await knownSessions.lookup(parsed.appOrigin, parsed.slug);
40779
+ if (found.status === "unlisted") return parsed;
40780
+ if (found.status === "unreadable") {
40781
+ throw new Error(
40782
+ `The list of known sessions at ${found.listUrl} could not be read (${found.reason}). If this session is on a Session Worker, ask for its link with worker=, the Worker\u2019s address; otherwise try again later.`
40783
+ );
40784
+ }
40785
+ const hosted = { ...parsed, workerOrigin: found.workerOrigin, listedSessionId: found.sessionId };
40786
+ delete hosted.kind;
40787
+ delete hosted.chainId;
40788
+ return hosted;
40789
+ };
40790
+ const hasEnded = (sessionConfig) => {
40791
+ const endsAt = Date.parse(text(sessionConfig?.sessionEndsAt));
40792
+ return Number.isFinite(endsAt) && endsAt <= now();
40793
+ };
40794
+ const isSessionAdmin = (ctx, sessionConfig) => {
40795
+ const self2 = wallet.address.toLowerCase();
40796
+ const admins = [sessionConfig?.adminAddress, ...Array.isArray(sessionConfig?.adminAddresses) ? sessionConfig.adminAddresses : []];
40797
+ return admins.some((address) => text(address).toLowerCase() === self2) || ctx.client.tokenClaims?.scopes?.admin === true;
40798
+ };
40799
+ const mayAddLinks = (ctx, sessionConfig) => isSessionAdmin(ctx, sessionConfig) || ctx.client.tokenClaims?.scopes?.fetch === true;
40800
+ const describeGroups = async (ctx) => {
40801
+ let listed;
40802
+ let mine;
40803
+ try {
40804
+ [listed, mine] = await Promise.all([ctx.client.listGroups(), ctx.client.listMyMemberships()]);
40805
+ } catch (error) {
40806
+ if (error instanceof WorkerRequestError && error.status === 501) return {};
40807
+ if (error instanceof WorkerRequestError && error.code === "worker_group_capacity_reconciliation_required") {
40808
+ return { groupsUnavailable: "This session\u2019s groups can\u2019t be listed on its Worker yet." };
40809
+ }
40810
+ return { groupsUnavailable: describeError(error) };
40811
+ }
40812
+ const idOf = (group) => text(group?.groupId).toLowerCase();
40813
+ const memberOf = new Map(mine.filter((entry) => idOf(entry.group)).map((entry) => [idOf(entry.group), entry]));
40814
+ const entries = [
40815
+ ...listed.filter((group) => idOf(group)).map((group) => ({ group, member: memberOf.has(idOf(group)), memberCount: group.memberCount })),
40816
+ ...[...memberOf.values()].filter((entry) => !listed.some((group) => idOf(group) === idOf(entry.group))).map((entry) => ({ group: entry.group, member: true, memberCount: entry.memberCount }))
40817
+ ];
40818
+ const groups = entries.slice(0, MAX_GROUPS).map(({ group, member, memberCount }) => {
40819
+ const tags = Array.isArray(group.tags) ? group.tags.map((tag) => text(tag).slice(0, MAX_TAG_LENGTH2)).filter(Boolean).slice(0, MAX_GROUP_TAGS) : [];
40820
+ const members = Number.isSafeInteger(memberCount) && memberCount >= 0 ? memberCount : null;
40821
+ const limit = Number.isSafeInteger(group.memberLimit) && group.memberLimit > 0 ? group.memberLimit : 0;
40822
+ const closesAt = text(group.joinEndsAt);
40823
+ const open = text(group.joinMode).toLowerCase() === "open";
40824
+ let joining = open ? "Open: join with join_group." : "Only admins add members.";
40825
+ if (open && closesAt && Date.parse(closesAt) <= now()) joining = "Joining has closed.";
40826
+ else if (open && limit && members !== null && members >= limit) joining = "Full.";
40827
+ const removalAuth = text(group.removalAuth).toLowerCase() || "both";
40828
+ return {
40829
+ groupId: text(group.groupId),
40830
+ name: text(group.label).slice(0, MAX_TITLE_LENGTH),
40831
+ ...text(group.description) ? { description: text(group.description).slice(0, MAX_DESCRIPTION_LENGTH) } : {},
40832
+ ...tags.length ? { tags } : {},
40833
+ joining,
40834
+ ...open && closesAt ? { joinClosesAt: closesAt } : {},
40835
+ ...members !== null ? { members } : {},
40836
+ ...limit ? { memberLimit: limit } : {},
40837
+ member,
40838
+ ...Object.hasOwn(WHO_CAN_END_MEMBERSHIP, removalAuth) ? { whoCanEndMembership: WHO_CAN_END_MEMBERSHIP[removalAuth] } : {}
40839
+ };
40840
+ });
40841
+ return { groups };
40842
+ };
40843
+ const invitationFor = async (ctx, sessionConfig) => {
40844
+ if (ctx.registry || !participantsMayAddContext(sessionConfig) || hasEnded(sessionConfig) || !workerReadsContext(sessionConfig)) return {};
40845
+ const features = await ctx.client.readFeatures();
40846
+ if (!features?.includes("participant_context_v1")) return {};
40847
+ return { addingContext: contextInvitation({ links: features.includes("participant_context_links_v1") && mayAddLinks(ctx, sessionConfig) }) };
40848
+ };
40156
40849
  const remember = (ctx, title, recruitmentSource) => saveState((fresh) => {
40157
40850
  const key = sessionKey(ctx.info);
40158
- const stored = isRecord6(fresh.sessions[key]) ? fresh.sessions[key] : {};
40851
+ const stored = isRecord9(fresh.sessions[key]) ? fresh.sessions[key] : {};
40159
40852
  const previous = stored.sessionId && stored.sessionId !== ctx.client.sessionId ? {} : stored;
40160
40853
  fresh.sessions[key] = {
40161
40854
  ...previous,
@@ -40172,12 +40865,12 @@ var createParticipant = ({ config, wallet, fetchImpl = globalThis.fetch, now = (
40172
40865
  });
40173
40866
  const sessionState = (ctx) => {
40174
40867
  const entry = state?.sessions?.[sessionKey(ctx.info)];
40175
- return isRecord6(entry) ? entry : {};
40868
+ return isRecord9(entry) ? entry : {};
40176
40869
  };
40177
40870
  const rememberAnswers = (ctx, answered) => saveState((fresh) => {
40178
40871
  const entry = fresh.sessions[sessionKey(ctx.info)];
40179
- if (!isRecord6(entry) || entry.sessionId !== ctx.client.sessionId) return;
40180
- entry.answers = isRecord6(entry.answers) ? entry.answers : {};
40872
+ if (!isRecord9(entry) || entry.sessionId !== ctx.client.sessionId) return;
40873
+ entry.answers = isRecord9(entry.answers) ? entry.answers : {};
40181
40874
  answered.forEach(({ questionId, record, answeredAt, chainOrder, requestId }) => {
40182
40875
  entry.answers[questionId] = {
40183
40876
  value: record.answer.value,
@@ -40190,12 +40883,12 @@ var createParticipant = ({ config, wallet, fetchImpl = globalThis.fetch, now = (
40190
40883
  });
40191
40884
  const resolveSession = async (session) => {
40192
40885
  await loadState();
40193
- const ref = trim7(session);
40886
+ const ref = trim8(session);
40194
40887
  if (/^https?:\/\//i.test(ref)) {
40195
- const parsed = parseSessionLink(ref, { allowLocalWorkers: config.allowLocalWorkers });
40888
+ const parsed = await resolveLink(ref);
40196
40889
  const key2 = sessionKey(parsed);
40197
- if (!state.sessions[key2]) throw new Error("Join this session first with join_session.");
40198
- return openSession(state.sessions[key2]);
40890
+ if (!isRecord9(state.sessions[key2])) throw new Error("Join this session first with join_session.");
40891
+ return openEntry(state.sessions[key2]);
40199
40892
  }
40200
40893
  let key = state.current;
40201
40894
  if (ref) {
@@ -40206,14 +40899,15 @@ var createParticipant = ({ config, wallet, fetchImpl = globalThis.fetch, now = (
40206
40899
  if (!key) throw new Error(`No joined session named "${slug}". Join it first with join_session.`);
40207
40900
  }
40208
40901
  const entry = state.sessions[key];
40209
- if (!key || !isRecord6(entry)) throw new Error("No session joined yet. Call join_session with a session link.");
40210
- return openSession({
40211
- workerOrigin: normalizeWorkerOrigin(entry.workerOrigin, { allowLocalWorkers: config.allowLocalWorkers }),
40212
- slug: normalizeSessionSlug(entry.slug),
40213
- appOrigin: text(entry.appOrigin),
40214
- ...entry.kind === "registry" ? { kind: "registry", chainId: entry.chainId } : {}
40215
- });
40902
+ if (!key || !isRecord9(entry)) throw new Error("No session joined yet. Call join_session with a session link.");
40903
+ return openEntry(entry);
40216
40904
  };
40905
+ const openEntry = async (entry) => openSession({
40906
+ workerOrigin: normalizeWorkerOrigin(entry.workerOrigin, { allowLocalWorkers: config.allowLocalWorkers }),
40907
+ slug: normalizeSessionSlug(entry.slug),
40908
+ appOrigin: text(entry.appOrigin),
40909
+ ...entry.kind === "registry" ? { kind: "registry", chainId: entry.chainId } : { sessionId: text(entry.sessionId) }
40910
+ });
40217
40911
  const ensureReady = async (ctx) => {
40218
40912
  await ctx.client.refreshConfig();
40219
40913
  ctx.info.appOrigin = ctx.client.loginOrigin;
@@ -40226,33 +40920,27 @@ var createParticipant = ({ config, wallet, fetchImpl = globalThis.fetch, now = (
40226
40920
  };
40227
40921
  const readCached = async (ctx, storageId) => {
40228
40922
  if (ctx.records.has(storageId)) return ctx.records.get(storageId);
40229
- if (now() - (ctx.missing.get(storageId) ?? -Infinity) < MISSING_RECORD_RETRY_MS) return null;
40230
- let payload = null;
40923
+ if (now() - (ctx.missing.get(storageId) ?? -Infinity) < MISSING_RECORD_RETRY_MS) return void 0;
40231
40924
  try {
40232
- payload = await ctx.client.read(storageId);
40925
+ const payload = await ctx.client.read(storageId);
40926
+ ctx.missing.delete(storageId);
40927
+ cacheRecord(ctx, storageId, payload);
40928
+ return payload;
40233
40929
  } catch (error) {
40234
40930
  if (!(error instanceof WorkerRequestError) || error.status !== 404) throw error;
40235
- }
40236
- if (payload === null) {
40237
40931
  ctx.missing.set(storageId, now());
40238
40932
  if (ctx.missing.size > MAX_CACHED_RECORDS) ctx.missing.delete(ctx.missing.keys().next().value);
40239
- } else {
40240
- ctx.missing.delete(storageId);
40241
- cacheRecord(ctx, storageId, payload);
40933
+ return void 0;
40242
40934
  }
40243
- return payload;
40244
40935
  };
40245
40936
  const readMany = async (ctx, storageIds) => {
40246
40937
  const deadline = now() + READ_DEADLINE_MS;
40247
- let complete = true;
40248
40938
  const payloads = await mapLimit(storageIds, READ_CONCURRENCY, async (storageId) => {
40249
- if (!ctx.records.has(storageId) && (now() >= deadline || signal?.aborted)) {
40250
- complete = false;
40251
- return void 0;
40252
- }
40253
- return readCached(ctx, storageId);
40939
+ if (!ctx.records.has(storageId) && (now() >= deadline || signal?.aborted)) return void 0;
40940
+ return readCached(ctx, storageId).catch(() => void 0);
40254
40941
  });
40255
- return { payloads, complete };
40942
+ const unread = payloads.filter((payload) => payload === void 0).length;
40943
+ return { payloads, complete: unread === 0, unread };
40256
40944
  };
40257
40945
  const loadQuestions = async (ctx) => {
40258
40946
  const sessionConfig = await ensureReady(ctx);
@@ -40262,7 +40950,7 @@ var createParticipant = ({ config, wallet, fetchImpl = globalThis.fetch, now = (
40262
40950
  const all2 = [];
40263
40951
  for (const row of result.items) {
40264
40952
  try {
40265
- if (!isRecord6(row.payload) || typeof row.payload.type !== "string") continue;
40953
+ if (!isRecord9(row.payload) || typeof row.payload.type !== "string") continue;
40266
40954
  const payload = isLockedQuestion(row.payload) ? { ...row.payload, prompt: "[encrypted]", locked: true } : row.payload;
40267
40955
  if (typeof payload.prompt !== "string") continue;
40268
40956
  all2.push({
@@ -40283,15 +40971,15 @@ var createParticipant = ({ config, wallet, fetchImpl = globalThis.fetch, now = (
40283
40971
  }
40284
40972
  const { items, complete } = await ctx.client.listAll("questions", { maxItems: MAX_QUESTIONS2, signal });
40285
40973
  const hidden = new Set(items.filter((item) => item.hidden === true).map((item) => text(item.metadata?.resourceId).toLowerCase()));
40286
- const rows = items.filter((item) => item.hidden !== true && text(item.storageRef?.id));
40287
- const { payloads, complete: readComplete } = await readMany(ctx, rows.map((item) => text(item.storageRef.id)));
40288
40974
  const blocked = idList(sessionConfig.BLOCKED_QUESTION_IDS);
40975
+ const rows = items.filter((item) => item.hidden !== true && text(item.storageRef?.id) && !hidden.has(text(item.metadata?.resourceId).toLowerCase()) && !blocked.has(text(item.metadata?.resourceId).toLowerCase()));
40976
+ const { payloads, complete: readComplete, unread } = await readMany(ctx, rows.map((item) => text(item.storageRef.id)));
40289
40977
  const highlighted = idList(sessionConfig.HIGHLIGHTED_QUESTION_IDS);
40290
40978
  const versions = /* @__PURE__ */ new Map();
40291
40979
  rows.forEach((item, index) => {
40292
40980
  try {
40293
40981
  const payload = payloads[index];
40294
- if (!isRecord6(payload) || typeof payload.prompt !== "string" || typeof payload.type !== "string") return;
40982
+ if (!isRecord9(payload) || typeof payload.prompt !== "string" || typeof payload.type !== "string") return;
40295
40983
  if (text(payload.sessionSlug) !== ctx.info.slug) return;
40296
40984
  if (text(payload.sessionId) && normalizeSessionIdHex(text(payload.sessionId)) !== ctx.client.sessionId) return;
40297
40985
  const id = (text(payload.id) || text(item.metadata?.resourceId)).toLowerCase();
@@ -40328,11 +41016,12 @@ var createParticipant = ({ config, wallet, fetchImpl = globalThis.fetch, now = (
40328
41016
  questions.locked = all.length - questions.length;
40329
41017
  questions.lockedIds = new Set(all.filter((question) => isLockedQuestion(question)).map((question) => question.id));
40330
41018
  questions.complete = complete && readComplete;
41019
+ questions.unread = unread;
40331
41020
  return questions;
40332
41021
  };
40333
41022
  const toEntries = async (ctx, items) => {
40334
- const rows = items.filter((item) => text(item.storageRef?.id));
40335
- const { payloads, complete } = await readMany(ctx, rows.map((item) => text(item.storageRef.id)));
41023
+ const rows = items.filter((item) => item.hidden !== true && text(item.storageRef?.id));
41024
+ const { payloads, complete, unread } = await readMany(ctx, rows.map((item) => text(item.storageRef.id)));
40336
41025
  const entries = rows.map((item, index) => ({
40337
41026
  storageId: text(item.storageRef.id),
40338
41027
  createdAt: text(item.metadata?.createdAt) || text(item.storageRef?.createdAt),
@@ -40340,22 +41029,23 @@ var createParticipant = ({ config, wallet, fetchImpl = globalThis.fetch, now = (
40340
41029
  payload: payloads[index]
40341
41030
  }));
40342
41031
  entries.complete = complete;
41032
+ entries.unread = unread;
40343
41033
  return entries;
40344
41034
  };
40345
41035
  const scanMyAnswers = async (ctx) => {
40346
- if (ctx.ownScan && (!ctx.registry || ctx.ownScan.complete) && now() - ctx.ownScan.at < OWN_ANSWER_SCAN_MAX_AGE_MS && ctx.ownScan.sessionId === ctx.client.sessionId) {
41036
+ if (ctx.ownScan && ctx.ownScan.complete && now() - ctx.ownScan.at < OWN_ANSWER_SCAN_MAX_AGE_MS && ctx.ownScan.sessionId === ctx.client.sessionId && ctx.ownScan.windowKey === ctx.registry?.windowKey) {
40347
41037
  return ctx.ownScan;
40348
41038
  }
40349
41039
  if (ctx.registry) {
40350
41040
  const questions = await loadQuestions(ctx);
40351
41041
  const questionIds = new Set(questions.map((question) => question.id));
40352
- const { entries: entries2, complete: complete2, chainOrders } = await ctx.registry.readAnswers({ questionIds, maxRecords: MAX_OWN_ANSWER_ITEMS, mine: true, signal });
41042
+ const { entries: entries2, complete: complete2, chainOrders, unreadAnswers } = await ctx.registry.readAnswers({ questionIds, maxRecords: MAX_OWN_ANSWER_ITEMS, mine: true, signal });
40353
41043
  const latest2 = latestAnswersByQuestion(entries2, { registryConfig: ctx.client.config, questionIds });
40354
41044
  const answers2 = /* @__PURE__ */ new Map();
40355
41045
  latest2.forEach((byResponder, id) => {
40356
41046
  if (byResponder.has(wallet.address.toLowerCase())) answers2.set(id, byResponder.get(wallet.address.toLowerCase()));
40357
41047
  });
40358
- ctx.ownScan = { at: now(), sessionId: ctx.client.sessionId, answers: answers2, complete: complete2, chainOrders };
41048
+ ctx.ownScan = { at: now(), sessionId: ctx.client.sessionId, windowKey: ctx.registry.windowKey, answers: answers2, complete: complete2, chainOrders, unread: unreadAnswers };
40359
41049
  return ctx.ownScan;
40360
41050
  }
40361
41051
  const { items, complete: listed } = await ctx.client.listAll("responses", {
@@ -40374,7 +41064,7 @@ var createParticipant = ({ config, wallet, fetchImpl = globalThis.fetch, now = (
40374
41064
  const entry = byResponder.get(self2);
40375
41065
  if (entry) answers.set(questionId, entry);
40376
41066
  });
40377
- ctx.ownScan = { at: now(), sessionId: ctx.client.sessionId, answers, complete };
41067
+ ctx.ownScan = { at: now(), sessionId: ctx.client.sessionId, answers, complete, unread: entries.unread };
40378
41068
  return ctx.ownScan;
40379
41069
  };
40380
41070
  const loadMyAnswers = async (ctx) => {
@@ -40384,10 +41074,10 @@ var createParticipant = ({ config, wallet, fetchImpl = globalThis.fetch, now = (
40384
41074
  let complete = scan.complete;
40385
41075
  const blocks = /* @__PURE__ */ new Map();
40386
41076
  await loadState();
40387
- const local = sessionState(ctx).sessionId === ctx.client.sessionId && isRecord6(sessionState(ctx).answers) ? sessionState(ctx).answers : {};
41077
+ const local = sessionState(ctx).sessionId === ctx.client.sessionId && isRecord9(sessionState(ctx).answers) ? sessionState(ctx).answers : {};
40388
41078
  for (const [questionId, answer] of Object.entries(local)) {
40389
- if (!isRecord6(answer)) continue;
40390
- if (ctx.registry && !scan.complete) continue;
41079
+ if (!isRecord9(answer)) continue;
41080
+ if (ctx.registry && (!scan.complete || !ctx.registry.containsBlock(answer.blockNumber))) continue;
40391
41081
  const known = mine.get(questionId);
40392
41082
  const chainOrder = scan.chainOrders?.get(questionId);
40393
41083
  if (ctx.registry && chainOrder && compareChainOrder(answer, chainOrder) < 0) continue;
@@ -40408,6 +41098,7 @@ var createParticipant = ({ config, wallet, fetchImpl = globalThis.fetch, now = (
40408
41098
  if (value === "" || value === null || value === void 0 || Array.isArray(value) && !value.length) mine.delete(questionId);
40409
41099
  });
40410
41100
  mine.complete = complete;
41101
+ mine.unread = scan.unread;
40411
41102
  return mine;
40412
41103
  };
40413
41104
  const sessionSummary = (ctx, sessionConfig) => ({
@@ -40423,12 +41114,12 @@ var createParticipant = ({ config, wallet, fetchImpl = globalThis.fetch, now = (
40423
41114
  address: wallet.address,
40424
41115
  profile: profile(),
40425
41116
  currentSession: state.sessions[state.current]?.slug || null,
40426
- sessions: await mapLimit(Object.values(state.sessions).filter(isRecord6), READ_CONCURRENCY, async (entry) => ({
41117
+ sessions: await mapLimit(Object.values(state.sessions).filter(isRecord9), READ_CONCURRENCY, async (entry) => ({
40427
41118
  session: entry.slug,
40428
41119
  title: entry.title || entry.slug,
40429
41120
  webUrl: buildSessionWebUrl(entry),
40430
41121
  joinedAt: entry.joinedAt,
40431
- testEth: await resolveSession(buildSessionWebUrl(entry)).then((ctx) => ctx.client.describeTestEth()).catch(() => ({ offered: false, reason: "Session availability could not be checked." }))
41122
+ testEth: await openEntry(entry).then((ctx) => ctx.client.describeTestEth()).catch(() => ({ offered: false, reason: "Session availability could not be checked." }))
40432
41123
  }))
40433
41124
  };
40434
41125
  },
@@ -40444,9 +41135,9 @@ var createParticipant = ({ config, wallet, fetchImpl = globalThis.fetch, now = (
40444
41135
  },
40445
41136
  async joinSession({ link, worker, session, inviteCode, groupPassword, claimPassword } = {}) {
40446
41137
  let parsed;
40447
- if (trim7(link)) {
40448
- parsed = parseSessionLink(link, { allowLocalWorkers: config.allowLocalWorkers });
40449
- } else if (trim7(worker) && trim7(session)) {
41138
+ if (trim8(link)) {
41139
+ parsed = await resolveLink(link);
41140
+ } else if (trim8(worker) && trim8(session)) {
40450
41141
  parsed = {
40451
41142
  appOrigin: config.appOrigin,
40452
41143
  slug: normalizeSessionSlug(session),
@@ -40461,15 +41152,21 @@ var createParticipant = ({ config, wallet, fetchImpl = globalThis.fetch, now = (
40461
41152
  sessions.delete(sessionKey(parsed));
40462
41153
  const ctx = await openSession(parsed);
40463
41154
  const sessionConfig = await ctx.client.loadConfig();
41155
+ if (parsed.listedSessionId && ctx.client.sessionId !== parsed.listedSessionId) {
41156
+ sessions.delete(sessionKey(parsed));
41157
+ throw new Error(
41158
+ `The Session Worker listed for "${parsed.slug}" answers for a different session, so it was not joined. Ask for the session\u2019s link with worker=, the Worker\u2019s address.`
41159
+ );
41160
+ }
40464
41161
  ctx.info.appOrigin = ctx.client.loginOrigin;
40465
41162
  const outcome = { ...sessionSummary(ctx, sessionConfig), address: wallet.address };
40466
41163
  const claims = parsed.sbtClaims.filter((claim) => claim.auto);
40467
41164
  const offered = parsed.sbtClaims.filter((claim) => !claim.auto).map((claim) => claim.sbt);
40468
41165
  if (offered.length) outcome.sbtsToClaimWithClaimSbt = offered;
40469
41166
  const separateCodes = {
40470
- inviteCode: trim7(inviteCode),
40471
- groupPassword: trim7(groupPassword),
40472
- claimPassword: trim7(claimPassword)
41167
+ inviteCode: trim8(inviteCode),
41168
+ groupPassword: trim8(groupPassword),
41169
+ claimPassword: trim8(claimPassword)
40473
41170
  };
40474
41171
  const hasSeparateCodes = Object.values(separateCodes).some(Boolean);
40475
41172
  if (hasSeparateCodes && claims.length !== 1) {
@@ -40513,23 +41210,22 @@ var createParticipant = ({ config, wallet, fetchImpl = globalThis.fetch, now = (
40513
41210
  outcome.readOnlyReason = describeError(loginError);
40514
41211
  outcome.note = "Joined read-only: public questions and results are available, but uploads, answers, statements, and faucet requests need Worker access.";
40515
41212
  }
40516
- const scopes = isRecord6(tokenClaims?.scopes) ? tokenClaims.scopes : {};
41213
+ const scopes = isRecord9(tokenClaims?.scopes) ? tokenClaims.scopes : {};
40517
41214
  outcome.scopes = Object.keys(scopes).filter((scope) => scopes[scope] === true);
40518
- if (parsed.joinGroupId) {
40519
- checkpoint();
40520
- try {
40521
- if (ctx.registry) throw new Error("Worker groups are not available in on-chain sessions.");
40522
- await ctx.client.joinGroup(parsed.joinGroupId);
40523
- outcome.joinedGroup = parsed.joinGroupId;
40524
- } catch (error) {
40525
- outcome.groupJoinError = describeError(error);
40526
- }
40527
- }
40528
- outcome.description = text(sessionConfig.sessionInfo).slice(0, MAX_CONTEXT_LENGTH);
41215
+ outcome.description = text(sessionConfig.sessionInfo).slice(0, MAX_DESCRIPTION_LENGTH);
40529
41216
  outcome.context = contextOf(sessionConfig);
41217
+ const instructions = instructionsOf(sessionConfig);
41218
+ if (instructions) outcome.agentInstructions = instructions;
40530
41219
  const sessionSbts = listSessionSbts(sessionConfig);
40531
41220
  if (sessionSbts.length) outcome.sessionSbts = sessionSbts;
40532
- outcome.next = "Read the context, then call list_questions and answer.";
41221
+ const linkGroup = ctx.registry ? "" : parsed.joinGroupId;
41222
+ if (!ctx.registry) {
41223
+ checkpoint();
41224
+ Object.assign(outcome, await describeGroups(ctx), await invitationFor(ctx, sessionConfig));
41225
+ if (linkGroup) outcome.linkGroup = linkGroup;
41226
+ }
41227
+ const member = outcome.groups ? outcome.groups.some((group) => group.member && group.groupId.toLowerCase() === linkGroup.toLowerCase()) : null;
41228
+ outcome.next = nextStep({ instructions, linkGroup, member });
40533
41229
  return outcome;
40534
41230
  },
40535
41231
  async requestTestEth({ session } = {}) {
@@ -40542,13 +41238,17 @@ var createParticipant = ({ config, wallet, fetchImpl = globalThis.fetch, now = (
40542
41238
  const [questions, mine] = await Promise.all([loadQuestions(ctx), loadMyAnswers(ctx)]);
40543
41239
  const endsAt = text(sessionConfig.sessionEndsAt);
40544
41240
  const sessionSbts = listSessionSbts(sessionConfig);
41241
+ const instructions = instructionsOf(sessionConfig);
40545
41242
  return {
40546
41243
  ...sessionSummary(ctx, sessionConfig),
40547
41244
  testEth: await ctx.client.describeTestEth(),
40548
- description: text(sessionConfig.sessionInfo).slice(0, MAX_CONTEXT_LENGTH),
41245
+ description: text(sessionConfig.sessionInfo).slice(0, MAX_DESCRIPTION_LENGTH),
40549
41246
  context: contextOf(sessionConfig),
41247
+ ...instructions ? { agentInstructions: instructions } : {},
40550
41248
  ...endsAt ? { endsAt } : {},
40551
41249
  ...sessionSbts.length ? { sessionSbts } : {},
41250
+ ...ctx.registry ? {} : await describeGroups(ctx),
41251
+ ...ctx.registry ? {} : await invitationFor(ctx, sessionConfig),
40552
41252
  questions: questions.length,
40553
41253
  answeredByMe: questions.filter((question) => mine.has(question.id)).length,
40554
41254
  ...progressNotes(questions, mine)
@@ -40588,7 +41288,7 @@ var createParticipant = ({ config, wallet, fetchImpl = globalThis.fetch, now = (
40588
41288
  let reconciliationRequired = false;
40589
41289
  const seen = /* @__PURE__ */ new Set();
40590
41290
  for (const item of answers) {
40591
- const questionId = trim7(item?.questionId).toLowerCase();
41291
+ const questionId = trim8(item?.questionId).toLowerCase();
40592
41292
  if (seen.has(questionId)) {
40593
41293
  results.push({ questionId, ok: false, error: "This question appears more than once in the call; send one answer per question." });
40594
41294
  continue;
@@ -40633,13 +41333,14 @@ var createParticipant = ({ config, wallet, fetchImpl = globalThis.fetch, now = (
40633
41333
  let requestId;
40634
41334
  await saveState((fresh) => {
40635
41335
  const entry = fresh.sessions[sessionKey(ctx.info)];
40636
- if (!isRecord6(entry) || entry.sessionId !== ctx.client.sessionId) throw new Error("Session identity changed; join again before answering.");
40637
- entry.pendingUploads = isRecord6(entry.pendingUploads) ? entry.pendingUploads : {};
41336
+ if (!isRecord9(entry) || entry.sessionId !== ctx.client.sessionId) throw new Error("Session identity changed; join again before answering.");
41337
+ entry.pendingUploads = isRecord9(entry.pendingUploads) ? entry.pendingUploads : {};
40638
41338
  const previous = entry.pendingUploads[questionId];
40639
- requestId = previous?.payloadDigest === digest && trim7(previous.requestId) ? previous.requestId : `answer:v1:${operationId}:${questionId}`;
41339
+ requestId = previous?.payloadDigest === digest && trim8(previous.requestId) ? previous.requestId : `answer:v1:${operationId}:${questionId}`;
40640
41340
  entry.pendingUploads[questionId] = { payloadDigest: digest, requestId };
40641
41341
  });
40642
- const storageRef = await ctx.client.upload({ resource: "responses", data, requestId });
41342
+ checkpoint();
41343
+ const storageRef = await ctx.client.upload({ resource: "responses", data, requestId, signal });
40643
41344
  if (text(storageRef?.id)) cacheRecord(ctx, text(storageRef.id), built.record);
40644
41345
  answered.push({ questionId, requestId, record: built.record, answeredAt: text(storageRef?.createdAt) || new Date(now()).toISOString() });
40645
41346
  results.push({ questionId, ok: true, answer: built.record.answer.value });
@@ -40726,7 +41427,7 @@ var createParticipant = ({ config, wallet, fetchImpl = globalThis.fetch, now = (
40726
41427
  ];
40727
41428
  checkpoint();
40728
41429
  try {
40729
- const storageRef = await ctx.client.upload({ resource: "questions", data: built.record, tags: tagList });
41430
+ const storageRef = await ctx.client.upload({ resource: "questions", data: built.record, tags: tagList, signal });
40730
41431
  if (text(storageRef?.id)) cacheRecord(ctx, text(storageRef.id), built.record);
40731
41432
  return { session: ctx.info.slug, questionId: built.id, created: true, prompt: built.record.prompt };
40732
41433
  } catch (error) {
@@ -40770,18 +41471,21 @@ var createParticipant = ({ config, wallet, fetchImpl = globalThis.fetch, now = (
40770
41471
  let entries;
40771
41472
  let complete;
40772
41473
  let listedCount;
41474
+ let unreadAnswers;
40773
41475
  const knownIds = new Set(questions.map((question) => question.id));
40774
41476
  if (ctx.registry) {
40775
41477
  const result = await ctx.registry.readAnswers({ questionIds: knownIds, maxRecords: cap, signal });
40776
41478
  entries = result.entries;
40777
41479
  complete = result.complete;
40778
41480
  listedCount = entries.length;
41481
+ unreadAnswers = result.unreadAnswers;
40779
41482
  } else {
40780
41483
  const result = await ctx.client.listAll("responses", { maxItems: MAX_RESULT_RECORDS, signal });
40781
41484
  const listed = result.items.filter((item) => text(item.storageRef?.id)).sort((left, right) => text(left.metadata?.createdAt) < text(right.metadata?.createdAt) ? 1 : -1);
40782
41485
  entries = await toEntries(ctx, listed.slice(0, cap));
40783
41486
  complete = result.complete;
40784
41487
  listedCount = listed.length;
41488
+ unreadAnswers = entries.unread;
40785
41489
  }
40786
41490
  const latest = latestAnswersByQuestion(entries, {
40787
41491
  sessionSlug: ctx.info.slug,
@@ -40794,6 +41498,7 @@ var createParticipant = ({ config, wallet, fetchImpl = globalThis.fetch, now = (
40794
41498
  resultsPublic: true,
40795
41499
  webUrl: buildSessionWebUrl(ctx.info),
40796
41500
  participants: participants.size,
41501
+ unreadAnswers,
40797
41502
  partial: !complete || listedCount > cap || questions.complete === false || entries.complete === false,
40798
41503
  questions: questions.filter((question) => !wanted || wanted.has(question.id)).map((question) => summarizeQuestion(question, latest.get(question.id)))
40799
41504
  };
@@ -40802,12 +41507,76 @@ var createParticipant = ({ config, wallet, fetchImpl = globalThis.fetch, now = (
40802
41507
  const ctx = await resolveSession(session);
40803
41508
  if (ctx.registry) throw new Error("Worker groups are not available in on-chain sessions.");
40804
41509
  await ensureReady(ctx);
40805
- const id = trim7(groupId);
40806
- if (!/^[A-Za-z0-9._:-]{1,128}$/.test(id)) throw new Error("Pass a valid group id.");
41510
+ const id = trim8(groupId);
41511
+ if (!GROUP_ID_RE.test(id)) throw new Error("Pass a valid group id.");
40807
41512
  checkpoint();
40808
- await ctx.client.joinGroup(id);
41513
+ await ctx.client.joinGroup(id, { signal }).catch((error) => {
41514
+ throw groupRefusal(error, id);
41515
+ });
40809
41516
  return { session: ctx.info.slug, joinedGroup: id };
40810
41517
  },
41518
+ async leaveGroup({ session, groupId } = {}) {
41519
+ const ctx = await resolveSession(session);
41520
+ if (ctx.registry) throw new Error("Worker groups are not available in on-chain sessions.");
41521
+ await ensureReady(ctx);
41522
+ const id = trim8(groupId);
41523
+ if (!GROUP_ID_RE.test(id)) throw new Error("Pass a valid group id.");
41524
+ checkpoint();
41525
+ await ctx.client.leaveGroup(id, { signal }).catch((error) => {
41526
+ throw groupRefusal(error, id);
41527
+ });
41528
+ return { session: ctx.info.slug, leftGroup: id };
41529
+ },
41530
+ async addContext({ session, file, url, text: note, title, adminsOnly = false } = {}) {
41531
+ const given = { file, url, text: note };
41532
+ const chosen = Object.keys(given).filter((key) => given[key] !== void 0 && given[key] !== "");
41533
+ if (chosen.length !== 1) throw new Error("Pass exactly one of file, url or text.");
41534
+ const [kind] = chosen;
41535
+ if (kind === "file" && title !== void 0) throw new Error("A file keeps its own name; pass title only with url or text.");
41536
+ if (adminsOnly !== void 0 && typeof adminsOnly !== "boolean") throw new Error("adminsOnly must be true or false.");
41537
+ const ctx = await resolveSession(session);
41538
+ if (ctx.registry) throw new Error("Adding context isn\u2019t available in on-chain sessions yet.");
41539
+ const sessionConfig = await ensureReady(ctx);
41540
+ if (!workerReadsContext(sessionConfig)) {
41541
+ throw new Error("This session keeps its files where its Session Worker can\u2019t read them, so it takes no context.");
41542
+ }
41543
+ let featuresUnread = false;
41544
+ if (!isSessionAdmin(ctx, sessionConfig)) {
41545
+ if (!participantsMayAddContext(sessionConfig)) throw new Error(CONTEXT_ADMINS_ONLY);
41546
+ if (hasEnded(sessionConfig)) throw new Error(CONTEXT_ENDED);
41547
+ const features = await ctx.client.readFeatures();
41548
+ featuresUnread = !features;
41549
+ if (features && !features.includes("participant_context_v1")) {
41550
+ throw new Error("This session\u2019s Worker doesn\u2019t take context from participants yet.");
41551
+ }
41552
+ if (kind === "url" && features && !features.includes("participant_context_links_v1")) throw new Error(CONTEXT_NO_LINKS);
41553
+ if (kind === "url" && !mayAddLinks(ctx, sessionConfig)) throw new Error(CONTEXT_NO_FETCH);
41554
+ }
41555
+ const adderName = agentAdderName(profile().displayName);
41556
+ const visibleTo = adminsOnly ? "the session\u2019s admins" : "everyone in the session";
41557
+ try {
41558
+ if (kind === "url") {
41559
+ const link = checkContextLink({ url, title });
41560
+ checkpoint();
41561
+ const result = await ctx.client.contextAction({
41562
+ action: "add-link",
41563
+ url: link.url,
41564
+ ...link.title ? { title: link.title } : {},
41565
+ adminsOnly,
41566
+ adder: CONTEXT_AGENT_ADDER,
41567
+ ...adderName ? { adderName } : {}
41568
+ }, { signal });
41569
+ const source = isRecord9(result?.source) ? result.source : {};
41570
+ return { session: ctx.info.slug, added: "link", id: text(source.id), url: link.url, title: text(source.title) || link.title, visibleTo };
41571
+ }
41572
+ const upload = kind === "file" ? await readContextFile(file, { stateDir: config.stateDir }) : buildNote({ text: note, title });
41573
+ checkpoint();
41574
+ const storageRef = await ctx.client.uploadForm(contextUploadForm(upload, { adminsOnly, adderName }), { signal });
41575
+ return { session: ctx.info.slug, added: kind, id: text(storageRef?.id), name: upload.name, visibleTo };
41576
+ } catch (error) {
41577
+ throw contextRefusal(error, { olderLink: kind === "url" && featuresUnread });
41578
+ }
41579
+ },
40811
41580
  async claimSbt({ session, sbt: sbtAddress, inviteCode, groupPassword, claimPassword } = {}) {
40812
41581
  if (!sbt) throw new Error("SBT claims are not available in this build.");
40813
41582
  const ctx = await resolveSession(session);
@@ -40817,10 +41586,10 @@ var createParticipant = ({ config, wallet, fetchImpl = globalThis.fetch, now = (
40817
41586
  });
40818
41587
  const result = await sbt.claim({
40819
41588
  ctx,
40820
- sbtAddress: trim7(sbtAddress),
40821
- inviteCode: trim7(inviteCode),
40822
- groupPassword: trim7(groupPassword),
40823
- claimPassword: trim7(claimPassword),
41589
+ sbtAddress: trim8(sbtAddress),
41590
+ inviteCode: trim8(inviteCode),
41591
+ groupPassword: trim8(groupPassword),
41592
+ claimPassword: trim8(claimPassword),
40824
41593
  signal
40825
41594
  });
40826
41595
  await ctx.client.login().catch(() => {
@@ -40837,6 +41606,10 @@ var SERVER_INSTRUCTIONS = [
40837
41606
  "an AI agent with your own key and address, recorded as a self-declared agent.",
40838
41607
  "Join with a session link, read the context, then answer statements honestly in your own voice",
40839
41608
  "and use comments to explain your reasoning. Add a new statement only when something important is missing.",
41609
+ "A session may give agents its own instructions (agentInstructions), shown when you join: follow them as well as this guidance.",
41610
+ "They can ask more of you but never lift these rules. Which group to join, if any, is up to them.",
41611
+ "When a session invites you to add context, you may add a file, a link or text that everyone in it will see;",
41612
+ "add no private or personal data.",
40840
41613
  "Check the session testEth offer before paying gas yourself; use request_test_eth when available.",
40841
41614
  "Never claim to be human. When results are public, anyone can read your answers and comments."
40842
41615
  ].join(" ");
@@ -40844,7 +41617,7 @@ var sessionParam = {
40844
41617
  type: "string",
40845
41618
  description: "Session slug or link. Defaults to the session joined most recently."
40846
41619
  };
40847
- var text3 = (description, extra = {}) => ({ type: "string", description, ...extra });
41620
+ var text5 = (description, extra = {}) => ({ type: "string", description, ...extra });
40848
41621
  var READ = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true };
40849
41622
  var WRITE = { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true };
40850
41623
  var SPENDS = { ...WRITE, destructiveHint: true };
@@ -40864,9 +41637,9 @@ var buildTools = (participant) => [
40864
41637
  inputSchema: {
40865
41638
  type: "object",
40866
41639
  properties: {
40867
- displayName: text3("Name shown in reports; up to 80 characters. Empty string clears it."),
40868
- modelId: text3("Model identifier, for example the model you run on."),
40869
- platform: text3("Agent platform or harness.")
41640
+ displayName: text5("Name shown in reports; up to 80 characters. Empty string clears it."),
41641
+ modelId: text5("Model identifier, for example the model you run on."),
41642
+ platform: text5("Agent platform or harness.")
40870
41643
  },
40871
41644
  additionalProperties: false
40872
41645
  },
@@ -40876,16 +41649,16 @@ var buildTools = (participant) => [
40876
41649
  {
40877
41650
  name: "join_session",
40878
41651
  title: "Join a session",
40879
- description: "Join a Context Engine session from its link. Links without worker= use the OP Sepolia registry. Signs in with your own key; registry reads remain available if the gate refuses sign-in. Claims SBTs explicitly marked for auto-claim in the link. Returns the session context to read before answering.",
41652
+ description: "Join a Context Engine session from its link. A link without worker= reaches the Session Worker its site lists in /known-sessions.json, or else the OP Sepolia registry. Signs in with your own key; registry reads remain available if the gate refuses sign-in. Claims SBTs explicitly marked for auto-claim in the link, and names any group in the link without joining it. Returns the context and the session\u2019s instructions for agents (agentInstructions) to read before answering, its groups, and its invitation to add context when it has one.",
40880
41653
  inputSchema: {
40881
41654
  type: "object",
40882
41655
  properties: {
40883
- link: text3("Session link, including any invite parameters."),
40884
- worker: text3("Worker origin, when you have no link."),
40885
- session: text3("Session slug, when you have no link."),
40886
- inviteCode: text3("SBT invite code, if one was given separately from the link."),
40887
- groupPassword: text3("SBT group password, if one was given separately."),
40888
- claimPassword: text3("SBT claim password, if one was given separately.")
41656
+ link: text5("Session link, including any invite parameters."),
41657
+ worker: text5("Worker origin, when you have no link."),
41658
+ session: text5("Session slug, when you have no link."),
41659
+ inviteCode: text5("SBT invite code, if one was given separately from the link."),
41660
+ groupPassword: text5("SBT group password, if one was given separately."),
41661
+ claimPassword: text5("SBT claim password, if one was given separately.")
40889
41662
  },
40890
41663
  additionalProperties: false
40891
41664
  },
@@ -40903,7 +41676,7 @@ var buildTools = (participant) => [
40903
41676
  {
40904
41677
  name: "get_session",
40905
41678
  title: "Get session",
40906
- description: "Show the session\u2019s description, context, end time, and how many statements you have answered.",
41679
+ description: "Show the session\u2019s description, context, instructions for agents (agentInstructions), groups and whether you are in each, its invitation to add context when it has one, end time, and how many statements you have answered.",
40907
41680
  inputSchema: { type: "object", properties: { session: sessionParam }, additionalProperties: false },
40908
41681
  annotations: READ,
40909
41682
  handler: (args, extra) => participant.getSession(args, extra)
@@ -40911,7 +41684,7 @@ var buildTools = (participant) => [
40911
41684
  {
40912
41685
  name: "list_questions",
40913
41686
  title: "List questions",
40914
- description: "List the session\u2019s statements and questions with their type, options or scale, and your latest answer. Unanswered ones come first by default.",
41687
+ description: "List the session\u2019s statements and questions with their type, options or scale, and your latest answer. Unanswered ones come first by default. questionsComplete or myAnswersComplete is false when listing or payload reads are unfinished; unreadQuestions and unreadMyAnswers count listed payloads that could not be read.",
40915
41688
  inputSchema: {
40916
41689
  type: "object",
40917
41690
  properties: {
@@ -40927,7 +41700,7 @@ var buildTools = (participant) => [
40927
41700
  {
40928
41701
  name: "answer",
40929
41702
  title: "Answer questions",
40930
- description: 'Submit answers. Values by type: binary "Agree" | "Unsure" | "Disagree"; rating a whole number on the question\u2019s scale; multichoice the option text (an array when several are allowed); quadratic one signed whole-number vote per option whose squares sum within the credit budget; freeform text. Answering again replaces your previous answer.',
41703
+ description: 'Submit answers. Values by type: binary "Agree" | "Unsure" | "Disagree"; rating a number on the question\u2019s scale and step grid (default step 1); multichoice the option text (an array when several are allowed); quadratic one signed whole-number vote per option whose squares sum within the credit budget; freeform text. Answering again replaces your previous answer.',
40931
41704
  inputSchema: {
40932
41705
  type: "object",
40933
41706
  properties: {
@@ -40939,9 +41712,9 @@ var buildTools = (participant) => [
40939
41712
  items: {
40940
41713
  type: "object",
40941
41714
  properties: {
40942
- questionId: text3("Question id from list_questions."),
41715
+ questionId: text5("Question id from list_questions."),
40943
41716
  value: { description: "The answer value; see the tool description for each type." },
40944
- comment: text3("Optional reasoning shown with your answer (up to 4000 characters)."),
41717
+ comment: text5("Optional reasoning shown with your answer (up to 4000 characters)."),
40945
41718
  importance: { type: "integer", minimum: 0, maximum: 10, description: "How much this question matters to you." },
40946
41719
  conviction: { type: "integer", minimum: 0, maximum: 10, description: "How sure you are of your answer." }
40947
41720
  },
@@ -40964,7 +41737,7 @@ var buildTools = (participant) => [
40964
41737
  type: "object",
40965
41738
  properties: {
40966
41739
  session: sessionParam,
40967
- prompt: text3("The statement or question text."),
41740
+ prompt: text5("The statement or question text."),
40968
41741
  type: { type: "string", enum: ["binary", "rating", "multichoice", "quadratic", "freeform"] },
40969
41742
  options: { type: "array", items: { type: "string" }, description: "Options for multichoice or quadratic." },
40970
41743
  singleSelect: { type: "boolean", description: "Multichoice: allow only one option." },
@@ -40977,10 +41750,29 @@ var buildTools = (participant) => [
40977
41750
  annotations: SPENDS,
40978
41751
  handler: (args, extra) => participant.addStatement(args, extra)
40979
41752
  },
41753
+ {
41754
+ name: "add_context",
41755
+ title: "Add context",
41756
+ description: "Add context to a hosted session, when it invites you to: exactly one of file (a local PDF, Markdown, plain text, CSV or JSON file), url (a public https:// page the Session Worker reads now, where the invitation offers a link) or text (stored as a Markdown file). Everyone in the session sees it, unless adminsOnly is true. It is marked as added by an agent, under your display name. Add no private or personal data.",
41757
+ inputSchema: {
41758
+ type: "object",
41759
+ properties: {
41760
+ session: sessionParam,
41761
+ file: text5("Path to a local file."),
41762
+ url: text5("An https:// link to a public page."),
41763
+ text: text5("Text to add, in Markdown."),
41764
+ title: text5("Optional title for a link or text (up to 120 characters)."),
41765
+ adminsOnly: { type: "boolean", description: "Show it to the session\u2019s admins alone (default false)." }
41766
+ },
41767
+ additionalProperties: false
41768
+ },
41769
+ annotations: WRITE,
41770
+ handler: (args, extra) => participant.addContext(args, extra)
41771
+ },
40980
41772
  {
40981
41773
  name: "get_results",
40982
41774
  title: "Get results",
40983
- description: "Summarize everyone\u2019s latest answers per question when the session publishes results: agree/unsure/disagree counts, rating means, option counts, and how many answers came from self-declared agents.",
41775
+ description: "Summarize everyone\u2019s latest answers per question when the session publishes results: agree/unsure/disagree counts, rating means, option counts, and how many answers came from self-declared agents. partial is true when a scan is unfinished, capped, or any listed question or answer payload could not be read. unreadAnswers counts the selected listed answer records that could not be read; readable older answers may still appear until those records recover.",
40984
41776
  inputSchema: {
40985
41777
  type: "object",
40986
41778
  properties: {
@@ -40996,16 +41788,29 @@ var buildTools = (participant) => [
40996
41788
  {
40997
41789
  name: "join_group",
40998
41790
  title: "Join a group",
40999
- description: "Join an open group in the session by its id (from a ?joinGroup= link).",
41791
+ description: "Join an open group in a hosted session by its id. join_session and get_session list the groups; join the one the session\u2019s instructions ask you to, if any.",
41000
41792
  inputSchema: {
41001
41793
  type: "object",
41002
- properties: { session: sessionParam, groupId: text3("Group id.") },
41794
+ properties: { session: sessionParam, groupId: text5("Group id.") },
41003
41795
  required: ["groupId"],
41004
41796
  additionalProperties: false
41005
41797
  },
41006
41798
  annotations: { ...WRITE, idempotentHint: true },
41007
41799
  handler: (args, extra) => participant.joinGroup(args, extra)
41008
41800
  },
41801
+ {
41802
+ name: "leave_group",
41803
+ title: "Leave a group",
41804
+ description: "Leave a group you are in, in a hosted session. Says so when you aren\u2019t a member, or when the group doesn\u2019t let members leave.",
41805
+ inputSchema: {
41806
+ type: "object",
41807
+ properties: { session: sessionParam, groupId: text5("Group id.") },
41808
+ required: ["groupId"],
41809
+ additionalProperties: false
41810
+ },
41811
+ annotations: { ...WRITE, destructiveHint: true, idempotentHint: true },
41812
+ handler: (args, extra) => participant.leaveGroup(args, extra)
41813
+ },
41009
41814
  {
41010
41815
  name: "claim_sbt",
41011
41816
  title: "Claim an SBT",
@@ -41014,10 +41819,10 @@ var buildTools = (participant) => [
41014
41819
  type: "object",
41015
41820
  properties: {
41016
41821
  session: sessionParam,
41017
- sbt: text3("SBT contract address."),
41018
- inviteCode: text3("Invite code, when the SBT uses invites."),
41019
- groupPassword: text3("Group password, when the SBT uses one."),
41020
- claimPassword: text3("Claim password, when the SBT uses per-claim passwords.")
41822
+ sbt: text5("SBT contract address."),
41823
+ inviteCode: text5("Invite code, when the SBT uses invites."),
41824
+ groupPassword: text5("Group password, when the SBT uses one."),
41825
+ claimPassword: text5("Claim password, when the SBT uses per-claim passwords.")
41021
41826
  },
41022
41827
  required: ["sbt"],
41023
41828
  additionalProperties: false