holosphere 2.0.0-alpha4 → 2.0.0-alpha6
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.
- package/dist/cjs/holosphere.cjs +1 -1
- package/dist/esm/holosphere.js +1 -1
- package/dist/index-BtKHqqet.cjs +5 -0
- package/dist/index-BtKHqqet.cjs.map +1 -0
- package/dist/{index-CBitK71M.cjs → index-CmzkI7SI.cjs} +2 -2
- package/dist/{index-CBitK71M.cjs.map → index-CmzkI7SI.cjs.map} +1 -1
- package/dist/{index-Cz-PLCUR.js → index-JFz-dW43.js} +2 -2
- package/dist/{index-Cz-PLCUR.js.map → index-JFz-dW43.js.map} +1 -1
- package/dist/{index-CV0eOogK.js → index-NOravBLu.js} +733 -164
- package/dist/index-NOravBLu.js.map +1 -0
- package/dist/{indexeddb-storage-CRsZyB2f.cjs → indexeddb-storage-C4HsulhA.cjs} +2 -2
- package/dist/{indexeddb-storage-CRsZyB2f.cjs.map → indexeddb-storage-C4HsulhA.cjs.map} +1 -1
- package/dist/{indexeddb-storage-DZaGlY_a.js → indexeddb-storage-OtSAVDZY.js} +2 -2
- package/dist/{indexeddb-storage-DZaGlY_a.js.map → indexeddb-storage-OtSAVDZY.js.map} +1 -1
- package/dist/{memory-storage-BkUi6sZG.js → memory-storage-ChpcYvxA.js} +2 -2
- package/dist/{memory-storage-BkUi6sZG.js.map → memory-storage-ChpcYvxA.js.map} +1 -1
- package/dist/{memory-storage-C0DuUsdY.cjs → memory-storage-MD6ED00P.cjs} +2 -2
- package/dist/{memory-storage-C0DuUsdY.cjs.map → memory-storage-MD6ED00P.cjs.map} +1 -1
- package/dist/{secp256k1-0kPdAVkK.cjs → secp256k1-DcTYQrqC.cjs} +2 -2
- package/dist/{secp256k1-0kPdAVkK.cjs.map → secp256k1-DcTYQrqC.cjs.map} +1 -1
- package/dist/{secp256k1-DN4FVXcv.js → secp256k1-PfNOEI7a.js} +2 -2
- package/dist/{secp256k1-DN4FVXcv.js.map → secp256k1-PfNOEI7a.js.map} +1 -1
- package/package.json +1 -1
- package/src/contracts/abis/Bundle.json +1438 -1435
- package/src/contracts/deployer.js +32 -3
- package/src/federation/handshake.js +13 -5
- package/src/index.js +9 -1
- package/src/storage/gun-async.js +55 -6
- package/src/storage/gun-auth.js +81 -30
- package/src/storage/gun-wrapper.js +56 -48
- package/src/storage/nostr-async.js +149 -14
- package/src/storage/nostr-client.js +574 -48
- package/dist/index-BB_vVJgv.cjs +0 -5
- package/dist/index-BB_vVJgv.cjs.map +0 -1
- package/dist/index-CV0eOogK.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getPublicKey as getPublicKey$2,
|
|
1
|
+
import { getPublicKey as getPublicKey$2, finalizeEvent, SimplePool, nip19, nip04, verifyEvent as verifyEvent$1 } from "nostr-tools";
|
|
2
2
|
import * as h3 from "h3-js";
|
|
3
3
|
import { latLngToCell, getResolution, cellToParent, cellToChildren, isValidCell } from "h3-js";
|
|
4
4
|
import Ajv from "ajv";
|
|
@@ -361,17 +361,84 @@ async function createPersistentStorage(namespace, options = {}) {
|
|
|
361
361
|
const isBrowser = typeof window !== "undefined" && typeof window.indexedDB !== "undefined";
|
|
362
362
|
typeof process !== "undefined" && process.versions && void 0;
|
|
363
363
|
if (isBrowser) {
|
|
364
|
-
const { IndexedDBStorage } = await import("./indexeddb-storage-
|
|
364
|
+
const { IndexedDBStorage } = await import("./indexeddb-storage-OtSAVDZY.js");
|
|
365
365
|
const storage = new IndexedDBStorage();
|
|
366
366
|
await storage.init(namespace);
|
|
367
367
|
return storage;
|
|
368
368
|
} else {
|
|
369
|
-
const { MemoryStorage } = await import("./memory-storage-
|
|
369
|
+
const { MemoryStorage } = await import("./memory-storage-ChpcYvxA.js");
|
|
370
370
|
const storage = new MemoryStorage();
|
|
371
371
|
await storage.init(namespace);
|
|
372
372
|
return storage;
|
|
373
373
|
}
|
|
374
374
|
}
|
|
375
|
+
let globalPool = null;
|
|
376
|
+
let globalPoolRelays = /* @__PURE__ */ new Set();
|
|
377
|
+
function getGlobalPool(config = {}) {
|
|
378
|
+
if (!globalPool) {
|
|
379
|
+
globalPool = new SimplePool({
|
|
380
|
+
enableReconnect: config.enableReconnect !== false,
|
|
381
|
+
enablePing: config.enablePing !== false
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
return globalPool;
|
|
385
|
+
}
|
|
386
|
+
const pendingQueries$1 = /* @__PURE__ */ new Map();
|
|
387
|
+
const PENDING_QUERY_TIMEOUT = 5e3;
|
|
388
|
+
const activeSubscriptions = /* @__PURE__ */ new Map();
|
|
389
|
+
const backgroundRefreshThrottle = /* @__PURE__ */ new Map();
|
|
390
|
+
const BACKGROUND_REFRESH_INTERVAL = 3e4;
|
|
391
|
+
const pendingWrites = /* @__PURE__ */ new Map();
|
|
392
|
+
const WRITE_DEBOUNCE_MS = 500;
|
|
393
|
+
const authorSubscriptions = /* @__PURE__ */ new Map();
|
|
394
|
+
const AUTHOR_SUB_INIT_TIMEOUT = 5e3;
|
|
395
|
+
class LRUCache {
|
|
396
|
+
constructor(maxSize = 500) {
|
|
397
|
+
this.maxSize = maxSize;
|
|
398
|
+
this.cache = /* @__PURE__ */ new Map();
|
|
399
|
+
}
|
|
400
|
+
get(key) {
|
|
401
|
+
if (!this.cache.has(key)) return void 0;
|
|
402
|
+
const value = this.cache.get(key);
|
|
403
|
+
this.cache.delete(key);
|
|
404
|
+
this.cache.set(key, value);
|
|
405
|
+
return value;
|
|
406
|
+
}
|
|
407
|
+
set(key, value) {
|
|
408
|
+
if (this.cache.has(key)) {
|
|
409
|
+
this.cache.delete(key);
|
|
410
|
+
}
|
|
411
|
+
this.cache.set(key, value);
|
|
412
|
+
while (this.cache.size > this.maxSize) {
|
|
413
|
+
const oldestKey = this.cache.keys().next().value;
|
|
414
|
+
this.cache.delete(oldestKey);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
has(key) {
|
|
418
|
+
return this.cache.has(key);
|
|
419
|
+
}
|
|
420
|
+
delete(key) {
|
|
421
|
+
return this.cache.delete(key);
|
|
422
|
+
}
|
|
423
|
+
clear() {
|
|
424
|
+
this.cache.clear();
|
|
425
|
+
}
|
|
426
|
+
get size() {
|
|
427
|
+
return this.cache.size;
|
|
428
|
+
}
|
|
429
|
+
keys() {
|
|
430
|
+
return this.cache.keys();
|
|
431
|
+
}
|
|
432
|
+
values() {
|
|
433
|
+
return this.cache.values();
|
|
434
|
+
}
|
|
435
|
+
entries() {
|
|
436
|
+
return this.cache.entries();
|
|
437
|
+
}
|
|
438
|
+
forEach(callback) {
|
|
439
|
+
this.cache.forEach(callback);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
375
442
|
let webSocketPolyfillPromise = null;
|
|
376
443
|
function ensureWebSocket() {
|
|
377
444
|
if (typeof globalThis.WebSocket !== "undefined") {
|
|
@@ -407,8 +474,12 @@ class NostrClient {
|
|
|
407
474
|
this.publicKey = getPublicKey$2(this.privateKey);
|
|
408
475
|
this.config = config;
|
|
409
476
|
this._subscriptions = /* @__PURE__ */ new Map();
|
|
410
|
-
this._eventCache =
|
|
477
|
+
this._eventCache = new LRUCache(config.cacheSize || 500);
|
|
478
|
+
this._cacheIndex = /* @__PURE__ */ new Map();
|
|
411
479
|
this.persistentStorage = null;
|
|
480
|
+
this._persistQueue = /* @__PURE__ */ new Map();
|
|
481
|
+
this._persistTimer = null;
|
|
482
|
+
this._persistBatchMs = config.persistBatchMs || 100;
|
|
412
483
|
this._initReady = this._initialize();
|
|
413
484
|
}
|
|
414
485
|
/**
|
|
@@ -418,10 +489,8 @@ class NostrClient {
|
|
|
418
489
|
async _initialize() {
|
|
419
490
|
await ensureWebSocket();
|
|
420
491
|
if (this.relays.length > 0) {
|
|
421
|
-
this.pool =
|
|
422
|
-
|
|
423
|
-
enablePing: this.config.enablePing !== false
|
|
424
|
-
});
|
|
492
|
+
this.pool = getGlobalPool(this.config);
|
|
493
|
+
this.relays.forEach((r) => globalPoolRelays.add(r));
|
|
425
494
|
} else {
|
|
426
495
|
this.pool = {
|
|
427
496
|
publish: (relays, event) => [Promise.resolve()],
|
|
@@ -433,6 +502,69 @@ class NostrClient {
|
|
|
433
502
|
};
|
|
434
503
|
}
|
|
435
504
|
await this._initPersistentStorage();
|
|
505
|
+
if (this.relays.length > 0) {
|
|
506
|
+
this._initLongLivedSubscription();
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
/**
|
|
510
|
+
* Initialize a long-lived subscription to keep cache fresh
|
|
511
|
+
* This replaces polling with a single persistent subscription
|
|
512
|
+
* @private
|
|
513
|
+
*/
|
|
514
|
+
_initLongLivedSubscription() {
|
|
515
|
+
const subKey = this.publicKey;
|
|
516
|
+
if (authorSubscriptions.has(subKey)) {
|
|
517
|
+
return;
|
|
518
|
+
}
|
|
519
|
+
const subInfo = {
|
|
520
|
+
subscription: null,
|
|
521
|
+
initialized: false,
|
|
522
|
+
initPromise: null,
|
|
523
|
+
initResolve: null
|
|
524
|
+
};
|
|
525
|
+
subInfo.initPromise = new Promise((resolve) => {
|
|
526
|
+
subInfo.initResolve = resolve;
|
|
527
|
+
});
|
|
528
|
+
authorSubscriptions.set(subKey, subInfo);
|
|
529
|
+
const filter = {
|
|
530
|
+
kinds: [3e4],
|
|
531
|
+
authors: [this.publicKey]
|
|
532
|
+
};
|
|
533
|
+
const sub = this.pool.subscribeMany(
|
|
534
|
+
this.relays,
|
|
535
|
+
[filter],
|
|
536
|
+
{
|
|
537
|
+
onevent: (event) => {
|
|
538
|
+
if (event.pubkey !== this.publicKey) {
|
|
539
|
+
return;
|
|
540
|
+
}
|
|
541
|
+
this._cacheEvent(event);
|
|
542
|
+
},
|
|
543
|
+
oneose: () => {
|
|
544
|
+
if (!subInfo.initialized) {
|
|
545
|
+
subInfo.initialized = true;
|
|
546
|
+
subInfo.initResolve();
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
);
|
|
551
|
+
subInfo.subscription = sub;
|
|
552
|
+
setTimeout(() => {
|
|
553
|
+
if (!subInfo.initialized) {
|
|
554
|
+
subInfo.initialized = true;
|
|
555
|
+
subInfo.initResolve();
|
|
556
|
+
}
|
|
557
|
+
}, AUTHOR_SUB_INIT_TIMEOUT);
|
|
558
|
+
}
|
|
559
|
+
/**
|
|
560
|
+
* Wait for long-lived subscription to complete initial load
|
|
561
|
+
* @private
|
|
562
|
+
*/
|
|
563
|
+
async _waitForSubscriptionInit() {
|
|
564
|
+
const subInfo = authorSubscriptions.get(this.publicKey);
|
|
565
|
+
if (subInfo && subInfo.initPromise) {
|
|
566
|
+
await subInfo.initPromise;
|
|
567
|
+
}
|
|
436
568
|
}
|
|
437
569
|
/**
|
|
438
570
|
* Initialize persistent storage
|
|
@@ -542,15 +674,63 @@ class NostrClient {
|
|
|
542
674
|
}
|
|
543
675
|
/**
|
|
544
676
|
* Publish event to relays
|
|
677
|
+
* Supports debouncing for replaceable events (kind 30000-39999) to avoid rapid updates
|
|
545
678
|
* @param {Object} event - Unsigned event object
|
|
546
679
|
* @param {Object} options - Publish options
|
|
547
680
|
* @param {boolean} options.waitForRelays - Wait for relay confirmation (default: false for speed)
|
|
681
|
+
* @param {boolean} options.debounce - Debounce rapid writes to same d-tag (default: true for replaceable events)
|
|
548
682
|
* @returns {Promise<Object>} Signed event with relay publish results
|
|
549
683
|
*/
|
|
550
684
|
async publish(event, options = {}) {
|
|
551
685
|
await this._initReady;
|
|
552
686
|
const waitForRelays = options.waitForRelays || false;
|
|
553
|
-
const
|
|
687
|
+
const isReplaceable = event.kind >= 3e4 && event.kind < 4e4;
|
|
688
|
+
const shouldDebounce = isReplaceable && options.debounce !== false && !waitForRelays;
|
|
689
|
+
if (shouldDebounce) {
|
|
690
|
+
const dTag = event.tags?.find((t) => t[0] === "d");
|
|
691
|
+
if (dTag && dTag[1]) {
|
|
692
|
+
return this._debouncedPublish(event, dTag[1], options);
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
return this._doPublish(event, options);
|
|
696
|
+
}
|
|
697
|
+
/**
|
|
698
|
+
* Debounced publish - coalesces rapid writes to the same d-tag
|
|
699
|
+
* @private
|
|
700
|
+
*/
|
|
701
|
+
_debouncedPublish(event, dTagPath, options) {
|
|
702
|
+
return new Promise((resolve, reject) => {
|
|
703
|
+
const existing = pendingWrites.get(dTagPath);
|
|
704
|
+
if (existing) {
|
|
705
|
+
clearTimeout(existing.timer);
|
|
706
|
+
existing.resolve({
|
|
707
|
+
event: null,
|
|
708
|
+
results: [],
|
|
709
|
+
debounced: true,
|
|
710
|
+
supersededBy: event
|
|
711
|
+
});
|
|
712
|
+
}
|
|
713
|
+
const timer = setTimeout(async () => {
|
|
714
|
+
pendingWrites.delete(dTagPath);
|
|
715
|
+
try {
|
|
716
|
+
const result = await this._doPublish(event, options);
|
|
717
|
+
resolve(result);
|
|
718
|
+
} catch (err) {
|
|
719
|
+
reject(err);
|
|
720
|
+
}
|
|
721
|
+
}, WRITE_DEBOUNCE_MS);
|
|
722
|
+
pendingWrites.set(dTagPath, { event, timer, resolve, reject });
|
|
723
|
+
const signedEvent = finalizeEvent(event, this.privateKey);
|
|
724
|
+
this._cacheEvent(signedEvent);
|
|
725
|
+
});
|
|
726
|
+
}
|
|
727
|
+
/**
|
|
728
|
+
* Internal publish implementation
|
|
729
|
+
* @private
|
|
730
|
+
*/
|
|
731
|
+
async _doPublish(event, options = {}) {
|
|
732
|
+
const waitForRelays = options.waitForRelays || false;
|
|
733
|
+
const signedEvent = event.id && event.sig ? event : finalizeEvent(event, this.privateKey);
|
|
554
734
|
await this._cacheEvent(signedEvent);
|
|
555
735
|
if (this.outboxQueue) {
|
|
556
736
|
await this.outboxQueue.enqueue(signedEvent, this.relays);
|
|
@@ -613,20 +793,39 @@ class NostrClient {
|
|
|
613
793
|
}
|
|
614
794
|
/**
|
|
615
795
|
* Query events from relays
|
|
796
|
+
* Uses long-lived subscription for cache updates - avoids polling
|
|
616
797
|
* @param {Object} filter - Nostr filter object
|
|
617
798
|
* @param {Object} options - Query options
|
|
618
799
|
* @param {number} options.timeout - Query timeout in ms (default: 30000, set to 0 for no timeout)
|
|
619
800
|
* @param {boolean} options.localFirst - Return local cache immediately, refresh in background (default: true)
|
|
801
|
+
* @param {boolean} options.forceRelay - Force relay query even if subscription cache is available (default: false)
|
|
620
802
|
* @returns {Promise<Array>} Array of events
|
|
621
803
|
*/
|
|
622
804
|
async query(filter, options = {}) {
|
|
623
805
|
await this._initReady;
|
|
624
806
|
const timeout = options.timeout !== void 0 ? options.timeout : 3e4;
|
|
625
807
|
const localFirst = options.localFirst !== false;
|
|
808
|
+
const forceRelay = options.forceRelay === true;
|
|
626
809
|
if (this.relays.length === 0) {
|
|
627
810
|
const matchingEvents = this._getMatchingCachedEvents(filter);
|
|
628
811
|
return matchingEvents;
|
|
629
812
|
}
|
|
813
|
+
const subInfo = authorSubscriptions.get(this.publicKey);
|
|
814
|
+
const isOwnDataQuery = filter.authors && filter.authors.length === 1 && filter.authors[0] === this.publicKey;
|
|
815
|
+
if (!forceRelay && isOwnDataQuery && subInfo && subInfo.initialized) {
|
|
816
|
+
const matchingEvents = this._getMatchingCachedEvents(filter);
|
|
817
|
+
return matchingEvents;
|
|
818
|
+
}
|
|
819
|
+
if (isOwnDataQuery && subInfo && !subInfo.initialized) {
|
|
820
|
+
await Promise.race([
|
|
821
|
+
subInfo.initPromise,
|
|
822
|
+
new Promise((resolve) => setTimeout(resolve, Math.min(timeout, AUTHOR_SUB_INIT_TIMEOUT)))
|
|
823
|
+
]);
|
|
824
|
+
if (subInfo.initialized) {
|
|
825
|
+
const matchingEvents = this._getMatchingCachedEvents(filter);
|
|
826
|
+
return matchingEvents;
|
|
827
|
+
}
|
|
828
|
+
}
|
|
630
829
|
if (filter["#d"] && filter["#d"].length === 1 && filter.kinds && filter.kinds.length === 1) {
|
|
631
830
|
const dTagKey = `d:${filter.kinds[0]}:${filter["#d"][0]}`;
|
|
632
831
|
const dTagCached = this._eventCache.get(dTagKey);
|
|
@@ -647,22 +846,78 @@ class NostrClient {
|
|
|
647
846
|
}
|
|
648
847
|
/**
|
|
649
848
|
* Query relays and update cache
|
|
849
|
+
* Uses global pending queries map to deduplicate identical concurrent queries
|
|
650
850
|
* @private
|
|
651
851
|
*/
|
|
652
852
|
async _queryRelaysAndCache(filter, cacheKey, timeout) {
|
|
653
|
-
|
|
654
|
-
if (
|
|
655
|
-
|
|
853
|
+
const pending = pendingQueries$1.get(cacheKey);
|
|
854
|
+
if (pending && Date.now() - pending.timestamp < PENDING_QUERY_TIMEOUT) {
|
|
855
|
+
return pending.promise;
|
|
656
856
|
}
|
|
657
|
-
|
|
658
|
-
|
|
857
|
+
const queryPromise = (async () => {
|
|
858
|
+
try {
|
|
859
|
+
let events = await this.pool.querySync(this.relays, filter, { timeout });
|
|
860
|
+
if (filter.authors && filter.authors.length > 0) {
|
|
861
|
+
events = events.filter((event) => filter.authors.includes(event.pubkey));
|
|
862
|
+
}
|
|
863
|
+
this._eventCache.set(cacheKey, {
|
|
864
|
+
events,
|
|
865
|
+
timestamp: Date.now()
|
|
866
|
+
});
|
|
867
|
+
this._indexCacheEntry(cacheKey, filter);
|
|
868
|
+
return events;
|
|
869
|
+
} finally {
|
|
870
|
+
pendingQueries$1.delete(cacheKey);
|
|
871
|
+
}
|
|
872
|
+
})();
|
|
873
|
+
pendingQueries$1.set(cacheKey, {
|
|
874
|
+
promise: queryPromise,
|
|
659
875
|
timestamp: Date.now()
|
|
660
876
|
});
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
877
|
+
return queryPromise;
|
|
878
|
+
}
|
|
879
|
+
/**
|
|
880
|
+
* Limit cache size (called after cache operations)
|
|
881
|
+
* Note: LRU cache handles this automatically, kept for API compatibility
|
|
882
|
+
* @private
|
|
883
|
+
*/
|
|
884
|
+
_limitCacheSize() {
|
|
885
|
+
}
|
|
886
|
+
/**
|
|
887
|
+
* Add cache entry to reverse index for fast invalidation
|
|
888
|
+
* @private
|
|
889
|
+
*/
|
|
890
|
+
_indexCacheEntry(cacheKey, filter) {
|
|
891
|
+
if (filter.kinds) {
|
|
892
|
+
for (const kind2 of filter.kinds) {
|
|
893
|
+
if (!this._cacheIndex.has(kind2)) {
|
|
894
|
+
this._cacheIndex.set(kind2, /* @__PURE__ */ new Set());
|
|
895
|
+
}
|
|
896
|
+
this._cacheIndex.get(kind2).add(cacheKey);
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
/**
|
|
901
|
+
* Remove cache entry from reverse index
|
|
902
|
+
* @private
|
|
903
|
+
*/
|
|
904
|
+
_unindexCacheEntry(cacheKey) {
|
|
905
|
+
if (!cacheKey.startsWith("{")) return;
|
|
906
|
+
try {
|
|
907
|
+
const filter = JSON.parse(cacheKey);
|
|
908
|
+
if (filter.kinds) {
|
|
909
|
+
for (const kind2 of filter.kinds) {
|
|
910
|
+
const indexSet = this._cacheIndex.get(kind2);
|
|
911
|
+
if (indexSet) {
|
|
912
|
+
indexSet.delete(cacheKey);
|
|
913
|
+
if (indexSet.size === 0) {
|
|
914
|
+
this._cacheIndex.delete(kind2);
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
} catch {
|
|
664
920
|
}
|
|
665
|
-
return events;
|
|
666
921
|
}
|
|
667
922
|
/**
|
|
668
923
|
* Refresh cache in background (fire and forget)
|
|
@@ -687,18 +942,33 @@ class NostrClient {
|
|
|
687
942
|
}
|
|
688
943
|
/**
|
|
689
944
|
* Internal method to refresh a path from relays
|
|
945
|
+
* Throttled to avoid flooding the relay with repeated requests
|
|
690
946
|
* @private
|
|
691
947
|
*/
|
|
692
948
|
async _doBackgroundPathRefresh(path, kind2, options) {
|
|
693
949
|
if (this.relays.length === 0) return;
|
|
950
|
+
const lastRefresh = backgroundRefreshThrottle.get(path);
|
|
951
|
+
if (lastRefresh && Date.now() - lastRefresh < BACKGROUND_REFRESH_INTERVAL) {
|
|
952
|
+
return;
|
|
953
|
+
}
|
|
954
|
+
backgroundRefreshThrottle.set(path, Date.now());
|
|
955
|
+
if (backgroundRefreshThrottle.size > 1e3) {
|
|
956
|
+
const cutoff = Date.now() - BACKGROUND_REFRESH_INTERVAL;
|
|
957
|
+
for (const [key, timestamp] of backgroundRefreshThrottle) {
|
|
958
|
+
if (timestamp < cutoff) {
|
|
959
|
+
backgroundRefreshThrottle.delete(key);
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
}
|
|
694
963
|
const filter = {
|
|
695
964
|
kinds: [kind2],
|
|
696
965
|
authors: options.authors || [this.publicKey],
|
|
697
966
|
"#d": [path],
|
|
698
967
|
limit: 1
|
|
699
968
|
};
|
|
969
|
+
const cacheKey = JSON.stringify(filter);
|
|
700
970
|
const timeout = options.timeout || 3e4;
|
|
701
|
-
const events = await this.
|
|
971
|
+
const events = await this._queryRelaysAndCache(filter, cacheKey, timeout);
|
|
702
972
|
const authorFiltered = events.filter(
|
|
703
973
|
(e) => (options.authors || [this.publicKey]).includes(e.pubkey)
|
|
704
974
|
);
|
|
@@ -720,17 +990,25 @@ class NostrClient {
|
|
|
720
990
|
}
|
|
721
991
|
/**
|
|
722
992
|
* Internal method to refresh a prefix from relays
|
|
993
|
+
* Throttled to avoid flooding the relay with repeated requests
|
|
723
994
|
* @private
|
|
724
995
|
*/
|
|
725
996
|
async _doBackgroundPrefixRefresh(prefix, kind2, options) {
|
|
726
997
|
if (this.relays.length === 0) return;
|
|
998
|
+
const throttleKey = `prefix:${prefix}`;
|
|
999
|
+
const lastRefresh = backgroundRefreshThrottle.get(throttleKey);
|
|
1000
|
+
if (lastRefresh && Date.now() - lastRefresh < BACKGROUND_REFRESH_INTERVAL) {
|
|
1001
|
+
return;
|
|
1002
|
+
}
|
|
1003
|
+
backgroundRefreshThrottle.set(throttleKey, Date.now());
|
|
727
1004
|
const filter = {
|
|
728
1005
|
kinds: [kind2],
|
|
729
1006
|
authors: options.authors || [this.publicKey],
|
|
730
1007
|
limit: options.limit || 1e3
|
|
731
1008
|
};
|
|
1009
|
+
const cacheKey = JSON.stringify(filter);
|
|
732
1010
|
const timeout = options.timeout || 3e4;
|
|
733
|
-
let events = await this.
|
|
1011
|
+
let events = await this._queryRelaysAndCache(filter, cacheKey, timeout);
|
|
734
1012
|
events = events.filter(
|
|
735
1013
|
(e) => (options.authors || [this.publicKey]).includes(e.pubkey)
|
|
736
1014
|
);
|
|
@@ -805,6 +1083,7 @@ class NostrClient {
|
|
|
805
1083
|
}
|
|
806
1084
|
/**
|
|
807
1085
|
* Subscribe to events
|
|
1086
|
+
* Uses subscription deduplication to avoid creating multiple identical subscriptions
|
|
808
1087
|
* @param {Object} filter - Nostr filter object
|
|
809
1088
|
* @param {Function} onEvent - Callback for each event
|
|
810
1089
|
* @param {Object} options - Subscription options
|
|
@@ -812,7 +1091,8 @@ class NostrClient {
|
|
|
812
1091
|
*/
|
|
813
1092
|
async subscribe(filter, onEvent, options = {}) {
|
|
814
1093
|
await this._initReady;
|
|
815
|
-
const subId = `sub-${Date.now()}-${Math.random().toString(36).
|
|
1094
|
+
const subId = `sub-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
|
|
1095
|
+
const filterKey = JSON.stringify(filter);
|
|
816
1096
|
if (this.relays.length === 0) {
|
|
817
1097
|
const matchingEvents = this._getMatchingCachedEvents(filter);
|
|
818
1098
|
const mockSub = {
|
|
@@ -837,6 +1117,32 @@ class NostrClient {
|
|
|
837
1117
|
}
|
|
838
1118
|
};
|
|
839
1119
|
}
|
|
1120
|
+
const existing = activeSubscriptions.get(filterKey);
|
|
1121
|
+
if (existing) {
|
|
1122
|
+
existing.callbacks.add(onEvent);
|
|
1123
|
+
existing.refCount++;
|
|
1124
|
+
return {
|
|
1125
|
+
id: subId,
|
|
1126
|
+
unsubscribe: () => {
|
|
1127
|
+
existing.callbacks.delete(onEvent);
|
|
1128
|
+
existing.refCount--;
|
|
1129
|
+
if (existing.refCount === 0) {
|
|
1130
|
+
if (existing.subscription && existing.subscription.close) {
|
|
1131
|
+
existing.subscription.close();
|
|
1132
|
+
}
|
|
1133
|
+
activeSubscriptions.delete(filterKey);
|
|
1134
|
+
}
|
|
1135
|
+
this._subscriptions.delete(subId);
|
|
1136
|
+
}
|
|
1137
|
+
};
|
|
1138
|
+
}
|
|
1139
|
+
const callbacks = /* @__PURE__ */ new Set([onEvent]);
|
|
1140
|
+
const subscriptionInfo = {
|
|
1141
|
+
callbacks,
|
|
1142
|
+
refCount: 1,
|
|
1143
|
+
subscription: null
|
|
1144
|
+
};
|
|
1145
|
+
activeSubscriptions.set(filterKey, subscriptionInfo);
|
|
840
1146
|
const sub = this.pool.subscribeMany(
|
|
841
1147
|
this.relays,
|
|
842
1148
|
[filter],
|
|
@@ -848,18 +1154,33 @@ class NostrClient {
|
|
|
848
1154
|
}
|
|
849
1155
|
}
|
|
850
1156
|
this._cacheEvent(event);
|
|
851
|
-
|
|
1157
|
+
const subInfo = activeSubscriptions.get(filterKey);
|
|
1158
|
+
if (subInfo) {
|
|
1159
|
+
for (const cb of subInfo.callbacks) {
|
|
1160
|
+
try {
|
|
1161
|
+
cb(event);
|
|
1162
|
+
} catch (err) {
|
|
1163
|
+
console.warn("[nostr] Subscription callback error:", err.message);
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
852
1167
|
},
|
|
853
1168
|
oneose: () => {
|
|
854
1169
|
if (options.onEOSE) options.onEOSE();
|
|
855
1170
|
}
|
|
856
1171
|
}
|
|
857
1172
|
);
|
|
1173
|
+
subscriptionInfo.subscription = sub;
|
|
858
1174
|
this._subscriptions.set(subId, sub);
|
|
859
1175
|
return {
|
|
860
1176
|
id: subId,
|
|
861
1177
|
unsubscribe: () => {
|
|
862
|
-
|
|
1178
|
+
callbacks.delete(onEvent);
|
|
1179
|
+
subscriptionInfo.refCount--;
|
|
1180
|
+
if (subscriptionInfo.refCount === 0) {
|
|
1181
|
+
if (sub.close) sub.close();
|
|
1182
|
+
activeSubscriptions.delete(filterKey);
|
|
1183
|
+
}
|
|
863
1184
|
this._subscriptions.delete(subId);
|
|
864
1185
|
}
|
|
865
1186
|
};
|
|
@@ -895,42 +1216,52 @@ class NostrClient {
|
|
|
895
1216
|
}
|
|
896
1217
|
/**
|
|
897
1218
|
* Invalidate query caches that might be affected by a new event
|
|
1219
|
+
* Uses reverse index for O(1) lookup instead of O(n) scan
|
|
898
1220
|
* @private
|
|
899
1221
|
*/
|
|
900
1222
|
_invalidateQueryCachesForEvent(event) {
|
|
1223
|
+
const indexedKeys = this._cacheIndex.get(event.kind);
|
|
1224
|
+
if (!indexedKeys || indexedKeys.size === 0) {
|
|
1225
|
+
return;
|
|
1226
|
+
}
|
|
901
1227
|
const keysToDelete = [];
|
|
902
|
-
for (const
|
|
903
|
-
|
|
1228
|
+
for (const cacheKey of indexedKeys) {
|
|
1229
|
+
const cached = this._eventCache.get(cacheKey);
|
|
1230
|
+
if (!cached) {
|
|
1231
|
+
indexedKeys.delete(cacheKey);
|
|
1232
|
+
continue;
|
|
1233
|
+
}
|
|
904
1234
|
try {
|
|
905
1235
|
const filter = JSON.parse(cacheKey);
|
|
906
1236
|
if (this._eventMatchesFilter(event, filter)) {
|
|
907
1237
|
keysToDelete.push(cacheKey);
|
|
908
1238
|
}
|
|
909
1239
|
} catch {
|
|
1240
|
+
indexedKeys.delete(cacheKey);
|
|
910
1241
|
}
|
|
911
1242
|
}
|
|
912
1243
|
for (const key of keysToDelete) {
|
|
913
1244
|
this._eventCache.delete(key);
|
|
1245
|
+
this._unindexCacheEntry(key);
|
|
914
1246
|
}
|
|
915
1247
|
}
|
|
916
1248
|
/**
|
|
917
|
-
* Cache event in memory and persist
|
|
1249
|
+
* Cache event in memory and persist (batched)
|
|
918
1250
|
* @private
|
|
919
1251
|
*/
|
|
920
1252
|
async _cacheEvent(event) {
|
|
921
1253
|
this._cacheEventSync(event);
|
|
922
1254
|
if (this.persistentStorage) {
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
storageKey = dTag[1];
|
|
929
|
-
}
|
|
1255
|
+
let storageKey = event.id;
|
|
1256
|
+
if (event.kind >= 3e4 && event.kind < 4e4) {
|
|
1257
|
+
const dTag = event.tags.find((t) => t[0] === "d");
|
|
1258
|
+
if (dTag && dTag[1]) {
|
|
1259
|
+
storageKey = dTag[1];
|
|
930
1260
|
}
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
1261
|
+
}
|
|
1262
|
+
this._persistQueue.set(storageKey, event);
|
|
1263
|
+
if (!this._persistTimer) {
|
|
1264
|
+
this._persistTimer = setTimeout(() => this._flushPersistQueue(), this._persistBatchMs);
|
|
934
1265
|
}
|
|
935
1266
|
}
|
|
936
1267
|
if (this.relays.length === 0) {
|
|
@@ -945,6 +1276,26 @@ class NostrClient {
|
|
|
945
1276
|
}
|
|
946
1277
|
}
|
|
947
1278
|
}
|
|
1279
|
+
/**
|
|
1280
|
+
* Flush batched persistent writes
|
|
1281
|
+
* @private
|
|
1282
|
+
*/
|
|
1283
|
+
async _flushPersistQueue() {
|
|
1284
|
+
this._persistTimer = null;
|
|
1285
|
+
if (!this.persistentStorage || this._persistQueue.size === 0) {
|
|
1286
|
+
return;
|
|
1287
|
+
}
|
|
1288
|
+
const toWrite = Array.from(this._persistQueue.entries());
|
|
1289
|
+
this._persistQueue.clear();
|
|
1290
|
+
const writePromises = toWrite.map(async ([key, event]) => {
|
|
1291
|
+
try {
|
|
1292
|
+
await this.persistentStorage.put(key, event);
|
|
1293
|
+
} catch (error) {
|
|
1294
|
+
console.warn(`Failed to persist event ${key}:`, error.message);
|
|
1295
|
+
}
|
|
1296
|
+
});
|
|
1297
|
+
await Promise.all(writePromises);
|
|
1298
|
+
}
|
|
948
1299
|
/**
|
|
949
1300
|
* Get cached events matching a filter
|
|
950
1301
|
* @private
|
|
@@ -1032,11 +1383,25 @@ class NostrClient {
|
|
|
1032
1383
|
}
|
|
1033
1384
|
/**
|
|
1034
1385
|
* Close all connections and subscriptions
|
|
1386
|
+
* @param {Object} options - Close options
|
|
1387
|
+
* @param {boolean} options.flush - Flush pending writes before closing (default: true)
|
|
1035
1388
|
*/
|
|
1036
|
-
close() {
|
|
1389
|
+
async close(options = {}) {
|
|
1390
|
+
const shouldFlush = options.flush !== false;
|
|
1391
|
+
if (shouldFlush && this._persistTimer) {
|
|
1392
|
+
clearTimeout(this._persistTimer);
|
|
1393
|
+
await this._flushPersistQueue();
|
|
1394
|
+
}
|
|
1037
1395
|
if (this.syncService) {
|
|
1038
1396
|
this.syncService.stop();
|
|
1039
1397
|
}
|
|
1398
|
+
const authorSub = authorSubscriptions.get(this.publicKey);
|
|
1399
|
+
if (authorSub && authorSub.subscription) {
|
|
1400
|
+
if (authorSub.subscription.close) {
|
|
1401
|
+
authorSub.subscription.close();
|
|
1402
|
+
}
|
|
1403
|
+
authorSubscriptions.delete(this.publicKey);
|
|
1404
|
+
}
|
|
1040
1405
|
for (const sub of this._subscriptions.values()) {
|
|
1041
1406
|
if (sub.close) {
|
|
1042
1407
|
sub.close();
|
|
@@ -1047,6 +1412,7 @@ class NostrClient {
|
|
|
1047
1412
|
this._subscriptions.clear();
|
|
1048
1413
|
this.pool.close(this.relays);
|
|
1049
1414
|
this._eventCache.clear();
|
|
1415
|
+
this._cacheIndex.clear();
|
|
1050
1416
|
}
|
|
1051
1417
|
/**
|
|
1052
1418
|
* Get relay status
|
|
@@ -1194,16 +1560,53 @@ function gunPut(gunChain, data, timeout = 1e3) {
|
|
|
1194
1560
|
});
|
|
1195
1561
|
});
|
|
1196
1562
|
}
|
|
1197
|
-
async function gunMap(gunChain, timeout =
|
|
1563
|
+
async function gunMap(gunChain, timeout = 5e3) {
|
|
1198
1564
|
return new Promise((resolve) => {
|
|
1199
1565
|
const items = {};
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1566
|
+
let settled = false;
|
|
1567
|
+
let expectedCount = 0;
|
|
1568
|
+
let receivedCount = 0;
|
|
1569
|
+
const tryResolve = () => {
|
|
1570
|
+
if (settled) return;
|
|
1571
|
+
if (expectedCount > 0 && receivedCount >= expectedCount) {
|
|
1572
|
+
settled = true;
|
|
1573
|
+
resolve(items);
|
|
1574
|
+
}
|
|
1575
|
+
};
|
|
1576
|
+
gunChain.once((parentData) => {
|
|
1577
|
+
if (settled) return;
|
|
1578
|
+
if (!parentData) {
|
|
1579
|
+
settled = true;
|
|
1580
|
+
resolve({});
|
|
1581
|
+
return;
|
|
1582
|
+
}
|
|
1583
|
+
const keys = Object.keys(parentData).filter((k) => k !== "_");
|
|
1584
|
+
if (keys.length === 0) {
|
|
1585
|
+
settled = true;
|
|
1586
|
+
resolve({});
|
|
1587
|
+
return;
|
|
1588
|
+
}
|
|
1589
|
+
expectedCount = keys.filter((k) => {
|
|
1590
|
+
const item = parentData[k];
|
|
1591
|
+
return item && typeof item === "object" && item["#"];
|
|
1592
|
+
}).length;
|
|
1593
|
+
if (expectedCount === 0) {
|
|
1594
|
+
settled = true;
|
|
1595
|
+
resolve({});
|
|
1596
|
+
return;
|
|
1203
1597
|
}
|
|
1598
|
+
gunChain.map().once((data, key) => {
|
|
1599
|
+
if (settled || !data || key.startsWith("_")) return;
|
|
1600
|
+
items[key] = data;
|
|
1601
|
+
receivedCount++;
|
|
1602
|
+
tryResolve();
|
|
1603
|
+
});
|
|
1204
1604
|
});
|
|
1205
1605
|
setTimeout(() => {
|
|
1206
|
-
|
|
1606
|
+
if (!settled) {
|
|
1607
|
+
settled = true;
|
|
1608
|
+
resolve(items);
|
|
1609
|
+
}
|
|
1207
1610
|
}, timeout);
|
|
1208
1611
|
});
|
|
1209
1612
|
}
|
|
@@ -1298,11 +1701,36 @@ async function read$2(gun, path) {
|
|
|
1298
1701
|
}
|
|
1299
1702
|
return data;
|
|
1300
1703
|
}
|
|
1301
|
-
async function readAll$2(gun, path) {
|
|
1704
|
+
async function readAll$2(gun, path, timeout = 5e3) {
|
|
1302
1705
|
return new Promise((resolve) => {
|
|
1303
1706
|
const output2 = /* @__PURE__ */ new Map();
|
|
1304
1707
|
let settled = false;
|
|
1708
|
+
let expectedCount = 0;
|
|
1709
|
+
let receivedCount = 0;
|
|
1305
1710
|
const ref = gun.get(path);
|
|
1711
|
+
const tryResolve = () => {
|
|
1712
|
+
if (settled) return;
|
|
1713
|
+
if (expectedCount > 0 && receivedCount >= expectedCount) {
|
|
1714
|
+
settled = true;
|
|
1715
|
+
resolve(Array.from(output2.values()));
|
|
1716
|
+
}
|
|
1717
|
+
};
|
|
1718
|
+
const parseItem = (data) => {
|
|
1719
|
+
if (!data) return null;
|
|
1720
|
+
let item = null;
|
|
1721
|
+
if (data._json && typeof data._json === "string") {
|
|
1722
|
+
try {
|
|
1723
|
+
item = JSON.parse(data._json);
|
|
1724
|
+
} catch (e) {
|
|
1725
|
+
}
|
|
1726
|
+
} else if (typeof data === "string") {
|
|
1727
|
+
try {
|
|
1728
|
+
item = JSON.parse(data);
|
|
1729
|
+
} catch (e) {
|
|
1730
|
+
}
|
|
1731
|
+
}
|
|
1732
|
+
return item;
|
|
1733
|
+
};
|
|
1306
1734
|
ref.once((parentData) => {
|
|
1307
1735
|
if (settled) return;
|
|
1308
1736
|
if (!parentData) {
|
|
@@ -1316,64 +1744,47 @@ async function readAll$2(gun, path) {
|
|
|
1316
1744
|
resolve([]);
|
|
1317
1745
|
return;
|
|
1318
1746
|
}
|
|
1747
|
+
const referenceKeys = [];
|
|
1319
1748
|
for (const key of keys) {
|
|
1320
1749
|
const rawItem = parentData[key];
|
|
1321
1750
|
if (!rawItem) continue;
|
|
1322
|
-
let item = null;
|
|
1323
1751
|
if (typeof rawItem === "object" && rawItem["#"]) {
|
|
1752
|
+
referenceKeys.push(key);
|
|
1324
1753
|
continue;
|
|
1325
1754
|
}
|
|
1326
|
-
|
|
1327
|
-
try {
|
|
1328
|
-
item = JSON.parse(rawItem._json);
|
|
1329
|
-
} catch (e) {
|
|
1330
|
-
}
|
|
1331
|
-
} else if (typeof rawItem === "string") {
|
|
1332
|
-
try {
|
|
1333
|
-
item = JSON.parse(rawItem);
|
|
1334
|
-
} catch (e) {
|
|
1335
|
-
}
|
|
1336
|
-
}
|
|
1755
|
+
const item = parseItem(rawItem);
|
|
1337
1756
|
if (item && item.id && !item._deleted) {
|
|
1338
1757
|
output2.set(item.id, item);
|
|
1758
|
+
receivedCount++;
|
|
1339
1759
|
}
|
|
1340
1760
|
}
|
|
1341
|
-
|
|
1761
|
+
expectedCount = referenceKeys.length;
|
|
1762
|
+
if (expectedCount === 0) {
|
|
1342
1763
|
settled = true;
|
|
1343
1764
|
resolve(Array.from(output2.values()));
|
|
1344
1765
|
return;
|
|
1345
1766
|
}
|
|
1346
1767
|
ref.map().once((data, key) => {
|
|
1347
1768
|
if (settled || !data || key === "_") return;
|
|
1348
|
-
|
|
1349
|
-
if (data._json && typeof data._json === "string") {
|
|
1350
|
-
try {
|
|
1351
|
-
item = JSON.parse(data._json);
|
|
1352
|
-
} catch (e) {
|
|
1353
|
-
}
|
|
1354
|
-
} else if (typeof data === "string") {
|
|
1355
|
-
try {
|
|
1356
|
-
item = JSON.parse(data);
|
|
1357
|
-
} catch (e) {
|
|
1358
|
-
}
|
|
1359
|
-
}
|
|
1769
|
+
const item = parseItem(data);
|
|
1360
1770
|
if (item && item.id && !item._deleted) {
|
|
1361
|
-
output2.
|
|
1771
|
+
if (!output2.has(item.id)) {
|
|
1772
|
+
output2.set(item.id, item);
|
|
1773
|
+
receivedCount++;
|
|
1774
|
+
tryResolve();
|
|
1775
|
+
}
|
|
1776
|
+
} else {
|
|
1777
|
+
receivedCount++;
|
|
1778
|
+
tryResolve();
|
|
1362
1779
|
}
|
|
1363
1780
|
});
|
|
1364
|
-
setTimeout(() => {
|
|
1365
|
-
if (!settled) {
|
|
1366
|
-
settled = true;
|
|
1367
|
-
resolve(Array.from(output2.values()));
|
|
1368
|
-
}
|
|
1369
|
-
}, 500);
|
|
1370
1781
|
});
|
|
1371
1782
|
setTimeout(() => {
|
|
1372
1783
|
if (!settled) {
|
|
1373
1784
|
settled = true;
|
|
1374
1785
|
resolve(Array.from(output2.values()));
|
|
1375
1786
|
}
|
|
1376
|
-
},
|
|
1787
|
+
}, timeout);
|
|
1377
1788
|
});
|
|
1378
1789
|
}
|
|
1379
1790
|
async function update$2(gun, path, updates) {
|
|
@@ -2457,11 +2868,12 @@ class GunAuth {
|
|
|
2457
2868
|
}
|
|
2458
2869
|
/**
|
|
2459
2870
|
* Read all data from a private lens
|
|
2871
|
+
* First gets count of items, then collects until count is reached
|
|
2460
2872
|
* @param {string} lens - Lens name
|
|
2461
|
-
* @param {number} timeout - Timeout in ms
|
|
2873
|
+
* @param {number} timeout - Timeout in ms (fallback)
|
|
2462
2874
|
* @returns {Promise<Object[]>} Array of data objects
|
|
2463
2875
|
*/
|
|
2464
|
-
async readAllPrivate(lens, timeout =
|
|
2876
|
+
async readAllPrivate(lens, timeout = 5e3) {
|
|
2465
2877
|
if (!this.isAuthenticated()) {
|
|
2466
2878
|
throw new Error("Not authenticated");
|
|
2467
2879
|
}
|
|
@@ -2469,37 +2881,75 @@ class GunAuth {
|
|
|
2469
2881
|
const results = [];
|
|
2470
2882
|
const seen = /* @__PURE__ */ new Set();
|
|
2471
2883
|
const ref = this.getPrivatePath(lens);
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2884
|
+
let settled = false;
|
|
2885
|
+
let expectedCount = 0;
|
|
2886
|
+
let receivedCount = 0;
|
|
2887
|
+
const tryResolve = () => {
|
|
2888
|
+
if (settled) return;
|
|
2889
|
+
if (expectedCount > 0 && receivedCount >= expectedCount) {
|
|
2890
|
+
settled = true;
|
|
2891
|
+
resolve(results);
|
|
2476
2892
|
}
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
parsed = JSON.parse(data._json);
|
|
2492
|
-
} catch (e) {
|
|
2493
|
-
}
|
|
2494
|
-
} else if (typeof data === "object") {
|
|
2495
|
-
parsed = { ...data };
|
|
2496
|
-
delete parsed["_"];
|
|
2893
|
+
};
|
|
2894
|
+
const parseItem = (data) => {
|
|
2895
|
+
if (!data) return null;
|
|
2896
|
+
let parsed = null;
|
|
2897
|
+
if (typeof data === "string") {
|
|
2898
|
+
try {
|
|
2899
|
+
parsed = JSON.parse(data);
|
|
2900
|
+
} catch (e) {
|
|
2901
|
+
parsed = data;
|
|
2902
|
+
}
|
|
2903
|
+
} else if (data._json && typeof data._json === "string") {
|
|
2904
|
+
try {
|
|
2905
|
+
parsed = JSON.parse(data._json);
|
|
2906
|
+
} catch (e) {
|
|
2497
2907
|
}
|
|
2908
|
+
} else if (typeof data === "object") {
|
|
2909
|
+
parsed = { ...data };
|
|
2910
|
+
delete parsed["_"];
|
|
2911
|
+
}
|
|
2912
|
+
return parsed;
|
|
2913
|
+
};
|
|
2914
|
+
ref.once((parentData) => {
|
|
2915
|
+
if (settled) return;
|
|
2916
|
+
if (!parentData) {
|
|
2917
|
+
settled = true;
|
|
2918
|
+
resolve([]);
|
|
2919
|
+
return;
|
|
2920
|
+
}
|
|
2921
|
+
const keys = Object.keys(parentData).filter((k) => k !== "_");
|
|
2922
|
+
if (keys.length === 0) {
|
|
2923
|
+
settled = true;
|
|
2924
|
+
resolve([]);
|
|
2925
|
+
return;
|
|
2926
|
+
}
|
|
2927
|
+
expectedCount = keys.filter((k) => {
|
|
2928
|
+
const item = parentData[k];
|
|
2929
|
+
return item && typeof item === "object" && item["#"];
|
|
2930
|
+
}).length;
|
|
2931
|
+
if (expectedCount === 0) {
|
|
2932
|
+
settled = true;
|
|
2933
|
+
resolve([]);
|
|
2934
|
+
return;
|
|
2935
|
+
}
|
|
2936
|
+
ref.map().once((data, key) => {
|
|
2937
|
+
if (settled || !data || key.startsWith("_") || seen.has(key)) return;
|
|
2938
|
+
seen.add(key);
|
|
2939
|
+
const parsed = parseItem(data);
|
|
2498
2940
|
if (parsed && !parsed._deleted) {
|
|
2499
2941
|
results.push(parsed);
|
|
2500
2942
|
}
|
|
2501
|
-
|
|
2943
|
+
receivedCount++;
|
|
2944
|
+
tryResolve();
|
|
2945
|
+
});
|
|
2502
2946
|
});
|
|
2947
|
+
setTimeout(() => {
|
|
2948
|
+
if (!settled) {
|
|
2949
|
+
settled = true;
|
|
2950
|
+
resolve(results);
|
|
2951
|
+
}
|
|
2952
|
+
}, timeout);
|
|
2503
2953
|
});
|
|
2504
2954
|
}
|
|
2505
2955
|
/**
|
|
@@ -3196,11 +3646,11 @@ class GunDBBackend extends StorageBackend {
|
|
|
3196
3646
|
}
|
|
3197
3647
|
}
|
|
3198
3648
|
const name = "holosphere";
|
|
3199
|
-
const version$1 = "2.0.0-
|
|
3649
|
+
const version$1 = "2.0.0-alpha6";
|
|
3200
3650
|
const description = "Holonic geospatial communication infrastructure combining H3 hexagonal indexing with distributed P2P storage";
|
|
3201
3651
|
const type = "module";
|
|
3202
3652
|
const bin = {
|
|
3203
|
-
"holosphere-activitypub": "
|
|
3653
|
+
"holosphere-activitypub": "bin/holosphere-activitypub.js"
|
|
3204
3654
|
};
|
|
3205
3655
|
const main = "./dist/cjs/holosphere.cjs";
|
|
3206
3656
|
const module = "./dist/esm/holosphere.js";
|
|
@@ -3941,6 +4391,9 @@ const h3Operations = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.define
|
|
|
3941
4391
|
toHolon
|
|
3942
4392
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
3943
4393
|
const globalSubscriptions = /* @__PURE__ */ new Map();
|
|
4394
|
+
const singlePathSubscriptions = /* @__PURE__ */ new Map();
|
|
4395
|
+
const pendingQueries = /* @__PURE__ */ new Map();
|
|
4396
|
+
const QUERY_DEDUP_WINDOW = 2e3;
|
|
3944
4397
|
async function nostrPut(client, path, data, kind2 = 3e4) {
|
|
3945
4398
|
const dataEvent = {
|
|
3946
4399
|
kind: kind2,
|
|
@@ -3977,6 +4430,27 @@ async function nostrGet(client, path, kind2 = 3e4, options = {}) {
|
|
|
3977
4430
|
}
|
|
3978
4431
|
}
|
|
3979
4432
|
}
|
|
4433
|
+
const queryKey = `get:${client.publicKey}:${kind2}:${path}:${authors.join(",")}`;
|
|
4434
|
+
const pending = pendingQueries.get(queryKey);
|
|
4435
|
+
if (pending && Date.now() - pending.timestamp < QUERY_DEDUP_WINDOW) {
|
|
4436
|
+
return pending.promise;
|
|
4437
|
+
}
|
|
4438
|
+
const queryPromise = _executeNostrGet(client, path, kind2, authors, timeout, options);
|
|
4439
|
+
pendingQueries.set(queryKey, {
|
|
4440
|
+
promise: queryPromise,
|
|
4441
|
+
timestamp: Date.now()
|
|
4442
|
+
});
|
|
4443
|
+
queryPromise.finally(() => {
|
|
4444
|
+
setTimeout(() => {
|
|
4445
|
+
const current = pendingQueries.get(queryKey);
|
|
4446
|
+
if (current && current.promise === queryPromise) {
|
|
4447
|
+
pendingQueries.delete(queryKey);
|
|
4448
|
+
}
|
|
4449
|
+
}, QUERY_DEDUP_WINDOW);
|
|
4450
|
+
});
|
|
4451
|
+
return queryPromise;
|
|
4452
|
+
}
|
|
4453
|
+
async function _executeNostrGet(client, path, kind2, authors, timeout, options) {
|
|
3980
4454
|
const filter = {
|
|
3981
4455
|
kinds: [kind2],
|
|
3982
4456
|
authors,
|
|
@@ -4010,24 +4484,24 @@ async function nostrGetAll(client, pathPrefix, kind2 = 3e4, options = {}) {
|
|
|
4010
4484
|
if (!options.skipPersistent && client.persistentGetAll) {
|
|
4011
4485
|
const persistedEvents = await client.persistentGetAll(pathPrefix);
|
|
4012
4486
|
if (persistedEvents.length > 0) {
|
|
4013
|
-
const
|
|
4487
|
+
const byPath = /* @__PURE__ */ new Map();
|
|
4014
4488
|
for (const event of persistedEvents) {
|
|
4015
4489
|
if (!event || !event.tags) continue;
|
|
4016
4490
|
const dTag = event.tags.find((t) => t[0] === "d");
|
|
4017
4491
|
if (!dTag || !dTag[1] || !dTag[1].startsWith(pathPrefix)) continue;
|
|
4018
4492
|
const path = dTag[1];
|
|
4019
|
-
const existing =
|
|
4493
|
+
const existing = byPath.get(path);
|
|
4020
4494
|
if (!existing || event.created_at > existing.created_at) {
|
|
4021
4495
|
try {
|
|
4022
4496
|
const data = JSON.parse(event.content);
|
|
4023
4497
|
if (data._deleted) {
|
|
4024
|
-
|
|
4498
|
+
byPath.delete(path);
|
|
4025
4499
|
continue;
|
|
4026
4500
|
}
|
|
4027
4501
|
if (options.includeAuthor) {
|
|
4028
4502
|
data._author = event.pubkey;
|
|
4029
4503
|
}
|
|
4030
|
-
|
|
4504
|
+
byPath.set(path, { data, created_at: event.created_at });
|
|
4031
4505
|
} catch (error) {
|
|
4032
4506
|
}
|
|
4033
4507
|
}
|
|
@@ -4035,9 +4509,30 @@ async function nostrGetAll(client, pathPrefix, kind2 = 3e4, options = {}) {
|
|
|
4035
4509
|
if (client.refreshPrefixInBackground) {
|
|
4036
4510
|
client.refreshPrefixInBackground(pathPrefix, kind2, { authors, timeout, limit: limit2 });
|
|
4037
4511
|
}
|
|
4038
|
-
return Array.from(
|
|
4512
|
+
return Array.from(byPath.values()).map((item) => item.data);
|
|
4039
4513
|
}
|
|
4040
4514
|
}
|
|
4515
|
+
const queryKey = `getAll:${client.publicKey}:${kind2}:${pathPrefix}:${authors.join(",")}`;
|
|
4516
|
+
const pending = pendingQueries.get(queryKey);
|
|
4517
|
+
if (pending && Date.now() - pending.timestamp < QUERY_DEDUP_WINDOW) {
|
|
4518
|
+
return pending.promise;
|
|
4519
|
+
}
|
|
4520
|
+
const queryPromise = _executeNostrGetAll(client, pathPrefix, kind2, authors, timeout, limit2, options);
|
|
4521
|
+
pendingQueries.set(queryKey, {
|
|
4522
|
+
promise: queryPromise,
|
|
4523
|
+
timestamp: Date.now()
|
|
4524
|
+
});
|
|
4525
|
+
queryPromise.finally(() => {
|
|
4526
|
+
setTimeout(() => {
|
|
4527
|
+
const current = pendingQueries.get(queryKey);
|
|
4528
|
+
if (current && current.promise === queryPromise) {
|
|
4529
|
+
pendingQueries.delete(queryKey);
|
|
4530
|
+
}
|
|
4531
|
+
}, QUERY_DEDUP_WINDOW);
|
|
4532
|
+
});
|
|
4533
|
+
return queryPromise;
|
|
4534
|
+
}
|
|
4535
|
+
async function _executeNostrGetAll(client, pathPrefix, kind2, authors, timeout, limit2, options) {
|
|
4041
4536
|
const filter = {
|
|
4042
4537
|
kinds: [kind2],
|
|
4043
4538
|
authors,
|
|
@@ -4226,7 +4721,29 @@ async function nostrDeleteAll(client, pathPrefix, kind2 = 3e4) {
|
|
|
4226
4721
|
}
|
|
4227
4722
|
function nostrSubscribe(client, path, callback, options = {}) {
|
|
4228
4723
|
const kind2 = options.kind || 3e4;
|
|
4229
|
-
|
|
4724
|
+
const subscriptionKey = `single:${client.publicKey}:${kind2}:${path}`;
|
|
4725
|
+
const existing = singlePathSubscriptions.get(subscriptionKey);
|
|
4726
|
+
if (existing) {
|
|
4727
|
+
existing.callbacks.push(callback);
|
|
4728
|
+
return {
|
|
4729
|
+
unsubscribe: () => {
|
|
4730
|
+
const idx = existing.callbacks.indexOf(callback);
|
|
4731
|
+
if (idx > -1) {
|
|
4732
|
+
existing.callbacks.splice(idx, 1);
|
|
4733
|
+
}
|
|
4734
|
+
if (existing.callbacks.length === 0) {
|
|
4735
|
+
existing.subscription.unsubscribe();
|
|
4736
|
+
singlePathSubscriptions.delete(subscriptionKey);
|
|
4737
|
+
}
|
|
4738
|
+
}
|
|
4739
|
+
};
|
|
4740
|
+
}
|
|
4741
|
+
const callbacks = [callback];
|
|
4742
|
+
const subscriptionInfo = {
|
|
4743
|
+
callbacks,
|
|
4744
|
+
subscription: null
|
|
4745
|
+
};
|
|
4746
|
+
singlePathSubscriptions.set(subscriptionKey, subscriptionInfo);
|
|
4230
4747
|
const filter = {
|
|
4231
4748
|
kinds: [kind2],
|
|
4232
4749
|
authors: [client.publicKey],
|
|
@@ -4239,11 +4756,6 @@ function nostrSubscribe(client, path, callback, options = {}) {
|
|
|
4239
4756
|
filter,
|
|
4240
4757
|
(event) => {
|
|
4241
4758
|
if (event.pubkey !== client.publicKey) {
|
|
4242
|
-
console.warn("[nostrSubscribe] Rejecting event from different author:", {
|
|
4243
|
-
expected: client.publicKey,
|
|
4244
|
-
received: event.pubkey,
|
|
4245
|
-
eventId: event.id
|
|
4246
|
-
});
|
|
4247
4759
|
return;
|
|
4248
4760
|
}
|
|
4249
4761
|
try {
|
|
@@ -4251,7 +4763,13 @@ function nostrSubscribe(client, path, callback, options = {}) {
|
|
|
4251
4763
|
if (data._deleted) {
|
|
4252
4764
|
return;
|
|
4253
4765
|
}
|
|
4254
|
-
|
|
4766
|
+
for (const cb of callbacks) {
|
|
4767
|
+
try {
|
|
4768
|
+
cb(data, event);
|
|
4769
|
+
} catch (err) {
|
|
4770
|
+
console.error("Subscription callback error:", err);
|
|
4771
|
+
}
|
|
4772
|
+
}
|
|
4255
4773
|
} catch (error) {
|
|
4256
4774
|
console.error("Failed to parse event in subscription:", error);
|
|
4257
4775
|
}
|
|
@@ -4261,7 +4779,19 @@ function nostrSubscribe(client, path, callback, options = {}) {
|
|
|
4261
4779
|
}
|
|
4262
4780
|
}
|
|
4263
4781
|
);
|
|
4264
|
-
|
|
4782
|
+
subscriptionInfo.subscription = subscription;
|
|
4783
|
+
return {
|
|
4784
|
+
unsubscribe: () => {
|
|
4785
|
+
const idx = callbacks.indexOf(callback);
|
|
4786
|
+
if (idx > -1) {
|
|
4787
|
+
callbacks.splice(idx, 1);
|
|
4788
|
+
}
|
|
4789
|
+
if (callbacks.length === 0) {
|
|
4790
|
+
subscription.unsubscribe();
|
|
4791
|
+
singlePathSubscriptions.delete(subscriptionKey);
|
|
4792
|
+
}
|
|
4793
|
+
}
|
|
4794
|
+
};
|
|
4265
4795
|
}
|
|
4266
4796
|
async function nostrSubscribeMany(client, pathPrefix, callback, options = {}) {
|
|
4267
4797
|
const kind2 = options.kind || 3e4;
|
|
@@ -5013,7 +5543,7 @@ const sha256 = sha256$1;
|
|
|
5013
5543
|
let secp256k1 = null;
|
|
5014
5544
|
async function loadCrypto() {
|
|
5015
5545
|
if (!secp256k1) {
|
|
5016
|
-
const module2 = await import("./secp256k1-
|
|
5546
|
+
const module2 = await import("./secp256k1-PfNOEI7a.js");
|
|
5017
5547
|
secp256k1 = module2.secp256k1;
|
|
5018
5548
|
}
|
|
5019
5549
|
return secp256k1;
|
|
@@ -6228,8 +6758,8 @@ async function initiateFederationHandshake(holosphere, privateKey, params) {
|
|
|
6228
6758
|
message
|
|
6229
6759
|
} = params;
|
|
6230
6760
|
try {
|
|
6231
|
-
const {
|
|
6232
|
-
const senderPubKey =
|
|
6761
|
+
const { getPublicKey: getPublicKey2 } = await Promise.resolve().then(() => nostrUtils);
|
|
6762
|
+
const senderPubKey = getPublicKey2(privateKey);
|
|
6233
6763
|
const request = createFederationRequest({
|
|
6234
6764
|
senderHolonId: holonId,
|
|
6235
6765
|
senderHolonName: holonName,
|
|
@@ -6264,8 +6794,8 @@ async function acceptFederationRequest$1(holosphere, privateKey, params) {
|
|
|
6264
6794
|
message
|
|
6265
6795
|
} = params;
|
|
6266
6796
|
try {
|
|
6267
|
-
const {
|
|
6268
|
-
const responderPubKey =
|
|
6797
|
+
const { getPublicKey: getPublicKey2 } = await Promise.resolve().then(() => nostrUtils);
|
|
6798
|
+
const responderPubKey = getPublicKey2(privateKey);
|
|
6269
6799
|
if (holosphere.client) {
|
|
6270
6800
|
await addFederatedPartner(holosphere.client, holosphere.config.appName, senderPubKey, {
|
|
6271
6801
|
alias: request.senderHolonName,
|
|
@@ -6277,6 +6807,10 @@ async function acceptFederationRequest$1(holosphere, privateKey, params) {
|
|
|
6277
6807
|
}
|
|
6278
6808
|
}
|
|
6279
6809
|
}
|
|
6810
|
+
await holosphere.federateHolon(holonId, senderPubKey, {
|
|
6811
|
+
lensConfig,
|
|
6812
|
+
partnerName: request.senderHolonName
|
|
6813
|
+
});
|
|
6280
6814
|
const response = createFederationResponse({
|
|
6281
6815
|
requestId: request.requestId,
|
|
6282
6816
|
status: "accepted",
|
|
@@ -16643,7 +17177,7 @@ class ChainManager {
|
|
|
16643
17177
|
*/
|
|
16644
17178
|
async _loadEthers() {
|
|
16645
17179
|
if (!this.ethers) {
|
|
16646
|
-
const ethersModule = await import("./index-
|
|
17180
|
+
const ethersModule = await import("./index-JFz-dW43.js");
|
|
16647
17181
|
this.ethers = ethersModule;
|
|
16648
17182
|
}
|
|
16649
17183
|
return this.ethers;
|
|
@@ -16827,11 +17361,11 @@ class ChainManager {
|
|
|
16827
17361
|
* @param {boolean} [useSigner=true] - Use signer for write operations
|
|
16828
17362
|
* @returns {Contract}
|
|
16829
17363
|
*/
|
|
16830
|
-
async getContract(address,
|
|
17364
|
+
async getContract(address, abi2, useSigner = true) {
|
|
16831
17365
|
this._requireInitialized();
|
|
16832
17366
|
const ethers = await this._loadEthers();
|
|
16833
17367
|
const signerOrProvider = useSigner && this.signer ? this.signer : this.provider;
|
|
16834
|
-
return new ethers.Contract(address,
|
|
17368
|
+
return new ethers.Contract(address, abi2, signerOrProvider);
|
|
16835
17369
|
}
|
|
16836
17370
|
/**
|
|
16837
17371
|
* Deploy a contract
|
|
@@ -16840,13 +17374,13 @@ class ChainManager {
|
|
|
16840
17374
|
* @param {Array} [constructorArgs=[]] - Constructor arguments
|
|
16841
17375
|
* @returns {Promise<{contract, address, deployTx}>}
|
|
16842
17376
|
*/
|
|
16843
|
-
async deployContract(
|
|
17377
|
+
async deployContract(abi2, bytecode2, constructorArgs = []) {
|
|
16844
17378
|
this._requireInitialized();
|
|
16845
17379
|
if (!this.signer) {
|
|
16846
17380
|
throw new Error("Signer required for contract deployment");
|
|
16847
17381
|
}
|
|
16848
17382
|
const ethers = await this._loadEthers();
|
|
16849
|
-
const factory = new ethers.ContractFactory(
|
|
17383
|
+
const factory = new ethers.ContractFactory(abi2, bytecode2, this.signer);
|
|
16850
17384
|
const contract = await factory.deploy(...constructorArgs);
|
|
16851
17385
|
await contract.waitForDeployment();
|
|
16852
17386
|
const address = await contract.getAddress();
|
|
@@ -22565,7 +23099,7 @@ const AppreciativeABI = [
|
|
|
22565
23099
|
anonymous: false
|
|
22566
23100
|
}
|
|
22567
23101
|
];
|
|
22568
|
-
const
|
|
23102
|
+
const abi = [
|
|
22569
23103
|
{
|
|
22570
23104
|
type: "constructor",
|
|
22571
23105
|
inputs: [
|
|
@@ -24000,6 +24534,11 @@ const BundleABI = [
|
|
|
24000
24534
|
]
|
|
24001
24535
|
}
|
|
24002
24536
|
];
|
|
24537
|
+
const bytecode = "0x60806040526040518060400160405280600681526020017f42756e646c650000000000000000000000000000000000000000000000000000815250600290816200004a9190620006da565b5034801562000057575f80fd5b5060405162007e0338038062007e0383398181016040528101906200007d9190620009a6565b60015f819055505f821180156200009b5750670de0b6b3a764000082105b620000dd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000d49062000ac6565b60405180910390fd5b8460035f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508460045f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503360055f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508260019081620001ae9190620006da565b5081601381905550806014819055506001600985604051620001d1919062000b26565b90815260200160405180910390205f6101000a81548160ff021916908315150217905550600684908060018154018082558091505060019003905f5260205f20015f909190919091509081620002289190620006da565b50620002396200024460201b60201c565b505050505062000d3a565b60185f620002539190620003e9565b600160145462000264919062000b6b565b67ffffffffffffffff81111562000280576200027f62000480565b5b604051908082528060200260200182016040528015620002af5781602001602082028036833780820191505090505b5060189080519060200190620002c792919062000409565b505f6019819055505f670de0b6b3a764000090505f5b60145481116200037b578160188281548110620002ff57620002fe62000ba5565b5b905f5260205f2001819055508160155f8381526020019081526020015f20805490506200032d919062000bd2565b60195f8282546200033f919062000b6b565b925050819055506200036382601354670de0b6b3a76400006200037f60201b60201c565b91508080620003729062000c1c565b915050620002dd565b5050565b5f808211620003c5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620003bc9062000cb6565b60405180910390fd5b818385620003d4919062000bd2565b620003e0919062000d03565b90509392505050565b5080545f8255905f5260205f209081019062000406919062000459565b50565b828054828255905f5260205f2090810192821562000446579160200282015b828111156200044557825182559160200191906001019062000428565b5b50905062000455919062000459565b5090565b5b8082111562000472575f815f9055506001016200045a565b5090565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680620004f257607f821691505b602082108103620005085762000507620004ad565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026200056c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826200052f565b6200057886836200052f565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f620005c2620005bc620005b68462000590565b62000599565b62000590565b9050919050565b5f819050919050565b620005dd83620005a2565b620005f5620005ec82620005c9565b8484546200053b565b825550505050565b5f90565b6200060b620005fd565b62000618818484620005d2565b505050565b5b818110156200063f57620006335f8262000601565b6001810190506200061e565b5050565b601f8211156200068e5762000658816200050e565b620006638462000520565b8101602085101562000673578190505b6200068b620006828562000520565b8301826200061d565b50505b505050565b5f82821c905092915050565b5f620006b05f198460080262000693565b1980831691505092915050565b5f620006ca83836200069f565b9150826002028217905092915050565b620006e58262000476565b67ffffffffffffffff81111562000701576200070062000480565b5b6200070d8254620004da565b6200071a82828562000643565b5f60209050601f83116001811462000750575f84156200073b578287015190505b620007478582620006bd565b865550620007b6565b601f19841662000760866200050e565b5f5b82811015620007895784890151825560018201915060208501945060208101905062000762565b86831015620007a95784890151620007a5601f8916826200069f565b8355505b6001600288020188555050505b505050505050565b5f604051905090565b5f80fd5b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f620007fa82620007cf565b9050919050565b6200080c81620007ee565b811462000817575f80fd5b50565b5f815190506200082a8162000801565b92915050565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b620008538262000838565b810181811067ffffffffffffffff8211171562000875576200087462000480565b5b80604052505050565b5f62000889620007be565b905062000897828262000848565b919050565b5f67ffffffffffffffff821115620008b957620008b862000480565b5b620008c48262000838565b9050602081019050919050565b5f5b83811015620008f0578082015181840152602081019050620008d3565b5f8484015250505050565b5f620009116200090b846200089c565b6200087e565b90508281526020810184848401111562000930576200092f62000834565b5b6200093d848285620008d1565b509392505050565b5f82601f8301126200095c576200095b62000830565b5b81516200096e848260208601620008fb565b91505092915050565b620009828162000590565b81146200098d575f80fd5b50565b5f81519050620009a08162000977565b92915050565b5f805f805f60a08688031215620009c257620009c1620007c7565b5b5f620009d1888289016200081a565b955050602086015167ffffffffffffffff811115620009f557620009f4620007cb565b5b62000a038882890162000945565b945050604086015167ffffffffffffffff81111562000a275762000a26620007cb565b5b62000a358882890162000945565b935050606062000a488882890162000990565b925050608062000a5b8882890162000990565b9150509295509295909350565b5f82825260208201905092915050565b7f53746565706e657373206d7573742062652030203c2073203c203165313800005f82015250565b5f62000aae601e8362000a68565b915062000abb8262000a78565b602082019050919050565b5f6020820190508181035f83015262000adf8162000aa0565b9050919050565b5f81905092915050565b5f62000afc8262000476565b62000b08818562000ae6565b935062000b1a818560208601620008d1565b80840191505092915050565b5f62000b33828462000af0565b915081905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f62000b778262000590565b915062000b848362000590565b925082820190508082111562000b9f5762000b9e62000b3e565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f62000bde8262000590565b915062000beb8362000590565b925082820262000bfb8162000590565b9150828204841483151762000c155762000c1462000b3e565b5b5092915050565b5f62000c288262000590565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820362000c5d5762000c5c62000b3e565b5b600182019050919050565b7f4469766973696f6e206279207a65726f000000000000000000000000000000005f82015250565b5f62000c9e60108362000a68565b915062000cab8262000c68565b602082019050919050565b5f6020820190508181035f83015262000ccf8162000c90565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f62000d0f8262000590565b915062000d1c8362000590565b92508262000d2f5762000d2e62000cd6565b5b828204905092915050565b6170bb8062000d485f395ff3fe608060405260043610610338575f3560e01c806377e7fca2116101aa578063c21be6ae116100f6578063dad4ae3711610094578063e1f1c4a71161006e578063e1f1c4a714610ca5578063e8d5940d14610ccf578063ead6252014610cf7578063f59e4f6514610d3357610349565b8063dad4ae3714610c03578063de8fa43114610c3f578063e15b3f5f14610c6957610349565b8063cafa4ffa116100d0578063cafa4ffa14610b4b578063cc18494814610b75578063d118a53f14610bb1578063d7841a1c14610bdb57610349565b8063c21be6ae14610aa9578063c45a015514610ae5578063ca22431314610b0f57610349565b8063873010d911610163578063918f96871161013d578063918f9687146109e1578063981a63dc14610a09578063b801603514610a45578063b99ef1fa14610a6d57610349565b8063873010d91461095157806387563ec11461098d5780638da5cb5b146109b757610349565b806377e7fca2146108355780637a3c22eb1461085f5780637b0a7e33146108875780637c59dd5f146108c35780637ed628bb146108ff578063804d74701461092957610349565b806339bfeae31161028457806357a32534116102225780636a146024116101fc5780636a1460241461078f5780636bd39c52146107b95780636cc6837e146107e35780636d2687c0146107f957610349565b806357a325341461071557806360a1da831461075157806362d73eb81461077957610349565b80634635fd681161025e5780634635fd681461064b57806351599b151461068757806353055481146106c35780635744426e146106ff57610349565b806339bfeae3146105ab578063404880d9146105e7578063441179e51461062357610349565b806321670f22116102f15780633477ee2e116102cb5780633477ee2e146104e3578063363454ee1461051f578063372c3e7c1461055b57806338eccabd1461058357610349565b806321670f221461046157806328c317d71461047d57806333d6e65f146104b957610349565b806302d05d3f1461035557806306a49fce1461037f57806306fdde03146103a957806312feb905146103d35780631821fcab146103fd5780631a2f4ee51461043957610349565b36610349576103475f34610d5d565b005b6103535f34610d5d565b005b348015610360575f80fd5b50610369611149565b604051610376919061509c565b60405180910390f35b34801561038a575f80fd5b5061039361116e565b6040516103a091906151fa565b60405180910390f35b3480156103b4575f80fd5b506103bd611242565b6040516103ca9190615262565b60405180910390f35b3480156103de575f80fd5b506103e76112ce565b6040516103f491906151fa565b60405180910390f35b348015610408575f80fd5b50610423600480360381019061041e91906153bf565b6113a2565b604051610430919061541e565b60405180910390f35b348015610444575f80fd5b5061045f600480360381019061045a9190615461565b6113cf565b005b61047b600480360381019061047691906154c9565b610d5d565b005b348015610488575f80fd5b506104a3600480360381019061049e91906153bf565b6114f8565b6040516104b091906155be565b60405180910390f35b3480156104c4575f80fd5b506104cd6115a1565b6040516104da919061541e565b60405180910390f35b3480156104ee575f80fd5b50610509600480360381019061050491906155de565b6115a7565b6040516105169190615262565b60405180910390f35b34801561052a575f80fd5b50610545600480360381019061054091906153bf565b61164d565b6040516105529190615623565b60405180910390f35b348015610566575f80fd5b50610581600480360381019061057c91906155de565b611682565b005b34801561058e575f80fd5b506105a960048036038101906105a491906153bf565b611723565b005b3480156105b6575f80fd5b506105d160048036038101906105cc91906153bf565b61189c565b6040516105de9190615623565b60405180910390f35b3480156105f2575f80fd5b5061060d600480360381019061060891906153bf565b6118d1565b60405161061a9190615623565b60405180910390f35b34801561062e575f80fd5b506106496004803603810190610644919061563c565b611906565b005b348015610656575f80fd5b50610671600480360381019061066c91906155de565b611c2b565b60405161067e9190615262565b60405180910390f35b348015610692575f80fd5b506106ad60048036038101906106a891906153bf565b611cd1565b6040516106ba9190615623565b60405180910390f35b3480156106ce575f80fd5b506106e960048036038101906106e49190615696565b611d06565b6040516106f6919061541e565b60405180910390f35b34801561070a575f80fd5b50610713611d1b565b005b348015610720575f80fd5b5061073b600480360381019061073691906153bf565b611e3f565b604051610748919061541e565b60405180910390f35b34801561075c575f80fd5b50610777600480360381019061077291906156c1565b611e6c565b005b348015610784575f80fd5b5061078d612201565b005b34801561079a575f80fd5b506107a361245e565b6040516107b0919061541e565b60405180910390f35b3480156107c4575f80fd5b506107cd61246a565b6040516107da919061541e565b60405180910390f35b3480156107ee575f80fd5b506107f7612470565b005b348015610804575f80fd5b5061081f600480360381019061081a91906155de565b612987565b60405161082c9190615262565b60405180910390f35b348015610840575f80fd5b50610849612a2d565b604051610856919061541e565b60405180910390f35b34801561086a575f80fd5b50610885600480360381019061088091906153bf565b612a33565b005b348015610892575f80fd5b506108ad60048036038101906108a891906155de565b612c87565b6040516108ba91906151fa565b60405180910390f35b3480156108ce575f80fd5b506108e960048036038101906108e491906153bf565b612d6c565b6040516108f69190615623565b60405180910390f35b34801561090a575f80fd5b50610913612da1565b6040516109209190615623565b60405180910390f35b348015610934575f80fd5b5061094f600480360381019061094a91906157fd565b612db3565b005b34801561095c575f80fd5b50610977600480360381019061097291906155de565b612fac565b604051610984919061541e565b60405180910390f35b348015610998575f80fd5b506109a1612fcc565b6040516109ae919061541e565b60405180910390f35b3480156109c2575f80fd5b506109cb612fd2565b6040516109d8919061509c565b60405180910390f35b3480156109ec575f80fd5b50610a076004803603810190610a0291906153bf565b612ff7565b005b348015610a14575f80fd5b50610a2f6004803603810190610a2a91906153bf565b6131ab565b604051610a3c9190615262565b60405180910390f35b348015610a50575f80fd5b50610a6b6004803603810190610a669190615904565b61325e565b005b348015610a78575f80fd5b50610a936004803603810190610a8e91906153bf565b61368c565b604051610aa0919061541e565b60405180910390f35b348015610ab4575f80fd5b50610acf6004803603810190610aca91906153bf565b6136b9565b604051610adc919061509c565b60405180910390f35b348015610af0575f80fd5b50610af9613701565b604051610b06919061509c565b60405180910390f35b348015610b1a575f80fd5b50610b356004803603810190610b3091906156c1565b613726565b604051610b42919061541e565b60405180910390f35b348015610b56575f80fd5b50610b5f61375e565b604051610b6c919061541e565b60405180910390f35b348015610b80575f80fd5b50610b9b6004803603810190610b96919061563c565b613764565b604051610ba8919061509c565b60405180910390f35b348015610bbc575f80fd5b50610bc56137c4565b604051610bd29190615a31565b60405180910390f35b348015610be6575f80fd5b50610c016004803603810190610bfc91906155de565b61381a565b005b348015610c0e575f80fd5b50610c296004803603810190610c2491906153bf565b613947565b604051610c369190615623565b60405180910390f35b348015610c4a575f80fd5b50610c5361397c565b604051610c60919061541e565b60405180910390f35b348015610c74575f80fd5b50610c8f6004803603810190610c8a91906153bf565b613988565b604051610c9c919061541e565b60405180910390f35b348015610cb0575f80fd5b50610cb96139b5565b604051610cc6919061541e565b60405180910390f35b348015610cda575f80fd5b50610cf56004803603810190610cf09190615a51565b6139bb565b005b348015610d02575f80fd5b50610d1d6004803603810190610d189190615461565b613ca9565b604051610d2a9190615262565b60405180910390f35b348015610d3e575f80fd5b50610d47613d5a565b604051610d549190615262565b60405180910390f35b610d65613de6565b5f8034118015610da057505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16145b90505f8115610e18573492503373ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff167f37de26b9f29dba736fb8291dad9ace7d2f6dc76e3e5faaeca097145b5298f94b5f86604051610e0b929190615ac7565b60405180910390a3610f8a565b8390505f600d5f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20548273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610e93919061509c565b602060405180830381865afa158015610eae573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ed29190615b02565b610edc9190615b5a565b905083811015610f21576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f1890615bd7565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff167f37de26b9f29dba736fb8291dad9ace7d2f6dc76e3e5faaeca097145b5298f94b8787604051610f80929190615ac7565b60405180910390a3505b5f610f9a84600e54612710613e2a565b90505f8185610fa99190615b5a565b90505f8083118015610fbf57505f601080549050115b15610fde57610fd087848787613e8d565b81610fdb9190615bf5565b90505b5f82118015610fee57505f601954115b1561100d57610fff87838787613fb6565b8161100a9190615bf5565b90505b3073ffffffffffffffffffffffffffffffffffffffff167fd83308e9158842b2115ec5e6f6395db42fff24e4b5506ef42fe33854fafad655878388611087576040518060400160405280600581526020017f45524332300000000000000000000000000000000000000000000000000000008152506110be565b6040518060400160405280600381526020017f45544800000000000000000000000000000000000000000000000000000000008152505b6040516110cd93929190615c28565b60405180910390a23073ffffffffffffffffffffffffffffffffffffffff167fc2d2b959adca67349f750fed9ef9eaefbec59f24fa563c7fa410157130395c4060018761111a578961111c565b5f5b89855f604051611130959493929190615d96565b60405180910390a25050505050611145614184565b5050565b60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6060601b805480602002602001604051908101604052809291908181526020015f905b82821015611239578382905f5260205f200180546111ae90615c91565b80601f01602080910402602001604051908101604052809291908181526020018280546111da90615c91565b80156112255780601f106111fc57610100808354040283529160200191611225565b820191905f5260205f20905b81548152906001019060200180831161120857829003601f168201915b505050505081526020019060010190611191565b50505050905090565b6001805461124f90615c91565b80601f016020809104026020016040519081016040528092919081815260200182805461127b90615c91565b80156112c65780601f1061129d576101008083540402835291602001916112c6565b820191905f5260205f20905b8154815290600101906020018083116112a957829003601f168201915b505050505081565b60606010805480602002602001604051908101604052809291908181526020015f905b82821015611399578382905f5260205f2001805461130e90615c91565b80601f016020809104026020016040519081016040528092919081815260200182805461133a90615c91565b80156113855780601f1061135c57610100808354040283529160200191611385565b820191905f5260205f20905b81548152906001019060200180831161136857829003601f168201915b5050505050815260200190600101906112f1565b50505050905090565b6016818051602081018201805184825260208301602085012081835280955050505050505f915090505481565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461145e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161145590615e38565b60405180910390fd5b612710818361146d9190615bf5565b146114ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114a490615ea0565b60405180910390fd5b81600e8190555080600f819055507f29dd4a83e71eab2a472a8bb7a7bb9467395098acb48b07c8d9ea7294de0ba0ae82826040516114ec929190615ebe565b60405180910390a15050565b6060600c8260405161150a9190615f1f565b908152602001604051809103902080548060200260200160405190810160405280929190818152602001828054801561159557602002820191905f5260205f20905b815f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001906001019080831161154c575b50505050509050919050565b60145481565b601b81815481106115b6575f80fd5b905f5260205f20015f9150905080546115ce90615c91565b80601f01602080910402602001604051908101604052809291908181526020018280546115fa90615c91565b80156116455780601f1061161c57610100808354040283529160200191611645565b820191905f5260205f20905b81548152906001019060200180831161162857829003601f168201915b505050505081565b6008818051602081018201805184825260208301602085012081835280955050505050505f915054906101000a900460ff1681565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611711576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161170890615e38565b60405180910390fd5b8060148190555061172061418d565b50565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146117b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117a990615e38565b60405180910390fd5b6017816040516117c29190615f1f565b90815260200160405180910390205f9054906101000a900460ff1661181c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161181390615f7f565b60405180910390fd5b611825816142ab565b5f6017826040516118369190615f1f565b90815260200160405180910390205f6101000a81548160ff02191690831515021790555061186261418d565b7fe6db474363a3116f4cf525fc0d78d9dd53e214383db31efef8368f08c4bf7991816040516118919190615262565b60405180910390a150565b601e818051602081018201805184825260208301602085012081835280955050505050505f915054906101000a900460ff1681565b6009818051602081018201805184825260208301602085012081835280955050505050505f915054906101000a900460ff1681565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611995576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161198c90615e38565b60405180910390fd5b6009826040516119a59190615f1f565b90815260200160405180910390205f9054906101000a900460ff166119ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119f690615fe7565b60405180910390fd5b601454811115611a44576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a3b9061604f565b60405180910390fd5b5f601783604051611a559190615f1f565b90815260200160405180910390205f9054906101000a900460ff16611a9a577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611aba565b601683604051611aaa9190615f1f565b9081526020016040518091039020545b9050601783604051611acc9190615f1f565b90815260200160405180910390205f9054906101000a900460ff1615611af657611af5836142ab565b5b81601684604051611b079190615f1f565b90815260200160405180910390208190555060155f8381526020019081526020015f2083908060018154018082558091505060019003905f5260205f20015f909190919091509081611b5991906161ef565b506001601784604051611b6c9190615f1f565b90815260200160405180910390205f6101000a81548160ff021916908315150217905550611b9861418d565b7f9bca84993827a6bd2bc824f45db9e0ae931cf1f7b1706b7c735ba0102300b4ca8383604051611bc99291906162be565b60405180910390a13073ffffffffffffffffffffffffffffffffffffffff167f7d482c93a88a92e4d27ba697265785162f607bc0ac6c55b868232b3ba3fbb63d6001858486604051611c1e94939291906162ec565b60405180910390a2505050565b60068181548110611c3a575f80fd5b905f5260205f20015f915090508054611c5290615c91565b80601f0160208091040260200160405190810160405280929190818152602001828054611c7e90615c91565b8015611cc95780601f10611ca057610100808354040283529160200191611cc9565b820191905f5260205f20905b815481529060010190602001808311611cac57829003601f168201915b505050505081565b601c818051602081018201805184825260208301602085012081835280955050505050505f915054906101000a900460ff1681565b600d602052805f5260405f205f915090505481565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611daa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611da190615e38565b60405180910390fd5b601a5f9054906101000a900460ff16611df8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611def90616387565b60405180910390fd5b5f601a5f6101000a81548160ff0219169083151502179055507f990bb31515adefe5ecd88a4dca3e9772b32d484c81e22cae38d5482e0d9f35e460405160405180910390a1565b600a818051602081018201805184825260208301602085012081835280955050505050505f915090505481565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611efb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ef290615e38565b60405180910390fd5b611f03613de6565b600882604051611f139190615f1f565b90815260200160405180910390205f9054906101000a900460ff1615611f6e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f65906163ef565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611fdc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fd390616457565b60405180910390fd5b600982604051611fec9190615f1f565b90815260200160405180910390205f9054906101000a900460ff16612046576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161203d906164bf565b60405180910390fd5b5f600a836040516120579190615f1f565b9081526020016040518091039020549050600160088460405161207a9190615f1f565b90815260200160405180910390205f6101000a81548160ff0219169083151502179055505f73ffffffffffffffffffffffffffffffffffffffff166007846040516120c59190615f1f565b90815260200160405180910390205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff160361216b578160078460405161211f9190615f1f565b90815260200160405180910390205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b61217583836143c9565b61217f83836144c5565b5f8111156121f4578173ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff167f605614956ef211f270ab0b08a13dd69698dc38d70e20899e1051ae2e1ae6cd5b6001865f866040516121eb94939291906164dd565b60405180910390a35b506121fd614184565b5050565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612290576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161228790615e38565b60405180910390fd5b5f5b601b80549050811015612340575f601d601b83815481106122b6576122b561652e565b5b905f5260205f20016040516122cb91906165db565b9081526020016040518091039020819055505f601c601b83815481106122f4576122f361652e565b5b905f5260205f200160405161230991906165db565b90815260200160405180910390205f6101000a81548160ff0219169083151502179055508080612338906165f1565b915050612292565b50601b5f61234e9190614f5b565b5f5b600680549050811015612415575f601e600683815481106123745761237361652e565b5b905f5260205f200160405161238991906165db565b90815260200160405180910390205f6101000a81548160ff02191690831515021790555060405180602001604052805f815250601f600683815481106123d2576123d161652e565b5b905f5260205f20016040516123e791906165db565b9081526020016040518091039020908161240191906161ef565b50808061240d906165f1565b915050612350565b506001601a5f6101000a81548160ff0219169083151502179055507fc475c26aa25ed8e85a7faa790e5f63b5d7ee1025f12821f4c9bfddd36ab4d11260405160405180910390a1565b670de0b6b3a764000081565b600e5481565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146124ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124f690615e38565b60405180910390fd5b601a5f9054906101000a900460ff1661254d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161254490616387565b60405180910390fd5b5f601b8054905011612594576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161258b90616682565b60405180910390fd5b5f601b5f815481106125a9576125a861652e565b5b905f5260205f200180546125bc90615c91565b80601f01602080910402602001604051908101604052809291908181526020018280546125e890615c91565b80156126335780601f1061260a57610100808354040283529160200191612633565b820191905f5260205f20905b81548152906001019060200180831161261657829003601f168201915b505050505090505f601d601b5f815481106126515761265061652e565b5b905f5260205f200160405161266691906165db565b90815260200160405180910390205490505f600190505b601b805490508110156127c05781601d601b83815481106126a1576126a061652e565b5b905f5260205f20016040516126b691906165db565b90815260200160405180910390205411156127ad57601d601b82815481106126e1576126e061652e565b5b905f5260205f20016040516126f691906165db565b9081526020016040518091039020549150601b818154811061271b5761271a61652e565b5b905f5260205f2001805461272e90615c91565b80601f016020809104026020016040519081016040528092919081815260200182805461275a90615c91565b80156127a55780601f1061277c576101008083540402835291602001916127a5565b820191905f5260205f20905b81548152906001019060200180831161278857829003601f168201915b505050505092505b80806127b8906165f1565b91505061267d565b505f6007836040516127d29190615f1f565b90815260200160405180910390205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612870576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161286790616710565b60405180910390fd5b5f60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160035f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505f601a5f6101000a81548160ff0219169083151502179055507f5e99cd5235d5c8c4f0f8dc2626c83130cf843047e4ecbe4c111076e2b31a0d52848460405161291f9291906162be565b60405180910390a18173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a350505050565b60108181548110612996575f80fd5b905f5260205f20015f9150905080546129ae90615c91565b80601f01602080910402602001604051908101604052809291908181526020018280546129da90615c91565b8015612a255780601f106129fc57610100808354040283529160200191612a25565b820191905f5260205f20905b815481529060010190602001808311612a0857829003601f168201915b505050505081565b600f5481565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612ac2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ab990615e38565b60405180910390fd5b601a5f9054906101000a900460ff16612b10576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b0790616387565b60405180910390fd5b600981604051612b209190615f1f565b90815260200160405180910390205f9054906101000a900460ff16612b7a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b7190616778565b60405180910390fd5b601c81604051612b8a9190615f1f565b90815260200160405180910390205f9054906101000a900460ff1615612be5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bdc906167e0565b60405180910390fd5b601b81908060018154018082558091505060019003905f5260205f20015f909190919091509081612c1691906161ef565b506001601c82604051612c299190615f1f565b90815260200160405180910390205f6101000a81548160ff0219169083151502179055507f134c877b5bd4770ffc56867fc5d2c549dd813a5db276d378f8d855a04fc7aa1d81604051612c7c9190615262565b60405180910390a150565b606060155f8381526020019081526020015f20805480602002602001604051908101604052809291908181526020015f905b82821015612d61578382905f5260205f20018054612cd690615c91565b80601f0160208091040260200160405190810160405280929190818152602001828054612d0290615c91565b8015612d4d5780601f10612d2457610100808354040283529160200191612d4d565b820191905f5260205f20905b815481529060010190602001808311612d3057829003601f168201915b505050505081526020019060010190612cb9565b505050509050919050565b6011818051602081018201805184825260208301602085012081835280955050505050505f915054906101000a900460ff1681565b601a5f9054906101000a900460ff1681565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612e42576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e3990615e38565b60405180910390fd5b5f5b8151811015612fa8575f828281518110612e6157612e6061652e565b5b60200260200101519050600981604051612e7b9190615f1f565b90815260200160405180910390205f9054906101000a900460ff1615612ea15750612f95565b6001600982604051612eb39190615f1f565b90815260200160405180910390205f6101000a81548160ff021916908315150217905550600681908060018154018082558091505060019003905f5260205f20015f909190919091509081612f0891906161ef565b507fdfaa3c24567cbffbf024ddfd8dfca7a224b307e94b0df5437facad0f2fea2f9b81604051612f389190615262565b60405180910390a13073ffffffffffffffffffffffffffffffffffffffff167f954917c11fc57299ff064c483b4113756221231fcea3a1a3aa54ebd605a9c1e860018333604051612f8b939291906167fe565b60405180910390a2505b8080612fa0906165f1565b915050612e44565b5050565b60188181548110612fbb575f80fd5b905f5260205f20015f915090505481565b60135481565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614613086576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161307d90615e38565b60405180910390fd5b6009816040516130969190615f1f565b90815260200160405180910390205f9054906101000a900460ff166131a85760016009826040516130c79190615f1f565b90815260200160405180910390205f6101000a81548160ff021916908315150217905550600681908060018154018082558091505060019003905f5260205f20015f90919091909150908161311c91906161ef565b507fdfaa3c24567cbffbf024ddfd8dfca7a224b307e94b0df5437facad0f2fea2f9b8160405161314c9190615262565b60405180910390a13073ffffffffffffffffffffffffffffffffffffffff167f954917c11fc57299ff064c483b4113756221231fcea3a1a3aa54ebd605a9c1e86001833360405161319f939291906167fe565b60405180910390a25b50565b601f818051602081018201805184825260208301602085012081835280955050505050505f9150905080546131df90615c91565b80601f016020809104026020016040519081016040528092919081815260200182805461320b90615c91565b80156132565780601f1061322d57610100808354040283529160200191613256565b820191905f5260205f20905b81548152906001019060200180831161323957829003601f168201915b505050505081565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146132ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132e490615e38565b60405180910390fd5b8051825114613331576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016133289061688b565b60405180910390fd5b5f5b6010805490508110156133e1575f6012601083815481106133575761335661652e565b5b905f5260205f200160405161336c91906165db565b9081526020016040518091039020819055505f6011601083815481106133955761339461652e565b5b905f5260205f20016040516133aa91906165db565b90815260200160405180910390205f6101000a81548160ff02191690831515021790555080806133d9906165f1565b915050613333565b5060105f6133ef9190614f5b565b5f805b83518110156136095760098482815181106134105761340f61652e565b5b60200260200101516040516134259190615f1f565b90815260200160405180910390205f9054906101000a900460ff1661347f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613476906168f3565b60405180910390fd5b5f8382815181106134935761349261652e565b5b6020026020010151116134db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016134d29061695b565b60405180910390fd5b60108482815181106134f0576134ef61652e565b5b6020026020010151908060018154018082558091505060019003905f5260205f20015f90919091909150908161352691906161ef565b506001601185838151811061353e5761353d61652e565b5b60200260200101516040516135539190615f1f565b90815260200160405180910390205f6101000a81548160ff02191690831515021790555082818151811061358a5761358961652e565b5b602002602001015160128583815181106135a7576135a661652e565b5b60200260200101516040516135bc9190615f1f565b9081526020016040518091039020819055508281815181106135e1576135e061652e565b5b6020026020010151826135f49190615bf5565b91508080613601906165f1565b9150506133f2565b50612710811461364e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613645906169c3565b60405180910390fd5b7f7749ddba77d660c1351ff548a0bf5b09743d6ad44914e3cb9a29a1f805fb09fe838360405161367f9291906169e1565b60405180910390a1505050565b601d818051602081018201805184825260208301602085012081835280955050505050505f915090505481565b6007818051602081018201805184825260208301602085012081835280955050505050505f915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600b82805160208101820180518482526020830160208501208183528095505050505050602052805f5260405f205f91509150505481565b60195481565b600c828051602081018201805184825260208301602085012081835280955050505050508181548110613795575f80fd5b905f5260205f20015f915091509054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6060601880548060200260200160405190810160405280929190818152602001828054801561381057602002820191905f5260205f20905b8154815260200190600101908083116137fc575b5050505050905090565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146138a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016138a090615e38565b60405180910390fd5b5f811180156138bf5750670de0b6b3a764000081105b6138fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016138f590616a60565b60405180910390fd5b8060138190555061390d61418d565b7f5fad7fda6b8fb652ca59780d340772fed3852ba698b3a4cd40ebc117b8ec57508160405161393c919061541e565b60405180910390a150565b6017818051602081018201805184825260208301602085012081835280955050505050505f915054906101000a900460ff1681565b5f600680549050905090565b6012818051602081018201805184825260208301602085012081835280955050505050505f915090505481565b61271081565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614613a4a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a4190615e38565b60405180910390fd5b601a5f9054906101000a900460ff16613a98576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a8f90616387565b60405180910390fd5b600982604051613aa89190615f1f565b90815260200160405180910390205f9054906101000a900460ff16613b02576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613af990616ac8565b60405180910390fd5b601c81604051613b129190615f1f565b90815260200160405180910390205f9054906101000a900460ff16613b6c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613b6390616b30565b60405180910390fd5b601e82604051613b7c9190615f1f565b90815260200160405180910390205f9054906101000a900460ff1615613bd7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613bce90616b98565b60405180910390fd5b6001601e83604051613be99190615f1f565b90815260200160405180910390205f6101000a81548160ff02191690831515021790555080601f83604051613c1e9190615f1f565b90815260200160405180910390209081613c3891906161ef565b50601d81604051613c499190615f1f565b90815260200160405180910390205f815480929190613c67906165f1565b91905055507f137ad23732468494166ec34d1367743690ffa17f6ceac8429cba8fc35d088b6e8282604051613c9d929190616bb6565b60405180910390a15050565b6015602052815f5260405f208181548110613cc2575f80fd5b905f5260205f20015f91509150508054613cdb90615c91565b80601f0160208091040260200160405190810160405280929190818152602001828054613d0790615c91565b8015613d525780601f10613d2957610100808354040283529160200191613d52565b820191905f5260205f20905b815481529060010190602001808311613d3557829003601f168201915b505050505081565b60028054613d6790615c91565b80601f0160208091040260200160405190810160405280929190818152602001828054613d9390615c91565b8015613dde5780601f10613db557610100808354040283529160200191613dde565b820191905f5260205f20905b815481529060010190602001808311613dc157829003601f168201915b505050505081565b60025f5403613e21576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025f81905550565b5f808211613e6d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613e6490616c35565b60405180910390fd5b818385613e7a9190616c53565b613e849190616cc1565b90509392505050565b5f805f90505b601080549050811015613fad575f60108281548110613eb557613eb461652e565b5b905f5260205f20018054613ec890615c91565b80601f0160208091040260200160405190810160405280929190818152602001828054613ef490615c91565b8015613f3f5780601f10613f1657610100808354040283529160200191613f3f565b820191905f5260205f20905b815481529060010190602001808311613f2257829003601f168201915b505050505090505f613f7287601284604051613f5b9190615f1f565b908152602001604051809103902054612710613e2a565b90505f811115613f9857613f898289838989614737565b8380613f94906165f1565b9450505b50508080613fa5906165f1565b915050613e93565b50949350505050565b5f805f90505b601454811161417b575f60155f8381526020019081526020015f208054905090505f8103613fea5750614168565b5f60188381548110613fff57613ffe61652e565b5b905f5260205f200154826140139190616c53565b90505f6140238883601954613e2a565b90505f83826140329190616cc1565b90505f805b85811015614161575f60018761404d9190615b5a565b820361406657828561405f9190615b5a565b9050614078565b83905083836140759190615bf5565b92505b5f81111561414d5761413e60155f8a81526020019081526020015f2083815481106140a6576140a561652e565b5b905f5260205f200180546140b990615c91565b80601f01602080910402602001604051908101604052809291908181526020018280546140e590615c91565b80156141305780601f1061410757610100808354040283529160200191614130565b820191905f5260205f20905b81548152906001019060200180831161411357829003601f168201915b50505050508e838e8e614737565b8880614149906165f1565b9950505b508080614159906165f1565b915050614037565b5050505050505b8080614173906165f1565b915050613fbc565b50949350505050565b60015f81905550565b60185f61419a9190614f79565b60016014546141a99190615bf5565b67ffffffffffffffff8111156141c2576141c161529b565b5b6040519080825280602002602001820160405280156141f05781602001602082028036833780820191505090505b5060189080519060200190614206929190614f97565b505f6019819055505f670de0b6b3a764000090505f5b60145481116142a757816018828154811061423a5761423961652e565b5b905f5260205f2001819055508160155f8381526020019081526020015f20805490506142669190616c53565b60195f8282546142769190615bf5565b9250508190555061429282601354670de0b6b3a7640000613e2a565b9150808061429f906165f1565b91505061421c565b5050565b5f6016826040516142bc9190615f1f565b90815260200160405180910390205490505f60155f8381526020019081526020015f2090505f5b81805490508110156143c357838051906020012082828154811061430a5761430961652e565b5b905f5260205f200160405161431f9190616d8d565b6040518091039020036143b057816001838054905061433e9190615b5a565b8154811061434f5761434e61652e565b5b905f5260205f200182828154811061436a5761436961652e565b5b905f5260205f2001908161437e9190616dca565b50818054806143905761438f616eaf565b5b600190038181905f5260205f20015f6143a99190614fe2565b90556143c3565b80806143bb906165f1565b9150506142e3565b50505050565b5f600a836040516143da9190615f1f565b90815260200160405180910390205490505f8111156144c0575f600a846040516144049190615f1f565b9081526020016040518091039020819055505f8273ffffffffffffffffffffffffffffffffffffffff168260405161443b90616eff565b5f6040518083038185875af1925050503d805f8114614475576040519150601f19603f3d011682016040523d82523d5f602084013e61447a565b606091505b50509050806144be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016144b590616f5d565b60405180910390fd5b505b505050565b5f600c836040516144d69190615f1f565b908152602001604051809103902080548060200260200160405190810160405280929190818152602001828054801561456157602002820191905f5260205f20905b815f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311614518575b505050505090505f5b8151811015614731575f600b856040516145849190615f1f565b90815260200160405180910390205f8484815181106145a6576145a561652e565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205490505f81111561471d575f600b866040516146039190615f1f565b90815260200160405180910390205f8585815181106146255761462461652e565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f208190555080600d5f8585815181106146815761468061652e565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546146d09190615b5a565b9250508190555061471c84828585815181106146ef576146ee61652e565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff16614e419092919063ffffffff16565b5b508080614729906165f1565b91505061456a565b50505050565b5f6007866040516147489190615f1f565b90815260200160405180910390205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156147cb57505f8273ffffffffffffffffffffffffffffffffffffffff163b115b90506008876040516147dd9190615f1f565b90815260200160405180910390205f9054906101000a900460ff16801561483057505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b15614a715783156148e9575f8273ffffffffffffffffffffffffffffffffffffffff168660405161486090616eff565b5f6040518083038185875af1925050503d805f811461489a576040519150601f19603f3d011682016040523d82523d5f602084013e61489f565b606091505b50509050806148e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016148da90616fc5565b60405180910390fd5b50614915565b61491482868573ffffffffffffffffffffffffffffffffffffffff16614e419092919063ffffffff16565b5b8173ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff167f7d6a6b7452c2fec7981096e354fb3311f3f3b800ff27def1017b22cbff2751908784886149a6576040518060400160405280600581526020017f45524332300000000000000000000000000000000000000000000000000000008152506149dd565b6040518060400160405280600381526020017f45544800000000000000000000000000000000000000000000000000000000008152505b6040516149ec93929190616fe3565b60405180910390a38173ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff167f71e611184866cc19c5f49af6c856ce9bde5a13bcd197c7499b61ab410ac9439960018a88614a51578a614a53565b5f5b8a604051614a6494939291906164dd565b60405180910390a3614e38565b8315614ab05784600a88604051614a889190615f1f565b90815260200160405180910390205f828254614aa49190615bf5565b92505081905550614c50565b5f600b88604051614ac19190615f1f565b90815260200160405180910390205f8873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205403614b8d57600c87604051614b209190615f1f565b908152602001604051809103902086908060018154018082558091505060019003905f5260205f20015f9091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b84600b88604051614b9e9190615f1f565b90815260200160405180910390205f8873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614bf59190615bf5565b9250508190555084600d5f8873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614c489190615bf5565b925050819055505b5f73ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff167f7d6a6b7452c2fec7981096e354fb3311f3f3b800ff27def1017b22cbff275190875f88614ce1576040518060400160405280600c81526020017f53544f5245445f45524332300000000000000000000000000000000000000000815250614d18565b6040518060400160405280600a81526020017f53544f5245445f455448000000000000000000000000000000000000000000008152505b604051614d2793929190616fe3565b60405180910390a35f601188604051614d409190615f1f565b90815260200160405180910390205f9054906101000a900460ff16614d9a576040518060400160405280600481526020017f7a6f6e6500000000000000000000000000000000000000000000000000000000815250614dd1565b6040518060400160405280600a81526020017f70657263656e74616765000000000000000000000000000000000000000000008152505b90503073ffffffffffffffffffffffffffffffffffffffff167ff9700e8ac41cc506d3f79229bad9981619140b63838136cdb10ac6ba5f6976ab60018a88614e19578a614e1b565b5f5b8a86604051614e2e95949392919061701f565b60405180910390a2505b50505050505050565b614ebb838473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8585604051602401614e74929190615ac7565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050614ec0565b505050565b5f8060205f8451602086015f885af180614edf576040513d5f823e3d81fd5b3d92505f519150505f8214614ef8576001811415614f13565b5f8473ffffffffffffffffffffffffffffffffffffffff163b145b15614f5557836040517f5274afe7000000000000000000000000000000000000000000000000000000008152600401614f4c919061509c565b60405180910390fd5b50505050565b5080545f8255905f5260205f2090810190614f76919061501f565b50565b5080545f8255905f5260205f2090810190614f949190615042565b50565b828054828255905f5260205f20908101928215614fd1579160200282015b82811115614fd0578251825591602001919060010190614fb5565b5b509050614fde9190615042565b5090565b508054614fee90615c91565b5f825580601f10614fff575061501c565b601f0160209004905f5260205f209081019061501b9190615042565b5b50565b5b8082111561503e575f81816150359190614fe2565b50600101615020565b5090565b5b80821115615059575f815f905550600101615043565b5090565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6150868261505d565b9050919050565b6150968161507c565b82525050565b5f6020820190506150af5f83018461508d565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f81519050919050565b5f82825260208201905092915050565b5f5b838110156151155780820151818401526020810190506150fa565b5f8484015250505050565b5f601f19601f8301169050919050565b5f61513a826150de565b61514481856150e8565b93506151548185602086016150f8565b61515d81615120565b840191505092915050565b5f6151738383615130565b905092915050565b5f602082019050919050565b5f615191826150b5565b61519b81856150bf565b9350836020820285016151ad856150cf565b805f5b858110156151e857848403895281516151c98582615168565b94506151d48361517b565b925060208a019950506001810190506151b0565b50829750879550505050505092915050565b5f6020820190508181035f8301526152128184615187565b905092915050565b5f82825260208201905092915050565b5f615234826150de565b61523e818561521a565b935061524e8185602086016150f8565b61525781615120565b840191505092915050565b5f6020820190508181035f83015261527a818461522a565b905092915050565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6152d182615120565b810181811067ffffffffffffffff821117156152f0576152ef61529b565b5b80604052505050565b5f615302615282565b905061530e82826152c8565b919050565b5f67ffffffffffffffff82111561532d5761532c61529b565b5b61533682615120565b9050602081019050919050565b828183375f83830152505050565b5f61536361535e84615313565b6152f9565b90508281526020810184848401111561537f5761537e615297565b5b61538a848285615343565b509392505050565b5f82601f8301126153a6576153a5615293565b5b81356153b6848260208601615351565b91505092915050565b5f602082840312156153d4576153d361528b565b5b5f82013567ffffffffffffffff8111156153f1576153f061528f565b5b6153fd84828501615392565b91505092915050565b5f819050919050565b61541881615406565b82525050565b5f6020820190506154315f83018461540f565b92915050565b61544081615406565b811461544a575f80fd5b50565b5f8135905061545b81615437565b92915050565b5f80604083850312156154775761547661528b565b5b5f6154848582860161544d565b92505060206154958582860161544d565b9150509250929050565b6154a88161507c565b81146154b2575f80fd5b50565b5f813590506154c38161549f565b92915050565b5f80604083850312156154df576154de61528b565b5b5f6154ec858286016154b5565b92505060206154fd8582860161544d565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6155398161507c565b82525050565b5f61554a8383615530565b60208301905092915050565b5f602082019050919050565b5f61556c82615507565b6155768185615511565b935061558183615521565b805f5b838110156155b1578151615598888261553f565b97506155a383615556565b925050600181019050615584565b5085935050505092915050565b5f6020820190508181035f8301526155d68184615562565b905092915050565b5f602082840312156155f3576155f261528b565b5b5f6156008482850161544d565b91505092915050565b5f8115159050919050565b61561d81615609565b82525050565b5f6020820190506156365f830184615614565b92915050565b5f80604083850312156156525761565161528b565b5b5f83013567ffffffffffffffff81111561566f5761566e61528f565b5b61567b85828601615392565b925050602061568c8582860161544d565b9150509250929050565b5f602082840312156156ab576156aa61528b565b5b5f6156b8848285016154b5565b91505092915050565b5f80604083850312156156d7576156d661528b565b5b5f83013567ffffffffffffffff8111156156f4576156f361528f565b5b61570085828601615392565b9250506020615711858286016154b5565b9150509250929050565b5f67ffffffffffffffff8211156157355761573461529b565b5b602082029050602081019050919050565b5f80fd5b5f61575c6157578461571b565b6152f9565b9050808382526020820190506020840283018581111561577f5761577e615746565b5b835b818110156157c657803567ffffffffffffffff8111156157a4576157a3615293565b5b8086016157b18982615392565b85526020850194505050602081019050615781565b5050509392505050565b5f82601f8301126157e4576157e3615293565b5b81356157f484826020860161574a565b91505092915050565b5f602082840312156158125761581161528b565b5b5f82013567ffffffffffffffff81111561582f5761582e61528f565b5b61583b848285016157d0565b91505092915050565b5f67ffffffffffffffff82111561585e5761585d61529b565b5b602082029050602081019050919050565b5f61588161587c84615844565b6152f9565b905080838252602082019050602084028301858111156158a4576158a3615746565b5b835b818110156158cd57806158b9888261544d565b8452602084019350506020810190506158a6565b5050509392505050565b5f82601f8301126158eb576158ea615293565b5b81356158fb84826020860161586f565b91505092915050565b5f806040838503121561591a5761591961528b565b5b5f83013567ffffffffffffffff8111156159375761593661528f565b5b615943858286016157d0565b925050602083013567ffffffffffffffff8111156159645761596361528f565b5b615970858286016158d7565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6159ac81615406565b82525050565b5f6159bd83836159a3565b60208301905092915050565b5f602082019050919050565b5f6159df8261597a565b6159e98185615984565b93506159f483615994565b805f5b83811015615a24578151615a0b88826159b2565b9750615a16836159c9565b9250506001810190506159f7565b5085935050505092915050565b5f6020820190508181035f830152615a4981846159d5565b905092915050565b5f8060408385031215615a6757615a6661528b565b5b5f83013567ffffffffffffffff811115615a8457615a8361528f565b5b615a9085828601615392565b925050602083013567ffffffffffffffff811115615ab157615ab061528f565b5b615abd85828601615392565b9150509250929050565b5f604082019050615ada5f83018561508d565b615ae7602083018461540f565b9392505050565b5f81519050615afc81615437565b92915050565b5f60208284031215615b1757615b1661528b565b5b5f615b2484828501615aee565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f615b6482615406565b9150615b6f83615406565b9250828203905081811115615b8757615b86615b2d565b5b92915050565b7f496e73756666696369656e7420746f6b656e2062616c616e63650000000000005f82015250565b5f615bc1601a8361521a565b9150615bcc82615b8d565b602082019050919050565b5f6020820190508181035f830152615bee81615bb5565b9050919050565b5f615bff82615406565b9150615c0a83615406565b9250828201905080821115615c2257615c21615b2d565b5b92915050565b5f606082019050615c3b5f83018661540f565b615c48602083018561540f565b8181036040830152615c5a818461522a565b9050949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680615ca857607f821691505b602082108103615cbb57615cba615c64565b5b50919050565b5f819050815f5260205f209050919050565b5f8154615cdf81615c91565b615ce9818661521a565b9450600182165f8114615d035760018114615d1957615d4b565b60ff198316865281151560200286019350615d4b565b615d2285615cc1565b5f5b83811015615d4357815481890152600182019150602081019050615d24565b808801955050505b50505092915050565b5f819050919050565b5f819050919050565b5f615d80615d7b615d7684615d54565b615d5d565b615406565b9050919050565b615d9081615d66565b82525050565b5f60a0820190508181035f830152615dae8188615cd3565b9050615dbd602083018761508d565b615dca604083018661540f565b615dd7606083018561540f565b615de46080830184615d87565b9695505050505050565b7f4f6e6c79206f776e6572000000000000000000000000000000000000000000005f82015250565b5f615e22600a8361521a565b9150615e2d82615dee565b602082019050919050565b5f6020820190508181035f830152615e4f81615e16565b9050919050565b7f4d7573742073756d20746f2031303030300000000000000000000000000000005f82015250565b5f615e8a60118361521a565b9150615e9582615e56565b602082019050919050565b5f6020820190508181035f830152615eb781615e7e565b9050919050565b5f604082019050615ed15f83018561540f565b615ede602083018461540f565b9392505050565b5f81905092915050565b5f615ef9826150de565b615f038185615ee5565b9350615f138185602086016150f8565b80840191505092915050565b5f615f2a8284615eef565b915081905092915050565b7f4e6f7420616e206578746572696f72206d656d626572000000000000000000005f82015250565b5f615f6960168361521a565b9150615f7482615f35565b602082019050919050565b5f6020820190508181035f830152615f9681615f5d565b9050919050565b7f4d75737420626520612062756e646c65206d656d6265720000000000000000005f82015250565b5f615fd160178361521a565b9150615fdc82615f9d565b602082019050919050565b5f6020820190508181035f830152615ffe81615fc5565b9050919050565b7f5a6f6e65206f7574206f662072616e67650000000000000000000000000000005f82015250565b5f61603960118361521a565b915061604482616005565b602082019050919050565b5f6020820190508181035f8301526160668161602d565b9050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026160b77fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261607c565b6160c1868361607c565b95508019841693508086168417925050509392505050565b5f6160f36160ee6160e984615406565b615d5d565b615406565b9050919050565b5f819050919050565b61610c836160d9565b616120616118826160fa565b848454616088565b825550505050565b5f90565b616134616128565b61613f818484616103565b505050565b5b81811015616162576161575f8261612c565b600181019050616145565b5050565b601f8211156161a75761617881615cc1565b6161818461606d565b81016020851015616190578190505b6161a461619c8561606d565b830182616144565b50505b505050565b5f82821c905092915050565b5f6161c75f19846008026161ac565b1980831691505092915050565b5f6161df83836161b8565b9150826002028217905092915050565b6161f8826150de565b67ffffffffffffffff8111156162115761621061529b565b5b61621b8254615c91565b616226828285616166565b5f60209050601f831160018114616257575f8415616245578287015190505b61624f85826161d4565b8655506162b6565b601f19841661626586615cc1565b5f5b8281101561628c57848901518255600182019150602085019450602081019050616267565b868310156162a957848901516162a5601f8916826161b8565b8355505b6001600288020188555050505b505050505050565b5f6040820190508181035f8301526162d6818561522a565b90506162e5602083018461540f565b9392505050565b5f6080820190508181035f8301526163048187615cd3565b90508181036020830152616318818661522a565b9050616327604083018561540f565b616334606083018461540f565b95945050505050565b7f4e6f2061637469766520656c656374696f6e00000000000000000000000000005f82015250565b5f61637160128361521a565b915061637c8261633d565b602082019050919050565b5f6020820190508181035f83015261639e81616365565b9050919050565b7f416c726561647920636c61696d656400000000000000000000000000000000005f82015250565b5f6163d9600f8361521a565b91506163e4826163a5565b602082019050919050565b5f6020820190508181035f830152616406816163cd565b9050919050565b7f496e76616c69642062656e6566696369617279000000000000000000000000005f82015250565b5f61644160138361521a565b915061644c8261640d565b602082019050919050565b5f6020820190508181035f83015261646e81616435565b9050919050565b7f4e6f742061206d656d62657200000000000000000000000000000000000000005f82015250565b5f6164a9600c8361521a565b91506164b482616475565b602082019050919050565b5f6020820190508181035f8301526164d68161649d565b9050919050565b5f6080820190508181035f8301526164f58187615cd3565b90508181036020830152616509818661522a565b9050616518604083018561508d565b616525606083018461540f565b95945050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f815461656781615c91565b6165718186615ee5565b9450600182165f811461658b57600181146165a0576165d2565b60ff19831686528115158202860193506165d2565b6165a985615cc1565b5f5b838110156165ca578154818901526001820191506020810190506165ab565b838801955050505b50505092915050565b5f6165e6828461655b565b915081905092915050565b5f6165fb82615406565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361662d5761662c615b2d565b5b600182019050919050565b7f4e6f2063616e64696461746573000000000000000000000000000000000000005f82015250565b5f61666c600d8361521a565b915061667782616638565b602082019050919050565b5f6020820190508181035f83015261669981616660565b9050919050565b7f57696e6e6572206d757374206861766520636c61696d656420746f20726563655f8201527f697665206f776e65727368697000000000000000000000000000000000000000602082015250565b5f6166fa602d8361521a565b9150616705826166a0565b604082019050919050565b5f6020820190508181035f830152616727816166ee565b9050919050565b7f4d7573742062652061206d656d626572000000000000000000000000000000005f82015250565b5f61676260108361521a565b915061676d8261672e565b602082019050919050565b5f6020820190508181035f83015261678f81616756565b9050919050565b7f416c726561647920612063616e646964617465000000000000000000000000005f82015250565b5f6167ca60138361521a565b91506167d582616796565b602082019050919050565b5f6020820190508181035f8301526167f7816167be565b9050919050565b5f6060820190508181035f8301526168168186615cd3565b9050818103602083015261682a818561522a565b9050616839604083018461508d565b949350505050565b7f4172726179206c656e677468206d69736d6174636800000000000000000000005f82015250565b5f61687560158361521a565b915061688082616841565b602082019050919050565b5f6020820190508181035f8301526168a281616869565b9050919050565b7f55736572206d75737420626520612062756e646c65206d656d626572000000005f82015250565b5f6168dd601c8361521a565b91506168e8826168a9565b602082019050919050565b5f6020820190508181035f83015261690a816168d1565b9050919050565b7f50657263656e74616765206d75737420626520706f73697469766500000000005f82015250565b5f616945601b8361521a565b915061695082616911565b602082019050919050565b5f6020820190508181035f83015261697281616939565b9050919050565b7f50657263656e7461676573206d7573742073756d20746f2031303030300000005f82015250565b5f6169ad601d8361521a565b91506169b882616979565b602082019050919050565b5f6020820190508181035f8301526169da816169a1565b9050919050565b5f6040820190508181035f8301526169f98185615187565b90508181036020830152616a0d81846159d5565b90509392505050565b7f53746565706e657373206d7573742062652030203c2073203c203165313800005f82015250565b5f616a4a601e8361521a565b9150616a5582616a16565b602082019050919050565b5f6020820190508181035f830152616a7781616a3e565b9050919050565b7f566f746572206d7573742062652061206d656d626572000000000000000000005f82015250565b5f616ab260168361521a565b9150616abd82616a7e565b602082019050919050565b5f6020820190508181035f830152616adf81616aa6565b9050919050565b7f4e6f7420612076616c69642063616e64696461746500000000000000000000005f82015250565b5f616b1a60158361521a565b9150616b2582616ae6565b602082019050919050565b5f6020820190508181035f830152616b4781616b0e565b9050919050565b7f416c726561647920766f746564000000000000000000000000000000000000005f82015250565b5f616b82600d8361521a565b9150616b8d82616b4e565b602082019050919050565b5f6020820190508181035f830152616baf81616b76565b9050919050565b5f6040820190508181035f830152616bce818561522a565b90508181036020830152616be2818461522a565b90509392505050565b7f4469766973696f6e206279207a65726f000000000000000000000000000000005f82015250565b5f616c1f60108361521a565b9150616c2a82616beb565b602082019050919050565b5f6020820190508181035f830152616c4c81616c13565b9050919050565b5f616c5d82615406565b9150616c6883615406565b9250828202616c7681615406565b91508282048414831517616c8d57616c8c615b2d565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f616ccb82615406565b9150616cd683615406565b925082616ce657616ce5616c94565b5b828204905092915050565b5f81905092915050565b5f819050815f5260205f209050919050565b5f8154616d1981615c91565b616d238186616cf1565b9450600182165f8114616d3d5760018114616d5257616d84565b60ff1983168652811515820286019350616d84565b616d5b85616cfb565b5f5b83811015616d7c57815481890152600182019150602081019050616d5d565b838801955050505b50505092915050565b5f616d988284616d0d565b915081905092915050565b5f81549050616db181615c91565b9050919050565b5f819050815f5260205f209050919050565b818103616dd8575050616ead565b616de182616da3565b67ffffffffffffffff811115616dfa57616df961529b565b5b616e048254615c91565b616e0f828285616166565b5f601f831160018114616e3c575f8415616e2a578287015490505b616e3485826161d4565b865550616ea6565b601f198416616e4a87616db8565b9650616e5586615cc1565b5f5b82811015616e7c57848901548255600182019150600185019450602081019050616e57565b86831015616e995784890154616e95601f8916826161b8565b8355505b6001600288020188555050505b5050505050505b565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603160045260245ffd5b50565b5f616eea5f83616cf1565b9150616ef582616edc565b5f82019050919050565b5f616f0982616edf565b9150819050919050565b7f45544820636c61696d206661696c6564000000000000000000000000000000005f82015250565b5f616f4760108361521a565b9150616f5282616f13565b602082019050919050565b5f6020820190508181035f830152616f7481616f3b565b9050919050565b7f455448207472616e73666572206661696c6564000000000000000000000000005f82015250565b5f616faf60138361521a565b9150616fba82616f7b565b602082019050919050565b5f6020820190508181035f830152616fdc81616fa3565b9050919050565b5f606082019050616ff65f83018661540f565b6170036020830185615614565b8181036040830152617015818461522a565b9050949350505050565b5f60a0820190508181035f8301526170378188615cd3565b9050818103602083015261704b818761522a565b905061705a604083018661508d565b617067606083018561540f565b8181036080830152617079818461522a565b9050969550505050505056fea2646970667358221220e61ca743da8bf74312a4d4f6b348b3282428098da8234b281a8987056df9bb6364736f6c63430008140033";
|
|
24538
|
+
const BundleABI = {
|
|
24539
|
+
abi,
|
|
24540
|
+
bytecode
|
|
24541
|
+
};
|
|
24003
24542
|
const HolonsABI = [
|
|
24004
24543
|
{
|
|
24005
24544
|
type: "function",
|
|
@@ -25407,7 +25946,7 @@ class ContractDeployer {
|
|
|
25407
25946
|
*/
|
|
25408
25947
|
async _loadEthers() {
|
|
25409
25948
|
if (!this.ethers) {
|
|
25410
|
-
this.ethers = await import("./index-
|
|
25949
|
+
this.ethers = await import("./index-JFz-dW43.js");
|
|
25411
25950
|
}
|
|
25412
25951
|
return this.ethers;
|
|
25413
25952
|
}
|
|
@@ -25615,6 +26154,7 @@ class ContractDeployer {
|
|
|
25615
26154
|
}
|
|
25616
26155
|
/**
|
|
25617
26156
|
* Deploy a Bundle contract (2-way split with steepness)
|
|
26157
|
+
* This is the simplest way to deploy a holon - no registry needed!
|
|
25618
26158
|
* @param {string} name - Contract name
|
|
25619
26159
|
* @param {number} [steepness=500000000000000000n] - Steepness factor (0.5e18 = 50% decay)
|
|
25620
26160
|
* @param {number} [nZones=6] - Number of zones
|
|
@@ -25627,18 +26167,41 @@ class ContractDeployer {
|
|
|
25627
26167
|
const deployerAddress = await signer.getAddress();
|
|
25628
26168
|
const creatorUserId = options.creatorUserId || "creator";
|
|
25629
26169
|
const steepnessValue = steepness || ethers.parseEther("0.5");
|
|
26170
|
+
const abi2 = BundleABI.abi || BundleABI;
|
|
26171
|
+
const bytecode2 = BundleABI.bytecode;
|
|
26172
|
+
if (!bytecode2) {
|
|
26173
|
+
throw new Error("Bundle bytecode not available. Please rebuild contracts.");
|
|
26174
|
+
}
|
|
25630
26175
|
const result = await this._deployContract(
|
|
25631
|
-
|
|
25632
|
-
|
|
26176
|
+
abi2,
|
|
26177
|
+
bytecode2,
|
|
25633
26178
|
[deployerAddress, creatorUserId, name2, steepnessValue, nZones]
|
|
25634
26179
|
);
|
|
25635
26180
|
return {
|
|
25636
26181
|
...result,
|
|
25637
26182
|
type: "Bundle",
|
|
25638
26183
|
steepness: steepnessValue,
|
|
25639
|
-
nZones
|
|
26184
|
+
nZones,
|
|
26185
|
+
creatorUserId,
|
|
26186
|
+
name: name2
|
|
25640
26187
|
};
|
|
25641
26188
|
}
|
|
26189
|
+
/**
|
|
26190
|
+
* Deploy a Bundle contract directly (simplified 1-click deployment)
|
|
26191
|
+
* No registry needed - just deploys and returns the address
|
|
26192
|
+
* @param {string} holonId - Unique identifier for the holon
|
|
26193
|
+
* @param {string} name - Display name for the holon
|
|
26194
|
+
* @param {Object} [options] - Options { steepness, nZones }
|
|
26195
|
+
* @returns {Promise<{address, txHash, contract}>}
|
|
26196
|
+
*/
|
|
26197
|
+
async deployBundleDirect(holonId, name2, options = {}) {
|
|
26198
|
+
const steepness = options.steepness;
|
|
26199
|
+
const nZones = options.nZones || 6;
|
|
26200
|
+
return this.deployBundle(name2, steepness, nZones, {
|
|
26201
|
+
creatorUserId: holonId,
|
|
26202
|
+
...options
|
|
26203
|
+
});
|
|
26204
|
+
}
|
|
25642
26205
|
/**
|
|
25643
26206
|
* Deploy a TestToken (ERC20 for testing)
|
|
25644
26207
|
* @param {string} [initialSupply='1000000'] - Initial supply in whole tokens
|
|
@@ -25698,11 +26261,11 @@ class ContractDeployer {
|
|
|
25698
26261
|
* @returns {Promise<Contract>}
|
|
25699
26262
|
*/
|
|
25700
26263
|
async getContract(address, type2) {
|
|
25701
|
-
const
|
|
25702
|
-
if (!
|
|
26264
|
+
const abi2 = ABIs[type2];
|
|
26265
|
+
if (!abi2) {
|
|
25703
26266
|
throw new Error(`Unknown contract type: ${type2}`);
|
|
25704
26267
|
}
|
|
25705
|
-
return this.chainManager.getContract(address,
|
|
26268
|
+
return this.chainManager.getContract(address, abi2.abi);
|
|
25706
26269
|
}
|
|
25707
26270
|
/**
|
|
25708
26271
|
* Get deployed contract addresses
|
|
@@ -25722,8 +26285,8 @@ class ContractDeployer {
|
|
|
25722
26285
|
* Internal: Deploy a contract
|
|
25723
26286
|
* @private
|
|
25724
26287
|
*/
|
|
25725
|
-
async _deployContract(
|
|
25726
|
-
const result = await this.chainManager.deployContract(
|
|
26288
|
+
async _deployContract(abi2, bytecode2, constructorArgs) {
|
|
26289
|
+
const result = await this.chainManager.deployContract(abi2, bytecode2, constructorArgs);
|
|
25727
26290
|
return {
|
|
25728
26291
|
contract: result.contract,
|
|
25729
26292
|
address: result.address,
|
|
@@ -25745,7 +26308,7 @@ class ContractOperations {
|
|
|
25745
26308
|
*/
|
|
25746
26309
|
async _loadEthers() {
|
|
25747
26310
|
if (!this.ethers) {
|
|
25748
|
-
this.ethers = await import("./index-
|
|
26311
|
+
this.ethers = await import("./index-JFz-dW43.js");
|
|
25749
26312
|
}
|
|
25750
26313
|
return this.ethers;
|
|
25751
26314
|
}
|
|
@@ -26420,11 +26983,11 @@ class HolonContracts {
|
|
|
26420
26983
|
if (this.holonContracts.has(holonId)) {
|
|
26421
26984
|
throw new Error(`Holon ${holonId} already has a contract. Use unlink() first.`);
|
|
26422
26985
|
}
|
|
26423
|
-
const
|
|
26424
|
-
if (!
|
|
26986
|
+
const abi2 = ABIs[type2];
|
|
26987
|
+
if (!abi2) {
|
|
26425
26988
|
throw new Error(`Unknown contract type: ${type2}`);
|
|
26426
26989
|
}
|
|
26427
|
-
const contract = await this.chainManager.getContract(contractAddress,
|
|
26990
|
+
const contract = await this.chainManager.getContract(contractAddress, abi2.abi);
|
|
26428
26991
|
try {
|
|
26429
26992
|
await contract.name();
|
|
26430
26993
|
} catch (error) {
|
|
@@ -26555,9 +27118,9 @@ class HolonContracts {
|
|
|
26555
27118
|
try {
|
|
26556
27119
|
const data = await this.storage.get?.(`holon_contract:${holonId}`);
|
|
26557
27120
|
if (data && data.address && data.type) {
|
|
26558
|
-
const
|
|
26559
|
-
if (
|
|
26560
|
-
const contract = await this.chainManager.getContract(data.address,
|
|
27121
|
+
const abi2 = ABIs[data.type];
|
|
27122
|
+
if (abi2) {
|
|
27123
|
+
const contract = await this.chainManager.getContract(data.address, abi2.abi);
|
|
26561
27124
|
const operations = new ContractOperations(contract, data.type, this.chainManager);
|
|
26562
27125
|
this.holonContracts.set(holonId, {
|
|
26563
27126
|
...data,
|
|
@@ -31861,17 +32424,17 @@ class Interface {
|
|
|
31861
32424
|
* Create a new Interface for the %%fragments%%.
|
|
31862
32425
|
*/
|
|
31863
32426
|
constructor(fragments) {
|
|
31864
|
-
let
|
|
32427
|
+
let abi2 = [];
|
|
31865
32428
|
if (typeof fragments === "string") {
|
|
31866
|
-
|
|
32429
|
+
abi2 = JSON.parse(fragments);
|
|
31867
32430
|
} else {
|
|
31868
|
-
|
|
32431
|
+
abi2 = fragments;
|
|
31869
32432
|
}
|
|
31870
32433
|
this.#functions = /* @__PURE__ */ new Map();
|
|
31871
32434
|
this.#errors = /* @__PURE__ */ new Map();
|
|
31872
32435
|
this.#events = /* @__PURE__ */ new Map();
|
|
31873
32436
|
const frags = [];
|
|
31874
|
-
for (const a of
|
|
32437
|
+
for (const a of abi2) {
|
|
31875
32438
|
try {
|
|
31876
32439
|
frags.push(Fragment.from(a));
|
|
31877
32440
|
} catch (error) {
|
|
@@ -31935,16 +32498,16 @@ class Interface {
|
|
|
31935
32498
|
*/
|
|
31936
32499
|
format(minimal) {
|
|
31937
32500
|
const format = minimal ? "minimal" : "full";
|
|
31938
|
-
const
|
|
31939
|
-
return
|
|
32501
|
+
const abi2 = this.fragments.map((f) => f.format(format));
|
|
32502
|
+
return abi2;
|
|
31940
32503
|
}
|
|
31941
32504
|
/**
|
|
31942
32505
|
* Return the JSON-encoded ABI. This is the format Solidiy
|
|
31943
32506
|
* returns.
|
|
31944
32507
|
*/
|
|
31945
32508
|
formatJson() {
|
|
31946
|
-
const
|
|
31947
|
-
return JSON.stringify(
|
|
32509
|
+
const abi2 = this.fragments.map((f) => f.format("json"));
|
|
32510
|
+
return JSON.stringify(abi2.map((j) => JSON.parse(j)));
|
|
31948
32511
|
}
|
|
31949
32512
|
/**
|
|
31950
32513
|
* The ABI coder that will be used to encode and decode binary
|
|
@@ -34598,12 +35161,12 @@ class BaseContract {
|
|
|
34598
35161
|
* optionally connected to a %%runner%% to perform operations on behalf
|
|
34599
35162
|
* of.
|
|
34600
35163
|
*/
|
|
34601
|
-
constructor(target,
|
|
35164
|
+
constructor(target, abi2, runner, _deployTx) {
|
|
34602
35165
|
assertArgument(typeof target === "string" || isAddressable(target), "invalid value for Contract target", "target", target);
|
|
34603
35166
|
if (runner == null) {
|
|
34604
35167
|
runner = null;
|
|
34605
35168
|
}
|
|
34606
|
-
const iface = Interface.from(
|
|
35169
|
+
const iface = Interface.from(abi2);
|
|
34607
35170
|
defineProperties(this, { target, runner, interface: iface });
|
|
34608
35171
|
Object.defineProperty(this, internal, { value: {} });
|
|
34609
35172
|
let addrPromise;
|
|
@@ -34966,10 +35529,10 @@ class BaseContract {
|
|
|
34966
35529
|
/**
|
|
34967
35530
|
* Create a new Class for the %%abi%%.
|
|
34968
35531
|
*/
|
|
34969
|
-
static buildClass(
|
|
35532
|
+
static buildClass(abi2) {
|
|
34970
35533
|
class CustomContract extends BaseContract {
|
|
34971
35534
|
constructor(address, runner = null) {
|
|
34972
|
-
super(address,
|
|
35535
|
+
super(address, abi2, runner);
|
|
34973
35536
|
}
|
|
34974
35537
|
}
|
|
34975
35538
|
return CustomContract;
|
|
@@ -34977,11 +35540,11 @@ class BaseContract {
|
|
|
34977
35540
|
/**
|
|
34978
35541
|
* Create a new BaseContract with a specified Interface.
|
|
34979
35542
|
*/
|
|
34980
|
-
static from(target,
|
|
35543
|
+
static from(target, abi2, runner) {
|
|
34981
35544
|
if (runner == null) {
|
|
34982
35545
|
runner = null;
|
|
34983
35546
|
}
|
|
34984
|
-
const contract = new this(target,
|
|
35547
|
+
const contract = new this(target, abi2, runner);
|
|
34985
35548
|
return contract;
|
|
34986
35549
|
}
|
|
34987
35550
|
}
|
|
@@ -35016,11 +35579,11 @@ class ContractQueries {
|
|
|
35016
35579
|
* @returns {ethers.Contract}
|
|
35017
35580
|
*/
|
|
35018
35581
|
getContract(address, flavor) {
|
|
35019
|
-
const
|
|
35020
|
-
if (!
|
|
35582
|
+
const abi2 = ContractABIs[flavor];
|
|
35583
|
+
if (!abi2) {
|
|
35021
35584
|
throw new Error(`Unknown contract flavor: ${flavor}`);
|
|
35022
35585
|
}
|
|
35023
|
-
return new Contract(address,
|
|
35586
|
+
return new Contract(address, abi2, this.provider);
|
|
35024
35587
|
}
|
|
35025
35588
|
/**
|
|
35026
35589
|
* Auto-detect contract flavor by calling flavor()
|
|
@@ -36993,6 +37556,7 @@ class HoloSphereBase extends HoloSphere$1 {
|
|
|
36993
37556
|
if (!Array.isArray(data.inbound)) data.inbound = [];
|
|
36994
37557
|
if (!Array.isArray(data.outbound)) data.outbound = [];
|
|
36995
37558
|
if (!data.lensConfig || typeof data.lensConfig !== "object") data.lensConfig = {};
|
|
37559
|
+
if (!data.partnerNames || typeof data.partnerNames !== "object") data.partnerNames = {};
|
|
36996
37560
|
if (!Array.isArray(data.federated)) {
|
|
36997
37561
|
const allFederated = /* @__PURE__ */ new Set([...data.inbound, ...data.outbound]);
|
|
36998
37562
|
data.federated = Array.from(allFederated);
|
|
@@ -37000,7 +37564,7 @@ class HoloSphereBase extends HoloSphere$1 {
|
|
|
37000
37564
|
return data;
|
|
37001
37565
|
}
|
|
37002
37566
|
async federateHolon(sourceHolon, targetHolon, options = {}) {
|
|
37003
|
-
const { lensConfig = { inbound: [], outbound: [] } } = options;
|
|
37567
|
+
const { lensConfig = { inbound: [], outbound: [] }, partnerName = null } = options;
|
|
37004
37568
|
if (sourceHolon === targetHolon) {
|
|
37005
37569
|
throw new Error("Cannot federate a holon with itself");
|
|
37006
37570
|
}
|
|
@@ -37011,15 +37575,20 @@ class HoloSphereBase extends HoloSphere$1 {
|
|
|
37011
37575
|
inbound: [],
|
|
37012
37576
|
outbound: [],
|
|
37013
37577
|
lensConfig: {},
|
|
37578
|
+
partnerNames: {},
|
|
37014
37579
|
timestamp: Date.now()
|
|
37015
37580
|
};
|
|
37016
37581
|
if (!Array.isArray(federationData.federated)) federationData.federated = [];
|
|
37017
37582
|
if (!Array.isArray(federationData.inbound)) federationData.inbound = [];
|
|
37018
37583
|
if (!Array.isArray(federationData.outbound)) federationData.outbound = [];
|
|
37019
37584
|
if (!federationData.lensConfig || typeof federationData.lensConfig !== "object") federationData.lensConfig = {};
|
|
37585
|
+
if (!federationData.partnerNames || typeof federationData.partnerNames !== "object") federationData.partnerNames = {};
|
|
37020
37586
|
if (!federationData.federated.includes(targetHolon)) {
|
|
37021
37587
|
federationData.federated.push(targetHolon);
|
|
37022
37588
|
}
|
|
37589
|
+
if (partnerName) {
|
|
37590
|
+
federationData.partnerNames[targetHolon] = partnerName;
|
|
37591
|
+
}
|
|
37023
37592
|
if (lensConfig.outbound && lensConfig.outbound.length > 0) {
|
|
37024
37593
|
if (!federationData.outbound.includes(targetHolon)) {
|
|
37025
37594
|
federationData.outbound.push(targetHolon);
|
|
@@ -37420,4 +37989,4 @@ export {
|
|
|
37420
37989
|
exists as y,
|
|
37421
37990
|
bytes as z
|
|
37422
37991
|
};
|
|
37423
|
-
//# sourceMappingURL=index-
|
|
37992
|
+
//# sourceMappingURL=index-NOravBLu.js.map
|